mirror of
https://github.com/lumapu/ahoy.git
synced 2025-04-29 18:26:21 +02:00
0.8.1030008
This commit is contained in:
parent
139baf680a
commit
06b34b16c4
4 changed files with 117 additions and 30 deletions
|
@ -265,6 +265,8 @@ typedef struct {
|
|||
//
|
||||
|
||||
zeroExportAction_t action;
|
||||
int8_t actionTimer;
|
||||
unsigned long actionTimestamp;
|
||||
uint16_t power;
|
||||
uint16_t MaxPower;
|
||||
int32_t limit;
|
||||
|
@ -682,6 +684,7 @@ class settings {
|
|||
//
|
||||
mCfg.plugin.zeroExport.groups[group].inverters[inv].waitAck = 0;
|
||||
mCfg.plugin.zeroExport.groups[group].inverters[inv].action = zeroExportAction_t::doNone;
|
||||
mCfg.plugin.zeroExport.groups[group].inverters[inv].actionTimer = 0;;
|
||||
mCfg.plugin.zeroExport.groups[group].inverters[inv].dcVoltage = 0;
|
||||
mCfg.plugin.zeroExport.groups[group].inverters[inv].limit = 0;
|
||||
mCfg.plugin.zeroExport.groups[group].inverters[inv].limitNew = 0;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 8
|
||||
#define VERSION_PATCH 1030007
|
||||
#define VERSION_PATCH 1030008
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
uint8_t ch;
|
||||
|
|
|
@ -109,6 +109,8 @@ class powermeter {
|
|||
#endif
|
||||
}
|
||||
|
||||
if ((power.P == 0) and (power.P1 == 0) && (power.P2 == 0) && (power.P3 == 0)) return;
|
||||
|
||||
bufferWrite(power, group);
|
||||
|
||||
// MQTT - Powermeter
|
||||
|
@ -153,6 +155,19 @@ class powermeter {
|
|||
*
|
||||
*/
|
||||
void onMqttConnect(void) {
|
||||
|
||||
#if defined(ZEROEXPORT_POWERMETER_MQTT)
|
||||
|
||||
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) {
|
||||
if (mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) {
|
||||
// if (String(mCfg->groups[group].pm_jsonPath) == "") return;
|
||||
|
||||
mMqtt->subscribe(String(mCfg->groups[group].pm_jsonPath).c_str(), QOS_2);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*defined(ZEROEXPORT_POWERMETER_MQTT)*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,17 +178,39 @@ class powermeter {
|
|||
|
||||
#if defined(ZEROEXPORT_POWERMETER_MQTT)
|
||||
// topic for powermeter?
|
||||
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) {
|
||||
if (mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) {
|
||||
// mLog["mqttDevice"] = "topicInverter";
|
||||
if (!topic.equals(mCfg->groups[group].pm_jsonPath)) return;
|
||||
mCfg->groups[group].pm_P = (int32_t)obj["val"];
|
||||
}
|
||||
}
|
||||
// for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) {
|
||||
// if (mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) {
|
||||
// // mLog["mqttDevice"] = "topicInverter";
|
||||
// if (!topic.equals(mCfg->groups[group].pm_jsonPath)) return;
|
||||
// mCfg->groups[group].pm_P = (int32_t)obj["val"];
|
||||
// }
|
||||
// }
|
||||
#endif /*defined(ZEROEXPORT_POWERMETER_MQTT)*/
|
||||
}
|
||||
|
||||
private:
|
||||
/** mqttSubscribe
|
||||
* when a MQTT Msg is needed to subscribe, then a publish is leading
|
||||
* @param gr
|
||||
* @param payload
|
||||
* @returns void
|
||||
*/
|
||||
void mqttSubscribe(String gr, String payload) {
|
||||
// mqttPublish(gr, payload);
|
||||
mMqtt->subscribe(gr.c_str(), QOS_2);
|
||||
}
|
||||
|
||||
/** mqttPublish
|
||||
* when a MQTT Msg is needed to Publish, but not to subscribe.
|
||||
* @param gr
|
||||
* @param payload
|
||||
* @param retain
|
||||
* @returns void
|
||||
*/
|
||||
void mqttPublish(String gr, String payload, bool retain = false) {
|
||||
mMqtt->publish(gr.c_str(), payload.c_str(), retain);
|
||||
}
|
||||
|
||||
HTTPClient http;
|
||||
|
||||
zeroExport_t *mCfg;
|
||||
|
|
|
@ -239,35 +239,35 @@ class ZeroExport {
|
|||
// Regelbegrenzung
|
||||
// TODO: Hier könnte man den maximalen Sprung begrenzen
|
||||
|
||||
// Keine Regelung wenn Maximalleistung des Inverters unbekannt ist
|
||||
if (CfgGroupInv->MaxPower == 0) {
|
||||
y = 0;
|
||||
mLog["yK"] = y;
|
||||
}
|
||||
|
||||
// Stellgröße y in W
|
||||
CfgGroupInv->limitNew += y;
|
||||
|
||||
// Check
|
||||
|
||||
if (CfgGroupInv->action == zeroExportAction_t::doNone) {
|
||||
// if ((CfgGroup->battSwitch == true) && (CfgGroupInv->limitNew > CfgGroupInv->powerMin) && (CfgGroupInv->power == 0) && (mCfg->sleep != true) && (CfgGroup->sleep != true)) {
|
||||
// TODO: Schlägt fehl, weil wenn MaxPower = 0 wird y auf 0 gesetzt und damit ist limitNew = powerMin
|
||||
if ((CfgGroup->battSwitch == true) && (CfgGroupInv->power == 0) && (mCfg->sleep != true) && (CfgGroup->sleep != true)) {
|
||||
if ((CfgGroup->battSwitch == true) && (CfgGroupInv->limitNew > CfgGroupInv->powerMin) && (CfgGroupInv->power == 0) && (mCfg->sleep != true) && (CfgGroup->sleep != true)) {
|
||||
if (CfgGroupInv->actionTimer < 0) CfgGroupInv->actionTimer = 0;
|
||||
if (CfgGroupInv->actionTimer == 0) CfgGroupInv->actionTimer = 1;
|
||||
if (CfgGroupInv->actionTimer > 10) {
|
||||
CfgGroupInv->action = zeroExportAction_t::doTurnOn;
|
||||
mLog["do"] = "doTurnOn";
|
||||
}
|
||||
|
||||
if (((CfgGroup->battSwitch == false) || (CfgGroupInv->limitNew < 0)) && (CfgGroupInv->power > 0)) {
|
||||
}
|
||||
// TODO: hier kommt eine CheckBox je Gruppe rein, die es verhindert, dass Inv ausgeschaltet werden.
|
||||
if ((CfgGroupInv->limitNew <= 0) && (CfgGroupInv->power > 0)) {
|
||||
if (CfgGroupInv->actionTimer > 0) CfgGroupInv->actionTimer = 0;
|
||||
if (CfgGroupInv->actionTimer == 0) CfgGroupInv->actionTimer = -1;
|
||||
if (CfgGroupInv->actionTimer < 30) {
|
||||
CfgGroupInv->action = zeroExportAction_t::doTurnOff;
|
||||
mLog["do"] = "doTurnOff";
|
||||
}
|
||||
|
||||
if (((mCfg->sleep == true) || (CfgGroup->sleep == true)) && (CfgGroupInv->power > 0)) {
|
||||
}
|
||||
if (((CfgGroup->battSwitch == false) || (mCfg->sleep == true) || (CfgGroup->sleep == true)) && (CfgGroupInv->power > 0)) {
|
||||
CfgGroupInv->action = zeroExportAction_t::doTurnOff;
|
||||
mLog["do"] = "sleep";
|
||||
}
|
||||
}
|
||||
mLog["doT"] = CfgGroupInv->action;
|
||||
|
||||
if (CfgGroupInv->action == zeroExportAction_t::doNone) {
|
||||
mLog["l"] = CfgGroupInv->limit;
|
||||
|
@ -302,6 +302,16 @@ class ZeroExport {
|
|||
|
||||
if (CfgGroupInv->limit != CfgGroupInv->limitNew) CfgGroupInv->action = zeroExportAction_t::doActivePowerContr;
|
||||
|
||||
if ((CfgGroupInv->limit == powerMin) && (CfgGroupInv->power == 0)) {
|
||||
CfgGroupInv->action = zeroExportAction_t::doNone;
|
||||
if (!mCfg->debug) {
|
||||
clearLog();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// CfgGroupInv->actionTimer = 0;
|
||||
// TODO: Timer stoppen wenn Limit gesetzt wird.
|
||||
mLog["lN"] = CfgGroupInv->limitNew;
|
||||
|
||||
CfgGroupInv->limit = CfgGroupInv->limitNew;
|
||||
|
@ -316,6 +326,8 @@ class ZeroExport {
|
|||
mApp->triggerTickSend(iv->id);
|
||||
CfgGroupInv->waitAck = 120;
|
||||
CfgGroupInv->action = zeroExportAction_t::doNone;
|
||||
CfgGroupInv->actionTimer = 0;
|
||||
CfgGroupInv->actionTimestamp = Tsp;
|
||||
}
|
||||
break;
|
||||
case zeroExportAction_t::doTurnOn:
|
||||
|
@ -323,6 +335,8 @@ class ZeroExport {
|
|||
mApp->triggerTickSend(iv->id);
|
||||
CfgGroupInv->waitAck = 120;
|
||||
CfgGroupInv->action = zeroExportAction_t::doNone;
|
||||
CfgGroupInv->actionTimer = 0;
|
||||
CfgGroupInv->actionTimestamp = Tsp;
|
||||
}
|
||||
break;
|
||||
case zeroExportAction_t::doTurnOff:
|
||||
|
@ -330,20 +344,19 @@ class ZeroExport {
|
|||
mApp->triggerTickSend(iv->id);
|
||||
CfgGroupInv->waitAck = 120;
|
||||
CfgGroupInv->action = zeroExportAction_t::doNone;
|
||||
CfgGroupInv->actionTimer = 0;
|
||||
CfgGroupInv->actionTimestamp = Tsp;
|
||||
}
|
||||
break;
|
||||
case zeroExportAction_t::doActivePowerContr:
|
||||
if ((CfgGroupInv->limit <= CfgGroupInv->powerMin) && (CfgGroupInv->power == 0)) {
|
||||
clearLog();
|
||||
return;
|
||||
}
|
||||
|
||||
iv->powerLimit[0] = static_cast<uint16_t>(CfgGroupInv->limit * 10.0);
|
||||
iv->powerLimit[1] = AbsolutNonPersistent;
|
||||
if (iv->setDevControlRequest(ActivePowerContr)) {
|
||||
mApp->triggerTickSend(iv->id);
|
||||
CfgGroupInv->waitAck = 60;
|
||||
CfgGroupInv->action = zeroExportAction_t::doNone;
|
||||
CfgGroupInv->actionTimer = 0;
|
||||
CfgGroupInv->actionTimestamp = Tsp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -382,6 +395,9 @@ class ZeroExport {
|
|||
if (mCfg->groups[group].inverters[inv].waitAck > 0) {
|
||||
mCfg->groups[group].inverters[inv].waitAck--;
|
||||
}
|
||||
|
||||
if (mCfg->groups[group].inverters[inv].actionTimer > 0) mCfg->groups[group].inverters[inv].actionTimer++;
|
||||
if (mCfg->groups[group].inverters[inv].actionTimer < 0) mCfg->groups[group].inverters[inv].actionTimer--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -537,6 +553,28 @@ class ZeroExport {
|
|||
|
||||
CfgGroupInv->dcVoltage = iv->getChannelFieldValue(CH1, FLD_UDC, rec);
|
||||
mLog["bU"] = ah::round1(CfgGroupInv->dcVoltage);
|
||||
|
||||
// Fallschirm 2: Für nicht übernommene Limits bzw. nicht regelnde Inverter
|
||||
// Bisher ist nicht geklärt ob der Inverter das Limit bestätigt hat
|
||||
// Erstmalig aufgetreten bei @knickohr am 28.04.2024 ... l=300 pM=300, p=9
|
||||
if (CfgGroupInv->MaxPower > 0) {
|
||||
uint16_t limitPercent = 100 / CfgGroupInv->MaxPower * CfgGroupInv->limit;
|
||||
uint16_t powerPercent = 100 / CfgGroupInv->MaxPower * CfgGroupInv->power;
|
||||
uint16_t delta = abs(limitPercent - powerPercent);
|
||||
if ((delta > 10) && (CfgGroupInv->power > 0)) {
|
||||
mLog["delta"] = delta;
|
||||
unsigned long delay = iv->getLastTs(rec) - CfgGroupInv->actionTimestamp;
|
||||
mLog["delay"] = delay;
|
||||
if (delay > 30000) {
|
||||
CfgGroupInv->action = zeroExportAction_t::doActivePowerContr;
|
||||
mLog["do"] = "doActivePowerContr";
|
||||
}
|
||||
if (delay > 60000) {
|
||||
CfgGroupInv->action = zeroExportAction_t::doRestart;
|
||||
mLog["do"] = "doRestart";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zeroExportQueue_t Entry;
|
||||
|
@ -560,6 +598,12 @@ class ZeroExport {
|
|||
*/
|
||||
void onMqttConnect(void) {
|
||||
mPowermeter.onMqttConnect();
|
||||
|
||||
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) {
|
||||
// if (String(mCfg->groups[group].battSoC) == "") return;
|
||||
|
||||
mMqtt->subscribe(String(mCfg->groups[group].battSoC).c_str(), QOS_2);
|
||||
}
|
||||
}
|
||||
|
||||
/** onMqttMessage
|
||||
|
@ -570,6 +614,9 @@ class ZeroExport {
|
|||
void onMqttMessage(JsonObject obj) {
|
||||
if (!mIsInitialized) return;
|
||||
|
||||
if (mCfg->debug) mLog["d"] = obj;
|
||||
sendLog();
|
||||
clearLog();
|
||||
mPowermeter.onMqttMessage(obj);
|
||||
|
||||
String topic = String(obj["topic"]);
|
||||
|
|
Loading…
Add table
Reference in a new issue