Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added configuration of BLE scan parameters via LoRaWAN #17

Merged
merged 16 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BresserWeatherSensorLW.ino
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ void setup()
// or whatever is interfering with the device <-> gateway airwaves.
uint32_t sleepForSeconds = min((bootCountSinceUnsuccessfulJoin++ + 1UL) * 60UL, 3UL * 60UL);
log_i("Boots since unsuccessful join: %u", bootCountSinceUnsuccessfulJoin);
log_i("Retrying join in %u seconds", sleepForSeconds);
log_i("Retrying join in %u seconds", (unsigned int)sleepForSeconds);

gotoSleep(sleepForSeconds);
}
Expand Down
48 changes: 38 additions & 10 deletions BresserWeatherSensorLWCfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
// 20240410 Removed obsolete defines
// 20240413 Refactored ADC handling
// 20240423 Added define ARDUINO_heltec_wifi_lora_32_V3
// 20240427 Added BLE configuration/status via LoRaWAN
//
// Note:
// Depending on board package file date, either
Expand Down Expand Up @@ -113,8 +114,8 @@
#define CMD_SET_SLEEP_INTERVAL_LONG 0xA9

// Downlink (command):
// byte1: sleep_interval_long[15:8]
// byte2: sleep_interval_long[ 7:0]
// byte0: sleep_interval_long[15:8]
// byte1: sleep_interval_long[ 7:0]

// Uplink: n.a.

Expand Down Expand Up @@ -143,7 +144,7 @@
#define CMD_GET_WS_TIMEOUT 0xC0

// Downlink (command)
// byte0:
// byte0: 0x00

// Uplink (response):
// byte0: ws_timeout[ 7: 0]
Expand Down Expand Up @@ -259,17 +260,42 @@
// Port: CMD_SET_BLE_ADDR
#define CMD_SET_BLE_ADDR 0xC9

// Uplink (command):
// byte1: ble_addr0[47:24]
// byte2: ble_addr0[23:32]
// byte3: ble_addr0[31:24]
// byte4: ble_addr0[23:16]
// byte5: ble_addr0[15: 8]
// byte6: ble_addr0[ 7: 0]
// Downlink (command):
// byte0: ble_addr0[47:24]
// byte1: ble_addr0[23:32]
// byte2: ble_addr0[31:24]
// byte3: ble_addr0[23:16]
// byte4: ble_addr0[15: 8]
// byte5: ble_addr0[ 7: 0]
// ...

// Response: n.a.

// CMD_GET_BLE_CONFIG
// -------------------
// Note: Scan time in seconds
// Port: CMD_GET_BLE_CONFIG
#define CMD_GET_BLE_CONFIG 0xCA

// Downlink (command):
// byte0: 0x00

// Uplink (response):
// byte0: 0x01 (active scan) / 0x00 (passive scan)
// byte1: scan_time[7:0]

// CMD_SET_BLE_CONFIG
// -------------------
// Note: Scan time in seconds
// Port: CMD_SET_BLE_CONFIG
#define CMD_SET_BLE_CONFIG 0xCB

// Uplink (command):
// byte0: active_scan - 0x01 (active scan) / 0x00 (passive scan)
// byte1: scan_time[7:0]

// Response: n.a.

// ===========================


Expand Down Expand Up @@ -474,6 +500,8 @@ const uint8_t UBATT_SAMPLES = 10;
#if defined(MITHERMOMETER_EN) || defined(THEENGSDECODER_EN)
// BLE scan time in seconds
#define BLE_SCAN_TIME 31
// BLE scan mode (0: passive / 1: active)
#define BLE_SCAN_MODE 1

