gridPowerDelta

This commit is contained in:
Patrick Haßel 2025-09-03 11:09:07 +02:00
parent 951d15ac81
commit f72c04b9b3
5 changed files with 89 additions and 50 deletions

View File

@ -69,7 +69,7 @@ public:
return (digitalRead(pin) == HIGH) ^ inverted; return (digitalRead(pin) == HIGH) ^ inverted;
} }
void set(const bool state) { virtual void set(const bool state) {
_write(state); _write(state);
onCount = 0; onCount = 0;
} }

View File

@ -15,10 +15,14 @@ class Relay final : public Output {
String topic; String topic;
bool gridPowerDeltaOffEnabled = false;
long gridPowerDeltaOnThreshold = 0; long gridPowerDeltaOnThreshold = 0;
long gridPowerDeltaOnDelay = 0; long gridPowerDeltaOnDelay = 0;
bool gridPowerDeltaOnEnabled = false;
long gridPowerDeltaOffThreshold = 0; long gridPowerDeltaOffThreshold = 0;
long gridPowerDeltaOffDelay = 0; long gridPowerDeltaOffDelay = 0;
@ -41,11 +45,13 @@ public:
topic = configRead(path("topic"), topicFallback); topic = configRead(path("topic"), topicFallback);
gridPowerDeltaOnThreshold = configRead(path("autoOnThreshold"), -400L); gridPowerDeltaOnEnabled = configRead(path("gridPowerDeltaOnEnabled"), false);
gridPowerDeltaOnDelay = configRead(path("autoOnDelay"), 30000L); gridPowerDeltaOnThreshold = configRead(path("gridPowerDeltaOnThreshold"), 0L);
gridPowerDeltaOnDelay = configRead(path("gridPowerDeltaOnDelay"), 0L);
gridPowerDeltaOffThreshold = configRead(path("autoOffThreshold"), 100L); gridPowerDeltaOffEnabled = configRead(path("gridPowerDeltaOffEnabled"), false);
gridPowerDeltaOffDelay = configRead(path("autoOffDelay"), 30000L); gridPowerDeltaOffThreshold = configRead(path("gridPowerDeltaOffThreshold"), 0L);
gridPowerDeltaOffDelay = configRead(path("gridPowerDeltaOffDelay"), 0L);
_applyInitial(); _applyInitial();
} }
@ -80,30 +86,38 @@ public:
configWrite(path("topic"), topicFallback, value); configWrite(path("topic"), topicFallback, value);
} }
void setAutoOnThreshold(const long value) { void setGridPowerDeltaOnEnabled(const bool value) {
gridPowerDeltaOnEnabled = value;
configWrite(path("gridPowerDeltaOnEnabled"), false, value);
}
void setGridPowerDeltaOnThreshold(const long value) {
gridPowerDeltaOnThreshold = value; gridPowerDeltaOnThreshold = value;
configWrite(path("autoOnThreshold"), 0L, value); configWrite(path("gridPowerDeltaOnThreshold"), 0L, value);
} }
void setAutoOnDelay(const long value) { void setGridPowerDeltaOnDelay(const long value) {
gridPowerDeltaOnDelay = value; gridPowerDeltaOnDelay = value;
configWrite(path("autoOnDelay"), 0L, value); configWrite(path("gridPowerDeltaOnDelay"), 0L, value);
} }
void setAutoOffThreshold(const long value) { void setGridPowerDeltaOffEnabled(const bool value) {
gridPowerDeltaOffEnabled = value;
configWrite(path("gridPowerDeltaOffEnabled"), false, value);
}
void setGridPowerDeltaOffThreshold(const long value) {
gridPowerDeltaOffThreshold = value; gridPowerDeltaOffThreshold = value;
configWrite(path("autoOffThreshold"), 0L, value); configWrite(path("gridPowerDeltaOffThreshold"), 0L, value);
} }
void setAutoOffDelay(const long value) { void setGridPowerDeltaOffDelay(const long value) {
gridPowerDeltaOffDelay = value; gridPowerDeltaOffDelay = value;
configWrite(path("autoOffDelay"), 0L, value); configWrite(path("gridPowerDeltaOffDelay"), 0L, value);
} }
void json(const JsonObject json) const { void json(const JsonObject json) const {
json["name"] = name; json["name"] = name;
json["state"] = get();
json["stateAgeMillis"] = millis() - stateMillis;
json["initial"] = initialToString(initial); json["initial"] = initialToString(initial);
json["onCount"] = onCount; json["onCount"] = onCount;
json["onMillis"] = onMillis; json["onMillis"] = onMillis;
@ -111,10 +125,21 @@ public:
json["topic"] = topic; json["topic"] = topic;
json["autoOnThreshold"] = gridPowerDeltaOnThreshold; json["gridPowerDeltaOffEnabled"] = gridPowerDeltaOffEnabled;
json["autoOnDelay"] = gridPowerDeltaOnDelay; json["gridPowerDeltaOnThreshold"] = gridPowerDeltaOnThreshold;
json["autoOffThreshold"] = gridPowerDeltaOffThreshold; json["gridPowerDeltaOnDelay"] = gridPowerDeltaOnDelay;
json["autoOffDelay"] = gridPowerDeltaOffDelay;
json["gridPowerDeltaOnEnabled"] = gridPowerDeltaOnEnabled;
json["gridPowerDeltaOffThreshold"] = gridPowerDeltaOffThreshold;
json["gridPowerDeltaOffDelay"] = gridPowerDeltaOffDelay;
json["state"] = get();
json["stateAgeMillis"] = millis() - stateMillis;
}
void set(const bool state) override {
Output::set(state);
gridPowerDeltaMillis = 0;
} }
protected: protected:
@ -134,37 +159,51 @@ private:
} }
void doGridPowerDelta() { void doGridPowerDelta() {
const auto age = millis() - gridPowerDeltaMillis; if (isnan(gridPowerDeltaValue) || millis() - gridPowerDeltaMillis > 10000) {
return;
}
if (get()) { if (get()) {
if (gridPowerDelta > gridPowerDeltaOffThreshold) { gridPowerDeltaOff();
if (gridPowerDeltaMillis == 0) {
Serial.printf("[%s] CONSUMING TOO MUCH: Preparing to power OFF...\n", name.c_str());
gridPowerDeltaMillis = max(1UL, millis());
} else {
if (age > gridPowerDeltaOffDelay) {
gridPowerDeltaMillis = 0;
set(false);
}
}
} else if (gridPowerDeltaMillis > 0) {
Serial.printf("[%s] Powering off CANCELED!\n", name.c_str());
gridPowerDeltaMillis = 0;
}
} else { } else {
if (gridPowerDelta < gridPowerDeltaOnThreshold) { gridPowerDeltaOn();
if (gridPowerDeltaMillis == 0) { }
Serial.printf("[%s] PRODUCING TOO MUCH: Preparing to power ON...\n", name.c_str()); }
gridPowerDeltaMillis = max(1UL, millis());
} else { void gridPowerDeltaOff() {
if (age > gridPowerDeltaOnDelay) { if (!gridPowerDeltaOffEnabled) {
gridPowerDeltaMillis = 0; return;
set(true); }
} if (gridPowerDeltaValue > gridPowerDeltaOffThreshold) {
if (gridPowerDeltaMillis == 0) {
Serial.printf("[%s] CONSUMING TOO MUCH: Preparing to power OFF...\n", name.c_str());
gridPowerDeltaMillis = max(1UL, millis());
} else {
if (millis() - gridPowerDeltaMillis > gridPowerDeltaOffDelay) {
set(false);
} }
} else if (gridPowerDeltaMillis > 0) {
Serial.printf("[%s] Powering on CANCELED!\n", name.c_str());
gridPowerDeltaMillis = 0;
} }
} else if (gridPowerDeltaMillis > 0) {
Serial.printf("[%s] Powering off CANCELED!\n", name.c_str());
gridPowerDeltaMillis = 0;
}
}
void gridPowerDeltaOn() {
if (!gridPowerDeltaOnEnabled) {
return;
}
if (gridPowerDeltaValue < gridPowerDeltaOnThreshold) {
if (gridPowerDeltaMillis == 0) {
Serial.printf("[%s] PRODUCING TOO MUCH: Preparing to power ON...\n", name.c_str());
gridPowerDeltaMillis = max(1UL, millis());
} else {
if (millis() - gridPowerDeltaMillis > gridPowerDeltaOnDelay) {
set(true);
}
}
} else if (gridPowerDeltaMillis > 0) {
Serial.printf("[%s] Powering on CANCELED!\n", name.c_str());
gridPowerDeltaMillis = 0;
} }
} }

