Skip to content

Commit

Permalink
[BT] Regular BT connect based on time (#1423)
Browse files Browse the repository at this point in the history
instead of number of scans, as users changing the interval to continuous scanning may have connect attempts to frequently
  • Loading branch information
1technophile authored Jan 26, 2023
1 parent a64acab commit 4e885a7
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 24 deletions.
10 changes: 4 additions & 6 deletions docs/use/ble.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
22 changes: 14 additions & 8 deletions main/ZgatewayBT.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -97,6 +97,8 @@ void BTConfig_init() {
BTConfig.ignoreWBlist = false;
}

unsigned long timeBetweenConnect = 0;

template <typename T> // 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 <typename T>
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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));
Expand Down
6 changes: 3 additions & 3 deletions main/ZmqttDiscovery.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions main/config_BT.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions main/config_mqttDiscovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ const char* availableHASSUnits[] = {"W",
"°F",
"ms",
"s",
"min",
"hPa",
"L",
"kg",
Expand Down
2 changes: 1 addition & 1 deletion main/main.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 4e885a7

Please sign in to comment.