From 4e885a7cd0c28fa54dbb8c4cb87cdedc4c567e0c Mon Sep 17 00:00:00 2001 From: Florian Date: Thu, 26 Jan 2023 09:28:16 -0600 Subject: [PATCH] [BT] Regular BT connect based on time (#1423) instead of number of scans, as users changing the interval to continuous scanning may have connect attempts to frequently --- docs/use/ble.md | 10 ++++------ main/ZgatewayBT.ino | 22 ++++++++++++++-------- main/ZmqttDiscovery.ino | 6 +++--- main/config_BT.h | 12 ++++++------ main/config_mqttDiscovery.h | 1 + main/main.ino | 2 +- 6 files changed, 29 insertions(+), 24 deletions(-) diff --git a/docs/use/ble.md b/docs/use/ble.md index a3498fe6..5364b1be 100644 --- a/docs/use/ble.md +++ b/docs/use/ble.md @@ -113,16 +113,14 @@ If you want to scan continuously for BLE devices, for example for beacon locatio In this case you should deactivate the BLE connection mechanism to avoid concurrency between scan and connections (see chapter below, bleconnect). ::: tip -For certain devices like LYWSD03MMC OpenMQTTGateway use a connection (due to the fact that the advertized data are encrypted), this connection mechanism is launched after every `ScanBeforeConnect` per default, you can modify it by following the procedure below. +For certain devices like LYWSD03MMC OpenMQTTGateway use a connection (due to the fact that the advertized data are encrypted), this connection mechanism is launched after every `TimeBtwConnect` per default, you can modify it by following the procedure below. ::: -## Setting the number of scans between connection attempts +## Setting the time between connection attempts -If you want to change the number of BLE scans that are done before a BLE connect you can change it by MQTT, if you want the BLE connect to be every 30 scans: +If you want to change the time between BLE connect you can change it by MQTT, if you want the BLE connect time to be every 300s: -`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"scanbcnct":30}'` - -The BLE connect will be done every 30 * (`TimeBtwRead` + `Scan_duration`), 30 * (55000 + 10000) = 1950000ms +`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"intervalcnct":300000}'` ## Setting if the gateway publishes all the BLE devices scanned or only the detected sensors (default: false) diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index 2c6fd8d6..e5075f28 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -83,7 +83,7 @@ void BTConfig_init() { BTConfig.bleConnect = AttemptBLEConnect; BTConfig.BLEinterval = TimeBtwRead; BTConfig.activeScan = ActiveBLEScan; - BTConfig.BLEscanBeforeConnect = ScanBeforeConnect; + BTConfig.intervalConnect = TimeBtwConnect; BTConfig.pubOnlySensors = PublishOnlySensors; BTConfig.presenceEnable = HassPresence; BTConfig.presenceTopic = subjectHomePresence; @@ -97,6 +97,8 @@ void BTConfig_init() { BTConfig.ignoreWBlist = false; } +unsigned long timeBetweenConnect = 0; + template // Declared here to avoid pre-compilation issue (missing "template" in auto declaration by pio) void BTConfig_update(JsonObject& data, const char* key, T& var); template @@ -117,7 +119,7 @@ void stateBTMeasures(bool start) { jo["bleconnect"] = BTConfig.bleConnect; jo["interval"] = BTConfig.BLEinterval; jo["activescan"] = BTConfig.activeScan; - jo["scanbcnct"] = BTConfig.BLEscanBeforeConnect; + jo["intervalcnct"] = BTConfig.intervalConnect; jo["onlysensors"] = BTConfig.pubOnlySensors; jo["hasspresence"] = BTConfig.presenceEnable; jo["presenceTopic"] = BTConfig.presenceTopic; @@ -152,7 +154,7 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) { // Define if the scan is active or passive BTConfig_update(BTdata, "activescan", BTConfig.activeScan); // Number of scan before a connect set - BTConfig_update(BTdata, "scanbcnct", BTConfig.BLEscanBeforeConnect); + BTConfig_update(BTdata, "intervalcnct", BTConfig.intervalConnect); // publish all BLE devices discovered or only the identified sensors (like temperature sensors) BTConfig_update(BTdata, "onlysensors", BTConfig.pubOnlySensors); // Home Assistant presence message @@ -193,7 +195,7 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) { jo["bleconnect"] = BTConfig.bleConnect; jo["interval"] = BTConfig.BLEinterval; jo["activescan"] = BTConfig.activeScan; - jo["scanbcnct"] = BTConfig.BLEscanBeforeConnect; + jo["intervalcnct"] = BTConfig.intervalConnect; jo["onlysensors"] = BTConfig.pubOnlySensors; jo["hasspresence"] = BTConfig.presenceEnable; jo["presenceTopic"] = BTConfig.presenceTopic; @@ -717,9 +719,11 @@ void coreTask(void* pvParameters) { } else if (!ProcessLock) { if (xSemaphoreTake(semaphoreBLEOperation, pdMS_TO_TICKS(30000)) == pdTRUE) { BLEscan(); - // Launching a connect every BLEscanBeforeConnect - if ((!(scanCount % BTConfig.BLEscanBeforeConnect) || scanCount == 1) && BTConfig.bleConnect) + // Launching a connect every TimeBtwConnect + if (millis() > (timeBetweenConnect + BTConfig.intervalConnect) && BTConfig.bleConnect) { + timeBetweenConnect = millis(); BLEconnect(); + } dumpDevices(); xSemaphoreGive(semaphoreBLEOperation); } else { @@ -793,7 +797,7 @@ void setupBT() { BTConfig_init(); BTConfig_load(); Log.notice(F("BLE scans interval: %d" CR), BTConfig.BLEinterval); - Log.notice(F("BLE scans number before connect: %d" CR), BTConfig.BLEscanBeforeConnect); + Log.notice(F("BLE connects interval: %d" CR), BTConfig.intervalConnect); Log.notice(F("Publishing only BLE sensors: %T" CR), BTConfig.pubOnlySensors); Log.notice(F("Active BLE scan: %T" CR), BTConfig.activeScan); Log.notice(F("minrssi: %d" CR), -abs(BTConfig.minRssi)); @@ -1069,8 +1073,10 @@ void immediateBTAction(void* pvParameters) { std::swap(BLEactions, act_swap); // If we stopped the scheduled connect for this action, do the scheduled now - if ((!(scanCount % BTConfig.BLEscanBeforeConnect) || scanCount == 1) && BTConfig.bleConnect) + if (millis() > (timeBetweenConnect + BTConfig.intervalConnect) && BTConfig.bleConnect) { + timeBetweenConnect = millis(); BLEconnect(); + } xSemaphoreGive(semaphoreBLEOperation); } else { Log.error(F("BLE busy - command not sent" CR)); diff --git a/main/ZmqttDiscovery.ino b/main/ZmqttDiscovery.ino index 014c571d..f11b6afa 100644 --- a/main/ZmqttDiscovery.ino +++ b/main/ZmqttDiscovery.ino @@ -941,9 +941,9 @@ void pubMqttDiscovery() { stateClassNone //State Class ); createDiscovery("number", //set Type - subjectBTtoMQTT, "BT: Connnect every X scan(s)", (char*)getUniqueId("scanbcnct", "").c_str(), //set state_topic,name,uniqueId - "", "", "{{ value_json.scanbcnct }}", //set availability_topic,device_class,value_template, - "{\"scanbcnct\":{{value}},\"save\":true}", "", "", //set,payload_on,payload_off,unit_of_meas, + subjectBTtoMQTT, "BT: Connnect interval", (char*)getUniqueId("intervalcnct", "").c_str(), //set state_topic,name,uniqueId + "", "", "{{ value_json.intervalcnct/60000 }}", //set availability_topic,device_class,value_template, + "{\"intervalcnct\":{{value*60000}},\"save\":true}", "", "min", //set,payload_on,payload_off,unit_of_meas, 0, //set off_delay "", "", true, subjectMQTTtoBTset, //set,payload_available,payload_not available,is a gateway entity, command topic "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain diff --git a/main/config_BT.h b/main/config_BT.h index 1d08ed3d..12d7699f 100644 --- a/main/config_BT.h +++ b/main/config_BT.h @@ -66,7 +66,7 @@ extern int btQueueLengthCount; #define MinimumRSSI -100 //default minimum rssi value, all the devices below -100 will not be reported #ifndef Scan_duration -# define Scan_duration 10000 //define the time for a scan +# define Scan_duration 10000 //define the time for a scan); in milliseconds #endif #ifndef BLEScanInterval # define BLEScanInterval 52 // How often the scan occurs / switches channels; in milliseconds, @@ -77,15 +77,15 @@ extern int btQueueLengthCount; #ifndef ActiveBLEScan # define ActiveBLEScan true // Set active scanning, this will get more data from the advertiser. #endif -#ifndef ScanBeforeConnect -# define ScanBeforeConnect 10 //define number of scans before connecting to BLE devices (ESP32 only, minimum 1) +#ifndef TimeBtwConnect +# define TimeBtwConnect 3600000 //define default time between BLE connection attempt (not used for immediate actions); in milliseconds #endif #ifndef BLEScanDuplicateCacheSize # define BLEScanDuplicateCacheSize 200 #endif #ifndef TimeBtwRead -# define TimeBtwRead 55555 //define default time between 2 scans +# define TimeBtwRead 55555 //define default time between 2 scans); in milliseconds #endif #ifndef PublishOnlySensors @@ -131,8 +131,8 @@ unsigned long scanCount = 0; struct BTConfig_s { bool bleConnect; // Attempt a BLE connection to sensors with ESP32 bool activeScan; - unsigned int BLEinterval; // Time between 2 scans - unsigned int BLEscanBeforeConnect; // Number of BLE scans between connection cycles + unsigned long BLEinterval; // Time between 2 scans + unsigned long intervalConnect; // Time between 2 connects bool pubOnlySensors; // Publish only the identified sensors (like temperature sensors) bool presenceEnable; // Publish into Home Assistant presence topic String presenceTopic; // Home Assistant presence topic to publish on diff --git a/main/config_mqttDiscovery.h b/main/config_mqttDiscovery.h index f2752bbd..2a3e7d14 100644 --- a/main/config_mqttDiscovery.h +++ b/main/config_mqttDiscovery.h @@ -239,6 +239,7 @@ const char* availableHASSUnits[] = {"W", "°F", "ms", "s", + "min", "hPa", "L", "kg", diff --git a/main/main.ino b/main/main.ino index 52a6e780..1bac830c 100644 --- a/main/main.ino +++ b/main/main.ino @@ -1705,7 +1705,7 @@ void stateMeasures() { SYSdata["lowpowermode"] = (int)lowpowermode; # endif SYSdata["interval"] = BTConfig.BLEinterval; - SYSdata["scanbcnct"] = BTConfig.BLEscanBeforeConnect; + SYSdata["intervalcnct"] = BTConfig.intervalConnect; SYSdata["scnct"] = scanCount; # endif # ifdef ZboardM5STACK