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;
}
void set(const bool state) {
virtual void set(const bool state) {
_write(state);
onCount = 0;
}

View File

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

View File

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

View File

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