// List of known sensors' BLE addresses
#define KNOWN_BLE_ADDRESSES \
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ Meanwhile, refer to [BresserWeatherSensorTTN - README.md](https://github.com/mat
| <rtc_source> | Real time clock source; 0x00: GPS / 0x01: RTC / 0x02: LORA / 0x03: unsynched / 0x04: set (source unknown) |
| <sensors_incX> | Bresser sensor IDs include list; e.g. "0xDEADBEEF"; "0x00000000" => empty list => default values |
| <sensors_excX> | Bresser sensor IDs include list; e.g. "0xDEADBEEF"; "0x00000000" => empty list => default values |
| <ble_active> | BLE active scan; 1 (active scan) / 0 (passive scan) |
| <ble_scantime> | BLE scan time in seconds; 0...255 |
| <ble_addrX> | BLE sensor MAC addresses; e.g. "DE:AD:BE:EF:12:23" |

> [!WARNING]
Expand Down Expand Up @@ -149,6 +151,8 @@ Meanwhile, refer to [BresserWeatherSensorTTN - README.md](https://github.com/mat
| CMD_SET_SENSORS_EXC | 0xC7 (199) | sensors_exc0[31:24]<br>sensors_exc0[23:15]<br>sensors_exc0[16:8]<br>sensors_exc0[7:0]<br>... | n.a. |
| CMD_GET_BLE_ADDR | 0xC8 (200) | 0x00 | ble_addr0[47:40]<br>ble_addr0[39:32]<br>ble_addr0[31:24]<br>ble_addr0[23:15]<br>ble_addr0[16:8]<br>ble_addr0[7:0]<br>... |
| CMD_SET_BLE_ADDR | 0xC9 (201) | ble_addr0[47:40]<br>ble_addr0[39:32]<br>ble_addr0[31:24]<br>ble_addr0[23:15]<br>ble_addr0[16:8]<br>ble_addr0[7:0]<br>... | n.a. |
| CMD_GET_BLE_CONFIG | 0xCA (202) | 0x00 | ble_active[7:0]<br>ble_scantime[7:0] |
| CMD_SET_BLE_CONFIG | 0xCB (203) | ble_active[7:0]<br>ble_scantime[7:0] | n.a. |

### Using the Javascript Uplink/Downlink Formatters

Expand All @@ -168,4 +172,5 @@ Meanwhile, refer to [BresserWeatherSensorTTN - README.md](https://github.com/mat
| CMD_SET_SENSORS_EXC | {"sensors_exc": [<sensors_exc0>, ..., <sensors_excN>]} | n.a. |
| CMD_GET_BLE_ADDR | {"cmd": "CMD_GET_BLE_ADDR"} | {"ble_addr": [<ble_addr0>, ..., <ble_addrN>]} |
| CMD_SET_BLE_ADDR | {"ble_addr": [<ble_addr0>, ..., <ble_addrN>]} | n.a. |

| CMD_GET_BLE_CONFIG | {"cmd": "CMD_GET_BLE_CONFIG"} | {"ble_active": <ble_active>, "ble_scantime": <ble_scantime>} |
| CMD_SET_BLE_CONFIG | {"ble_active": <ble_active>, "ble_scantime": <ble_scantime>} | n.a. |
33 changes: 33 additions & 0 deletions scripts/downlink_formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
// port = CMD_SET_SENSORS_EXC, {"sensors_exc": [<sensors_exc0>, ..., <sensors_excN>]}
// port = CMD_GET_BLE_ADDR, {"cmd": "CMD_GET_BLE_ADDR"} / payload = 0x00
// port = CMD_SET_BLE_ADDR, {"ble_addr": [<ble_addr0>, ..., <ble_addrN>]}
// port = CMD_GET_BLE_CONFIG, {"cmd": "CMD_GET_BLE_CONFIG"} / payload = 0x00
// port = CMD_SET_BLE_CONFIG, {"ble_active": <ble_active>, "ble_scantime": <ble_scantime>}
//
// Responses:
// -----------
Expand All @@ -44,6 +46,8 @@
//
// CMD_GET_BLE_ADDR {"ble_addr": [<ble_addr0>, ...]}
//
// CMD_GET_BLE_CONFIG {"ble_active": <ble_active>, "ble_scantime": <ble_scantime>}
//
// <ws_timeout> : 0...255
// <sleep_interval> : 0...65535
// <sleep_interval> : 0...65535
Expand All @@ -52,6 +56,8 @@
// <rtc_source> : 0x00: GPS / 0x01: RTC / 0x02: LORA / 0x03: unsynched / 0x04: set (source unknown)
// <sensors_incN> : e.g. "0xDEADBEEF"
// <sensors_excN> : e.g. "0xDEADBEEF"
// <ble_active> : BLE scan mode - 0: passive / 1: active
// <ble_scantime> : BLE scan time in seconds (0...255)
// <ble_addrN> : e.g. "DE:AD:BE:EF:12:23"
//
//
Expand Down Expand Up @@ -89,6 +95,7 @@
// 20230821 Created
// 20240420 Updated for BresserWeatherSensorLW,
// renamed from downlink_formatter.js
// 20240427 Added BLE configuration
//
// ToDo:
// -
Expand All @@ -110,6 +117,8 @@ const CMD_GET_SENSORS_EXC = 0xC6;
const CMD_SET_SENSORS_EXC = 0xC7;
const CMD_GET_BLE_ADDR = 0xC8;
const CMD_SET_BLE_ADDR = 0xC9;
const CMD_GET_BLE_CONFIG = 0xCA;
const CMD_SET_BLE_CONFIG = 0xCB;


// Source of Real Time Clock setting
Expand Down Expand Up @@ -238,6 +247,14 @@ function encodeDownlink(input) {
errors: []
};
}
else if (input.data.cmd == "CMD_GET_BLE_CONFIG") {
return {
bytes: [0],
fPort: CMD_GET_BLE_CONFIG,
warnings: [],
errors: []
};
}
}
if (input.data.hasOwnProperty('sleep_interval')) {
return {
Expand Down Expand Up @@ -355,6 +372,14 @@ function encodeDownlink(input) {
errors: []
};
}
else if (input.data.hasOwnProperty('ble_active') && input.data.hasOwnProperty('ble_scantime')) {
return {
bytes: [input.data.ble_active, input.data.ble_scantime],
fPort: CMD_SET_BLE_CONFIG,
warnings: [],
errors: []
};
}
else {
return {
bytes: [],
Expand All @@ -374,6 +399,7 @@ function decodeDownlink(input) {
case CMD_GET_SENSORS_INC:
case CMD_GET_SENSORS_EXC:
case CMD_GET_BLE_ADDR:
case CMD_GET_BLE_CONFIG:
return {
data: [0],
warnings: [],
Expand Down Expand Up @@ -434,6 +460,13 @@ function decodeDownlink(input) {
sleep_interval_long: uint16BE(input.bytes.slice(3, 4))
}
};
case CMD_GET_BLE_CONFIG:
return {
data: {
ble_active: uint8(input.bytes[0]),
ble_timeout: uint8(input.bytes[1])
}
};
default:
return {
errors: ["unknown FPort"]
Expand Down
18 changes: 17 additions & 1 deletion scripts/uplink_formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// Commands:
// ----------
// (see constants for ports below)
// port = CMD_SET_WS_TIMEOUT, {"timeout": <timeout_in_seconds>}
// port = CMD_SET_WS_TIMEOUT, {"ws_timeout": <timeout_in_seconds>}
// port = CMD_SET_SLEEP_INTERVAL, {"sleep_interval": <interval_in_seconds>}
// port = CMD_SET_SLEEP_INTERVAL_LONG, {"sleep_interval_long": <interval_in_seconds>}
// port = CMD_GET_DATETIME, {"cmd": "CMD_GET_DATETIME"} / payload = 0x00
Expand All @@ -28,6 +28,9 @@
// port = CMD_SET_SENSORS_EXC, {"sensors_exc": [<sensors_exc0>, ..., <sensors_excN>]}
// port = CMD_GET_BLE_ADDR, {"cmd": "CMD_GET_BLE_ADDR"} / payload = 0x00
// port = CMD_SET_BLE_ADDR, {"ble_addr": [<ble_addr0>, ..., <ble_addrN>]}
// port = CMD_GET_BLE_CONFIG, {"cmd": "CMD_GET_BLE_CONFIG"} / payload = 0x00
// port = CMD_SET_BLE_CONFIG, {"ble_active": <ble_active>, "ble_scantime": <ble_scantime>}

//
// Responses:
// -----------
Expand All @@ -45,6 +48,8 @@
//
// CMD_GET_BLE_ADDR {"ble_addr": [<ble_addr0>, ...]}
//
// CMD_GET_BLE_CONFIG {"ble_active": <ble_active>, "ble_scantime": <ble_scantime>}
//
// <ws_timeout> : 0...255
// <sleep_interval> : 0...65535
// <sleep_interval> : 0...65535
Expand All @@ -53,6 +58,8 @@
// <rtc_source> : 0x00: GPS / 0x01: RTC / 0x02: LORA / 0x03: unsynched / 0x04: set (source unknown)
// <sensors_incN> : e.g. "0xDEADBEEF"
// <sensors_excN> : e.g. "0xDEADBEEF"
// <ble_active> : BLE scan mode - 0: passive / 1: active
// <ble_scantime> : BLE scan time in seconds (0...255)
// <ble_addrN> : e.g. "DE:AD:BE:EF:12:23"

// Based on:
Expand Down Expand Up @@ -89,6 +96,7 @@
// 20230821 Created
// 20240420 Updated for BresserWeatherSensorLW,
// renamed from ttn_uplink_formatter.js
// 20240427 Added BLE configuration
//
// ToDo:
// -
Expand All @@ -104,6 +112,7 @@ function decoder(bytes, port) {
const CMD_GET_SENSORS_INC = 0xC4;
const CMD_GET_SENSORS_EXC = 0xC6;
const CMD_GET_BLE_ADDR = 0xC8;
const CMD_GET_BLE_CONFIG = 0xCA;

const ONEWIRE_EN = 0;

Expand Down Expand Up @@ -454,6 +463,13 @@ function decoder(bytes, port) {
['ble_addr'
]
);
} else if (port === CMD_GET_BLE_CONFIG) {
return decode(
bytes,
[uint8, uint8
],
['ble_active', 'ble_scantime']
);
}

}
Expand Down
50 changes: 46 additions & 4 deletions src/AppLayer.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// payload.cpp
// AppLayer.cpp
//
// Create data payload from sensor or simulated data
// LoRaWAN node application layer
//
// - Create data payload from sensor or simulated data
// - Decode sensor specific commands
// - Encode sensor specific status responses
// - Retain sensor specific parameters
//
// This implementation is specific for the BresserWeatherSensorLW project
//
Expand Down Expand Up @@ -42,6 +47,7 @@
// Fixed getBleAddr()
// Implemented resetting of knownBLEAddresses to defaults
// 20240426 Added BLE address initialization after updating via downlink
// 20240427 Added BLE configuration/status via LoRaWAN
//
//
// ToDo:
Expand Down Expand Up @@ -78,6 +84,7 @@ AppLayer::decodeDownlink(uint8_t port, uint8_t *payload, size_t size)
appPrefs.begin("BWS-LW-APP", false);
appPrefs.putUChar("ws_timeout", payload[0]);
appPrefs.end();
return 0;
}

if ((port == CMD_GET_SENSORS_INC) && (payload[0] == 0x00) && (size == 1))
Expand Down Expand Up @@ -119,6 +126,22 @@ AppLayer::decodeDownlink(uint8_t port, uint8_t *payload, size_t size)
payload[i + 3]);
}
weatherSensor.setSensorsExc(payload, size);
return 0;
}

#if defined(MITHERMOMETER_EN) || defined(THEENGSDECODER_EN)
if ((port == CMD_GET_BLE_CONFIG) && (payload[0] == 0x00) && (size == 1)) {
log_d("Get BLE config");
return CMD_GET_BLE_CONFIG;
}

if ((port == CMD_SET_BLE_CONFIG) && (size == 2))
{
appPrefs.begin("BWS-LW-APP", false);
appPrefs.putUChar("ble_active", payload[0]);
appPrefs.putUChar("ble_scantime", payload[1]);
appPrefs.end();
return 0;
}

if ((port == CMD_GET_BLE_ADDR) && (payload[0] == 0x00) && (size == 1))
Expand All @@ -127,7 +150,6 @@ AppLayer::decodeDownlink(uint8_t port, uint8_t *payload, size_t size)
return CMD_GET_BLE_ADDR;
}

