gridPowerDelta
This commit is contained in:
parent
c4d30371cf
commit
0eb51d8ad6
@ -85,7 +85,7 @@ public:
|
||||
this->onCount = onCount_;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
virtual void loop() {
|
||||
const auto status = get();
|
||||
const auto ageMillis = millis() - stateMillis;
|
||||
if (status) {
|
||||
|
||||
115
src/Relay.h
115
src/Relay.h
@ -11,36 +11,55 @@ class Relay final : public Output {
|
||||
|
||||
String topicFallback;
|
||||
|
||||
const uint8_t index;
|
||||
|
||||
String topic;
|
||||
|
||||
const uint8_t index;
|
||||
long gridPowerDeltaOnThreshold = 0;
|
||||
|
||||
long gridPowerDeltaOnDelay = 0;
|
||||
|
||||
long gridPowerDeltaOffThreshold = 0;
|
||||
|
||||
long gridPowerDeltaOffDelay = 0;
|
||||
|
||||
unsigned long gridPowerDeltaMillis = 0;
|
||||
|
||||
public:
|
||||
|
||||
Relay(const uint8_t index, const String &topic, const char *name, const uint8_t pin, const bool inverted, const bool logState) : Output(name, pin, inverted, logState), nameFallback(name), topicFallback(topic), topic(topic), index(index) {
|
||||
Relay(const uint8_t index, const String &topic, const char *name, const uint8_t pin, const bool inverted, const bool logState) : Output(name, pin, inverted, logState), nameFallback(name), topicFallback(topic), index(index), topic(topic) {
|
||||
//
|
||||
}
|
||||
|
||||
void setup() override {
|
||||
Output::setup();
|
||||
|
||||
Output::setName(configRead(path("name"), nameFallback));
|
||||
topic = configRead(path("topic"), topicFallback);
|
||||
Output::setInitial(configRead(path("initial"), INITIAL_OFF));
|
||||
Output::setOnMillis(configRead(path("onMillis"), 0L));
|
||||
Output::setOffMillis(configRead(path("offMillis"), 0L));
|
||||
|
||||
topic = configRead(path("topic"), topicFallback);
|
||||
|
||||
gridPowerDeltaOnThreshold = configRead(path("autoOnThreshold"), -400L);
|
||||
gridPowerDeltaOnDelay = configRead(path("autoOnDelay"), 30000L);
|
||||
|
||||
gridPowerDeltaOffThreshold = configRead(path("autoOffThreshold"), 100L);
|
||||
gridPowerDeltaOffDelay = configRead(path("autoOffDelay"), 30000L);
|
||||
|
||||
_applyInitial();
|
||||
}
|
||||
|
||||
void loop() override {
|
||||
Output::loop();
|
||||
doGridPowerDelta();
|
||||
}
|
||||
|
||||
void setName(const String &value) override {
|
||||
Output::setName(value);
|
||||
configWrite(path("name"), nameFallback, value);
|
||||
}
|
||||
|
||||
void setTopic(const String &value) {
|
||||
topic = value;
|
||||
configWrite(path("topic"), topicFallback, value);
|
||||
}
|
||||
|
||||
void setInitial(const Initial value) override {
|
||||
Output::setInitial(value);
|
||||
configWrite(path("initial"), INITIAL_OFF, value);
|
||||
@ -56,23 +75,46 @@ public:
|
||||
configWrite(path("offMillis"), 0L, value);
|
||||
}
|
||||
|
||||
void setTopic(const String &value) {
|
||||
topic = value;
|
||||
configWrite(path("topic"), topicFallback, value);
|
||||
}
|
||||
|
||||
void setAutoOnThreshold(const long value) {
|
||||
gridPowerDeltaOnThreshold = value;
|
||||
configWrite(path("autoOnThreshold"), 0L, value);
|
||||
}
|
||||
|
||||
void setAutoOnDelay(const long value) {
|
||||
gridPowerDeltaOnDelay = value;
|
||||
configWrite(path("autoOnDelay"), 0L, value);
|
||||
}
|
||||
|
||||
void setAutoOffThreshold(const long value) {
|
||||
gridPowerDeltaOffThreshold = value;
|
||||
configWrite(path("autoOffThreshold"), 0L, value);
|
||||
}
|
||||
|
||||
void setAutoOffDelay(const long value) {
|
||||
gridPowerDeltaOffDelay = value;
|
||||
configWrite(path("autoOffDelay"), 0L, value);
|
||||
}
|
||||
|
||||
void json(const JsonObject json) const {
|
||||
json["name"] = name;
|
||||
json["topic"] = topic;
|
||||
json["state"] = get();
|
||||
json["stateAgeMillis"] = millis() - stateMillis;
|
||||
json["initial"] = initialToString(initial);
|
||||
json["onCount"] = onCount;
|
||||
json["onMillis"] = onMillis;
|
||||
json["offMillis"] = offMillis;
|
||||
}
|
||||
|
||||
private:
|
||||
json["topic"] = topic;
|
||||
|
||||
String path(const char *name) const {
|
||||
char path[64];
|
||||
snprintf(path, sizeof(path), "/relay%d/%s", index, name);
|
||||
return String(path);
|
||||
json["autoOnThreshold"] = gridPowerDeltaOnThreshold;
|
||||
json["autoOnDelay"] = gridPowerDeltaOnDelay;
|
||||
json["autoOffThreshold"] = gridPowerDeltaOffThreshold;
|
||||
json["autoOffDelay"] = gridPowerDeltaOffDelay;
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -83,6 +125,49 @@ protected:
|
||||
mqttPublish(topic, doc);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
String path(const char *name) const {
|
||||
char path[64];
|
||||
snprintf(path, sizeof(path), "/relay%d/%s", index, name);
|
||||
return String(path);
|
||||
}
|
||||
|
||||
void doGridPowerDelta() {
|
||||
const auto age = millis() - gridPowerDeltaMillis;
|
||||
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;
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
} else if (gridPowerDeltaMillis > 0) {
|
||||
Serial.printf("[%s] Powering on CANCELED!\n", name.c_str());
|
||||
gridPowerDeltaMillis = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
36
src/mqtt.cpp
36
src/mqtt.cpp
@ -5,6 +5,8 @@
|
||||
|
||||
#include "PubSubClient.h"
|
||||
|
||||
const String GRID_POWER_DELTA_TOPIC = "electricity/grid/power/signed/w";
|
||||
|
||||
WiFiClient wifiClient;
|
||||
|
||||
PubSubClient client(wifiClient);
|
||||
@ -13,10 +15,32 @@ bool mqttShouldConnect = false;
|
||||
|
||||
unsigned long mqttLast = 0;
|
||||
|
||||
unsigned long warningLast = 0;
|
||||
|
||||
void mqttSetup() {
|
||||
mqttShouldConnect = true;
|
||||
}
|
||||
|
||||
double gridPowerDelta = NAN;
|
||||
|
||||
double gridPowerDeltaMillis = 0;
|
||||
|
||||
void mqttReceive(const char *topic, const uint8_t *bytes, const unsigned int length) {
|
||||
if (length >= 100) {
|
||||
Serial.println("[MQTT] Inbound buffer overflow");
|
||||
return;
|
||||
}
|
||||
char string[100];
|
||||
memcpy(string, bytes, length);
|
||||
const auto payload = String(string);
|
||||
if (GRID_POWER_DELTA_TOPIC == topic) {
|
||||
gridPowerDelta = payload.toDouble();
|
||||
gridPowerDeltaMillis = millis();
|
||||
} else {
|
||||
Serial.printf("[MQTT] Received unexpected topic: %s\n", topic);
|
||||
}
|
||||
}
|
||||
|
||||
void mqttLoop() {
|
||||
if (client.loop()) {
|
||||
if (!mqttShouldConnect) {
|
||||
@ -24,20 +48,22 @@ void mqttLoop() {
|
||||
Serial.println("[MQTT] Stopped.");
|
||||
}
|
||||
} else if (mqttShouldConnect) {
|
||||
const auto host = configRead("/mqtt/host", "", false);
|
||||
const auto host = configRead("/mqtt/host", "10.0.0.50", false);
|
||||
if (host == "") {
|
||||
return;
|
||||
}
|
||||
if (mqttLast == 0 || millis() - mqttLast >= 3000) {
|
||||
const auto id = configRead("/mqtt/id", "test", false);
|
||||
const auto user = configRead("/mqtt/user", "", false);
|
||||
const auto pass = configRead("/mqtt/pass", "", false, true);
|
||||
const auto port = configRead("/mqtt/port", 1883L, false);
|
||||
const auto id = configRead("/mqtt/id", "test");
|
||||
const auto user = configRead("/mqtt/user", "");
|
||||
const auto pass = configRead("/mqtt/pass", "", true, true);
|
||||
const auto port = configRead("/mqtt/port", 1883L);
|
||||
mqttLast = max(1UL, millis());
|
||||
client.setServer(host.c_str(), port);
|
||||
Serial.printf("[MQTT] Connecting: %s:%ld\n", host.c_str(), port);
|
||||
if (client.connect(id.c_str(), user.c_str(), pass.c_str())) {
|
||||
Serial.printf("[MQTT] Connected.\n");
|
||||
client.subscribe(GRID_POWER_DELTA_TOPIC.c_str());
|
||||
client.setCallback(mqttReceive);
|
||||
} else {
|
||||
Serial.printf("[MQTT] Failed to connect.\n");
|
||||
}
|
||||
|
||||
@ -3,6 +3,10 @@
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
extern double gridPowerDelta;
|
||||
|
||||
extern double gridPowerDeltaMillis;
|
||||
|
||||
void mqttSetup();
|
||||
|
||||
void mqttLoop();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user