Skip to content

Commit

Permalink
Added separation between LoRaWAN and application layer
Browse files Browse the repository at this point in the history
  • Loading branch information
matthias-bs committed Apr 14, 2024
1 parent 74f7912 commit cfb0f4f
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 222 deletions.
33 changes: 14 additions & 19 deletions BresserWeatherSensorLW.ino
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ using namespace PowerFeather;
#include <RadioLib.h>
#include <ESP32Time.h>
#include "BresserWeatherSensorLWCfg.h"
#include "src/payload.h"
#include "src/AppLayer.h"
#include "src/adc/adc.h"

// Time zone info
Expand Down Expand Up @@ -198,6 +198,9 @@ bool rtcSyncReq = false;
/// Real time clock
ESP32Time rtc;

/// Application layer
AppLayer appLayer(&rtc, &rtcLastClockSync);

#if defined(ESP32)
// abbreviated version from the Arduino-ESP32 package, see
// https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/deepsleep.html
Expand Down Expand Up @@ -334,10 +337,10 @@ void decodeDownlink(uint8_t port, uint8_t *payload, size_t size)
log_d("Get date/time");
uplinkReq = CMD_GET_DATETIME;
}
else if ((payload[0] == CMD_GET_CONFIG) && (size == 1))
else if ((payload[0] == CMD_GET_LW_CONFIG) && (size == 1))
{
log_d("Get config");
uplinkReq = CMD_GET_CONFIG;
uplinkReq = CMD_GET_LW_CONFIG;
}
else if ((payload[0] == CMD_SET_DATETIME) && (size == 5))
{
Expand Down Expand Up @@ -370,7 +373,7 @@ void decodeDownlink(uint8_t port, uint8_t *payload, size_t size)
preferences.putUShort("sleep_int_long", prefs.sleep_interval_long);
preferences.end();
} else {
uplinkReq = decodeDownlinkApp(payload, size);
uplinkReq = appLayer.decodeDownlink(payload, size);
}
}
if (uplinkReq == 0)
Expand All @@ -394,7 +397,7 @@ void sendCfgUplink(void)
if (uplinkReq == CMD_GET_DATETIME)
{
log_d("Date/Time");
port = 2;
port = CMD_GET_DATETIME;
time_t t_now = rtc.getLocalEpoch();
encoder.writeUint8((t_now >> 24) & 0xff);
encoder.writeUint8((t_now >> 16) & 0xff);
Expand All @@ -414,20 +417,18 @@ void sendCfgUplink(void)
// TODO add flags for succesful LORA time sync/manual sync
encoder.writeUint8((rtcSyncReq) ? 0x03 : 0x02);
}
else if (uplinkReq)
else if (uplinkReq == CMD_GET_LW_CONFIG)
{
log_d("Config");
port = 3;
encoder.writeUint8(prefs.ws_timeout);
log_d("LoRaWAN Config");
port = CMD_GET_LW_CONFIG;
encoder.writeUint8(prefs.sleep_interval >> 8);
encoder.writeUint8(prefs.sleep_interval & 0xFF);
encoder.writeUint8(prefs.sleep_interval_long >> 8);
encoder.writeUint8(prefs.sleep_interval_long & 0xFF);
}
else
{
log_v("");
return;
appLayer.getConfigPayload(uplinkReq, port, encoder);
}
log_v("Configuration uplink: port=%d, size=%d", port, encoder.getLength());

Expand Down Expand Up @@ -505,8 +506,6 @@ void setup()
printDateTime();

preferences.begin("BWS-LW", false);
prefs.ws_timeout = preferences.getUChar("ws_timeout", WEATHERSENSOR_TIMEOUT);
log_d("Preferences: weathersensor_timeout: %u s", prefs.ws_timeout);
prefs.sleep_interval = preferences.getUShort("sleep_int", SLEEP_INTERVAL);
log_d("Preferences: sleep_interval: %u s", prefs.sleep_interval);
prefs.sleep_interval_long = preferences.getUShort("sleep_int_long", SLEEP_INTERVAL_LONG);
Expand Down Expand Up @@ -535,7 +534,7 @@ void setup()
rtcSyncReq,
runtimeExpired);