#if defined(MITHERMOMETER_EN) || defined(THEENGSDECODER_EN)
if ((port == CMD_SET_BLE_ADDR) && (size % 6 == 0))
{
log_d("Set BLE sensors MAC addresses");
Expand Down Expand Up @@ -162,6 +184,8 @@ void AppLayer::genPayload(uint8_t port, LoraEncoder &encoder)

void AppLayer::getPayloadStage1(uint8_t port, LoraEncoder &encoder)
{
(void)port; // suppress warning regarding unused parameter

#ifdef PIN_SUPPLY_IN
uint16_t supply_voltage = getVoltage(PIN_SUPPLY_IN, SUPPLY_SAMPLES, SUPPLY_DIV);
#endif
Expand All @@ -174,8 +198,14 @@ void AppLayer::getPayloadStage1(uint8_t port, LoraEncoder &encoder)
// Set sensor data invalid
bleSensors.resetData();

appPrefs.begin("BWS-LW-APP", false);
uint8_t ble_active = appPrefs.getUChar("ble_active", BLE_SCAN_MODE);
uint8_t ble_scantime = appPrefs.getUChar("ble_scantime", BLE_SCAN_TIME);
log_d("Preferences: ble_active: %u", ble_active);
log_d("Preferences: ble_scantime: %u s", ble_scantime);
appPrefs.end();
// Get sensor data - run BLE scan for <bleScanTime>
bleSensors.getData(BLE_SCAN_TIME);
bleSensors.getData(ble_scantime, ble_active);
#endif
#ifdef LIGHTNINGSENSOR_EN
time_t lightn_ts;
Expand Down Expand Up @@ -574,6 +604,18 @@ void AppLayer::getConfigPayload(uint8_t cmd, uint8_t &port, LoraEncoder &encoder
encoder.writeUint8(ws_timeout);
port = CMD_GET_WS_TIMEOUT;
}
#if defined(MITHERMOMETER_EN) || defined(THEENGSDECODER_EN)
else if (cmd == CMD_GET_BLE_CONFIG)
{
appPrefs.begin("BWS-LW-APP", false);
uint8_t ble_active = appPrefs.getUChar("ble_active", BLE_SCAN_MODE);
uint8_t ble_scantime = appPrefs.getUChar("ble_scantime", BLE_SCAN_TIME);
appPrefs.end();
encoder.writeUint8(ble_active);
encoder.writeUint8(ble_scantime);
port = CMD_GET_BLE_CONFIG;
}
#endif
else if (cmd == CMD_GET_SENSORS_INC)
{
uint8_t payload[48];
Expand Down
4 changes: 2 additions & 2 deletions src/AppLayer.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
///////////////////////////////////////////////////////////////////////////////
// payload.h
// AppLayer.h
//
// Create data payload from sensor or simulated data
// LoRaWAN node application layer
//
// created: 04/2024
//
Expand Down
Loading
Loading