From 1dfa2f17fb07e63fbfeb576ba506b012923e4dfa Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 30 Aug 2026 06:14:46 -0500 Subject: [PATCH] [RF] Fix RTL_433 duplicate detection swallowing rapid transmissions with differing payloads (#2357) * Initial plan * Fix RTL_433 duplicate detection to hash full payload instead of id+temperature_C --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: NorthernMan54 <19808920+NorthernMan54@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- main/gatewayRTL_433.cpp | 29 ++++++++++++++++++++++++++++- main/main.cpp | 4 ++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/main/gatewayRTL_433.cpp b/main/gatewayRTL_433.cpp index 965e889..f85eacd 100644 --- a/main/gatewayRTL_433.cpp +++ b/main/gatewayRTL_433.cpp @@ -273,7 +273,34 @@ void rtl_433_Callback(char* message) { return; } - unsigned long MQTTvalue = (int)RFrtl_433_ESPdata["id"] + round((float)RFrtl_433_ESPdata["temperature_C"]); + // Hash the message payload excluding volatile fields (time, rssi, snr, noise_floor) + // that change between retransmissions of the same physical signal. This replaces the + // previous id+temperature_C approach which failed for devices lacking temperature_C. + // Use an order-independent (additive) combination of per-key hashes since JsonObject + // iteration order is not guaranteed to be consistent. + unsigned long MQTTvalue = 0; + for (JsonPair kv : RFrtl_433_ESPdata) { + const char* key = kv.key().c_str(); + if (strcmp(key, "time") == 0 || strcmp(key, "time_ms") == 0 || strcmp(key, "rssi") == 0 || + strcmp(key, "snr") == 0 || strcmp(key, "noise_floor") == 0 || strcmp(key, "pulses") == 0 || + strcmp(key, "duration") == 0) { + continue; + } + unsigned long kvHash = 0; + for (int i = 0; key[i] != '\0'; i++) + kvHash = kvHash * 31 + (unsigned char)key[i]; + kvHash = kvHash * 31 + 0xFF; // separator between key and value + String val; + serializeJson(kv.value(), val); + for (unsigned int i = 0; i < val.length(); i++) + kvHash = kvHash * 31 + (unsigned char)val[i]; + kvHash ^= kvHash >> 16; + kvHash *= 0x85ebca6bUL; + kvHash ^= kvHash >> 13; + kvHash *= 0xc2b2ae35UL; + kvHash ^= kvHash >> 16; + MQTTvalue += kvHash; // additive combination is order-independent + } String topic = subjectRTL_433toMQTT; String model = RFrtl_433_ESPdata["model"]; String type = RFrtl_433_ESPdata["type"]; diff --git a/main/main.cpp b/main/main.cpp index 3a40c4b..21e67b2 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -940,7 +940,11 @@ std::pair discoverMQTTbroker() { THEENGS_LOG_TRACE(F("%d service(s) found" CR), n); for (int i = 0; i < n; ++i) { THEENGS_LOG_TRACE(F("Service %d %s found" CR), i, MDNS.hostname(i).c_str()); +# if defined(ESP32) + THEENGS_LOG_TRACE(F("IP %s Port %d" CR), MDNS.address(i).toString().c_str(), MDNS.port(i)); +# else THEENGS_LOG_TRACE(F("IP %s Port %d" CR), MDNS.IP(i).toString().c_str(), MDNS.port(i)); +# endif } if (n == 1) { THEENGS_LOG_TRACE(F("One MQTT server found setting parameters" CR));