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
+107 -50

No files matched your search

+14 -10
View File
@@ -1,17 +1,17 @@
/* /*
OpenMQTTGateway - ESP8266 or Arduino program for home automation OpenMQTTGateway - ESP8266 or Arduino program for home automation
Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker
Send and receiving command by MQTT Send and receiving command by MQTT
This program enables to: This program enables to:
- receive MQTT data from a topic and send signals corresponding to the received MQTT data - receive MQTT data from a topic and send signals corresponding to the received MQTT data
- publish MQTT data to a different topic related to received signals - publish MQTT data to a different topic related to received signals
Copyright: (c)Florian ROBERT Copyright: (c)Florian ROBERT
This file is part of OpenMQTTGateway. This file is part of OpenMQTTGateway.
OpenMQTTGateway is free software: you can redistribute it and/or modify OpenMQTTGateway is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@@ -41,11 +41,11 @@
* - mqtt_pass * - mqtt_pass
* - mqtt_server * - mqtt_server
* - mqtt_port * - mqtt_port
* *
* To completely disable WifiManager, define ESPWifiManualSetup. * To completely disable WifiManager, define ESPWifiManualSetup.
* If you do so, please don't forget to set these variables before compiling * If you do so, please don't forget to set these variables before compiling
* *
* Otherwise you can provide these credentials on the web interface after connecting * Otherwise you can provide these credentials on the web interface after connecting
* to the access point with your password (SSID: WifiManager_ssid, password: WifiManager_password) * to the access point with your password (SSID: WifiManager_ssid, password: WifiManager_password)
*/ */
/*-------------DEFINE GATEWAY NAME BELOW IT CAN ALSO BE DEFINED IN platformio.ini----------------*/ /*-------------DEFINE GATEWAY NAME BELOW IT CAN ALSO BE DEFINED IN platformio.ini----------------*/
@@ -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