View File

@ -75,7 +75,7 @@ void doLog(const String &path, const String &value, const bool isPassword, const
return; return;
} }
Serial.printf( Serial.printf(
"[CONFIG] %-25s = %-30s [%s]\n", "[CONFIG] %-40s = %-30s [%s]\n",
path.c_str(), path.c_str(),
isPassword ? "*" : value.c_str(), isPassword ? "*" : value.c_str(),
type == CONFIG_LOG_FALLBACK ? "fallback" : type == CONFIG_LOG_READ ? "READ" : type == CONFIG_LOG_UNCHANGED ? "UNCHANGED" : type == CONFIG_LOG_WRITE ? "WRITE" : "" type == CONFIG_LOG_FALLBACK ? "fallback" : type == CONFIG_LOG_READ ? "READ" : type == CONFIG_LOG_UNCHANGED ? "UNCHANGED" : type == CONFIG_LOG_WRITE ? "WRITE" : ""

View File

@ -21,7 +21,7 @@ void mqttSetup() {
mqttShouldConnect = true; mqttShouldConnect = true;
} }
double gridPowerDelta = NAN; double gridPowerDeltaValue = NAN;
double gridPowerDeltaMillis = 0; double gridPowerDeltaMillis = 0;
@ -34,7 +34,7 @@ void mqttReceive(const char *topic, const uint8_t *bytes, const unsigned int len
memcpy(string, bytes, length); memcpy(string, bytes, length);
const auto payload = String(string); const auto payload = String(string);
if (GRID_POWER_DELTA_TOPIC == topic) { if (GRID_POWER_DELTA_TOPIC == topic) {
gridPowerDelta = payload.toDouble(); gridPowerDeltaValue = payload.toDouble();
gridPowerDeltaMillis = millis(); gridPowerDeltaMillis = millis();
} else { } else {
Serial.printf("[MQTT] Received unexpected topic: %s\n", topic); Serial.printf("[MQTT] Received unexpected topic: %s\n", topic);

View File

@ -3,7 +3,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
extern double gridPowerDelta; extern double gridPowerDeltaValue;
extern double gridPowerDeltaMillis; extern double gridPowerDeltaMillis;