diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index 90c15765f6..68b75d1afe 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -717,37 +717,31 @@ void procBLETask(void* pvParameters) { if (advertisedDevice->haveServiceData()) { int serviceDataCount = advertisedDevice->getServiceDataCount(); Log.trace(F("Get services data number: %d" CR), serviceDataCount); + char initialBLEDataCharArray[JSON_MSG_BUFFER]; + serializeJson(BLEdata, initialBLEDataCharArray); for (int j = 0; j < serviceDataCount; j++) { std::string service_data = convertServiceData(advertisedDevice->getServiceData(j)); Log.trace(F("Service data: %s" CR), service_data.c_str()); std::string serviceDatauuid = advertisedDevice->getServiceDataUUID(j).toString(); Log.trace(F("Service data UUID: %s" CR), (char*)serviceDatauuid.c_str()); - if (j) { - // if we have more than one service data, we need to create a new BLEdata object to publish the data to MQTT - // we can't use the same BLEdata object because its servicedata would be overwritten by the next service data - // the decoder does not handle multiple servicedata in the same message - // note that we keep the decoded data during the different iterations of the loop, - // the goal is to avoid issue with certain controllers that do not handle multiple messages with undecoded data (OpenHAB for example) - JsonObject& BLEdataTemp = getBTJsonObject(); - bool ret = BLEdataTemp.set(BLEdata); - if (!ret) { - Log.error(F("BLEdataTemp.set(BLEdata) failed" CR)); - } else { - BLEdataTemp.remove("servicedata"); - BLEdataTemp["servicedata"] = (char*)service_data.c_str(); - BLEdataTemp.remove("servicedatauuid"); - BLEdataTemp["servicedatauuid"] = (char*)serviceDatauuid.c_str(); - PublishDeviceData(BLEdataTemp); - } - } else { + if (j == 0) { BLEdata["servicedata"] = (char*)service_data.c_str(); BLEdata["servicedatauuid"] = (char*)serviceDatauuid.c_str(); PublishDeviceData(BLEdata); + } else { + StaticJsonDocument doc; + deserializeJson(doc, initialBLEDataCharArray); + JsonObject& BLEdataTemp = getBTJsonObject(); + BLEdataTemp = doc.as(); + BLEdataTemp["servicedata"] = (char*)service_data.c_str(); + BLEdataTemp["servicedatauuid"] = (char*)serviceDatauuid.c_str(); + PublishDeviceData(BLEdataTemp); } } } else { PublishDeviceData(BLEdata); } + } else { Log.trace(F("Filtered MAC device" CR)); } @@ -1158,14 +1152,17 @@ void launchBTDiscovery(bool overrideDiscovery) { void PublishDeviceData(JsonObject& BLEdata) { if (abs((int)BLEdata["rssi"] | 0) < abs(BTConfig.minRssi)) { // process only the devices close enough - // If the BLEdata contains already decoded data from a previous servicedata iteration, the following one is not decoded and pubAdvData is false we don't publish this duplicate payload - if (process_bledata(BLEdata) < 0 && BLEdata.containsKey("model_id") && !BTConfig.pubAdvData) { - return; + // Decode the payload + process_bledata(BLEdata); + // If the device is not a sensor and pubOnlySensors is true we don't publish this payload + if (!BTConfig.pubOnlySensors || BLEdata.containsKey("model") || BLEdata.containsKey("distance")) { // Identified device + pubBT(BLEdata); } // If the device is a random MAC and pubRandomMACs is false we don't publish this payload if (!BTConfig.pubRandomMACs && (BLEdata["type"].as()).compare("RMAC") == 0) { return; } + // If pubAdvData is false we don't publish the adv data if (!BTConfig.pubAdvData) { BLEdata.remove("servicedatauuid"); BLEdata.remove("servicedata"); @@ -1179,9 +1176,7 @@ void PublishDeviceData(JsonObject& BLEdata) { BLEdata.remove("cont"); BLEdata.remove("track"); } - if (!BTConfig.pubOnlySensors || BLEdata.containsKey("model") || BLEdata.containsKey("distance")) { // Identified device - pubBT(BLEdata); - } + } else if (BLEdata.containsKey("distance")) { pubBT(BLEdata); } else { @@ -1189,7 +1184,11 @@ void PublishDeviceData(JsonObject& BLEdata) { } } -int process_bledata(JsonObject& BLEdata) { +void process_bledata(JsonObject& BLEdata) { + if (!BLEdata.containsKey("id")) { + Log.error(F("No mac address in the payload" CR)); + return; + } const char* mac = BLEdata["id"].as(); int model_id = BTConfig.extDecoderEnable ? -1 : decoder.decodeBLEJson(BLEdata); int mac_type = BLEdata["mac_type"].as(); @@ -1253,7 +1252,6 @@ int process_bledata(JsonObject& BLEdata) { if (!BTConfig.extDecoderEnable && model_id < 0) { Log.trace(F("No eligible device found " CR)); } - return model_id; } void hass_presence(JsonObject& HomePresence) {