From 5c5fba217c53045c615b70478107d7c4442ddc91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Tue, 7 Jan 2025 00:01:54 +0100 Subject: [PATCH] NodeTest fully working --- platformio.ini | 28 ++++++++++++++- src/NodeHeizung.h | 43 +++++++++++------------ src/NodeTest.h | 57 +++++++++++++++++++++++++++++++ src/patrix/clock.cpp | 14 +++++--- src/patrix/clock.h | 2 +- src/patrix/log.cpp | 3 +- src/patrix/main.cpp | 14 ++++++++ src/patrix/mqtt.cpp | 12 ++++++- src/patrix/mqtt.h | 4 +++ src/patrix/sensor/DHT22.h | 9 +++-- src/patrix/sensor/Dallas.h | 43 +++++++++-------------- src/patrix/sensor/DallasSensor.h | 1 + src/patrix/sensor/Max6675Sensor.h | 3 ++ src/patrix/wifi.cpp | 2 +- 14 files changed, 176 insertions(+), 59 deletions(-) create mode 100644 src/NodeTest.h diff --git a/platformio.ini b/platformio.ini index cd8b811..4dcf804 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,4 +1,4 @@ -[env:heizung] +[common] platform = espressif32 board = esp32dev framework = arduino @@ -17,5 +17,31 @@ monitor_speed = 115200 monitor_filters = esp32_exception_decoder build_flags = -DWIFI_SSID=\"HappyNet\" -DWIFI_PKEY=\"1Grausame!Sackratte7\" + +[env:test] +platform = ${common.platform} +board = ${common.board} +framework = ${common.framework} +lib_deps = ${common.lib_deps} +upload_port = ${common.upload_port} +upload_speed = ${common.upload_speed} +monitor_port = ${common.monitor_port} +monitor_speed = ${common.monitor_speed} +monitor_filters = ${common.monitor_filters} +build_flags = ${common.build_flags} + -DWIFI_HOST=\"Test\" + -DNODE_TEST + +[env:heizung] +platform = ${common.platform} +board = ${common.board} +framework = ${common.framework} +lib_deps = ${common.lib_deps} +upload_port = ${common.upload_port} +upload_speed = ${common.upload_speed} +monitor_port = ${common.monitor_port} +monitor_speed = ${common.monitor_speed} +monitor_filters = ${common.monitor_filters} +build_flags = ${common.build_flags} -DWIFI_HOST=\"Heizung\" -DNODE_HEIZUNG \ No newline at end of file diff --git a/src/NodeHeizung.h b/src/NodeHeizung.h index 3bd6d6e..1c771e0 100644 --- a/src/NodeHeizung.h +++ b/src/NodeHeizung.h @@ -9,6 +9,10 @@ class NodeHeizung final : public Node { + DHT22 keller; + + Max6675Sensor abgas; + Dallas dallas; DallasSensor pufferVorlauf; @@ -31,25 +35,22 @@ class NodeHeizung final : public Node { DallasSensor reserve; - Max6675Sensor abgas; - - DHT22 heizungsraum; - public: - NodeHeizung() : dallas(14), - pufferVorlauf(dallas, 0xAA0121125E4A7528, "heizung/puffer/vorlauf", 1.0), - pufferRuecklauf(dallas, 0x3E0121126A163B28, "heizung/puffer/ruecklauf", 1.0), - pufferEingang(dallas, 0x0201211240EE3128, "heizung/puffer/eingang", 1.0), - pufferSpeicher(dallas, 0x1001211233D3A428, "heizung/puffer/speicher", 1.0), - pufferAusgang(dallas, 0xE80121126FFD9328, "heizung/puffer/ausgang", 1.0), - pufferZirkulation(dallas, 0x540121124A48FD28, "heizung/puffer/zirkulation", 1.0), - heizkreisVorlauf(dallas, 0x330121126F984728, "heizung/heizkreis/vorlauf", 1.0), - heizkreisRuecklauf(dallas, 0x4201211270337B28, "heizung/heizkreis/ruecklauf", 1.0), - abwasser(dallas, 0x810121126EE53828, "abwasser", 1.0), - reserve(dallas, 0x0D0121126716CF28, "__RESERVE__", 1.0), - abgas(27, 26, 25, "heizung/abgas", 2), - heizungsraum(13, "heizungsraum", 0.5, 2, 0.5) { + NodeHeizung() : + keller(13, "keller", 0.5, 2, 0.5), + abgas(27, 26, 25, "heizung/abgas", 2), + dallas(14), + pufferVorlauf(dallas, 0xAA0121125E4A7528, "heizung/puffer/vorlauf", 1.0), + pufferRuecklauf(dallas, 0x3E0121126A163B28, "heizung/puffer/ruecklauf", 1.0), + pufferEingang(dallas, 0x0201211240EE3128, "heizung/puffer/eingang", 1.0), + pufferSpeicher(dallas, 0x1001211233D3A428, "heizung/puffer/speicher", 1.0), + pufferAusgang(dallas, 0xE80121126FFD9328, "heizung/puffer/ausgang", 1.0), + pufferZirkulation(dallas, 0x540121124A48FD28, "heizung/puffer/zirkulation", 1.0), + heizkreisVorlauf(dallas, 0x330121126F984728, "heizung/heizkreis/vorlauf", 1.0), + heizkreisRuecklauf(dallas, 0x4201211270337B28, "heizung/heizkreis/ruecklauf", 1.0), + abwasser(dallas, 0x810121126EE53828, "abwasser", 1.0), + reserve(dallas, 0x0D0121126716CF28, "__RESERVE__", 1.0) { // }; @@ -58,6 +59,8 @@ public: } void loop() override { + keller.loop(); + abgas.loop(); dallas.loop(); pufferVorlauf.loop(); pufferRuecklauf.loop(); @@ -69,11 +72,11 @@ public: heizkreisRuecklauf.loop(); abwasser.loop(); reserve.loop(); - abgas.loop(); - heizungsraum.loop(); } void toJson(JsonDocument& json) override { + keller.toJson(json); + abgas.toJson(json); pufferVorlauf.toJson(json); pufferRuecklauf.toJson(json); pufferEingang.toJson(json); @@ -84,8 +87,6 @@ public: heizkreisRuecklauf.toJson(json); abwasser.toJson(json); reserve.toJson(json); - abgas.toJson(json); - heizungsraum.toJson(json); } }; diff --git a/src/NodeTest.h b/src/NodeTest.h new file mode 100644 index 0000000..80e1ab0 --- /dev/null +++ b/src/NodeTest.h @@ -0,0 +1,57 @@ +#ifndef NODE_TEST_H +#define NODE_TEST_H + +#include + +#include "patrix/Node.h" +#include "patrix/sensor/Dallas.h" +#include "patrix/sensor/DallasSensor.h" +#include "patrix/sensor/Max6675Sensor.h" +#include "patrix/sensor/DHT22.h" + +class NodeTest final : public Node { + + Dallas dallas; + + DallasSensor test; + + DHT22 testraum; + +public: + + NodeTest() : dallas(27), + test(dallas, 0xC90417C1C5C0FF28, "test/ds18b20", 1.0), + testraum(26, "test/dht22", 0.5, 2, 0.5) { + // + }; + + void setup() override { + // TODO + } + + void send() { + JsonDocument json; + toJson(json); + mqttPublish(WiFiClass::getHostname(), json); + } + + void loop() override { + dallas.loop(); + test.loop(); + testraum.loop(); + static auto last = 0UL; + const auto now = millis(); + if (last == 0 || now - last >= 3000) { // TODO + last = now; + send(); + } + } + + void toJson(JsonDocument& json) override { + test.toJson(json); + testraum.toJson(json); + } + +}; + +#endif diff --git a/src/patrix/clock.cpp b/src/patrix/clock.cpp index 5dfad92..9941ee5 100644 --- a/src/patrix/clock.cpp +++ b/src/patrix/clock.cpp @@ -31,8 +31,7 @@ void clockLoop() { clockOffset = now; } else { startupTime = now - clockOffset; - const auto startStr = String(ctime(&startupTime)); - info("clock set after %ld seconds! So startup was at %s", clockOffset, startStr.c_str()); + info("clock set after %ld seconds! So startup was at %s", clockOffset, getClockStr()); } } @@ -40,9 +39,14 @@ bool isClockSet() { return startupTime != 0; } -String getClockStr() { - const auto t = time(nullptr); - return {ctime(&t)}; +char buffer[20]; + +char *getClockStr() { + const auto now = time(nullptr); + tm t{0}; + localtime_r(&now, &t); + snprintf(buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); + return buffer; } bool isCorrectTime(const time_t now) { diff --git a/src/patrix/clock.h b/src/patrix/clock.h index 43435ec..f3d992a 100644 --- a/src/patrix/clock.h +++ b/src/patrix/clock.h @@ -7,7 +7,7 @@ void clockLoop(); bool isClockSet(); -String getClockStr(); +char * getClockStr(); bool isCorrectTime(time_t now); diff --git a/src/patrix/log.cpp b/src/patrix/log.cpp index 931a076..58e1874 100644 --- a/src/patrix/log.cpp +++ b/src/patrix/log.cpp @@ -11,7 +11,7 @@ void log(const LogLevel level, const char *format, const va_list args) { if (level > logLevel) { return; } - Serial.print(getClockStr().c_str()); + Serial.print(getClockStr()); switch (level) { case ERROR: Serial.print(" [ERROR] "); @@ -30,6 +30,7 @@ void log(const LogLevel level, const char *format, const va_list args) { char message[256]; vsnprintf(message, sizeof message, format, args); Serial.print(message); + Serial.print("\n"); yield(); } diff --git a/src/patrix/main.cpp b/src/patrix/main.cpp index ff5cf9b..52d3ee8 100644 --- a/src/patrix/main.cpp +++ b/src/patrix/main.cpp @@ -4,12 +4,26 @@ #include "wifi.h" #include "clock.h" +#ifdef NODE_TEST + #include "NodeTest.h" + NodeTest node = NodeTest(); +#endif + +#ifdef NODE_HEIZUNG + #include "NodeHeizung.h" + NodeHeizung node = NodeHeizung(); +#endif + void setup() { Serial.begin(115200); + delay(500); + Serial.print("Startup\n"); + node.setup(); } void loop() { wifiLoop(); clockLoop(); mqttLoop(); + node.loop(); } diff --git a/src/patrix/mqtt.cpp b/src/patrix/mqtt.cpp index 40705c2..5450325 100644 --- a/src/patrix/mqtt.cpp +++ b/src/patrix/mqtt.cpp @@ -8,7 +8,9 @@ #define MQTT_RETRY_DELAY_MILLIS 3000 -PubSubClient mqtt; +WiFiClient wifiClient; + +PubSubClient mqtt(wifiClient); auto mqttHost = "10.0.0.50"; @@ -30,6 +32,7 @@ void mqttLoop() { snprintf(mqttWillTopic, sizeof(mqttWillTopic), "%s/online", WiFiClass::getHostname()); mqtt.setServer(mqttHost, mqttPort); mqtt.setKeepAlive(10); + mqtt.setBufferSize(512); mqttLastConnectMillis = millis(); info("mqtt connecting: host=%s, port=%d", mqttHost, mqttPort); if (mqtt.connect(WiFiClass::getHostname(), mqttWillTopic, 1, true, "false")) { @@ -42,3 +45,10 @@ void mqttLoop() { } } } + +void mqttPublish(const char *topic, const JsonDocument& json) { + char buffer[512]; + serializeJson(json, buffer); + info(buffer); + mqtt.publish(topic, buffer); +} diff --git a/src/patrix/mqtt.h b/src/patrix/mqtt.h index 7e70f67..2329cec 100644 --- a/src/patrix/mqtt.h +++ b/src/patrix/mqtt.h @@ -1,6 +1,10 @@ #ifndef MQTT_H #define MQTT_H +#include + void mqttLoop(); +void mqttPublish(const char *topic, const JsonDocument& json); + #endif diff --git a/src/patrix/sensor/DHT22.h b/src/patrix/sensor/DHT22.h index c4e270a..6c8db41 100644 --- a/src/patrix/sensor/DHT22.h +++ b/src/patrix/sensor/DHT22.h @@ -3,6 +3,8 @@ #include "dht_nonblocking.h" +#include "Sensor.h" + class DHT22 final : public Sensor { DHT_nonblocking sensor; @@ -26,8 +28,11 @@ public: } bool loop() override { - sensor.measure(&temperature, &humidityRelative); - humidityAbsolute = 6.112 * exp(17.67 * temperature / (243.5 + temperature)) * humidityRelative * 2.1674 / (temperature + 273.15); + if (sensor.measure(&temperature, &humidityRelative)) { + humidityAbsolute = 6.112 * exp(17.67 * temperature / (243.5 + temperature)) * humidityRelative * 2.1674 / (temperature + 273.15); + info("%s: temperature=%.1f^C, humidityRelative=%.0f%%, humidityAbsolute=%.0fmg/L", name, temperature, humidityRelative, humidityAbsolute); + } + return false; // TODO } void toJson(JsonDocument& json) override { diff --git a/src/patrix/sensor/Dallas.h b/src/patrix/sensor/Dallas.h index ec6a6cb..c737ed1 100644 --- a/src/patrix/sensor/Dallas.h +++ b/src/patrix/sensor/Dallas.h @@ -1,8 +1,8 @@ #ifndef DALLAS_H #define DALLAS_H +#include "../log.h" #include "OneWire.h" - #include "DallasTemperature.h" #define DALLAS_TIMEOUT_MILLISECONDS 3000 @@ -21,8 +21,6 @@ class Dallas { bool converted = false; - bool first = true; - public: explicit Dallas(const int pin) : oneWire(pin), sensors(&oneWire) { @@ -31,35 +29,28 @@ public: } void loop() { - if (converting) { - if (sensors.isConversionComplete()) { - if (first) { - first = false; - const auto count = sensors.getDeviceCount(); - if (count == 0) { - Serial.printf("ERROR: No Dallas devices found!\n"); - } else { - Serial.printf("Found %d Dallas devices:\n", count); - uint64_t address; - for (int index = 0; index < count; ++index) { - sensors.getAddress(reinterpret_cast(&address), index); - Serial.printf(" - 0x%016llX = %5.1f C\n", address, sensors.getTempC(reinterpret_cast(&address))); - } - } - } - converting = false; - converted = true; - } else if (millis() - lastMillis > DALLAS_TIMEOUT_MILLISECONDS) { - Serial.print("ERROR: Dallas timeout!\n"); - converting = false; - converted = false; + if (lastMillis == 0 || millis() - lastMillis > DALLAS_TIMEOUT_MILLISECONDS) { + if (converting) { + error("Dallas timeout!\n"); } - } else { sensors.requestTemperatures(); timestamp = time(nullptr); lastMillis = millis(); converting = true; converted = false; + } else if (converting && sensors.isConversionComplete()) { + const auto count = sensors.getDeviceCount(); + if (count != 0) { + uint64_t address; + for (int index = 0; index < count; ++index) { + sensors.getAddress(reinterpret_cast(&address), index); + info("Dallas %d/%d 0x%016llX = %5.1f ^C", index + 1, count, address, sensors.getTempC(reinterpret_cast(&address))); + } + } else { + warn("No Dallas devices found!"); + } + converting = false; + converted = true; } } diff --git a/src/patrix/sensor/DallasSensor.h b/src/patrix/sensor/DallasSensor.h index 46633bc..eec422b 100644 --- a/src/patrix/sensor/DallasSensor.h +++ b/src/patrix/sensor/DallasSensor.h @@ -25,6 +25,7 @@ public: if (sensors.isConverted()) { temperature = sensors.read(address); } + return false; // TODO } void toJson(JsonDocument& json) override { diff --git a/src/patrix/sensor/Max6675Sensor.h b/src/patrix/sensor/Max6675Sensor.h index 6045044..b49014b 100644 --- a/src/patrix/sensor/Max6675Sensor.h +++ b/src/patrix/sensor/Max6675Sensor.h @@ -3,6 +3,8 @@ #include "max6675.h" +#include "Sensor.h" + class Max6675Sensor final : public Sensor { MAX6675 sensor; @@ -22,6 +24,7 @@ public: bool loop() override { float current = sensor.readCelsius(); temperature = current; + return false; // TODO } void toJson(JsonDocument& json) override { diff --git a/src/patrix/wifi.cpp b/src/patrix/wifi.cpp index 375aa57..8d2cdb4 100644 --- a/src/patrix/wifi.cpp +++ b/src/patrix/wifi.cpp @@ -64,7 +64,7 @@ void wifiLoop() { ArduinoOTA.end(); WiFi.disconnect(); } - } else if (wifiConnected) { + } else if (!wifiConnected) { if (wifiTryMillis == 0 || millis() - wifiTryMillis >= WIFI_TIMEOUT_MILLIS) { wifiTryMillis = millis(); WiFiClass::hostname(wifiHost);