Modify new BT config using MQTT (#1259)

* Move BTConfig_default to ZgatewayBT.ino as BTConfig_init()

* Remove unused function declaration & typo

* Move bleconnect outside of ifdef ESP32

* Add new parameters to json payload on MQTTtoBT/config
And move them to function BTConfig_fromJson()

new parameters: [presenceEnable, presenceTopic, presenceUseBeaconUuid, extDecoderEnable,
extDecoderTopic, filterConnectable, pubKnownServiceData,
pubUnknownServiceData, pubKnownManufData, pubUnknownManufData,
pubServiceDataUUID, pubBeaconUuidForTopic]

* Add ignoreWBlist as new configuration parameter

* Keep hasspresence keyword (do not use presenceEnable)

* Documentation

* Typos & Optimizations arround RemoveJsonPropertyIf

* Template for BT config update

* Ensure BTConfig.minRssi sign does not matter

* Report configuration change on topic /commands/BTtoMQTT/config

# Conflicts:
#	main/ZgatewayBT.ino

* Add BT config bool commands (init, load, erase & save) to persist config parameters

* Documentation

* Fix pre-compilation issue

* Fix Code Format

* Use Preference only for ESP32

* Update Doc
This commit is contained in:
Bad
2022-09-03 22:08:07 +02:00
committed by GitHub
parent 9120d06932
commit 312ef858c1
5 changed files with 310 additions and 95 deletions

View File

@@ -11,7 +11,7 @@ You need to set `OpenHABAutoDiscovery` to true into `config_mqttDiscovery.h`
`#define OpenHABDiscovery true`
::: tip
If you are connecting to BLE devices it is highly recommended to set `BLE_FILTER_CONNECTABLE` to `1` in `config_BT.h`. Otherwise you may encounter incomplete data.
If you are connecting to BLE devices it is highly recommended to set `filterConnectable` to `true` in [BT configuration](../use/ble.md#advanced-filter-out-connectable-devices). Otherwise you may encounter incomplete data.
:::
The things will appear in the inbox of the paperUI, add them and links the channels. You should see them into the control panel for further usage.

View File

@@ -75,7 +75,13 @@ A white list is a list of MAC addresses permitted to be published by OMG
to set white list
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"white-list":["01:23:14:55:16:15","4C:65:77:88:9C:79","4C:65:A6:66:3C:79"]}'`
Note: if you want to filter (white or black list) on BLE sensors that are auto discovered, you need to wait for the discovery before applying the white or black list
Note: if you want to filter (white or black list) on BLE sensors that are auto discovered, you need to wait for the discovery before applying the white or black list, or temporarily disable it:
to temporarily disable white/black list
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"ignoreWBlist":true}'`
to enable white/black list back
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"ignoreWBlist":false}'`
::: tip
So as to keep your white/black list persistent you can publish it with the retain option of MQTT (-r with mosquitto_pub or retain check box of MQTT Explorer)
@@ -148,6 +154,41 @@ Or by an MQTT command.
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"hasspresence":true}'`
To change presence publication topic, use this MQTT command:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"presenceTopic":"presence/"}'`
To use iBeacon UUID for presence, instead of sender (random) MAC address, use this MQTT command:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"presenceUseBeaconUuid":true}'`
This will change usual payload for iBeacon from:
`{"id":"60:87:57:4C:9B:C2","mac_type":1,"rssi":-78,"distance":7.85288,"brand":"GENERIC","model":"iBeacon","model_id":"IBEACON","mfid":"4c00","uuid":"1de4b189115e45f6b44e509352269977","major":0,"minor":0,"txpower":-66}`
To:
`{"id":"1de4b189115e45f6b44e509352269977","mac_type":1,"rssi":-78,"distance":7.85288,"brand":"GENERIC","model":"iBeacon","model_id":"IBEACON","mfid":"4c00","uuid":"1de4b189115e45f6b44e509352269977","major":0,"minor":0,"txpower":-66,"mac":"60:87:57:4C:9B:C2"}`
Note: the MAC address is put in "mac" field.
## Setting if the gateway uses iBeacon UUID as topic, instead of (random) MAC address
By default, iBeacon are published like other devices, using a topic based on the MAC address of the sender.
But modern phones randomize their Bluetooth MAC address making it difficult to track iBeacon.
For example, the 2 following messages corresponds to the same iBeacon, but with different MAC and topics:
```
home/OpenMQTTGateway/BTtoMQTT/58782076BC24 {"id":"58:78:20:76:BC:24","mac_type":1,"rssi":-79,"brand":"GENERIC","model":"iBeacon","model_id":"IBEACON","mfid":"4c00","uuid":"1de4b189115e45f6b44e509352269977","major":0,"minor":0,"txpower":-66}
home/OpenMQTTGateway/BTtoMQTT/5210A84690AC {"id":"52:10:A8:46:90:AC","mac_type":1,"rssi":-77,"brand":"GENERIC","model":"iBeacon","model_id":"IBEACON","mfid":"4c00","uuid":"1de4b189115e45f6b44e509352269977","major":0,"minor":0,"txpower":-66}
```
To use iBeacon UUID as topic, use this MQTT command:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"pubBeaconUuidForTopic":true}'`
Resulting in such messages (for the same iBeacon as previously):
```
home/OpenMQTTGateway/BTtoMQTT/1de4b189115e45f6b44e509352269977 {"id":"52:10:A8:46:90:AC","mac_type":1,"rssi":-76,"brand":"GENERIC","model":"iBeacon","model_id":"IBEACON","mfid":"4c00","uuid":"1de4b189115e45f6b44e509352269977","major":0,"minor":0,"txpower":-66}
home/OpenMQTTGateway/BTtoMQTT/1de4b189115e45f6b44e509352269977 {"id":"7B:63:C6:82:DC:57","mac_type":1,"rssi":-83,"brand":"GENERIC","model":"iBeacon","model_id":"IBEACON","mfid":"4c00","uuid":"1de4b189115e45f6b44e509352269977","major":0,"minor":0,"txpower":-66}
```
## Setting the minimum RSSI accepted to publish device data
If you want to change the minimum RSSI value accepted for a device to be published, you can change it by MQTT. For example if you want to set -80
@@ -160,11 +201,83 @@ you can also accept all the devices by the following command:
The default value is set into config_BT.h
## ADVANCED: Setting up an external decoder
This advanced option is used to publish raw radio frames on a specific topic to be decoded by an external decoder instead of the integrated one.
To enable external decoder:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"extDecoderEnable":true}'`
To change the default external decoder topic to "undecoded":
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"extDecoderTopic":"undecoded"}'`
## ADVANCED: Filtering out connectable devices
[With OpenHAB integration](../integrate/openhab2.md), this configuration is highly recommended, otherwise you may encounter incomplete data.
If you want to enable this feature:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"filterConnectable":true}'`
## ADVANCED: Publishing known service data
If you want to enable this feature:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"pubKnownServiceData":true}'`
## ADVANCED: Publishing unknown service data
If you want to change the default behaviour, in case you are having too heavy service data:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"pubUnknownServiceData":false}'`
## ADVANCED: Publishing known manufacturer's data
If you want to change the default behaviour:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"pubKnownManufData":true}'`
## ADVANCED: Publishing unknown manufacturer's data
If you want to change the default behaviour, in case you are having too heavy service data:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"pubUnknownManufData":false}'`
## ADVANCED: Publishing the service UUID data
If you want to change the default behaviour:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"pubServiceDataUUID":true}'`
## Store BLE configuration into the gateway (only with ESP32 boards)
Open MQTT Gateway has the capability to save the current configuration and reload it at startup.
To store the running configuration into the gateway, use the command:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"save":true}'`
At any time, you can reload the stored configuration with the command:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"load":true}'`
If you want to erase the stored configuration, use the command:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"erase":true}'`
Note that it will not change the running configuration, only ensure default configuration is used at next startup.
By the way, if you want to load the default built-in configuration (on any board, not only ESP32), use the command:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"init":true}'`
Note that it will not change the stored configuration, `erase` or `save` is still needed to overwrite the saved configuration.
## Read/write BLE characteristics over MQTT (ESP32 only)
The gateway can read and write BLE characteristics from devices and provide the results in an MQTT message.
::: tip
These actions will be taken on the next BLE connection, which occurs after scanning and after the scan count is reached, [see above to set this.](#setting-the-number-of-scans-between-connection-attempts)
These actions will be taken on the next BLE connection, which occurs after scanning and after the scan count is reached, [see above to set this](#setting-the-number-of-scans-between-connection-attempts).
This can be overridden by providing an (optional) parameter `"immediate": true` within the command. This will cause the BLE scan to stop if currently in progress, allowing the command to be immediately processed. All other connection commands in queue will also be processed for the same device, commands for other devices will be deferred until the next normally scheduled connection.
**Note** Some devices need to have the MAC address type specified. You can find this type by checking the log/MQTT data and looking for "mac_type". By default the type is 0 but some devices use different type values. You must specify the correct type to connect successfully.

View File

@@ -61,7 +61,7 @@ QueueHandle_t BLEQueue;
using namespace std;
// Global struct to store live BT configuration data
BTConfig_s BTConfig = BTConfig_default;
BTConfig_s BTConfig;
# define device_flags_init 0 << 0
# define device_flags_isDisc 1 << 0
@@ -93,8 +93,154 @@ static BLEdevice NO_DEVICE_FOUND = {{0},
TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL};
static bool oneWhite = false;
void BTConfig_init() {
BTConfig.bleConnect = AttemptBLEConnect;
BTConfig.BLEinterval = TimeBtwRead;
BTConfig.BLEscanBeforeConnect = ScanBeforeConnect;
BTConfig.pubOnlySensors = PublishOnlySensors;
BTConfig.presenceEnable = HassPresence;
BTConfig.presenceTopic = subjectHomePresence;
BTConfig.presenceUseBeaconUuid = useBeaconUuidForPresence;
BTConfig.minRssi = MinimumRSSI;
BTConfig.extDecoderEnable = UseExtDecoder;
BTConfig.extDecoderTopic = MQTTDecodeTopic;
BTConfig.filterConnectable = BLE_FILTER_CONNECTABLE;
BTConfig.pubKnownServiceData = pubKnownBLEServiceData;
BTConfig.pubUnknownServiceData = pubUnknownBLEServiceData;
BTConfig.pubKnownManufData = pubBLEManufacturerData;
BTConfig.pubUnknownManufData = pubUnknownBLEManufacturerData;
BTConfig.pubServiceDataUUID = pubBLEServiceUUID;
BTConfig.pubBeaconUuidForTopic = useBeaconUuidForTopic;
BTConfig.ignoreWBlist = false;
}
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>
void BTConfig_update(JsonObject& data, const char* key, T& var) {
if (data.containsKey(key)) {
if (var != data[key].as<T>()) {
var = data[key].as<T>();
Log.notice(F("BT config %s changed: %s" CR), key, data[key].as<String>());
} else {
Log.notice(F("BT config %s unchanged: %s" CR), key, data[key].as<String>());
}
}
}
void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
// Attempts to connect to elligible devices or not
BTConfig_update(BTdata, "bleconnect", BTConfig.bleConnect);
// Scan interval set
if (BTdata.containsKey("interval") && BTdata["interval"] != 0)
BTConfig_update(BTdata, "interval", BTConfig.BLEinterval);
// Number of scan before a connect set
BTConfig_update(BTdata, "scanbcnct", BTConfig.BLEscanBeforeConnect);
// publish all BLE devices discovered or only the identified sensors (like temperature sensors)
BTConfig_update(BTdata, "onlysensors", BTConfig.pubOnlySensors);
// Home Assistant presence message
BTConfig_update(BTdata, "hasspresence", BTConfig.presenceEnable);
// Home Assistant presence message topic
BTConfig_update(BTdata, "presenceTopic", BTConfig.presenceTopic);
// Home Assistant presence message use iBeacon UUID
BTConfig_update(BTdata, "presenceUseBeaconUuid", BTConfig.presenceUseBeaconUuid);
// MinRSSI set
BTConfig_update(BTdata, "minrssi", BTConfig.minRssi);
// Send undecoded device data
BTConfig_update(BTdata, "extDecoderEnable", BTConfig.extDecoderEnable);
// Topic to send undecoded device data
BTConfig_update(BTdata, "extDecoderTopic", BTConfig.extDecoderTopic);
// Sets whether to filter publishing
BTConfig_update(BTdata, "filterConnectable", BTConfig.filterConnectable);
// Publish service data belonging to recognised sensors
BTConfig_update(BTdata, "pubKnownServiceData", BTConfig.pubKnownServiceData);
// Publish service data belonging to unrecognised sensors
BTConfig_update(BTdata, "pubUnknownServiceData", BTConfig.pubUnknownServiceData);
// Publish known manufacturer's data
BTConfig_update(BTdata, "pubKnownManufData", BTConfig.pubKnownManufData);
// Publish unknown manufacturer's data
BTConfig_update(BTdata, "pubUnknownManufData", BTConfig.pubUnknownManufData);
// Publish the service UUID data
BTConfig_update(BTdata, "pubServiceDataUUID", BTConfig.pubServiceDataUUID);
// Use iBeacon UUID as topic, instead of sender (random) MAC address
BTConfig_update(BTdata, "pubBeaconUuidForTopic", BTConfig.pubBeaconUuidForTopic);
// Disable Whitelist & Blacklist
BTConfig_update(BTdata, "ignoreWBlist", (BTConfig.ignoreWBlist));
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
JsonObject jo = jsonBuffer.to<JsonObject>();
jo["bleconnect"] = BTConfig.bleConnect;
jo["interval"] = BTConfig.BLEinterval;
jo["scanbcnct"] = BTConfig.BLEscanBeforeConnect;
jo["onlysensors"] = BTConfig.pubOnlySensors;
jo["hasspresence"] = BTConfig.presenceEnable;
jo["presenceTopic"] = BTConfig.presenceTopic;
jo["presenceUseBeaconUuid"] = BTConfig.presenceUseBeaconUuid;
jo["minrssi"] = -abs(BTConfig.minRssi); // Always export as negative value
jo["extDecoderEnable"] = BTConfig.extDecoderEnable;
jo["extDecoderTopic"] = BTConfig.extDecoderTopic;
jo["filterConnectable"] = BTConfig.filterConnectable;
jo["pubKnownServiceData"] = BTConfig.pubKnownServiceData;
jo["pubUnknownServiceData"] = BTConfig.pubUnknownServiceData;
jo["pubKnownManufData"] = BTConfig.pubKnownManufData;
jo["pubUnknownManufData"] = BTConfig.pubUnknownManufData;
jo["pubServiceDataUUID"] = BTConfig.pubServiceDataUUID;
jo["pubBeaconUuidForTopic"] = BTConfig.pubBeaconUuidForTopic;
jo["ignoreWBlist"] = BTConfig.ignoreWBlist;
if (startup) {
Log.notice(F("BT config: "));
serializeJsonPretty(jsonBuffer, Serial);
Serial.println();
return; // Do not try to erase/write/send config at startup
}
pub("/commands/BTtoMQTT/config", jo);
# if defined(ESP32)
if (BTdata.containsKey("erase") && BTdata["erase"].as<bool>()) {
// Erase config from NVS (non-volatile storage)
preferences.begin(Gateway_Short_Name, false);
preferences.remove("BTConfig");
preferences.end();
Log.notice(F("BT config erased" CR));
return; // Erase prevails on save, so skipping save
}
if (BTdata.containsKey("save") && BTdata["save"].as<bool>()) {
// Save config into NVS (non-volatile storage)
String conf = "";
serializeJson(jsonBuffer, conf);
preferences.begin(Gateway_Short_Name, false);
preferences.putString("BTConfig", conf);
preferences.end();
Log.notice(F("BT config saved" CR));
}
# endif
}
# if defined(ESP32)
void BTConfig_load() {
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
preferences.begin(Gateway_Short_Name, true);
auto error = deserializeJson(jsonBuffer, preferences.getString("BTConfig", "{}"));
preferences.end();
Log.notice(F("BT config loaded" CR));
if (error) {
Log.error(F("BT config deserialization failed: %s, buffer capacity: %u" CR), error.c_str(), jsonBuffer.capacity());
return;
}
if (jsonBuffer.isNull()) {
Log.warning(F("BT config is null" CR));
return;
}
JsonObject jo = jsonBuffer.as<JsonObject>();
BTConfig_fromJson(jo, true); // Never send mqtt message with config
Log.notice(F("BT config loaded" CR));
}
# endif
void pubBTMainCore(JsonObject& data, bool haPresenceEnabled = true) {
if (abs((int)data["rssi"] | 0) < BTConfig.minRssi && data.containsKey("id")) {
if (abs((int)data["rssi"] | 0) < abs(BTConfig.minRssi) && data.containsKey("id")) {
String topic = data["id"].as<const char*>();
topic.replace(":", ""); // Initially publish topic ends with MAC address
if (BTConfig.pubBeaconUuidForTopic && !BTConfig.extDecoderEnable && data.containsKey("model_id") && data["model_id"].as<String>() == "IBEACON")
@@ -210,9 +356,9 @@ void pubBT(JsonObject& data) {
bool ProcessLock = false; // Process lock when we want to use a critical function like OTA for example
BLEdevice* getDeviceByMac(const char* mac);
void createOrUpdateDevice(const char* mac, uint8_t flags, int model, int mac_type = 0);
BLEdevice* getDeviceByMac(const char* mac); // Declared here to avoid pre-compilation issue (misplaced auto declaration by pio)
BLEdevice* getDeviceByMac(const char* mac) {
Log.trace(F("getDeviceByMac %s" CR), mac);
@@ -446,7 +592,7 @@ void procBLETask(void* pvParameters) {
continue;
}
if ((!oneWhite || isWhite(device)) && !isBlack(device)) { //if not black listed MAC we go AND if we have no white MAC or this MAC is white we go out
if (BTConfig.ignoreWBlist || ((!oneWhite || isWhite(device)) && !isBlack(device))) { // Only if WBlist is disabled OR ((no white MAC OR this MAC is white) AND not a black listed MAC)
if (advertisedDevice->haveName())
BLEdata["name"] = (char*)advertisedDevice->getName().c_str();
if (advertisedDevice->haveManufacturerData()) {
@@ -625,8 +771,7 @@ void coreTask(void* pvParameters) {
}
}
void lowPowerESP32() // low power mode
{
void lowPowerESP32() { // low power mode
Log.trace(F("Going to deep sleep for: %l s" CR), (BTConfig.BLEinterval / 1000));
deepSleep(BTConfig.BLEinterval * 1000);
}
@@ -672,10 +817,12 @@ void changelowpowermode(int newLowPowerMode) {
}
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("Publishing only BLE sensors: %T" CR), BTConfig.pubOnlySensors);
Log.notice(F("minrssi: %d" CR), BTConfig.minRssi);
Log.notice(F("minrssi: %d" CR), -abs(BTConfig.minRssi));
Log.notice(F("Low Power Mode: %d" CR), lowpowermode);
atomic_init(&forceBTScan, 0); // in theory, we don't need this
@@ -733,10 +880,11 @@ unsigned long timebt = 0;
struct decompose d[6] = {{0, 12, true}, {12, 2, false}, {14, 2, false}, {16, 2, false}, {28, 4, true}, {32, 60, false}};
void setupBT() {
BTConfig_init();
Log.notice(F("BLE interval: %d" CR), BTConfig.BLEinterval);
Log.notice(F("BLE scans number before connect: %d" CR), BTConfig.BLEscanBeforeConnect);
Log.notice(F("Publishing only BLE sensors: %T" CR), BTConfig.pubOnlySensors);
Log.notice(F("minrssi: %d" CR), BTConfig.minRssi);
Log.notice(F("minrssi: %d" CR), -abs(BTConfig.minRssi));
softserial.begin(HMSerialSpeed);
softserial.print(F("AT+ROLE1" CR));
delay(100);
@@ -818,10 +966,10 @@ bool BTtoMQTT() {
BLEdata["id"] = (const char*)mac.c_str();
BLEdevice* device = getDeviceByMac((char*)mac.c_str());
if (isBlack(device))
if (!BTConfig.ignoreWBlist && isBlack(device))
return false; //if black listed MAC we go out
if (oneWhite && !isWhite(device))
return false; //if we have at least one white MAC and this MAC is not white we go out
if (!BTConfig.ignoreWBlist && oneWhite && !isWhite(device))
return false; //if WBlist is enabled AND we have at least one white MAC AND this MAC is not white we go out
BLEdata["rssi"] = (int)rssi;
if (!BTConfig.pubOnlySensors && BTConfig.presenceEnable)
@@ -878,7 +1026,7 @@ void launchBTDiscovery() {
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::GAEN) {
String macWOdots = String(p->macAdr);
macWOdots.replace(":", "");
if (!BTConfig.extDecoderEnable && // Do not decode if an external decoter is configured
if (!BTConfig.extDecoderEnable && // Do not decode if an external decoder is configured
p->sensorModel_id > TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL &&
p->sensorModel_id < TheengsDecoder::BLE_ID_NUM::BLE_ID_MAX &&
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) { // Exception on HHCCJCY01HHCC as this one is discoverable and connectable for battery retrieving
@@ -957,23 +1105,16 @@ void launchBTDiscovery() {
# endif
void PublishDeviceData(JsonObject& BLEdata, bool processBLEData) {
if (abs((int)BLEdata["rssi"] | 0) < BTConfig.minRssi) { // process only the devices close enough
if (abs((int)BLEdata["rssi"] | 0) < abs(BTConfig.minRssi)) { // process only the devices close enough
if (processBLEData) process_bledata(BLEdata);
if (!BTConfig.pubOnlySensors || BLEdata.containsKey("model") || BLEdata.containsKey("distance")) {
if (!BTConfig.pubServiceDataUUID)
RemoveJsonPropertyIf(BLEdata, "servicedatauuid", BLEdata.containsKey("model") && BLEdata.containsKey("servicedatauuid"));
if (!BTConfig.pubKnownServiceData)
RemoveJsonPropertyIf(BLEdata, "servicedata", BLEdata.containsKey("model") && BLEdata.containsKey("servicedata"));
if (!BTConfig.pubKnownManufData)
RemoveJsonPropertyIf(BLEdata, "manufacturerdata", BLEdata.containsKey("model") && BLEdata.containsKey("manufacturerdata"));
RemoveJsonPropertyIf(BLEdata, "servicedatauuid", !BTConfig.pubServiceDataUUID && BLEdata.containsKey("model"));
RemoveJsonPropertyIf(BLEdata, "servicedata", !BTConfig.pubKnownServiceData && BLEdata.containsKey("model"));
RemoveJsonPropertyIf(BLEdata, "manufacturerdata", !BTConfig.pubKnownManufData && BLEdata.containsKey("model"));
pubBT(BLEdata);
} else {
if (!BTConfig.pubUnknownServiceData) {
Log.trace(F("Unknown service data, removing it" CR));
RemoveJsonPropertyIf(BLEdata, "servicedata", BLEdata.containsKey("servicedata"));
}
if (!BTConfig.pubUnknownManufData)
RemoveJsonPropertyIf(BLEdata, "manufacturerdata", BLEdata.containsKey("model") && BLEdata.containsKey("manufacturerdata"));
RemoveJsonPropertyIf(BLEdata, "servicedata", !BTConfig.pubUnknownServiceData);
RemoveJsonPropertyIf(BLEdata, "manufacturerdata", !BTConfig.pubUnknownManufData && BLEdata.containsKey("model"));
}
} else if (BLEdata.containsKey("distance")) {
pubBT(BLEdata);
@@ -1018,7 +1159,7 @@ void process_bledata(JsonObject& BLEdata) {
}
}
}
if (model_id < 0) {
if (!BTConfig.extDecoderEnable && model_id < 0) {
Log.trace(F("No device found " CR));
}
}
@@ -1201,66 +1342,43 @@ void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding
# endif
}
// Scan interval set
if (BTdata.containsKey("interval")) {
Log.trace(F("BLE interval setup" CR));
unsigned int interval = BTdata["interval"];
if (interval == 0) {
// Force scan now
if (BTdata.containsKey("interval") && BTdata["interval"] == 0) {
Log.notice(F("BLE forced scan" CR));
# ifdef ESP32
atomic_store_explicit(&forceBTScan, 1, ::memory_order_seq_cst); // ask the other core to do the scan for us
atomic_store_explicit(&forceBTScan, 1, ::memory_order_seq_cst); // ask the other core to do the scan for us
# else
BTforceScan();
BTforceScan();
# endif
} else {
Log.trace(F("Previous interval: %d ms" CR), BTConfig.BLEinterval);
BTConfig.BLEinterval = interval;
Log.notice(F("New interval: %d ms" CR), BTConfig.BLEinterval);
}
}
// Number of scan before a connect set
if (BTdata.containsKey("scanbcnct")) {
Log.trace(F("BLE scans number before a connect setup" CR));
Log.trace(F("Previous number: %d" CR), BTConfig.BLEscanBeforeConnect);
BTConfig.BLEscanBeforeConnect = (unsigned int)BTdata["scanbcnct"];
Log.notice(F("New scan number before connect: %d" CR), BTConfig.BLEscanBeforeConnect);
}
// publish all BLE devices discovered or only the identified sensors (like temperature sensors)
if (BTdata.containsKey("onlysensors")) {
Log.trace(F("Do we publish only sensors" CR));
Log.trace(F("Previous value: %T" CR), BTConfig.pubOnlySensors);
BTConfig.pubOnlySensors = (bool)BTdata["onlysensors"];
Log.notice(F("New value onlysensors: %T" CR), BTConfig.pubOnlySensors);
/*
* Configuration modifications priorities:
* First `init=true` and `load=true` commands are executed (if both are present, INIT prevails on LOAD)
* Then parameters included in json are taken in account
* Finally `erase=true` and `save=true` commands are executed (if both are present, ERASE prevails on SAVE)
*/
if (BTdata.containsKey("init") && BTdata["init"].as<bool>()) {
// Restore the default (initial) configuration
BTConfig_init();
}
# ifdef ESP32
// Attempts to connect to elligible devices or not
if (BTdata.containsKey("bleconnect")) {
Log.trace(F("Do we initiate a connection to retrieve data" CR));
Log.trace(F("Previous value: %T" CR), BTConfig.bleConnect);
BTConfig.bleConnect = (bool)BTdata["bleconnect"];
Log.notice(F("New value bleConnect: %T" CR), BTConfig.bleConnect);
else if (BTdata.containsKey("load") && BTdata["load"].as<bool>()) {
// Load the saved configuration, if not initialised
BTConfig_load();
}
# endif
// Load config from json if available
BTConfig_fromJson(BTdata);
# ifdef ESP32
if (BTdata.containsKey("lowpowermode")) {
changelowpowermode((int)BTdata["lowpowermode"]);
}
MQTTtoBTAction(BTdata);
# endif
// MinRSSI set
if (BTdata.containsKey("minrssi")) {
// storing Min RSSI for further use if needed
Log.trace(F("Previous minrssi: %d" CR), BTConfig.minRssi);
// set Min RSSI if present if not setting default value
BTConfig.minRssi = abs((int)BTdata["minrssi"]);
Log.notice(F("New minrssi: %d" CR), BTConfig.minRssi);
}
// Home Assistant presence message
if (BTdata.containsKey("hasspresence")) {
// storing Min RSSI for further use if needed
Log.trace(F("Previous hasspresence: %T" CR), BTConfig.presenceEnable);
// set Min RSSI if present if not setting default value
BTConfig.presenceEnable = (bool)BTdata["hasspresence"];
Log.notice(F("New hasspresence: %T" CR), BTConfig.presenceEnable);
}
}
}
#endif

View File

@@ -63,7 +63,7 @@ extern int btQueueLengthCount;
# define BLE_FILTER_CONNECTABLE 0 // Sets whether to filter publishing of scanned devices that require a connection.
#endif // Setting this to 1 prevents overwriting the publication of the device connection data with the advertised data (Recommended for use with OpenHAB).
#define MinimumRSSI -100 //default minimum rssi value, all the devices below -90 will not be reported
#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
@@ -162,24 +162,7 @@ struct BTConfig_s {
bool pubUnknownManufData; // Publish the manufacturer's data (sometimes contains characters that aren't valid with receiving client)
bool pubServiceDataUUID; // Publish the service UUID data
bool pubBeaconUuidForTopic; // Use iBeacon UUID as topic, instead of sender (random) MAC address
} BTConfig_default = {
.bleConnect = AttemptBLEConnect,
.BLEinterval = TimeBtwRead,
.BLEscanBeforeConnect = ScanBeforeConnect,
.pubOnlySensors = PublishOnlySensors,
.presenceEnable = HassPresence,
.presenceTopic = subjectHomePresence,
.presenceUseBeaconUuid = useBeaconUuidForPresence,
.minRssi = abs(MinimumRSSI),
.extDecoderEnable = UseExtDecoder,
.extDecoderTopic = MQTTDecodeTopic,
.filterConnectable = BLE_FILTER_CONNECTABLE,
.pubKnownServiceData = pubKnownBLEServiceData,
.pubUnknownServiceData = pubUnknownBLEServiceData,
.pubKnownManufData = pubBLEManufacturerData,
.pubUnknownManufData = pubUnknownBLEManufacturerData,
.pubServiceDataUUID = pubBLEServiceUUID,
.pubBeaconUuidForTopic = useBeaconUuidForTopic,
bool ignoreWBlist; // Disable Whitelist & Blacklist
};
// Global struct to store live BT configuration data

View File

@@ -147,6 +147,7 @@ lib_deps =
${libraries.arduinolog}
build_flags =
-w ; supress all warnings
; -E ; generate precompiled source file (.pio/build/*/src/main.ino.cpp.o), use for precompilator debuging only (prevent compilation to succeed)
; '-DLOG_LEVEL=LOG_LEVEL_TRACE' ; Enable trace level logging
monitor_speed = 115200