From 46ac08ac9c0d30fcdd22abea18a4cad95fa79b92 Mon Sep 17 00:00:00 2001 From: Nagoydede Date: Wed, 16 Apr 2025 00:39:37 +0200 Subject: [PATCH] MQTT implementation. MQTT message sends only when there is a data update. Also update conf in Homeassistant --- linky_tic.ino | 33 ++++++++++++++++++++++++++------ tic.cpp | 53 +++++++++++++++++++++++++++++++++++++++------------ tic.h | 2 ++ 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/linky_tic.ino b/linky_tic.ino index a842543..846b0eb 100644 --- a/linky_tic.ino +++ b/linky_tic.ino @@ -19,6 +19,10 @@ ESP8266WebServer server(HTTP_PORT); WiFiClient espClient; PubSubClient mqttclient(espClient); +unsigned long previousMillis = 0; +unsigned long previousForceMillis = 0; +const long interval = 1000; + void mqttConnect() { // Loop until we're reconnected while (!mqttclient.connected()) { @@ -165,15 +169,32 @@ void loop() { server.handleClient(); readTicPort(); - - //Interface MQTT - if (!mqttclient.connected()) { - mqttConnect(); + unsigned long currentMillis = millis(); + + if (currentMillis - previousMillis >= interval) { + // save the last time you blinked the LED + previousMillis = currentMillis; + + //Interface MQTT + if (!mqttclient.connected()) { + mqttConnect(); + } + + mqttPublish(&mqttclient); } - //mqttPublish(&mqttclient); - mqttclient.loop(); + if (currentMillis - previousForceMillis >= (30*interval)) { + // save the last time you blinked the LED + previousForceMillis = currentMillis; + //Interface MQTT + if (!mqttclient.connected()) { + mqttConnect(); + } + + mqttForcePublish(&mqttclient); + } + mqttclient.loop(); /* // Si aucune requête n'est en cours, mettre l'ESP8266 en mode deep sleep diff --git a/tic.cpp b/tic.cpp index 70b3720..ab33752 100644 --- a/tic.cpp +++ b/tic.cpp @@ -116,14 +116,33 @@ static void processTrame(String &data) { } // If a match is found, update the corresponding TicValues entry if (t < NB_ETIQUETTE) { - TicValues[t] = gd; - // Depending on the group name, call the appropriate processing function - if (gd.name == "STGE") { - processStge(®Status, gd.value); - } else if (gd.name == "RELAIS") { - processRelais(&relaisStatus, gd.value); - } else if (gd.name == "PJOURF+1") { - processActionsCalendrier(gd.value); + //If there is a value update + if (TicValues[t].value.compareTo(gd.value) != 0) { + //There is some noise on instantaneous value, filter + if (SelectedEtiquette[t] == "SINSTS" || SelectedEtiquette[t] == "SINSTS1" || SelectedEtiquette[t] == "SINSTS2" || SelectedEtiquette[t] == "SINSTS3") { + int oldval = TicValues[t].value.toInt(); + int newcal = (gd.value.toInt() + oldval) / 2; + if (newcal < oldval*0.92 || newcal > oldval*1.02){ + gd.updated = true; + TicValues[t] = gd; + } + else { + TicValues[t].value = String(newcal); + } + } else { + gd.updated = true; + TicValues[t] = gd; + // Depending on the group name, call the appropriate processing function + if (gd.name == "STGE") { + processStge(®Status, gd.value); + } else if (gd.name == "RELAIS") { + processRelais(&relaisStatus, gd.value); + } else if (gd.name == "PJOURF+1") { + processActionsCalendrier(gd.value); + } + } + } else { + TicValues[t].updated = false; } } data = data.substring(index + 1); @@ -317,15 +336,25 @@ String ticBasicValuesAsJson() { void mqttPublish(PubSubClient *mqttclient) { for (int i = 0; i < NB_ETIQUETTE; ++i) { - if (SelectedEtiquette[i] == "LTARF" || SelectedEtiquette[i] == "EAST" || SelectedEtiquette[i] == "EASF01" || SelectedEtiquette[i] == "EASF02" || SelectedEtiquette[i] == "EASF03" || SelectedEtiquette[i] == "EASF04" || SelectedEtiquette[i] == "EASD01" || SelectedEtiquette[i] == "EASD02" || SelectedEtiquette[i] == "EASD03" || SelectedEtiquette[i] == "EASD04" || SelectedEtiquette[i] == "EAIT" || SelectedEtiquette[i] == "ERQ1" || SelectedEtiquette[i] == "ERQ2" || SelectedEtiquette[i] == "ERQ3" || SelectedEtiquette[i] == "ERQ4" || SelectedEtiquette[i] == "IRMS1" || SelectedEtiquette[i] == "IRMS2" || SelectedEtiquette[i] == "IRMS3" || SelectedEtiquette[i] == "URMS1" || SelectedEtiquette[i] == "URMS2" || SelectedEtiquette[i] == "URMS3" || SelectedEtiquette[i] == "SINSTS" || SelectedEtiquette[i] == "SINSTSI" || SelectedEtiquette[i] == "SINSTS1" || SelectedEtiquette[i] == "SINSTS2" || SelectedEtiquette[i] == "SINSTS3" || SelectedEtiquette[i] == "SINSTSI") { - String topic= MQTT_TOPIC; - topic += "/", - topic += SelectedEtiquette[i]; + if (TicValues[i].updated) { + String topic = MQTT_TOPIC; + topic += "/", + topic += SelectedEtiquette[i]; mqttclient->publish(topic.c_str(), TicValues[i].value.c_str()); + TicValues[i].updated = false; } } } +void mqttForcePublish(PubSubClient *mqttclient) { + for (int i = 0; i < NB_ETIQUETTE; ++i) { + String topic = MQTT_TOPIC; + topic += "/", + topic += SelectedEtiquette[i]; + mqttclient->publish(topic.c_str(), TicValues[i].value.c_str()); + } +} + /** * Reads data from the TicPort and processes it according to specific control characters. * diff --git a/tic.h b/tic.h index 7693859..557afbd 100644 --- a/tic.h +++ b/tic.h @@ -32,6 +32,7 @@ struct GroupDetail { String name; // Nom de l'étiquette String value; // Valeur associée à l'étiquette String horodate; // Horodatage de la valeur + bool updated; }; // Structure pour les bits de statut du registre @@ -161,4 +162,5 @@ void readTicPort(); String ticValuesAsJson(); String ticBasicValuesAsJson(); void mqttPublish(PubSubClient *mqttclient); +void mqttForcePublish(PubSubClient *mqttclient); #endif \ No newline at end of file