using Value class and publishing if due

This commit is contained in:
Patrick Haßel 2025-01-07 10:15:41 +01:00
parent d9be78d738
commit 32401a6560
11 changed files with 162 additions and 75 deletions

View File

@ -4,8 +4,8 @@
#include "patrix/Node.h"
#include "patrix/sensor/Dallas.h"
#include "patrix/sensor/DallasSensor.h"
#include "patrix/sensor/Max6675Sensor.h"
#include "patrix/sensor/DHT22.h"
#include "patrix/sensor/Max6675Sensor.h"
class NodeHeizung final : public Node {
@ -37,20 +37,19 @@ class NodeHeizung final : public Node {
public:
NodeHeizung() :
keller(13, "keller", 0.5, 2, 0.5),
abgas(27, 26, 25, "heizung/abgas", 2),
NodeHeizung() : keller(13, "keller", 0.5, 2, 0.5, 60),
abgas(27, 26, 25, "heizung/abgas", 2, 60),
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) {
pufferVorlauf(dallas, 0xAA0121125E4A7528, "heizung/puffer/vorlauf", 1.0, 60),
pufferRuecklauf(dallas, 0x3E0121126A163B28, "heizung/puffer/ruecklauf", 1.0, 60),
pufferEingang(dallas, 0x0201211240EE3128, "heizung/puffer/eingang", 1.0, 60),
pufferSpeicher(dallas, 0x1001211233D3A428, "heizung/puffer/speicher", 1.0, 60),
pufferAusgang(dallas, 0xE80121126FFD9328, "heizung/puffer/ausgang", 1.0, 60),
pufferZirkulation(dallas, 0x540121124A48FD28, "heizung/puffer/zirkulation", 1.0, 60),
heizkreisVorlauf(dallas, 0x330121126F984728, "heizung/heizkreis/vorlauf", 1.0, 60),
heizkreisRuecklauf(dallas, 0x4201211270337B28, "heizung/heizkreis/ruecklauf", 1.0, 60),
abwasser(dallas, 0x810121126EE53828, "abwasser", 1.0, 60),
reserve(dallas, 0x0D0121126716CF28, "__RESERVE__", 1.0, 60) {
//
};

View File

@ -4,7 +4,6 @@
#include <WiFi.h>
#include "patrix/Node.h"
#include "patrix/mqtt.h"
#include "patrix/sensor/Dallas.h"
#include "patrix/sensor/DallasSensor.h"
#include "patrix/sensor/DHT22.h"
@ -20,8 +19,8 @@ class NodeTest final : public Node {
public:
NodeTest() : dallas(27),
test(dallas, 0xC90417C1C5C0FF28, "test/ds18b20", 1.0),
testraum(26, "test/dht22", 0.5, 2, 0.5) {
test(dallas, 0xC90417C1C5C0FF28, "test/ds18b20", 1.0, 60),
testraum(26, "test/dht22", 0.5, 2, 1, 605) {
//
};
@ -29,21 +28,17 @@ public:
// 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();
if (test.isDue() || testraum.isDue()) {
JsonDocument json;
toJson(json);
if (mqttPublish(WiFiClass::getHostname(), json)) {
test.markSent();
testraum.markSent();
}
}
}

View File

@ -8,7 +8,7 @@
AsyncWebServer server(80);
void httpIndex(AsyncWebServerRequest *request) {
request->send(200, "text/plain", R"(<a href="/reboot">reboot</a>)");
request->send(200, "text/html", R"(<a href="/reboot">reboot</a>)");
}
void httpReboot(AsyncWebServerRequest *request) {

View File

@ -5,15 +5,18 @@
#include "http.h"
#include "mqtt.h"
#ifdef NODE_TEST
#include "NodeTest.h"
#include "sensor/DallasSensor.h"
#include "sensor/DHT22.h"
#include "sensor/Max6675Sensor.h"
#include "NodeTest.h"
#include "NodeHeizung.h"
#ifdef NODE_TEST
auto node = NodeTest();
#endif
#ifdef NODE_HEIZUNG
#include "NodeHeizung.h"
auto node = NodeHeizung();
#endif

View File

@ -46,9 +46,9 @@ void mqttLoop() {
}
}
void mqttPublish(const char *topic, const JsonDocument& json) {
bool mqttPublish(const char *topic, const JsonDocument& json) {
char buffer[512];
serializeJson(json, buffer);
info(buffer);
mqtt.publish(topic, buffer);
return mqtt.publish(topic, buffer);
}

View File

@ -5,6 +5,6 @@
void mqttLoop();
void mqttPublish(const char *topic, const JsonDocument& json);
bool mqttPublish(const char *topic, const JsonDocument& json);
#endif

View File

@ -9,36 +9,53 @@ class DHT22 final : public Sensor {
DHT_nonblocking sensor;
double temperatureThreshold;
Value temperature;
double humidityRelativeThreshold;
Value humidityRelative;
double humidityAbsoluteThreshold;
float temperature = NAN;
float humidityRelative = NAN;
double humidityAbsolute = NAN;
Value humidityAbsolute;
public:
DHT22(const int pin, const char *name, const double temperatureThreshold, const double humidityRelativeThreshold, const double humidityAbsoluteThreshold) : Sensor(name), sensor(pin, DHT_TYPE_22), temperatureThreshold(temperatureThreshold), humidityRelativeThreshold(humidityRelativeThreshold), humidityAbsoluteThreshold(humidityAbsoluteThreshold) {
DHT22(const int pin,
const char *name,
const double temperatureThreshold,
const double humidityRelativeThreshold,
const double humidityAbsoluteThreshold,
const unsigned long dueSeconds
) : Sensor(name),
sensor(pin, DHT_TYPE_22),
temperature("temperature", temperatureThreshold, dueSeconds),
humidityRelative("humidityRelative", humidityRelativeThreshold, dueSeconds),
humidityAbsolute("humidityAbsolute", humidityAbsoluteThreshold, dueSeconds) {
//
}
bool loop() override {
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);
float t, hr;
if (sensor.measure(&t, &hr)) {
temperature.update(t);
humidityRelative.update(hr);
humidityAbsolute.update(6.112 * exp(17.67 * t / (243.5 + t)) * hr * 2.1674 / (t + 273.15));
info("%s: temperature=%.1f^C, humidityRelative=%.0f%%, humidityAbsolute=%.0fmg/L", name, temperature.getCurrentValue(), humidityRelative.getCurrentValue(), humidityAbsolute.getCurrentValue());
}
return false; // TODO
}
void toJson(JsonDocument& json) override {
json[name]["temperature"] = temperature;
json[name]["humidity"]["relative"] = humidityRelative;
json[name]["humidity"]["absolute"] = humidityAbsolute;
json[name][temperature.getName()] = temperature.getCurrentValue();
json[name][humidityRelative.getName()] = humidityRelative.getCurrentValue();
json[name][humidityAbsolute.getName()] = humidityAbsolute.getCurrentValue();
}
bool isDue() const override {
return temperature.isDue() || humidityRelative.isDue() || humidityAbsolute.isDue();
}
void markSent() override {
temperature.markSent();
humidityRelative.markSent();
humidityAbsolute.markSent();
}
};

View File

@ -2,6 +2,7 @@
#define DALLAS_SENSOR_H
#include "Sensor.h"
#include "Value.h"
#include "Dallas.h"
@ -11,25 +12,40 @@ class DallasSensor final : public Sensor {
uint64_t address;
double threshold;
double temperature = NAN;
Value temperature;
public:
DallasSensor(Dallas& sensors, const uint64_t address, const char *name, const double threshold) : Sensor(name), sensors(sensors), address(address), threshold(threshold) {
// -
DallasSensor(
Dallas& sensors,
const uint64_t address,
const char *name,
const double threshold,
const unsigned long dueSeconds
) : Sensor(name),
sensors(sensors),
address(address),
temperature("temperature", threshold, dueSeconds) {
//
}
bool loop() override {
if (sensors.isConverted()) {
temperature = sensors.read(address);
temperature.update(sensors.read(address));
}
return false; // TODO
}
void toJson(JsonDocument& json) override {
json[name]["temperature"] = temperature;
json[name][temperature.getName()] = temperature.getCurrentValue();
}
bool isDue() const override {
return temperature.isDue();
}
void markSent() override {
temperature.markSent();
}
};

View File

@ -1,34 +1,50 @@
#ifndef MAX6675SENSOR_H
#define MAX6675SENSOR_H
#include "max6675.h"
#include "Sensor.h"
#include "Value.h"
#include "max6675.h"
class Max6675Sensor final : public Sensor {
MAX6675 sensor;
double threshold;
double temperature = NAN;
Value temperature;
unsigned long lastMillis = 0;
public:
explicit Max6675Sensor(const int8_t pinMISO, const int8_t pinCS, const int8_t pinCLK, const char *name, const double threshold) : Sensor(name), sensor(pinCLK, pinCS, pinMISO), threshold(threshold) {
// -
explicit Max6675Sensor(
const int8_t pinMISO,
const int8_t pinCS,
const int8_t pinCLK,
const char *name,
const double threshold,
const unsigned long dueSeconds
) : Sensor(name),
sensor(pinCLK, pinCS, pinMISO),
temperature("temperature", threshold, dueSeconds) {
//
}
bool loop() override {
float current = sensor.readCelsius();
temperature = current;
temperature.update(current);
return false; // TODO
}
void toJson(JsonDocument& json) override {
json[name]["temperature"] = temperature;
json[name][temperature.getName()] = temperature.getCurrentValue();
}
bool isDue() const override {
return temperature.isDue();
}
void markSent() override {
temperature.markSent();
}
};

View File

@ -21,6 +21,10 @@ public:
virtual void toJson(JsonDocument& json) = 0;
virtual bool isDue() const = 0;
virtual void markSent() = 0;
};
#endif

View File

@ -3,19 +3,56 @@
class Value {
const char *name;
double threshold;
double lastValue;
unsigned long dueSeconds;
unsigned long lastMillis;
double currentValue = NAN;
double sentValue;
unsigned long currentInterval = 0;
unsigned long sentMillis;
double sentValue = NAN;
unsigned long sentInterval = 0;
public:
Value(
const char *name,
const double threshold,
const unsigned long dueSeconds
) : name(name),
threshold(threshold),
dueSeconds(dueSeconds) {
//
}
void update(const double value) {
currentValue = value;
currentInterval = time(nullptr) / dueSeconds;
}
bool isDue() const {
const auto dueToNAN = isnan(currentValue) != isnan(sentValue);
const auto dueToThreshold = abs(sentValue - currentValue) >= threshold;
const auto dueToTime = currentInterval != sentInterval;
return dueToNAN || dueToThreshold || dueToTime;
}
void markSent() {
sentValue = currentValue;
sentInterval = currentInterval;
}
const char *getName() const {
return name;
}
double getCurrentValue() const {
return currentValue;
}
};