getPayloadStage1(1, encoder);
appLayer.getPayloadStage1(1, encoder);

int16_t state = 0; // return value for calls to RadioLib

Expand Down Expand Up @@ -658,12 +657,9 @@ void setup()
// ----- and now for the main event -----
log_i("Sending uplink");

// read some inputs
// uint8_t Digital2 = digitalRead(2);
// uint16_t Analog1 = analogRead(A1);

// get payload immediately before uplink - not used here
getPayloadStage2(1, encoder);
appLayer.getPayloadStage2(1, encoder);

uint8_t port = 1;
uint8_t downlinkPayload[MAX_DOWNLINK_SIZE]; // Make sure this fits your plans!
Expand Down Expand Up @@ -691,7 +687,6 @@ void setup()
log_i("Downlink data: ");
arrayDump(downlinkPayload, downlinkSize);
decodeDownlink(downlinkDetails.port, downlinkPayload, downlinkSize);
deviceDecodeDownlink(downlinkDetails.port, downlinkPayload, downlinkSize);
}
else
{
Expand Down
133 changes: 32 additions & 101 deletions src/payload.cpp → src/AppLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,103 +42,44 @@
//
///////////////////////////////////////////////////////////////////////////////

#include "payload.h"
#include "WeatherSensorCfg.h"
#include <WeatherSensor.h>
#include <ESP32Time.h>
#include <Preferences.h>
#include "../BresserWeatherSensorLWCfg.h"
#include "adc/adc.h"
#include "AppLayer.h"

#if defined(MITHERMOMETER_EN)
// BLE Temperature/Humidity Sensor
#include <ATC_MiThermometer.h>
#endif
#if defined(THEENGSDECODER_EN)
#include "BleSensors/BleSensors.h"
#endif
#ifdef RAINDATA_EN
#include "RainGauge.h"
#endif
#ifdef LIGHTNINGSENSOR_EN
#include "Lightning.h"
#endif
#ifdef ONEWIRE_EN
// Dallas/Maxim OneWire Temperature Sensor
#include <DallasTemperature.h>
#endif
#ifdef DISTANCESENSOR_EN
// A02YYUW / DFRobot SEN0311 Ultrasonic Distance Sensor
#include <DistanceSensor_A02YYUW.h>
#endif

extern time_t rtcLastClockSync;
extern ESP32Time rtc;

/// Preferences (stored in flash memory)
static Preferences appPrefs;

/// Bresser Weather Sensor Receiver
WeatherSensor weatherSensor;

#if defined(MITHERMOMETER_EN) || defined(THEENGSDECODER_EN)
std::vector<std::string> knownBLEAddresses = KNOWN_BLE_ADDRESSES;
#endif

#ifdef MITHERMOMETER_EN
// Setup BLE Temperature/Humidity Sensors
ATC_MiThermometer bleSensors(knownBLEAddresses); //!< Mijia Bluetooth Low Energy Thermo-/Hygrometer
#endif
#ifdef THEENGSDECODER_EN
BleSensors bleSensors(knownBLEAddresses);
#endif

#ifdef RAINDATA_EN
/// Rain data statistics
RainGauge rainGauge;
#endif

#ifdef LIGHTNINGSENSOR_EN
/// Lightning sensor post-processing
Lightning lightningProc;
#endif

#ifdef ONEWIRE_EN
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(PIN_ONEWIRE_BUS); //!< OneWire bus

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature temp_sensors(&oneWire); //!< Dallas temperature sensors connected to OneWire bus
#endif

#ifdef DISTANCESENSOR_EN
#if defined(ESP32)
DistanceSensor_A02YYUW distanceSensor(&Serial2);
#else
DistanceSensor_A02YYUW distanceSensor(&Serial1);
#endif
#endif

uint8_t decodeDownlinkApp(uint8_t *payload, size_t size)
uint8_t
AppLayer::decodeDownlink(uint8_t *payload, size_t size)
{
if ((payload[0] == CMD_SET_WEATHERSENSOR_TIMEOUT) && (size == 2))
if (payload[0] == CMD_RESET_RAINGAUGE)
{
if (size == 1)
{
log_d("Reset raingauge");
rainGauge.reset();
}
else if (size == 2)
{
log_d("Reset raingauge - flags: 0x%X", payload[1]);
rainGauge.reset(payload[1] & 0xF);
}
}
else if ((payload[0] == CMD_SET_WS_TIMEOUT) && (size == 2))
{
log_d("Set weathersensor_timeout: %u s", payload[1]);
appPrefs.begin("BWS-LW-APP", false);
appPrefs.putUChar("ws_timeout", payload[1]);
appPrefs.end();
}
return 0;
}

void genPayload(uint8_t port, LoraEncoder &encoder)
void AppLayer::genPayload(uint8_t port, LoraEncoder &encoder)
{
// unused
(void)port;
weatherSensor.genMessage(0, 0xfff0, SENSOR_TYPE_WEATHER1);
weatherSensor.genMessage(1, 0xfff1, SENSOR_TYPE_SOIL);
}

void getPayloadStage1(uint8_t port, LoraEncoder &encoder)
void AppLayer::getPayloadStage1(uint8_t port, LoraEncoder &encoder)
{
#ifdef PIN_SUPPLY_IN
uint16_t supply_voltage = getVoltage(PIN_SUPPLY_IN, SUPPLY_SAMPLES, SUPPLY_DIV);
Expand Down Expand Up @@ -178,11 +119,11 @@ void getPayloadStage1(uint8_t port, LoraEncoder &encoder)

#ifdef RAINDATA_EN
// Check if time is valid
if (rtcLastClockSync > 0)
if (*rtcLastClockSync > 0)
{
// Get local date and time
struct tm timeinfo;
time_t tnow = rtc.getLocalEpoch();
time_t tnow = rtc->getLocalEpoch();
localtime_r(&tnow, &timeinfo);

// Find weather sensor and determine rain gauge overflow limit
Expand All @@ -209,10 +150,10 @@ void getPayloadStage1(uint8_t port, LoraEncoder &encoder)

#ifdef LIGHTNINGSENSOR_EN
// Check if time is valid
if (rtcLastClockSync > 0)
if (*rtcLastClockSync > 0)
{
// Get local date and time
time_t tnow = rtc.getLocalEpoch();
time_t tnow = rtc->getLocalEpoch();

// Find lightning sensor
int ls = weatherSensor.findType(SENSOR_TYPE_LIGHTNING);
Expand Down Expand Up @@ -542,28 +483,18 @@ void getPayloadStage1(uint8_t port, LoraEncoder &encoder)
}
}

void getPayloadStage2(uint8_t port, LoraEncoder &encoder)
void AppLayer::getPayloadStage2(uint8_t port, LoraEncoder &encoder)
{
}

void deviceDecodeDownlink(uint8_t port, uint8_t *payload, size_t size)
void AppLayer::getConfigPayload(uint8_t cmd, uint8_t &port, LoraEncoder &encoder)
{
#ifdef RAINDATA_EN
if (port > 0)
if (cmd == CMD_GET_WS_TIMEOUT)
{
if (payload[0] == CMD_RESET_RAINGAUGE)
{
if (size == 1)
{
log_d("Reset raingauge");
rainGauge.reset();
}
else if (size == 2)
{
log_d("Reset raingauge - flags: 0x%X", payload[1]);
rainGauge.reset(payload[1] & 0xF);
}
}
appPrefs.begin("BWS-LW-APP", false);
uint8_t ws_timeout = appPrefs.getUChar("ws_timeout", WEATHERSENSOR_TIMEOUT);
appPrefs.end();
encoder.writeUint8(ws_timeout);
port = CMD_GET_WS_TIMEOUT;
}
#endif
}
Loading

0 comments on commit cfb0f4f

Please sign in to comment.