Browse Source

0.8.970010

pull/1551/head
Patrick Amrhein 10 months ago
parent
commit
d66d975d4f
  1. 97
      src/config/settings.h
  2. 2
      src/defines.h
  3. 258
      src/plugins/zeroExport/zeroExport.h

97
src/config/settings.h

@ -188,7 +188,7 @@ typedef struct {
// Plugin ZeroExport // Plugin ZeroExport
#if defined(PLUGIN_ZEROEXPORT) #if defined(PLUGIN_ZEROEXPORT)
#define ZEROEXPORT_DEV_POWERMETER //#define ZEROEXPORT_DEV_POWERMETER
#define ZEROEXPORT_MAX_GROUPS 6 #define ZEROEXPORT_MAX_GROUPS 6
#define ZEROEXPORT_GROUP_MAX_LEN_NAME 25 #define ZEROEXPORT_GROUP_MAX_LEN_NAME 25
#define ZEROEXPORT_GROUP_MAX_LEN_PM_URL 100 #define ZEROEXPORT_GROUP_MAX_LEN_PM_URL 100
@ -227,22 +227,7 @@ typedef enum {
Hichi = 4, Hichi = 4,
Tibber = 5, Tibber = 5,
} zeroExportPowermeterType_t; } zeroExportPowermeterType_t;
/*
typedef struct {
uint8_t type;
uint8_t ip;
uint8_t url;
bool login;
uint8_t username;
uint8_t password;
uint8_t group;
uint8_t phase;
uint16_t nextRun;
uint16_t interval;
uint8_t error;
uint16_t power;
} zeroExportPowermeter_t;
*/
typedef enum { typedef enum {
Sum = 0, Sum = 0,
L1 = 1, L1 = 1,
@ -261,9 +246,9 @@ typedef struct {
uint16_t powerMax; uint16_t powerMax;
// //
float power; int32_t power;
float limit; int32_t limit;
float limitNew; int32_t limitNew;
uint8_t waitLimitAck; uint8_t waitLimitAck;
uint8_t waitPowerAck; uint8_t waitPowerAck;
uint8_t waitRebootAck; uint8_t waitRebootAck;
@ -279,6 +264,7 @@ typedef struct {
typedef struct { typedef struct {
// General // General
bool enabled; bool enabled;
bool sleep;
char name[ZEROEXPORT_GROUP_MAX_LEN_NAME]; char name[ZEROEXPORT_GROUP_MAX_LEN_NAME];
// Powermeter // Powermeter
uint8_t pm_type; uint8_t pm_type;
@ -303,50 +289,37 @@ typedef struct {
// zeroExportState stateNext; // zeroExportState stateNext;
unsigned long lastRun; unsigned long lastRun;
unsigned long lastRefresh; unsigned long lastRefresh;
uint16_t sleep; uint16_t wait;
float eSum;
float eSum1;
float eSum2;
float eSum3;
float eOld;
float eOld1;
float eOld2;
float eOld3;
float Kp;
float Ki;
float Kd;
//float pm_P[5]; int32_t pm_P;
//float pm_P1[5]; int32_t pm_P1;
//float pm_P2[5]; int32_t pm_P2;
//float pm_P3[5]; int32_t pm_P3;
//uint8_t pm_iIn = 0;
//uint8_t pm_iOut = 0;
float pmPower;
float pmPowerL1;
float pmPowerL2;
float pmPowerL3;
bool publishPower = false; bool publishPower = false;
bool battSwitch; bool battSwitch;
float grpPower;
float grpPowerL1; // PID controller
float grpPowerL2; int32_t eSum;
float grpPowerL3; int32_t eSum1;
// float grpLimit; int32_t eSum2;
// float grpLimitL1; int32_t eSum3;
// float grpLimitL2; int32_t eOld;
// float grpLimitL3; int32_t eOld1;
int32_t eOld2;
// uint16_t power; // Aktueller Verbrauch int32_t eOld3;
// uint16_t powerLimitAkt; // Aktuelles Limit float Kp;
// uint16_t powerHyst; // Hysterese float Ki;
float Kd;
int32_t y;
int32_t y1;
int32_t y2;
int32_t y3;
} zeroExportGroup_t; } zeroExportGroup_t;
typedef struct { typedef struct {
bool enabled; bool enabled;
bool sleep;
bool log_over_webserial; bool log_over_webserial;
bool log_over_mqtt; bool log_over_mqtt;
bool debug; bool debug;
@ -675,12 +648,14 @@ class settings {
// Plugin ZeroExport // Plugin ZeroExport
#if defined(PLUGIN_ZEROEXPORT) #if defined(PLUGIN_ZEROEXPORT)
mCfg.plugin.zeroExport.enabled = false; mCfg.plugin.zeroExport.enabled = false;
mCfg.plugin.zeroExport.sleep = false;
mCfg.plugin.zeroExport.log_over_webserial = false; mCfg.plugin.zeroExport.log_over_webserial = false;
mCfg.plugin.zeroExport.log_over_mqtt = false; mCfg.plugin.zeroExport.log_over_mqtt = false;
mCfg.plugin.zeroExport.debug = false; mCfg.plugin.zeroExport.debug = false;
for(uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { for(uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) {
// General // General
mCfg.plugin.zeroExport.groups[group].enabled = false; mCfg.plugin.zeroExport.groups[group].enabled = false;
mCfg.plugin.zeroExport.groups[group].sleep = false;
snprintf(mCfg.plugin.zeroExport.groups[group].name, ZEROEXPORT_GROUP_MAX_LEN_NAME, "%s", DEF_ZEXPORT); snprintf(mCfg.plugin.zeroExport.groups[group].name, ZEROEXPORT_GROUP_MAX_LEN_NAME, "%s", DEF_ZEXPORT);
// Powermeter // Powermeter
mCfg.plugin.zeroExport.groups[group].pm_type = zeroExportPowermeterType_t::None; mCfg.plugin.zeroExport.groups[group].pm_type = zeroExportPowermeterType_t::None;
@ -719,11 +694,11 @@ class settings {
mCfg.plugin.zeroExport.groups[group].state = zeroExportState::INIT; mCfg.plugin.zeroExport.groups[group].state = zeroExportState::INIT;
mCfg.plugin.zeroExport.groups[group].lastRun = 0; mCfg.plugin.zeroExport.groups[group].lastRun = 0;
mCfg.plugin.zeroExport.groups[group].lastRefresh = 0; mCfg.plugin.zeroExport.groups[group].lastRefresh = 0;
mCfg.plugin.zeroExport.groups[group].sleep = 0; mCfg.plugin.zeroExport.groups[group].wait = 0;
mCfg.plugin.zeroExport.groups[group].pmPower = 0; mCfg.plugin.zeroExport.groups[group].pm_P = 0;
mCfg.plugin.zeroExport.groups[group].pmPowerL1 = 0; mCfg.plugin.zeroExport.groups[group].pm_P1 = 0;
mCfg.plugin.zeroExport.groups[group].pmPowerL2 = 0; mCfg.plugin.zeroExport.groups[group].pm_P2 = 0;
mCfg.plugin.zeroExport.groups[group].pmPowerL3 = 0; mCfg.plugin.zeroExport.groups[group].pm_P3 = 0;
mCfg.plugin.zeroExport.groups[group].battSwitch = false; mCfg.plugin.zeroExport.groups[group].battSwitch = false;
} }

2
src/defines.h

@ -13,7 +13,7 @@
//------------------------------------- //-------------------------------------
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 8 #define VERSION_MINOR 8
#define VERSION_PATCH 970009 #define VERSION_PATCH 970010
//------------------------------------- //-------------------------------------
typedef struct { typedef struct {

258
src/plugins/zeroExport/zeroExport.h

@ -69,9 +69,9 @@ class ZeroExport {
if (!cfgGroup->enabled) continue; if (!cfgGroup->enabled) continue;
// sleep // wait
if (Tsp <= (cfgGroup->lastRun + cfgGroup->sleep)) continue; if (Tsp <= (cfgGroup->lastRun + cfgGroup->wait)) continue;
cfgGroup->sleep = 0; cfgGroup->wait = 0;
mLog["g"] = group; mLog["g"] = group;
mLog["s"] = (uint8_t)cfgGroup->state; mLog["s"] = (uint8_t)cfgGroup->state;
@ -80,13 +80,13 @@ class ZeroExport {
case zeroExportState::INIT: case zeroExportState::INIT:
if (groupInit(group, &Tsp, &DoLog)) { if (groupInit(group, &Tsp, &DoLog)) {
cfgGroup->state = zeroExportState::WAITREFRESH; cfgGroup->state = zeroExportState::WAITREFRESH;
cfgGroup->sleep = 60000; cfgGroup->wait = 60000;
} else { } else {
cfgGroup->state = zeroExportState::INIT; cfgGroup->state = zeroExportState::INIT;
cfgGroup->sleep = 60000; cfgGroup->wait = 60000;
#if defined(ZEROEXPORT_DEV_POWERMETER) #if defined(ZEROEXPORT_DEV_POWERMETER)
cfgGroup->state = zeroExportState::WAITREFRESH; cfgGroup->state = zeroExportState::WAITREFRESH;
cfgGroup->sleep = 10000; cfgGroup->wait = 10000;
#endif #endif
} }
break; break;
@ -102,14 +102,14 @@ class ZeroExport {
if (groupGetInverterData(group, &Tsp, &DoLog)) { if (groupGetInverterData(group, &Tsp, &DoLog)) {
cfgGroup->state = zeroExportState::BATTERYPROTECTION; cfgGroup->state = zeroExportState::BATTERYPROTECTION;
} else { } else {
cfgGroup->sleep = 500; cfgGroup->wait = 500;
} }
break; break;
case zeroExportState::BATTERYPROTECTION: case zeroExportState::BATTERYPROTECTION:
if (groupBatteryprotection(group, &Tsp, &DoLog)) { if (groupBatteryprotection(group, &Tsp, &DoLog)) {
cfgGroup->state = zeroExportState::GETPOWERMETER; cfgGroup->state = zeroExportState::GETPOWERMETER;
} else { } else {
cfgGroup->sleep = 1000; cfgGroup->wait = 1000;
} }
break; break;
case zeroExportState::GETPOWERMETER: case zeroExportState::GETPOWERMETER:
@ -120,7 +120,7 @@ class ZeroExport {
cfgGroup->state = zeroExportState::PUBLISH; cfgGroup->state = zeroExportState::PUBLISH;
#endif #endif
} else { } else {
cfgGroup->sleep = 3000; cfgGroup->wait = 3000;
} }
break; break;
case zeroExportState::CONTROLLER: case zeroExportState::CONTROLLER:
@ -135,21 +135,21 @@ class ZeroExport {
if (groupPrognose(group, &Tsp, &DoLog)) { if (groupPrognose(group, &Tsp, &DoLog)) {
cfgGroup->state = zeroExportState::AUFTEILEN; cfgGroup->state = zeroExportState::AUFTEILEN;
} else { } else {
cfgGroup->sleep = 500; cfgGroup->wait = 500;
} }
break; break;
case zeroExportState::AUFTEILEN: case zeroExportState::AUFTEILEN:
if (groupAufteilen(group, &Tsp, &DoLog)) { if (groupAufteilen(group, &Tsp, &DoLog)) {
cfgGroup->state = zeroExportState::SETREBOOT; cfgGroup->state = zeroExportState::SETREBOOT;
} else { } else {
cfgGroup->sleep = 500; cfgGroup->wait = 500;
} }
break; break;
case zeroExportState::SETREBOOT: case zeroExportState::SETREBOOT:
if (groupSetReboot(group, &Tsp, &DoLog)) { if (groupSetReboot(group, &Tsp, &DoLog)) {
cfgGroup->state = zeroExportState::SETPOWER; cfgGroup->state = zeroExportState::SETPOWER;
} else { } else {
cfgGroup->sleep = 1000; cfgGroup->wait = 1000;
} }
break; break;
case zeroExportState::SETPOWER: case zeroExportState::SETPOWER:
@ -157,14 +157,14 @@ class ZeroExport {
cfgGroup->lastRefresh = Tsp; cfgGroup->lastRefresh = Tsp;
cfgGroup->state = zeroExportState::SETLIMIT; cfgGroup->state = zeroExportState::SETLIMIT;
} else { } else {
cfgGroup->sleep = 1000; cfgGroup->wait = 1000;
} }
break; break;
case zeroExportState::SETLIMIT: case zeroExportState::SETLIMIT:
if (groupSetLimit(group, &Tsp, &DoLog)) { if (groupSetLimit(group, &Tsp, &DoLog)) {
cfgGroup->state = zeroExportState::PUBLISH; cfgGroup->state = zeroExportState::PUBLISH;
} else { } else {
cfgGroup->sleep = 1000; cfgGroup->wait = 1000;
} }
break; break;
case zeroExportState::PUBLISH: case zeroExportState::PUBLISH:
@ -187,7 +187,7 @@ class ZeroExport {
default: default:
cfgGroup->lastRun = Tsp; cfgGroup->lastRun = Tsp;
cfgGroup->lastRefresh = Tsp; cfgGroup->lastRefresh = Tsp;
cfgGroup->sleep = 1000; cfgGroup->wait = 1000;
cfgGroup->state = zeroExportState::INIT; cfgGroup->state = zeroExportState::INIT;
break; break;
} }
@ -367,7 +367,7 @@ class ZeroExport {
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) {
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) {
// Keine Datenübernahme wenn falscher Inverter // Wrong Inverter -> ignore
if (iv->id != mCfg->groups[group].inverters[inv].id) continue; if (iv->id != mCfg->groups[group].inverters[inv].id) continue;
// Keine Datenübernahme wenn nicht enabled // Keine Datenübernahme wenn nicht enabled
@ -382,6 +382,7 @@ class ZeroExport {
// Keine Datenübernahme wenn setLimit läuft // Keine Datenübernahme wenn setLimit läuft
if (mCfg->groups[group].inverters[inv].waitLimitAck > 0) continue; if (mCfg->groups[group].inverters[inv].waitLimitAck > 0) continue;
// Calculate
int32_t ivLp = iv->actPowerLimit; int32_t ivLp = iv->actPowerLimit;
int32_t ivPm = iv->getMaxPower();; int32_t ivPm = iv->getMaxPower();;
int32_t ivL = (ivPm * ivLp) / 100; int32_t ivL = (ivPm * ivLp) / 100;
@ -427,6 +428,28 @@ class ZeroExport {
mLog["t"] = "onMqttMessage"; mLog["t"] = "onMqttMessage";
if (obj["path"] == "zero" && obj["cmd"] == "set") { if (obj["path"] == "zero" && obj["cmd"] == "set") {
/*
// "topic":"???/zero/set/enabled"
if (topic.indexOf("zero/set/enabled") != -1) {
}
else
// "topic":"???/zero/set/sleep"
if (topic.indexOf("zero/set/sleep") != -1) {
}
else
// "topic":"???/zero/set/groups/0/enabled"
if (topic.indexOf("zero/set/groups") != -1) {
String i = topic.substring(topic.length() - 10, topic.length() - 8);
uint8_t group = i.toInt();
mLog["g"] = group;
if (topic.indexOf("enabled") != -1) {
}
if (topic.indexOf("zero/set/groups") != -1) {
}
}
*/
// "topic":"inverter/zero/set/groups/0/enabled" // "topic":"inverter/zero/set/groups/0/enabled"
if (topic.indexOf("groups") != -1) { if (topic.indexOf("groups") != -1) {
// TODO: Topicprüfung // TODO: Topicprüfung
@ -766,23 +789,23 @@ class ZeroExport {
*doLog = true; *doLog = true;
mCfg->groups[group].pmPower = mPowermeter.getDataAVG(group).P; mCfg->groups[group].pm_P = mPowermeter.getDataAVG(group).P;
mCfg->groups[group].pmPowerL1 = mPowermeter.getDataAVG(group).P1; mCfg->groups[group].pm_P1 = mPowermeter.getDataAVG(group).P1;
mCfg->groups[group].pmPowerL2 = mPowermeter.getDataAVG(group).P2; mCfg->groups[group].pm_P2 = mPowermeter.getDataAVG(group).P2;
mCfg->groups[group].pmPowerL3 = mPowermeter.getDataAVG(group).P3; mCfg->groups[group].pm_P3 = mPowermeter.getDataAVG(group).P3;
if ( if (
(mCfg->groups[group].pmPower == 0) && (mCfg->groups[group].pm_P == 0) &&
(mCfg->groups[group].pmPowerL1 == 0) && (mCfg->groups[group].pm_P1 == 0) &&
(mCfg->groups[group].pmPowerL2 == 0) && (mCfg->groups[group].pm_P2 == 0) &&
(mCfg->groups[group].pmPowerL3 == 0)) { (mCfg->groups[group].pm_P3 == 0)) {
return false; return false;
} }
mLog["P"] = mCfg->groups[group].pmPower; mLog["P"] = mCfg->groups[group].pm_P;
mLog["P1"] = mCfg->groups[group].pmPowerL1; mLog["P1"] = mCfg->groups[group].pm_P1;
mLog["P2"] = mCfg->groups[group].pmPowerL2; mLog["P2"] = mCfg->groups[group].pm_P2;
mLog["P3"] = mCfg->groups[group].pmPowerL3; mLog["P3"] = mCfg->groups[group].pm_P3;
return true; return true;
} }
@ -793,113 +816,115 @@ class ZeroExport {
* @returns true/false * @returns true/false
*/ */
bool groupController(uint8_t group, unsigned long *tsp, bool *doLog) { bool groupController(uint8_t group, unsigned long *tsp, bool *doLog) {
zeroExportGroup_t *cfgGroup = &mCfg->groups[group];
if (mCfg->debug) mLog["t"] = "groupController"; if (mCfg->debug) mLog["t"] = "groupController";
mCfg->groups[group].lastRun = *tsp; cfgGroup->lastRun = *tsp;
*doLog = true; *doLog = true;
// Führungsgröße w in Watt // Führungsgröße w in Watt
float w = mCfg->groups[group].setPoint; int32_t w = cfgGroup->setPoint;
mLog["w"] = w; mLog["w"] = w;
// Regelgröße x in Watt // Regelgröße x in Watt
float x = mCfg->groups[group].pmPower; int32_t x = cfgGroup->pm_P;
float x1 = mCfg->groups[group].pmPowerL1; int32_t x1 = cfgGroup->pm_P1;
float x2 = mCfg->groups[group].pmPowerL2; int32_t x2 = cfgGroup->pm_P2;
float x3 = mCfg->groups[group].pmPowerL3; int32_t x3 = cfgGroup->pm_P3;
mLog["x"] = x; mLog["x"] = x;
mLog["x1"] = x1; mLog["x1"] = x1;
mLog["x2"] = x2; mLog["x2"] = x2;
mLog["x3"] = x3; mLog["x3"] = x3;
// Regelabweichung e in Watt // Regelabweichung e in Watt
float e = w - x; int32_t e = w - x;
float e1 = w - x1; int32_t e1 = w - x1;
float e2 = w - x2; int32_t e2 = w - x2;
float e3 = w - x3; int32_t e3 = w - x3;
mLog["e"] = e; mLog["e"] = e;
mLog["e1"] = e1; mLog["e1"] = e1;
mLog["e2"] = e2; mLog["e2"] = e2;
mLog["e3"] = e3; mLog["e3"] = e3;
if ( if (
(e < mCfg->groups[group].powerTolerance) && (e > -mCfg->groups[group].powerTolerance) && (e < cfgGroup->powerTolerance) && (e > -cfgGroup->powerTolerance) &&
(e1 < mCfg->groups[group].powerTolerance) && (e1 > -mCfg->groups[group].powerTolerance) && (e1 < cfgGroup->powerTolerance) && (e1 > -cfgGroup->powerTolerance) &&
(e2 < mCfg->groups[group].powerTolerance) && (e2 > -mCfg->groups[group].powerTolerance) && (e2 < cfgGroup->powerTolerance) && (e2 > -cfgGroup->powerTolerance) &&
(e3 < mCfg->groups[group].powerTolerance) && (e3 > -mCfg->groups[group].powerTolerance)) { (e3 < cfgGroup->powerTolerance) && (e3 > -cfgGroup->powerTolerance)) {
mLog["tol"] = mCfg->groups[group].powerTolerance; mLog["tol"] = cfgGroup->powerTolerance;
return false; return false;
} }
// Regler // Regler
float Kp = mCfg->groups[group].Kp; float Kp = cfgGroup->Kp;
float Ki = mCfg->groups[group].Ki; float Ki = cfgGroup->Ki;
float Kd = mCfg->groups[group].Kd; float Kd = cfgGroup->Kd;
unsigned long Ta = *tsp - mCfg->groups[group].lastRefresh; unsigned long Ta = *tsp - mCfg->groups[group].lastRefresh;
mLog["Kp"] = Kp; mLog["Kp"] = Kp;
mLog["Ki"] = Ki; mLog["Ki"] = Ki;
mLog["Kd"] = Kd; mLog["Kd"] = Kd;
mLog["Ta"] = Ta; mLog["Ta"] = Ta;
// - P-Anteil // - P-Anteil
float yP = Kp * e; int32_t yP = Kp * e;
float yP1 = Kp * e1; int32_t yP1 = Kp * e1;
float yP2 = Kp * e2; int32_t yP2 = Kp * e2;
float yP3 = Kp * e3; int32_t yP3 = Kp * e3;
mLog["yP"] = yP; mLog["yP"] = yP;
mLog["yP1"] = yP1; mLog["yP1"] = yP1;
mLog["yP2"] = yP2; mLog["yP2"] = yP2;
mLog["yP3"] = yP3; mLog["yP3"] = yP3;
// - I-Anteil // - I-Anteil
mCfg->groups[group].eSum += e; cfgGroup->eSum += e;
mCfg->groups[group].eSum1 += e1; cfgGroup->eSum1 += e1;
mCfg->groups[group].eSum2 += e2; cfgGroup->eSum2 += e2;
mCfg->groups[group].eSum3 += e3; cfgGroup->eSum3 += e3;
mLog["esum"] = mCfg->groups[group].eSum; mLog["esum"] = cfgGroup->eSum;
mLog["esum1"] = mCfg->groups[group].eSum1; mLog["esum1"] = cfgGroup->eSum1;
mLog["esum2"] = mCfg->groups[group].eSum2; mLog["esum2"] = cfgGroup->eSum2;
mLog["esum3"] = mCfg->groups[group].eSum3; mLog["esum3"] = cfgGroup->eSum3;
float yI = Ki * Ta * mCfg->groups[group].eSum; int32_t yI = Ki * Ta * cfgGroup->eSum;
float yI1 = Ki * Ta * mCfg->groups[group].eSum1; int32_t yI1 = Ki * Ta * cfgGroup->eSum1;
float yI2 = Ki * Ta * mCfg->groups[group].eSum2; int32_t yI2 = Ki * Ta * cfgGroup->eSum2;
float yI3 = Ki * Ta * mCfg->groups[group].eSum3; int32_t yI3 = Ki * Ta * cfgGroup->eSum3;
mLog["yI"] = yI; mLog["yI"] = yI;
mLog["yI1"] = yI1; mLog["yI1"] = yI1;
mLog["yI2"] = yI2; mLog["yI2"] = yI2;
mLog["yI3"] = yI3; mLog["yI3"] = yI3;
// - D-Anteil // - D-Anteil
mLog["ealt"] = mCfg->groups[group].eOld; mLog["ealt"] = cfgGroup->eOld;
mLog["ealt1"] = mCfg->groups[group].eOld1; mLog["ealt1"] = cfgGroup->eOld1;
mLog["ealt2"] = mCfg->groups[group].eOld2; mLog["ealt2"] = cfgGroup->eOld2;
mLog["ealt3"] = mCfg->groups[group].eOld3; mLog["ealt3"] = cfgGroup->eOld3;
float yD = Kd * (e - mCfg->groups[group].eOld) / Ta; int32_t yD = Kd * (e - cfgGroup->eOld) / Ta;
float yD1 = Kd * (e1 - mCfg->groups[group].eOld1) / Ta; int32_t yD1 = Kd * (e1 - cfgGroup->eOld1) / Ta;
float yD2 = Kd * (e2 - mCfg->groups[group].eOld2) / Ta; int32_t yD2 = Kd * (e2 - cfgGroup->eOld2) / Ta;
float yD3 = Kd * (e3 - mCfg->groups[group].eOld3) / Ta; int32_t yD3 = Kd * (e3 - cfgGroup->eOld3) / Ta;
mLog["yD"] = yD; mLog["yD"] = yD;
mLog["yD1"] = yD1; mLog["yD1"] = yD1;
mLog["yD2"] = yD2; mLog["yD2"] = yD2;
mLog["yD3"] = yD3; mLog["yD3"] = yD3;
mCfg->groups[group].eOld = e; cfgGroup->eOld = e;
mCfg->groups[group].eOld1 = e1; cfgGroup->eOld1 = e1;
mCfg->groups[group].eOld2 = e2; cfgGroup->eOld2 = e2;
mCfg->groups[group].eOld3 = e3; cfgGroup->eOld3 = e3;
// - PID-Anteil // - PID-Anteil
float y = yP + yI + yD; int32_t y = yP + yI + yD;
float y1 = yP1 + yI1 + yD1; int32_t y1 = yP1 + yI1 + yD1;
float y2 = yP2 + yI2 + yD2; int32_t y2 = yP2 + yI2 + yD2;
float y3 = yP3 + yI3 + yD3; int32_t y3 = yP3 + yI3 + yD3;
// Regelbegrenzung // Regelbegrenzung
// TODO: Hier könnte man den maximalen Sprung begrenzen // TODO: Hier könnte man den maximalen Sprung begrenzen
cfgGroup->y = y;
cfgGroup->y1 = y1;
cfgGroup->y2 = y2;
cfgGroup->y3 = y3;
mLog["y"] = y; mLog["y"] = y;
mLog["y1"] = y1; mLog["y1"] = y1;
mLog["y2"] = y2; mLog["y2"] = y2;
mLog["y3"] = y3; mLog["y3"] = y3;
mCfg->groups[group].grpPower = y;
mCfg->groups[group].grpPowerL1 = y1;
mCfg->groups[group].grpPowerL2 = y2;
mCfg->groups[group].grpPowerL3 = y3;
return true; return true;
} }
@ -931,10 +956,10 @@ class ZeroExport {
*doLog = true; *doLog = true;
float y = mCfg->groups[group].grpPower; float y = mCfg->groups[group].y;
float y1 = mCfg->groups[group].grpPowerL1; float y1 = mCfg->groups[group].y1;
float y2 = mCfg->groups[group].grpPowerL2; float y2 = mCfg->groups[group].y2;
float y3 = mCfg->groups[group].grpPowerL3; float y3 = mCfg->groups[group].y3;
// TDOD: nochmal durchdenken ... es muss für Sum und L1-3 sein // TDOD: nochmal durchdenken ... es muss für Sum und L1-3 sein
// uint16_t groupPmax = 0; // uint16_t groupPmax = 0;
@ -965,34 +990,20 @@ class ZeroExport {
continue; continue;
} }
// if ((cfgGroup->battSwitch) && (!cfgGroupInv->state)) {
// setPower(&logObj, group, inv, true);
// continue;
// }
// if ((!cfgGroup->battSwitch) && (cfgGroupInv->state)) {
// setPower(&logObj, group, inv, false);
// continue;
// }
// if (!cfgGroupInv->state) {
// continue;
// }
record_t<> *rec; record_t<> *rec;
rec = mIv[group][inv]->getRecordStruct(RealTimeRunData_Debug); rec = mIv[group][inv]->getRecordStruct(RealTimeRunData_Debug);
cfgGroupInv->power = mIv[group][inv]->getChannelFieldValue(CH0, FLD_PAC, rec); cfgGroupInv->power = mIv[group][inv]->getChannelFieldValue(CH0, FLD_PAC, rec);
if ((uint16_t)cfgGroupInv->power < ivPmin[cfgGroupInv->target]) { if (cfgGroupInv->power < ivPmin[cfgGroupInv->target]) {
grpTarget[cfgGroupInv->target] = true; grpTarget[cfgGroupInv->target] = true;
ivPmin[cfgGroupInv->target] = (uint16_t)cfgGroupInv->power; ivPmin[cfgGroupInv->target] = cfgGroupInv->power;
ivId_Pmin[cfgGroupInv->target] = inv; ivId_Pmin[cfgGroupInv->target] = inv;
// Hier kein return oder continue sonst dauerreboot // Hier kein return oder continue sonst dauerreboot
} }
if ((uint16_t)cfgGroupInv->power > ivPmax[cfgGroupInv->target]) { if (cfgGroupInv->power > ivPmax[cfgGroupInv->target]) {
grpTarget[cfgGroupInv->target] = true; grpTarget[cfgGroupInv->target] = true;
ivPmax[cfgGroupInv->target] = (uint16_t)cfgGroupInv->power; ivPmax[cfgGroupInv->target] = cfgGroupInv->power;
ivId_Pmax[cfgGroupInv->target] = inv; ivId_Pmax[cfgGroupInv->target] = inv;
// Hier kein return oder continue sonst dauerreboot // Hier kein return oder continue sonst dauerreboot
} }
@ -1007,22 +1018,22 @@ class ZeroExport {
} }
mLog[String(String("10") + String(i))] = String(i); mLog[String(String("10") + String(i))] = String(i);
float *deltaP; int32_t *deltaP;
switch (i) { switch (i) {
case 6: case 6:
case 3: case 3:
deltaP = &mCfg->groups[group].grpPowerL3; deltaP = &mCfg->groups[group].y3;
break; break;
case 5: case 5:
case 2: case 2:
deltaP = &mCfg->groups[group].grpPowerL2; deltaP = &mCfg->groups[group].y2;
break; break;
case 4: case 4:
case 1: case 1:
deltaP = &mCfg->groups[group].grpPowerL1; deltaP = &mCfg->groups[group].y1;
break; break;
case 0: case 0:
deltaP = &mCfg->groups[group].grpPower; deltaP = &mCfg->groups[group].y;
break; break;
} }
@ -1110,7 +1121,7 @@ class ZeroExport {
// Reset // Reset
if ((cfgGroupInv->doReboot == 2) && (cfgGroupInv->waitRebootAck == 0)) { if ((cfgGroupInv->doReboot == 2) && (cfgGroupInv->waitRebootAck == 0)) {
result = false; /// result = false;
cfgGroupInv->doReboot = 0; cfgGroupInv->doReboot = 0;
logObj["act"] = "done"; logObj["act"] = "done";
continue; continue;
@ -1191,7 +1202,7 @@ class ZeroExport {
// Reset // Reset
if ((cfgGroupInv->doPower != -1) && (cfgGroupInv->waitPowerAck == 0)) { if ((cfgGroupInv->doPower != -1) && (cfgGroupInv->waitPowerAck == 0)) {
result = false; /// result = false;
cfgGroupInv->doPower = -1; cfgGroupInv->doPower = -1;
logObj["act"] = "done"; logObj["act"] = "done";
continue; continue;
@ -1290,7 +1301,7 @@ class ZeroExport {
// Reset // Reset
if ((cfgGroupInv->doLimit) && (cfgGroupInv->waitLimitAck == 0)) { if ((cfgGroupInv->doLimit) && (cfgGroupInv->waitLimitAck == 0)) {
result = false; /// result = false;
cfgGroupInv->doLimit = false; cfgGroupInv->doLimit = false;
logObj["act"] = "done"; logObj["act"] = "done";
continue; continue;
@ -1345,7 +1356,7 @@ class ZeroExport {
// } // }
if (cfgGroupInv->limit == cfgGroupInv->limitNew) { if (cfgGroupInv->limit == cfgGroupInv->limitNew) {
logObj["act"] = "nothing to do"; /// logObj["act"] = "nothing to do";
continue; continue;
} }
@ -1404,11 +1415,17 @@ class ZeroExport {
// TODO: Global wird fälschlicherweise hier je nach anzahl der aktivierten Gruppen bis zu 6x ausgeführt. // TODO: Global wird fälschlicherweise hier je nach anzahl der aktivierten Gruppen bis zu 6x ausgeführt.
mMqtt->publish("zero/set/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false); mMqtt->publish("zero/set/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
mMqtt->subscribe("zero/set/enabled", QOS_2); mMqtt->subscribe("zero/set/enabled", QOS_2);
// TODO: Global wird fälschlicherweise hier je nach anzahl der aktivierten Gruppen bis zu 6x ausgeführt.
mMqtt->publish("zero/set/sleep", ((mCfg->sleep) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
mMqtt->subscribe("zero/set/sleep", QOS_2);
// General // General
gr = "zero/set/groups/" + String(group) + "/enabled"; gr = "zero/set/groups/" + String(group) + "/enabled";
mMqtt->publish(gr.c_str(), ((cfgGroup->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false); mMqtt->publish(gr.c_str(), ((cfgGroup->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
mMqtt->subscribe(gr.c_str(), QOS_2); mMqtt->subscribe(gr.c_str(), QOS_2);
gr = "zero/set/groups/" + String(group) + "/sleep";
mMqtt->publish(gr.c_str(), ((cfgGroup->sleep) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
mMqtt->subscribe(gr.c_str(), QOS_2);
// Powermeter // Powermeter
// TODO: fehlt // TODO: fehlt
@ -1426,21 +1443,26 @@ class ZeroExport {
// Global (zeroExport) // Global (zeroExport)
// TODO: Global wird fälschlicherweise hier je nach anzahl der aktivierten Gruppen bis zu 6x ausgeführt. // TODO: Global wird fälschlicherweise hier je nach anzahl der aktivierten Gruppen bis zu 6x ausgeführt.
mMqtt->publish("zero/state/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false); mMqtt->publish("zero/state/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
// TODO: Global wird fälschlicherweise hier je nach anzahl der aktivierten Gruppen bis zu 6x ausgeführt.
mMqtt->publish("zero/state/sleep", ((mCfg->sleep) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
// General // General
gr = "zero/state/groups/" + String(group) + "/enabled"; gr = "zero/state/groups/" + String(group) + "/enabled";
mMqtt->publish(gr.c_str(), ((cfgGroup->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false); mMqtt->publish(gr.c_str(), ((cfgGroup->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
gr = "zero/state/groups/" + String(group) + "/sleep";
mMqtt->publish(gr.c_str(), ((cfgGroup->sleep) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
gr = "zero/state/groups/" + String(group) + "/name"; gr = "zero/state/groups/" + String(group) + "/name";
mMqtt->publish(gr.c_str(), cfgGroup->name, false); mMqtt->publish(gr.c_str(), cfgGroup->name, false);
// Powermeter // Powermeter
// if (cfgGroup->publishPower) { // if (cfgGroup->publishPower) {
// cfgGroup->publishPower = false; // cfgGroup->publishPower = false;
obj["L1"] = cfgGroup->pmPowerL1; obj["Sum"] = cfgGroup->pm_P;
obj["L2"] = cfgGroup->pmPowerL2; obj["L1"] = cfgGroup->pm_P1;
obj["L3"] = cfgGroup->pmPowerL3; obj["L2"] = cfgGroup->pm_P2;
obj["Sum"] = cfgGroup->pmPower; obj["L3"] = cfgGroup->pm_P3;
mMqtt->publish("zero/state/powermeter/P", doc.as<std::string>().c_str(), false); mMqtt->publish("zero/state/powermeter/P", doc.as<std::string>().c_str(), false);
doc.clear(); doc.clear();
// } // }
@ -1448,10 +1470,10 @@ class ZeroExport {
// if (cfgGroup->pm_Publish_W) { // if (cfgGroup->pm_Publish_W) {
// cfgGroup->pm_Publish_W = false; // cfgGroup->pm_Publish_W = false;
// obj["todo"] = "true"; // obj["todo"] = "true";
// obj["Sum"] = cfgGroup->pm_P;
// obj["L1"] = cfgGroup->pm_P1; // obj["L1"] = cfgGroup->pm_P1;
// obj["L2"] = cfgGroup->pm_P2; // obj["L2"] = cfgGroup->pm_P2;
// obj["L2"] = cfgGroup->pm_P3; // obj["L2"] = cfgGroup->pm_P3;
// obj["Sum"] = cfgGroup->pm_P;
// mMqtt->publish("zero/powermeter/W", doc.as<std::string>().c_str(), false); // mMqtt->publish("zero/powermeter/W", doc.as<std::string>().c_str(), false);
// doc.clear(); // doc.clear();
// } // }

Loading…
Cancel
Save