From 604c8a3eafde9404ebbd2979cf24af137df9ff76 Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 7 May 2026 08:51:32 +0200 Subject: [PATCH] . --- .gitignore | 1 + src/DataSender.cpp | 83 ------------- src/DataSender.h | 27 ----- src/MyMqttClient.cpp | 44 +++++-- src/MyMqttClient.h | 8 +- src/Receivers433/ReceiverFunkThermometer.cpp | 118 +++++++++++-------- src/Receivers433/ReceiverFunkThermometer.h | 4 +- src/UpdateHandler.cpp | 3 +- src/Version.h | 2 +- src/fensterPiepser_NodeMCU_32S.cpp | 55 +++++++-- 10 files changed, 153 insertions(+), 192 deletions(-) delete mode 100644 src/DataSender.cpp delete mode 100644 src/DataSender.h diff --git a/.gitignore b/.gitignore index 89cc49c..26078fe 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch +.aider* diff --git a/src/DataSender.cpp b/src/DataSender.cpp deleted file mode 100644 index 54f771b..0000000 --- a/src/DataSender.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * DataSender.cpp - * - * Created on: 08.10.2022 - * Author: flori - */ - - -#include "main.h" -#include "MyWifiClient.h" -#include "Seconds.h" - -#include "DataSender.h" - -DataSender dataSender; - -#define SEND_INTERVAL_SECONDS 120 -#define DATA_SIZE_PER_FENSTER 11 - -static uint8_t buf[DATA_SIZE_PER_FENSTER * NUM_FENSTER]; - - -DataSender::DataSender() -{ - bRequestSendWifi = true; - tNextSend = SEND_INTERVAL_SECONDS; -} - -DataSender::~DataSender() -{ - // TODO Auto-generated destructor stub -} - - -/** - * - */ -void DataSender::onSetup(void) -{ - myWifiClient.onSetup(); -} - -/** - * - */ -void DataSender::onLoop(void) -{ - if (Seconds::Get() >= tNextSend ) - { - bRequestSendWifi = true; - } - - if (bRequestSendWifi && myWifiClient.canSend()) - { - bRequestSendWifi = false; - - for (uint8_t i = 0; i < NUM_FENSTER; i++) - { - uint8_t offset = DATA_SIZE_PER_FENSTER * i; - memcpy( &buf[offset], alleFenster[i]->name, 8 ); - - uint16_t remainingTime = (uint16_t) alleFenster[i]->GetRemainingTime(); - memcpy( &buf[offset+8], &remainingTime , 2); - - uint8_t state = alleFenster[i]->IsOpen() ? 1 : 0; - state |= alleFenster[i]->ShallPiep() ? 2 : 0; - memcpy( &buf[offset+10], &state , 1); - } - - myWifiClient.send(buf, sizeof(buf)); - tNextSend = Seconds::Get() + SEND_INTERVAL_SECONDS; - } - - myWifiClient.onLoop(); -} - -/** - * - */ -void DataSender::requestSend(void) -{ - bRequestSendWifi = true; -} diff --git a/src/DataSender.h b/src/DataSender.h deleted file mode 100644 index 1ba3831..0000000 --- a/src/DataSender.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * DataSender.h - * - * Created on: 08.10.2022 - * Author: flori - */ - -#ifndef DATASENDER_H_ -#define DATASENDER_H_ - -class DataSender -{ -public: - DataSender(); - virtual ~DataSender(); - void onSetup(void); - void onLoop(void); - void requestSend(void); -private: - bool bRequestSendWifi; - uint32_t tNextSend; - -}; - -extern DataSender dataSender; - -#endif /* DATASENDER_H_ */ diff --git a/src/MyMqttClient.cpp b/src/MyMqttClient.cpp index 4bacad2..762a434 100644 --- a/src/MyMqttClient.cpp +++ b/src/MyMqttClient.cpp @@ -5,6 +5,7 @@ */ #include +#include #include "MyMqttClient.h" #include "Version.h" @@ -14,12 +15,12 @@ MyMqttClient myMqttClient; MyMqttClient::MyMqttClient() - : mqttClient(wifiClient) + : pubSubClient(wifiClient) , lastConnectAttemptMs(0) , lastWifiReconnectMs(0) { - mqttClient.setServer(MQTT_BROKER_IP, MQTT_BROKER_PORT); - mqttClient.setKeepAlive(300); + pubSubClient.setServer(MQTT_BROKER_IP, MQTT_BROKER_PORT); + pubSubClient.setKeepAlive(600); } /** @@ -29,7 +30,7 @@ MyMqttClient::MyMqttClient() */ bool MyMqttClient::ensureConnected() { - if (mqttClient.connected()) + if (pubSubClient.connected()) { return true; } @@ -51,22 +52,24 @@ bool MyMqttClient::ensureConnected() bool ok; if (strlen(MQTT_USER) > 0) { - ok = mqttClient.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD); + ok = pubSubClient.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD, + MQTT_TEMP_RH, 0, true, "{\"T\":0,\"rh\":0,\"t\":0}"); } else { - ok = mqttClient.connect(MQTT_CLIENT_ID); + ok = pubSubClient.connect(MQTT_CLIENT_ID, nullptr, nullptr, + MQTT_TEMP_RH, 0, true, "{\"T\":0,\"rh\":0,\"t\":0}"); } if (ok) { Serial.println("[MQTT] Connected"); - mqttClient.publish(MQTT_TOPIC_STATUS, + pubSubClient.publish(MQTT_TOPIC_SYSTEM, "{\"e\":\"hello\",\"client\":\"" MQTT_CLIENT_ID VERSION_STR "\"}"); } else { - Serial.printf("[MQTT] Connect failed, rc=%d\n", mqttClient.state()); + Serial.printf("[MQTT] Connect failed, rc=%d\n", pubSubClient.state()); } return ok; @@ -75,13 +78,28 @@ bool MyMqttClient::ensureConnected() /** * Publishes an arbitrary status payload to MQTT_TOPIC_STATUS. */ -void MyMqttClient::publishStatus(const char* payload) +void MyMqttClient::publishStatus(const char* payload, bool retain) { if (!ensureConnected()) { return; } - mqttClient.publish(MQTT_TOPIC_STATUS , payload); + pubSubClient.publish(MQTT_TOPIC_STATUS, payload, retain); +} + +/** + * Publishes temperature and humidity data to MQTT_TEMP_RH topic. + */ +void MyMqttClient::publishTemperatureAndHumidity(int temperature, uint8_t humidity, uint32_t rawData) +{ + if (!ensureConnected()) + { + return; + } + char payload[80]; + snprintf(payload, sizeof(payload), + "{\"T\":%d,\"rh\":%u,\"t\":%lu, \"raw\":%lu}", temperature, humidity, (unsigned long)time(nullptr), (unsigned long)rawData); + pubSubClient.publish(MQTT_TEMP_RH, payload, true); } /** @@ -104,18 +122,18 @@ void MyMqttClient::onLoop() if (WiFi.isConnected()) { ensureConnected(); - mqttClient.loop(); + pubSubClient.loop(); static uint32_t tNextRssiMs = 0u; if (millis() >= tNextRssiMs) { tNextRssiMs = millis() + 600000u; - if (mqttClient.connected()) + if (pubSubClient.connected()) { char payload[48]; snprintf(payload, sizeof(payload), "{\"rssi\":%d }", (int)WiFi.RSSI()); - mqttClient.publish(MQTT_TOPIC_RSSI, payload); + pubSubClient.publish(MQTT_TOPIC_RSSI, payload); } } } diff --git a/src/MyMqttClient.h b/src/MyMqttClient.h index b16a442..40b4073 100644 --- a/src/MyMqttClient.h +++ b/src/MyMqttClient.h @@ -16,8 +16,10 @@ #define MQTT_BROKER_IP "flokke.de" #define MQTT_BROKER_PORT 1883 #define MQTT_CLIENT_ID "Fensterpiepser" PROJECT_VARIANT +#define MQTT_TOPIC_SYSTEM "fenster/system/" PROJECT_VARIANT #define MQTT_TOPIC_STATUS "fenster/status/" PROJECT_VARIANT #define MQTT_TOPIC_RSSI "fenster/rssi/" PROJECT_VARIANT +#define MQTT_TEMP_RH "fenster/temprh/" PROJECT_VARIANT // Optional: set to "" if no authentication required #define MQTT_USER "lightcontrol" #define MQTT_PASSWORD "mR9o3OYpAzUZvS" @@ -27,7 +29,7 @@ class MyMqttClient { private: WiFiClient wifiClient; - PubSubClient mqttClient; + PubSubClient pubSubClient; uint32_t lastConnectAttemptMs; uint32_t lastWifiReconnectMs; @@ -38,7 +40,9 @@ public: MyMqttClient(); void onLoop(); - void publishStatus(const char* payload); + void publishStatus(const char* payload, bool retain = false); + void publishTemperatureAndHumidity(int temperature, uint8_t humidity, uint32_t rawData); + void closeConnection() { pubSubClient.disconnect(); } }; extern MyMqttClient myMqttClient; diff --git a/src/Receivers433/ReceiverFunkThermometer.cpp b/src/Receivers433/ReceiverFunkThermometer.cpp index b584aaa..0dba8ba 100644 --- a/src/Receivers433/ReceiverFunkThermometer.cpp +++ b/src/Receivers433/ReceiverFunkThermometer.cpp @@ -5,12 +5,12 @@ * Author: flori */ #include "main.h" -#include "DataSender.h" #include "ReceiverFunkThermometer.h" +#include -#define DEBUG_LEVEL 0 +#define DEBUG_LEVEL 2 -#define MonitorPrint(x) // Serial.print(x) +#define MonitorPrint(x) Serial.print(x) ReceiverFunkThermometer receiverThermo; @@ -57,11 +57,11 @@ IRAM_ATTR void ReceiverFunkThermometer::Isr(uint32_t dtMicros, bool pinValue) SignalDurationThermometer_t thisDuration = FUNK_THERMO_INVALID; - if (dtMicros > 350 && dtMicros < 600) + if (dtMicros > 400 && dtMicros < 600) { thisDuration = MS_0_5; } - else if (dtMicros > 800 && dtMicros < 1200) + else if (dtMicros > 900 && dtMicros < 1100) { thisDuration = MS_1_0; } @@ -89,23 +89,9 @@ IRAM_ATTR void ReceiverFunkThermometer::Isr(uint32_t dtMicros, bool pinValue) } else if (pinValue == HIGH ) { -#if DEBUG_LEVEL > 1 - bool bprint = (rByteIndex > 0 || rBitIndex<7); -#else - bool bprint = false; -#endif - if (bprint) - { - sprintf(textBuf, "\n%d %d : ", rByteIndex, rBitIndex ); - MonitorPrint(textBuf); - } if (thisDuration==MS_2_0 && lastDuration == MS_0_5) { - if (bprint) - { - MonitorPrint(F("1")); - } /* bit 1 received */ rBytes[rByteIndex] |= (1 << rBitIndex); if (rBitIndex == 0) @@ -126,10 +112,6 @@ IRAM_ATTR void ReceiverFunkThermometer::Isr(uint32_t dtMicros, bool pinValue) } else if (thisDuration==MS_1_0 &&lastDuration == MS_0_5) { - if (bprint) - { - MonitorPrint(F("0")); - } /* bit 0 received */ if (rBitIndex == 0) { @@ -147,14 +129,9 @@ IRAM_ATTR void ReceiverFunkThermometer::Isr(uint32_t dtMicros, bool pinValue) rBytes[0] = 0; } } - - } - } lastDuration = thisDuration; - - } /** @@ -247,8 +224,53 @@ bytes received from woolworth temp 69 +6 +111 +93 +102 +10 + + +96 +6 +111 +93 +102 +10 + + * */ + + +IRAM_ATTR void ReceiverFunkThermometer::printBits(void) +{ + Serial.println(""); + Serial.println("T_RH"); + for (int i = 0; i < THERMO_KEY_NUMBYTES_PER_KEY; i++) + { + for (int j = 7; j >= 0; j--) + { + Serial.print((rBytes[i] >> j) & 0x01); + } + Serial.print(" "); + } +} + + +/* + +Fehler: (anderer Sensor?) +01100000 00000110 10011111 01011101 T_RH +01100000 00000110 10011111 01011101 105 / 93 + +Korrekt: +01011000 00000111 10001111 00110110 T_RH +01011000 00000111 10001111 00110110 120 / 54 +iiiiiiii tttttttt ttttffff hhhhhhhh + +*/ + IRAM_ATTR void ReceiverFunkThermometer::OnTempReceived(void) { @@ -258,24 +280,13 @@ IRAM_ATTR void ReceiverFunkThermometer::OnTempReceived(void) value : id id t t t 0xf h h */ #define PRINT_ON_TEMP_RECEIVED 0 -#if 0 - /* testdaten */ - rBytes[0] = 112u; - rBytes[1] = 255u; - rBytes[2] = 191u; - rBytes[3] = 89u; -#endif #if PRINT_ON_TEMP_RECEIVED - Serial.println(rBytes[0]); - Serial.println(rBytes[1]); - Serial.println(rBytes[2]); - Serial.println(rBytes[3]); + printBits(); #endif - if ((rBytes[2]&0xF) == 0xF) /* these 4 bits must be 1 */ +if ( ((rBytes[0]&0xF0)==0x50) /* id bits are 0101 */ + && (rBytes[2]&0xF) == 0xF) { - - int16_t tempInt = 0; int16_t tempNow = 0; uint8_t rhNow = rBytes[3]; @@ -291,20 +302,17 @@ IRAM_ATTR void ReceiverFunkThermometer::OnTempReceived(void) tempInt = (~tempInt) & 0xFFFu; tempInt += 1; } - #if PRINT_ON_TEMP_RECEIVED - Serial.println(tempInt); - #endif + /* do the rounding with positive number */ tempNow = (tempInt + 5) / 10; + dataLast.tempDeciCelsius = tempInt; if (isNegative) { /* set to negative */ tempNow = -tempNow; + dataLast.tempDeciCelsius = -dataLast.tempDeciCelsius; } - #if PRINT_ON_TEMP_RECEIVED - Serial.println(tempNow); - #endif int16_t dTempAbs = (tempNow >= dataLast.tempC) ? (tempNow - dataLast.tempC) : (dataLast.tempC - tempNow); uint8_t dRHAbs = (rhNow >= dataLast.rhPercent) ? (rhNow - dataLast.rhPercent) : (dataLast.rhPercent - rhNow); @@ -317,8 +325,18 @@ IRAM_ATTR void ReceiverFunkThermometer::OnTempReceived(void) (dRHAbs <= 2u) ) #endif { - bNewData = true; - data = dataLast; + if (data.tempDeciCelsius != dataLast.tempDeciCelsius || data.rhPercent != dataLast.rhPercent) + { + bNewData = true; + data = dataLast; + data.rawData = ((uint32_t)rBytes[0] << 24) | ((uint32_t)rBytes[1] << 16) | ((uint32_t)rBytes[2] << 8) | rBytes[3]; +#if PRINT_ON_TEMP_RECEIVED + Serial.print(data.tempDeciCelsius); + Serial.print(" / "); + Serial.println(data.rhPercent); +#endif + } + } } diff --git a/src/Receivers433/ReceiverFunkThermometer.h b/src/Receivers433/ReceiverFunkThermometer.h index d327206..20aee10 100644 --- a/src/Receivers433/ReceiverFunkThermometer.h +++ b/src/Receivers433/ReceiverFunkThermometer.h @@ -23,8 +23,10 @@ typedef enum typedef struct { + int16_t tempDeciCelsius; int16_t tempC; uint8_t rhPercent; + uint32_t rawData; } ReceiverFunkThermometerData_t; @@ -45,7 +47,7 @@ private: void OnTempReceived(void); void ResetBuffer(void); void NextByte(void); - + void printBits(void); uint8_t rBytes[THERMO_KEY_NUMBYTES_PER_KEY]; uint8_t rByteIndex = 0; diff --git a/src/UpdateHandler.cpp b/src/UpdateHandler.cpp index 194f6e4..f466c83 100644 --- a/src/UpdateHandler.cpp +++ b/src/UpdateHandler.cpp @@ -75,8 +75,7 @@ void UpdateHandler() webServer.on("/update", HTTP_POST, []() { webServer.sendHeader("Connection", "close"); - webServer.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); - myMqttClient.publishStatus("{\"event\":\"reset_update\", \"variant\": \"" PROJECT_VARIANT "\" }"); + webServer.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); ESP.restart(); }, []() { diff --git a/src/Version.h b/src/Version.h index e4120c2..7885132 100644 --- a/src/Version.h +++ b/src/Version.h @@ -17,7 +17,7 @@ #endif #define PROJECT_NAME "FENSTER_PIEPSER_NODEMCU_32_S_" PROJECT_VARIANT -#define VERSION_STR "_v2.0.3" +#define VERSION_STR "_v2.0.8" #endif /* VERSION_H_ */ diff --git a/src/fensterPiepser_NodeMCU_32S.cpp b/src/fensterPiepser_NodeMCU_32S.cpp index 88976f2..ed964de 100644 --- a/src/fensterPiepser_NodeMCU_32S.cpp +++ b/src/fensterPiepser_NodeMCU_32S.cpp @@ -11,7 +11,6 @@ #include "Display.h" #include "Display_SSD1306.h" #include "Seconds.h" -#include "DataSender.h" #include "InterruptHandler.h" #include "xcp/XcpPort.h" #include "UpdateHandler.h" @@ -61,9 +60,10 @@ #define TONE_FREQUENCY_HZ 2000 +#define TIMEOUT_WIFI_CONNECTION_MS 30000u + #define USE_XCP (1u) #define USE_WIFI (1u) /* WARNING, no OTA update without wifi ! */ -#define USE_DATASENDER (0u) /*---------------- GLOBAL VARIABLES ------------- */ uint32_t gtMillis; @@ -156,7 +156,7 @@ static void handleDispUpdate(void); static void handleKeyReceived(void); static void updateIsNighttime(); static void updatePiepPattern(void); - +static void handleWifiConnection(void); /** * @@ -174,8 +174,6 @@ void setup() WiFi.mode(WIFI_STA); WiFi.begin(ssidElektro, password); - dataSender.onSetup(); - const char* ntpServer = "ptbtime3.ptb.de"; const long gmtOffset_sec = 3600; const int daylightOffset_sec = 3600; @@ -254,11 +252,7 @@ void loop() #if USE_WIFI //updateIsNighttime(); - -#if USE_DATASENDER - dataSender.onLoop(); -#endif - + handleWifiConnection(); myMqttClient.onLoop(); UpdateHandler(); #endif @@ -280,6 +274,40 @@ void loop() loopCountSincePause++; } +/* don't call from interrupt, set gbRestartRequest to true instead */ +static void myEspRestart() +{ + myMqttClient.closeConnection(); + delay(100); + esp_restart(); +} + +/** + * + */ +static void handleWifiConnection(void) +{ + static uint32_t tDoSoftResetMs = 0; + + if (true == WiFi.isConnected()) + { + tDoSoftResetMs = 0; + } + else + { + if (tDoSoftResetMs == 0u) + { + tDoSoftResetMs = millis() + TIMEOUT_WIFI_CONNECTION_MS; + WiFi.reconnect(); + } + else if (millis() > tDoSoftResetMs) + { + myMqttClient.publishStatus("{\"reset\":\"reset due to WiFi connection timeout\"}"); + myEspRestart(); + } + } +} + static void handleDispUpdate(void) { /* cyclically request display update */ @@ -443,6 +471,8 @@ static void handleKeyReceived(void) /* update wait time according to temperature */ updateWaittime(); + + myMqttClient.publishTemperatureAndHumidity(thermoData.tempC, thermoData.rhPercent, thermoData.rawData); } @@ -460,7 +490,6 @@ static void handleKeyReceived(void) if (bWindowChanged) { bUpdateDisp = true; - dataSender.requestSend(); bRequestShortBeep = true; publishAllFensterStatus("move"); if (lastKeyDirection == DIRECTION_CLOSE) @@ -520,7 +549,7 @@ static void testWaitTime() static void publishAllFensterStatus(const char *event) { char payload[256]; - sprintf(payload, "{ \"e\": \"%s\", \"n\": %d, \"f\": [", event, NUM_FENSTER); + sprintf(payload, "{ \"t\": %lu, \"e\": \"%s\", \"n\": %d, \"f\": [", (unsigned long)time(nullptr), event, NUM_FENSTER); for (uint8_t i = 0; i < NUM_FENSTER; i++) { if (i>0) strcat(payload, ","); @@ -542,7 +571,7 @@ static void publishAllFensterStatus(const char *event) } strcat(payload, "] }"); - myMqttClient.publishStatus(payload); + myMqttClient.publishStatus(payload, true); } /**