Add option to offload decoding to an external gateway over MQTT. (#1216)

* Add option to offload decoding to an external gateway over MQTT.

* Change decode topic and add to config_bt
This commit is contained in:
h2zero authored and GitHub committed 2022-06-12 17:44:51 -05:00
1 parent 5b697e0306
commit 25b8123ff6
4 files changed
+97 -40

No files matched your search

+4
View File
@@ -172,6 +172,10 @@ const byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0x54, 0x95}; //W5100 ethernet shield
#endif #endif
#if defined(ESP8266) || defined(ESP32) #if defined(ESP8266) || defined(ESP32)
// Uncomment to use a device running TheengsGateway to decode BLE data. (https://github.com/theengs/gateway)
// Set the topic to the subscribe topic configured in the TheengGateway
// #define MQTTDecodeTopic "MQTTDecode"
// The root ca certificate used for validating the MQTT broker // The root ca certificate used for validating the MQTT broker
// The certificate must be in PEM ascii format // The certificate must be in PEM ascii format
const char* certificate PROGMEM = R"EOF(" const char* certificate PROGMEM = R"EOF("
+72 -39
View File
@@ -66,7 +66,9 @@ using namespace std;
# define device_flags_isBlackL 1 << 2 # define device_flags_isBlackL 1 << 2
# define device_flags_connect 1 << 3 # define device_flags_connect 1 << 3
# ifndef MQTTDecodeTopic
TheengsDecoder decoder; TheengsDecoder decoder;
# endif
struct decompose { struct decompose {
int start; int start;
@@ -95,7 +97,16 @@ void pubBTMainCore(JsonObject& data, bool haPresenceEnabled = true) {
if (abs((int)data["rssi"] | 0) < minRssi && data.containsKey("id")) { if (abs((int)data["rssi"] | 0) < minRssi && data.containsKey("id")) {
String mac_address = data["id"].as<const char*>(); String mac_address = data["id"].as<const char*>();
mac_address.replace(":", ""); mac_address.replace(":", "");
# ifdef MQTTDecodeTopic
String mactopic;
if (data.containsKey("model")) {
mactopic = subjectBTtoMQTT + String("/") + mac_address;
} else {
mactopic = String("/") + MQTTDecodeTopic;
}
# else
String mactopic = subjectBTtoMQTT + String("/") + mac_address; String mactopic = subjectBTtoMQTT + String("/") + mac_address;
# endif
pub((char*)mactopic.c_str(), data); pub((char*)mactopic.c_str(), data);
} }
if (haPresenceEnabled && data.containsKey("distance")) { if (haPresenceEnabled && data.containsKey("distance")) {
@@ -870,6 +881,7 @@ void launchBTDiscovery() {
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::GAEN) { p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::GAEN) {
String macWOdots = String(p->macAdr); String macWOdots = String(p->macAdr);
macWOdots.replace(":", ""); macWOdots.replace(":", "");
# ifndef MQTTDecodeTopic
if (p->sensorModel_id > TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL && if (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::BLE_ID_MAX &&
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) { // Exception on HHCCJCY01HHCC as this one is discoverable and connectable for battery retrieving p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) { // Exception on HHCCJCY01HHCC as this one is discoverable and connectable for battery retrieving
@@ -889,11 +901,11 @@ void launchBTDiscovery() {
String discovery_topic = String(subjectBTtoMQTT) + "/" + macWOdots; String discovery_topic = String(subjectBTtoMQTT) + "/" + macWOdots;
String entity_name = String(model_id.c_str()) + "-" + String(prop.key().c_str()); String entity_name = String(model_id.c_str()) + "-" + String(prop.key().c_str());
String unique_id = macWOdots + "-" + String(prop.key().c_str()); String unique_id = macWOdots + "-" + String(prop.key().c_str());
# if OpenHABDiscovery # if OpenHABDiscovery
String value_template = "{{ value_json." + String(prop.key().c_str()) + "}}"; String value_template = "{{ value_json." + String(prop.key().c_str()) + "}}";
# else # else
String value_template = "{{ value_json." + String(prop.key().c_str()) + " | is_defined }}"; String value_template = "{{ value_json." + String(prop.key().c_str()) + " | is_defined }}";
# endif # endif
if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::SBS1 && !strcmp(prop.key().c_str(), "state")) { if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::SBS1 && !strcmp(prop.key().c_str(), "state")) {
String payload_on = "{\"SBS1\":\"on\",\"mac\":\"" + String(p->macAdr) + "\"}"; String payload_on = "{\"SBS1\":\"on\",\"mac\":\"" + String(p->macAdr) + "\"}";
String payload_off = "{\"SBS1\":\"off\",\"mac\":\"" + String(p->macAdr) + "\"}"; String payload_off = "{\"SBS1\":\"off\",\"mac\":\"" + String(p->macAdr) + "\"}";
@@ -915,29 +927,33 @@ void launchBTDiscovery() {
} }
} }
} }
} else if (p->sensorModel_id > BLEconectable::id::MIN && } else
p->sensorModel_id < BLEconectable::id::MAX || # endif
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) { {
// Discovery of sensors from which we retrieve data by connect if (p->sensorModel_id > BLEconectable::id::MIN &&
if (p->sensorModel_id == BLEconectable::id::DT24_BLE) { p->sensorModel_id < BLEconectable::id::MAX ||
DT24Discovery(macWOdots.c_str(), "DT24-BLE"); p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
// Discovery of sensors from which we retrieve data only by connect
if (p->sensorModel_id == BLEconectable::id::DT24_BLE) {
DT24Discovery(macWOdots.c_str(), "DT24-BLE");
}
if (p->sensorModel_id == BLEconectable::id::LYWSD03MMC) {
LYWSD03MMCDiscovery(macWOdots.c_str(), "LYWSD03MMC");
}
if (p->sensorModel_id == BLEconectable::id::MHO_C401) {
MHO_C401Discovery(macWOdots.c_str(), "MHO-C401");
}
if (p->sensorModel_id == BLEconectable::id::XMWSDJ04MMC) {
XMWSDJ04MMCDiscovery(macWOdots.c_str(), "XMWSDJ04MMC");
}
if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
HHCCJCY01HHCCDiscovery(macWOdots.c_str(), "HHCCJCY01HHCC");
}
} else {
Log.trace(F("Device UNKNOWN_MODEL %s" CR), p->macAdr);
} }
if (p->sensorModel_id == BLEconectable::id::LYWSD03MMC) { p->isDisc = true; // we don't need the semaphore and all the search magic via createOrUpdateDevice
LYWSD03MMCDiscovery(macWOdots.c_str(), "LYWSD03MMC");
}
if (p->sensorModel_id == BLEconectable::id::MHO_C401) {
MHO_C401Discovery(macWOdots.c_str(), "MHO-C401");
}
if (p->sensorModel_id == BLEconectable::id::XMWSDJ04MMC) {
XMWSDJ04MMCDiscovery(macWOdots.c_str(), "XMWSDJ04MMC");
}
if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
HHCCJCY01HHCCDiscovery(macWOdots.c_str(), "HHCCJCY01HHCC");
}
} else {
Log.trace(F("Device UNKNOWN_MODEL %s" CR), p->macAdr);
} }
p->isDisc = true; // we don't need the semaphore and all the search magic via createOrUpdateDevice
} else { } else {
Log.trace(F("Device already discovered or that doesn't require discovery %s" CR), p->macAdr); Log.trace(F("Device already discovered or that doesn't require discovery %s" CR), p->macAdr);
} }
@@ -977,8 +993,10 @@ void PublishDeviceData(JsonObject& BLEdata, bool processBLEData) {
void process_bledata(JsonObject& BLEdata) { void process_bledata(JsonObject& BLEdata) {
const char* mac = BLEdata["id"].as<const char*>(); const char* mac = BLEdata["id"].as<const char*>();
int model_id = decoder.decodeBLEJson(BLEdata); int model_id = -1;
int mac_type = BLEdata["mac_type"].as<int>(); int mac_type = BLEdata["mac_type"].as<int>();
# ifndef MQTTDecodeTopic
model_id = decoder.decodeBLEJson(BLEdata);
if (model_id >= 0) { // Broadcaster devices if (model_id >= 0) { // Broadcaster devices
Log.trace(F("Decoder found device: %s" CR), BLEdata["model_id"].as<const char*>()); Log.trace(F("Decoder found device: %s" CR), BLEdata["model_id"].as<const char*>());
if (model_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) { if (model_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
@@ -986,22 +1004,37 @@ void process_bledata(JsonObject& BLEdata) {
} else { } else {
createOrUpdateDevice(mac, device_flags_init, model_id, mac_type); createOrUpdateDevice(mac, device_flags_init, model_id, mac_type);
} }
} else if (BLEdata.containsKey("name")) { // Connectable devices } else
std::string name = BLEdata["name"]; # endif
if (name.compare("LYWSD03MMC") == 0) {
model_id = BLEconectable::id::LYWSD03MMC; if (BLEdata.containsKey("name")) { // Connectable devices
else if (name.compare("DT24-BLE") == 0) std::string name = BLEdata["name"];
model_id = BLEconectable::id::DT24_BLE; if (name.compare("LYWSD03MMC") == 0)
else if (name.compare("MHO-C401") == 0) model_id = BLEconectable::id::LYWSD03MMC;
model_id = BLEconectable::id::MHO_C401; else if (name.compare("DT24-BLE") == 0)
else if (name.compare("XMWSDJ04MMC") == 0) model_id = BLEconectable::id::DT24_BLE;
model_id = BLEconectable::id::XMWSDJ04MMC; else if (name.compare("MHO-C401") == 0)
model_id = BLEconectable::id::MHO_C401;
else if (name.compare("XMWSDJ04MMC") == 0)
model_id = BLEconectable::id::XMWSDJ04MMC;
if (model_id > 0) { if (model_id > 0) {
Log.trace(F("Connectable device found: %s" CR), name.c_str()); Log.trace(F("Connectable device found: %s" CR), name.c_str());
createOrUpdateDevice(mac, device_flags_connect, model_id, mac_type); createOrUpdateDevice(mac, device_flags_connect, model_id, mac_type);
}
} }
} else { # ifdef MQTTDecodeTopic
else if (model_id < 0 && BLEdata.containsKey("servicedata")) {
const char* service_data = (const char*)(BLEdata["servicedata"] | "");
if (strstr(service_data, "209800") != NULL) {
model_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC;
Log.trace(F("Connectable device found: HHCCJCY01HHCC" CR));
createOrUpdateDevice(mac, device_flags_connect, model_id, mac_type);
}
}
# endif
}
if (model_id < 0) {
Log.trace(F("No device found " CR)); Log.trace(F("No device found " CR));
} }
} }
+4 -1
View File
@@ -52,7 +52,10 @@ bool bleConnect = AttemptBLECOnnect;
/*----------------------BT topics & parameters-------------------------*/ /*----------------------BT topics & parameters-------------------------*/
#define subjectBTtoMQTT "/BTtoMQTT" #define subjectBTtoMQTT "/BTtoMQTT"
#define subjectMQTTtoBTset "/commands/MQTTtoBT/config" #define subjectMQTTtoBTset "/commands/MQTTtoBT/config"
#define MinimumRSSI -100 //default minimum rssi value, all the devices below -90 will not be reported // Uncomment to send undecoded device data to another gateway device for decoding
// #define MQTTDecodeTopic "BTtoMQTT/undecoded"
#define MinimumRSSI -100 //default minimum rssi value, all the devices below -90 will not be reported
#ifndef Scan_duration #ifndef Scan_duration
# define Scan_duration 10000 //define the time for a scan # define Scan_duration 10000 //define the time for a scan
+17
View File
@@ -408,6 +408,23 @@ build_flags =
'-DLED_SEND_RECEIVE_ON=0' '-DLED_SEND_RECEIVE_ON=0'
'-DGateway_Name="OpenMQTTGateway_ESP32_BLE"' '-DGateway_Name="OpenMQTTGateway_ESP32_BLE"'
[env:esp32dev-ble-mqtt-decode]
platform = ${com.esp32_platform}
board = esp32dev
board_build.partitions = min_spiffs.csv
lib_deps =
${com-esp.lib_deps}
${libraries.wifimanager32}
${libraries.ble}
${libraries.decoder}
build_flags =
${com-esp.build_flags}
'-DZgatewayBT="BT"'
'-DLED_SEND_RECEIVE=2'
'-DLED_SEND_RECEIVE_ON=0'
'-DGateway_Name="OpenMQTTGateway_ESP32_BLE"'
'-DMQTTDecodeTopic="BTtoMQTT/undecoded"'
[env:esp32dev-ble-aws] [env:esp32dev-ble-aws]
platform = ${com.esp32_platform} platform = ${com.esp32_platform}
board = esp32dev board = esp32dev