Browse Source

0.8.970010-zero

0.8.970010-zero
pull/1557/head
tictrick 1 year ago
committed by GitHub
parent
commit
5c3814509d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 6
      src/app.cpp
  2. 117
      src/config/settings.h
  3. 2
      src/defines.h
  4. 267
      src/plugins/zeroExport/powermeter.h
  5. 1625
      src/plugins/zeroExport/zeroExport.h
  6. 1
      src/publisher/pubMqtt.h
  7. 2
      src/web/RestApi.h

6
src/app.cpp

@ -235,7 +235,7 @@ void app::regularTickers(void) {
// Plugin ZeroExport
#if defined(PLUGIN_ZEROEXPORT)
everySec(std::bind(&ZeroExportType::tickerSecond, &mZeroExport), "ZeroExport");
everySec(std::bind(&ZeroExportType::tickSecond, &mZeroExport), "ZeroExport");
#endif
// Plugin ZeroExport - Ende
@ -423,6 +423,10 @@ void app::tickMinute(void) {
//-----------------------------------------------------------------------------
void app::tickMidnight(void) {
#if defined(PLUGIN_ZEROEXPORT)
mZeroExport.tickMidnight();
#endif /*defined(PLUGIN_ZEROEXPORT)*/
uint32_t localTime = gTimezone.toLocal(mTimestamp);
uint32_t nxtTrig = gTimezone.toUTC(localTime - (localTime % 86400) + 86400); // next midnight local time
onceAt(std::bind(&app::tickMidnight, this), nxtTrig, "mid2");

117
src/config/settings.h

@ -188,7 +188,7 @@ typedef struct {
// Plugin ZeroExport
#if defined(PLUGIN_ZEROEXPORT)
#define ZEROEXPORT_DEV_POWERMETER
//#define ZEROEXPORT_DEV_POWERMETER
#define ZEROEXPORT_MAX_GROUPS 6
#define ZEROEXPORT_GROUP_MAX_LEN_NAME 25
#define ZEROEXPORT_GROUP_MAX_LEN_PM_URL 100
@ -203,19 +203,18 @@ typedef struct {
enum class zeroExportState : uint8_t {
INIT,
WAIT,
PUBLISH,
WAITREFRESH,
GETINVERTERACKS,
GETINVERTERDATA,
BATTERYPROTECTION,
GETPOWERMETER,
CONTROLLER,
PROGNOSE,
AUFTEILEN,
SETLIMIT,
SETPOWER,
SETREBOOT,
SETPOWER,
SETLIMIT,
PUBLISH,
EMERGENCY,
FINISH,
ERROR
};
@ -228,22 +227,7 @@ typedef enum {
Hichi = 4,
Tibber = 5,
} 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 {
Sum = 0,
L1 = 1,
@ -262,20 +246,25 @@ typedef struct {
uint16_t powerMax;
//
float power;
float limit;
float limitNew;
int32_t power;
int32_t limit;
int32_t limitNew;
uint8_t waitLimitAck;
uint8_t waitPowerAck;
uint8_t waitRebootAck;
unsigned long limitTsp;
float dcVoltage;
bool state;
//
int8_t doReboot;
int8_t doPower;
bool doLimit;
} zeroExportGroupInverter_t;
typedef struct {
// General
bool enabled;
bool sleep;
char name[ZEROEXPORT_GROUP_MAX_LEN_NAME];
// Powermeter
uint8_t pm_type;
@ -296,62 +285,46 @@ typedef struct {
uint16_t powerMax;
//
zeroExportState stateLast;
zeroExportState state;
zeroExportState stateNext;
// zeroExportState stateNext;
unsigned long lastRun;
unsigned long lastRefresh;
// bool waitForAck;
float eSum;
float eSum1;
float eSum2;
float eSum3;
float eOld;
float eOld1;
float eOld2;
float eOld3;
float Kp;
float Ki;
float Kd;
uint16_t wait;
float pm_P[5];
float pm_P1[5];
float pm_P2[5];
float pm_P3[5];
uint8_t pm_iIn = 0;
uint8_t pm_iOut = 0;
float pmPower;
float pmPowerL1;
float pmPowerL2;
float pmPowerL3;
int32_t pm_P;
int32_t pm_P1;
int32_t pm_P2;
int32_t pm_P3;
bool publishPower = false;
bool battSwitch;
float grpPower;
float grpPowerL1;
float grpPowerL2;
float grpPowerL3;
// float grpLimit;
// float grpLimitL1;
// float grpLimitL2;
// float grpLimitL3;
// uint16_t power; // Aktueller Verbrauch
// uint16_t powerLimitAkt; // Aktuelles Limit
// uint16_t powerHyst; // Hysterese
// PID controller
int32_t eSum;
int32_t eSum1;
int32_t eSum2;
int32_t eSum3;
int32_t eOld;
int32_t eOld1;
int32_t eOld2;
int32_t eOld3;
float Kp;
float Ki;
float Kd;
int32_t y;
int32_t y1;
int32_t y2;
int32_t y3;
} zeroExportGroup_t;
typedef struct {
bool enabled;
bool sleep;
bool log_over_webserial;
bool log_over_mqtt;
bool debug;
zeroExportGroup_t groups[ZEROEXPORT_MAX_GROUPS];
// uint8_t query_device; // 0 - Tibber, 1 - Shelly, 2 - other (rs232?)
// char monitor_url[ZEXPORT_ADDR_LEN];
// char json_path[ZEXPORT_ADDR_LEN];
@ -675,12 +648,14 @@ class settings {
// Plugin ZeroExport
#if defined(PLUGIN_ZEROEXPORT)
mCfg.plugin.zeroExport.enabled = false;
mCfg.plugin.zeroExport.sleep = false;
mCfg.plugin.zeroExport.log_over_webserial = false;
mCfg.plugin.zeroExport.log_over_mqtt = false;
mCfg.plugin.zeroExport.debug = false;
for(uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) {
// General
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);
// Powermeter
mCfg.plugin.zeroExport.groups[group].pm_type = zeroExportPowermeterType_t::None;
@ -699,6 +674,9 @@ class settings {
mCfg.plugin.zeroExport.groups[group].inverters[inv].waitLimitAck = false;
mCfg.plugin.zeroExport.groups[group].inverters[inv].waitPowerAck = false;
mCfg.plugin.zeroExport.groups[group].inverters[inv].waitRebootAck = false;
mCfg.plugin.zeroExport.groups[group].inverters[inv].doReboot = false;
mCfg.plugin.zeroExport.groups[group].inverters[inv].doPower = -1;
mCfg.plugin.zeroExport.groups[group].inverters[inv].doLimit = false;
}
// Battery
mCfg.plugin.zeroExport.groups[group].battEnabled = false;
@ -716,10 +694,11 @@ class settings {
mCfg.plugin.zeroExport.groups[group].state = zeroExportState::INIT;
mCfg.plugin.zeroExport.groups[group].lastRun = 0;
mCfg.plugin.zeroExport.groups[group].lastRefresh = 0;
mCfg.plugin.zeroExport.groups[group].pmPower = 0;
mCfg.plugin.zeroExport.groups[group].pmPowerL1 = 0;
mCfg.plugin.zeroExport.groups[group].pmPowerL2 = 0;
mCfg.plugin.zeroExport.groups[group].pmPowerL3 = 0;
mCfg.plugin.zeroExport.groups[group].wait = 0;
mCfg.plugin.zeroExport.groups[group].pm_P = 0;
mCfg.plugin.zeroExport.groups[group].pm_P1 = 0;
mCfg.plugin.zeroExport.groups[group].pm_P2 = 0;
mCfg.plugin.zeroExport.groups[group].pm_P3 = 0;
mCfg.plugin.zeroExport.groups[group].battSwitch = false;
}

2
src/defines.h

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

267
src/plugins/zeroExport/powermeter.h

@ -21,6 +21,13 @@ typedef struct {
float *Arg;
} OBISHandler;
typedef struct {
float P;
float P1;
float P2;
float P3;
} PowermeterBuffer_t;
class powermeter {
public:
powermeter() {
@ -29,44 +36,69 @@ class powermeter {
~powermeter() {
}
bool setup(zeroExport_t *cfg /*Hier muss noch geklärt werden was gebraucht wird*/) {
bool setup(zeroExport_t *cfg, JsonObject *log /*Hier muss noch geklärt werden was gebraucht wird*/) {
mCfg = cfg;
mLog = log;
return true;
}
void loop(void) {
}
/** groupGetPowermeter
* Holt die Daten vom Powermeter
* @param group
* @returns true/false
/** loop
* abfrage der gruppen um die aktuellen Werte (Zähler) zu ermitteln.
*/
bool getData(JsonObject logObj, uint8_t group) {
bool result = false;
switch (mCfg->groups[group].pm_type) {
case 1:
result = getPowermeterWattsShelly(logObj, group);
void loop(void)
{
unsigned long Tsp = millis();
if(Tsp - mPreviousTsp <= 1000) return; // skip when it is to fast
mPreviousTsp = Tsp;
PowermeterBuffer_t power;
for (u_short group = 0; group < ZEROEXPORT_MAX_GROUPS; group++)
{
switch (mCfg->groups[group].pm_type) {
case zeroExportPowermeterType_t::Shelly:
power = getPowermeterWattsShelly(*mLog, group);
break;
case 2:
result = getPowermeterWattsTasmota(logObj, group);
case zeroExportPowermeterType_t::Tasmota:
power = getPowermeterWattsTasmota(*mLog, group);
break;
case 3:
result = getPowermeterWattsMqtt(logObj, group);
case zeroExportPowermeterType_t::Mqtt:
power = getPowermeterWattsMqtt(*mLog, group);
break;
case 4:
result = getPowermeterWattsHichi(logObj, group);
case zeroExportPowermeterType_t::Hichi:
power = getPowermeterWattsHichi(*mLog, group);
break;
case 5:
result = getPowermeterWattsTibber(logObj, group);
case zeroExportPowermeterType_t::Tibber:
power = getPowermeterWattsTibber(*mLog, group);
break;
}
bufferWrite(power, group);
}
if (!result) {
logObj["err"] = "type: " + String(mCfg->groups[group].pm_type);
}
/** groupGetPowermeter
* Holt die Daten vom Powermeter
* @param group
* @returns true/false
*/
PowermeterBuffer_t getDataAVG(uint8_t group) {
PowermeterBuffer_t avg;
avg.P = avg.P1 = avg.P2 = avg.P2 = avg.P3 = 0;
for (int i = 0; i < 5; i++)
{
avg.P += mPowermeterBuffer[group][i].P;
avg.P1 += mPowermeterBuffer[group][i].P1;
avg.P2 += mPowermeterBuffer[group][i].P2;
avg.P3 += mPowermeterBuffer[group][i].P3;
}
avg.P = avg.P / 5;
avg.P1 = avg.P1 / 5;
avg.P2 = avg.P2 / 5;
avg.P3 = avg.P3 / 5;
return result;
return avg;
}
private:
@ -76,23 +108,18 @@ class powermeter {
* @param group
* @returns true/false
*/
bool getPowermeterWattsShelly(JsonObject logObj, uint8_t group) {
bool result = false;
PowermeterBuffer_t getPowermeterWattsShelly(JsonObject logObj, uint8_t group) {
PowermeterBuffer_t result;
result.P = result.P1 = result.P2 = result.P3 = 0;
logObj["mod"] = "getPowermeterWattsShelly";
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
HTTPClient http;
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http.setUserAgent("Ahoy-Agent");
// TODO: Ahoy-0.8.850024-zero
http.setConnectTimeout(1000);
http.setConnectTimeout(500);
http.setTimeout(1000);
// TODO: Timeout von 1000 reduzieren?
http.addHeader("Content-Type", "application/json");
http.addHeader("Accept", "application/json");
@ -107,57 +134,48 @@ class powermeter {
DeserializationError error = deserializeJson(doc, http.getString());
if (error) {
logObj["err"] = "deserializeJson: " + String(error.c_str());
return false;
return result;
} else {
if (doc.containsKey(F("total_power"))) {
// Shelly 3EM
mCfg->groups[group].pmPower = doc["total_power"];
result = true;
result.P = doc["total_power"];
} else if (doc.containsKey(F("em:0"))) {
// Shelly pro 3EM
mCfg->groups[group].pmPower = doc["em:0"]["total_act_power"];
result = true;
result.P = doc["em:0"]["total_act_power"];
} else {
// Keine Daten
mCfg->groups[group].pmPower = 0;
result.P = 0;
}
if (doc.containsKey(F("emeters"))) {
// Shelly 3EM
mCfg->groups[group].pmPowerL1 = doc["emeters"][0]["power"];
result = true;
result.P1 = doc["emeters"][0]["power"];
} else if (doc.containsKey(F("em:0"))) {
// Shelly pro 3EM
mCfg->groups[group].pmPowerL1 = doc["em:0"]["a_act_power"];
result = true;
result.P1 = doc["em:0"]["a_act_power"];
} else if (doc.containsKey(F("switch:0"))) {
// Shelly plus1pm plus2pm
mCfg->groups[group].pmPowerL1 = doc["switch:0"]["apower"];
mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL1;
result = true;
result.P1 = doc["switch:0"]["apower"];
result.P += result.P1;
} else if (doc.containsKey(F("apower"))) {
// Shelly Alternative
mCfg->groups[group].pmPowerL1 = doc["apower"];
mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL1;
result = true;
result.P1 = doc["apower"];
result.P += result.P1;
} else {
// Keine Daten
mCfg->groups[group].pmPowerL1 = 0;
result.P1 = 0;
}
if (doc.containsKey(F("emeters"))) {
// Shelly 3EM
mCfg->groups[group].pmPowerL2 = doc["emeters"][1]["power"];
result = true;
result.P2 = doc["emeters"][1]["power"];
} else if (doc.containsKey(F("em:0"))) {
// Shelly pro 3EM
mCfg->groups[group].pmPowerL2 = doc["em:0"]["b_act_power"];
result = true;
result.P2 = doc["em:0"]["b_act_power"];
} else if (doc.containsKey(F("switch:1"))) {
// Shelly plus1pm plus2pm
mCfg->groups[group].pmPowerL2 = doc["switch.1"]["apower"];
mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL2;
result = true;
result.P2 = doc["switch.1"]["apower"];
result.P += result.P2;
//} else if (doc.containsKey(F("apower"))) {
// Shelly Alternative
// mCfg->groups[group].pmPowerL2 = doc["apower"];
@ -165,22 +183,19 @@ class powermeter {
// ret = true;
} else {
// Keine Daten
mCfg->groups[group].pmPowerL2 = 0;
result.P2 = 0;
}
if (doc.containsKey(F("emeters"))) {
// Shelly 3EM
mCfg->groups[group].pmPowerL3 = doc["emeters"][2]["power"];
result = true;
result.P3 = doc["emeters"][2]["power"];
} else if (doc.containsKey(F("em:0"))) {
// Shelly pro 3EM
mCfg->groups[group].pmPowerL3 = doc["em:0"]["c_act_power"];
result = true;
result.P3 = doc["em:0"]["c_act_power"];
} else if (doc.containsKey(F("switch:2"))) {
// Shelly plus1pm plus2pm
mCfg->groups[group].pmPowerL3 = doc["switch:2"]["apower"];
mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL3;
result = true;
result.P3 = doc["switch:2"]["apower"];
result.P += result.P3;
//} else if (doc.containsKey(F("apower"))) {
// Shelly Alternative
// mCfg->groups[group].pmPowerL3 = doc["apower"];
@ -188,17 +203,11 @@ class powermeter {
// result = true;
} else {
// Keine Daten
mCfg->groups[group].pmPowerL3 = 0;
result.P3 = 0;
}
}
}
http.end();
logObj["P"] = mCfg->groups[group].pmPower;
logObj["P1"] = mCfg->groups[group].pmPowerL1;
logObj["P2"] = mCfg->groups[group].pmPowerL2;
logObj["P3"] = mCfg->groups[group].pmPowerL3;
return result;
}
@ -250,17 +259,11 @@ class powermeter {
* }
* }
*/
bool getPowermeterWattsTasmota(JsonObject logObj, uint8_t group) {
bool result = false;
PowermeterBuffer_t getPowermeterWattsTasmota(JsonObject logObj, uint8_t group) {
PowermeterBuffer_t result;
result.P = result.P1 = result.P2 = result.P3 = 0;
logObj["mod"] = "getPowermeterWattsTasmota";
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
result = true;
/*
// TODO: nicht komplett
@ -329,28 +332,18 @@ class powermeter {
* @param group
* @returns true/false
*/
bool getPowermeterWattsMqtt(JsonObject logObj, uint8_t group) {
bool result = false;
PowermeterBuffer_t getPowermeterWattsMqtt(JsonObject logObj, uint8_t group) {
PowermeterBuffer_t result;
result.P = result.P1 = result.P2 = result.P3 = 0;
logObj["mod"] = "getPowermeterWattsMqtt";
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
// Hier neuer Code - Anfang
// TODO: Noch nicht komplett
result = true;
// TODO: Noch nicht komplett
// Hier neuer Code - Ende
logObj["P"] = mCfg->groups[group].pmPower;
logObj["P1"] = mCfg->groups[group].pmPowerL1;
logObj["P2"] = mCfg->groups[group].pmPowerL2;
logObj["P3"] = mCfg->groups[group].pmPowerL3;
return result;
}
@ -360,28 +353,18 @@ class powermeter {
* @param group
* @returns true/false
*/
bool getPowermeterWattsHichi(JsonObject logObj, uint8_t group) {
bool result = false;
PowermeterBuffer_t getPowermeterWattsHichi(JsonObject logObj, uint8_t group) {
PowermeterBuffer_t result;
result.P = result.P1 = result.P2 = result.P3 = 0;
logObj["mod"] = "getPowermeterWattsHichi";
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
// Hier neuer Code - Anfang
// TODO: Noch nicht komplett
result = true;
// TODO: Noch nicht komplett
// Hier neuer Code - Ende
logObj["P"] = mCfg->groups[group].pmPower;
logObj["P1"] = mCfg->groups[group].pmPowerL1;
logObj["P2"] = mCfg->groups[group].pmPowerL2;
logObj["P3"] = mCfg->groups[group].pmPowerL3;
return result;
}
@ -391,6 +374,7 @@ class powermeter {
* @param group
* @returns true/false
* @TODO: Username & Passwort wird mittels base64 verschlüsselt. Dies wird für die Authentizierung benötigt. Wichtig diese im WebUI unkenntlich zu machen und base64 im eeprom zu speichern, statt klartext.
* @TODO: Abfrage Interval einbauen. Info: Datei-Size kann auch mal 0-bytes sein!
*/
sml_states_t currentState;
@ -415,7 +399,6 @@ class powermeter {
07 01 00 02 08 01 ff #objName: OBIS-Kennzahl für Wirkenergie Einspeisung Tarif1
07 01 00 02 08 02 ff #objName: OBIS-Kennzahl für Wirkenergie Einspeisung Tarif2
*/
const std::list<OBISHandler> smlHandlerList{
{{0x01, 0x00, 0x10, 0x07, 0x00, 0xff}, &smlOBISW, &_powerMeterTotal}, // total - OBIS-Kennzahl für momentane Gesamtwirkleistung
@ -426,18 +409,19 @@ class powermeter {
{{0x01, 0x00, 0x01, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterImport},
{{0x01, 0x00, 0x02, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterExport}};
bool getPowermeterWattsTibber(JsonObject logObj, uint8_t group) {
bool result = false;
PowermeterBuffer_t getPowermeterWattsTibber(JsonObject logObj, uint8_t group) {
mPreviousTsp = mPreviousTsp + 2000; // Zusätzliche Pause
PowermeterBuffer_t result;
result.P = result.P1 = result.P2 = result.P3 = 0;
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
logObj["mod"] = "getPowermeterWattsTibber";
HTTPClient http;
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http.setUserAgent("Ahoy-Agent");
http.setConnectTimeout(1000);
// TODO: Ahoy-0.8.850024-zero
http.setConnectTimeout(500);
http.setTimeout(1000);
http.addHeader("Content-Type", "application/json");
http.addHeader("Accept", "application/json");
@ -448,35 +432,25 @@ class powermeter {
http.begin(url);
http.addHeader("Authorization", "Basic " + auth);
if (http.GET() == HTTP_CODE_OK) {
if (http.GET() == HTTP_CODE_OK && http.getSize() > 0) {
String myString = http.getString();
char floatBuffer[20];
double readVal = 0;
unsigned char c;
for (int i = 0; i < http.getSize(); ++i) {
c = myString[i];
sml_states_t smlCurrentState = smlState(c);
switch (smlCurrentState) {
case SML_FINAL:
mCfg->groups[group].pmPower = _powerMeterTotal;
mCfg->groups[group].pmPowerL1 = _powerMeter1Power;
mCfg->groups[group].pmPowerL2 = _powerMeter2Power;
mCfg->groups[group].pmPowerL3 = _powerMeter3Power;
result.P = _powerMeterTotal;
result.P1 = _powerMeter1Power;
result.P2 = _powerMeter2Power;
result.P3 = _powerMeter3Power;
if(! (_powerMeter1Power && _powerMeter2Power && _powerMeter3Power))
{
mCfg->groups[group].pmPowerL1 = _powerMeterTotal / 3;
mCfg->groups[group].pmPowerL2 = _powerMeterTotal / 3;
mCfg->groups[group].pmPowerL3 = _powerMeterTotal / 3;
if(! (_powerMeter1Power && _powerMeter2Power && _powerMeter3Power)) {
result.P1 = result.P2 = result.P3 = _powerMeterTotal / 3;
}
// TODO: Ein return an dieser Stelle verhindert das ordnungsgemäße http.end()
result = true;
// return true;
break;
case SML_LISTEND:
// check handlers on last received list
@ -490,18 +464,25 @@ class powermeter {
}
}
}
http.end();
logObj["P"] = mCfg->groups[group].pmPower;
logObj["P1"] = mCfg->groups[group].pmPowerL1;
logObj["P2"] = mCfg->groups[group].pmPowerL2;
logObj["P3"] = mCfg->groups[group].pmPowerL3;
http.end();
return result;
}
private:
void bufferWrite(PowermeterBuffer_t raw, short group)
{
mPowermeterBuffer[group][mPowermeterBufferPos[group]] = raw;
mPowermeterBufferPos[group]++;
if(mPowermeterBufferPos[group] >= 5) mPowermeterBufferPos[group] = 0;
}
zeroExport_t *mCfg;
JsonObject *mLog;
unsigned long mPreviousTsp = 0;
PowermeterBuffer_t mPowermeterBuffer[ZEROEXPORT_MAX_GROUPS][5] = { 0 };
short mPowermeterBufferPos[ZEROEXPORT_MAX_GROUPS] = { 0 };
};
// TODO: Vorlagen für Powermeter-Analyse

1625
src/plugins/zeroExport/zeroExport.h

File diff suppressed because it is too large

1
src/publisher/pubMqtt.h

@ -311,6 +311,7 @@ class PubMqtt {
DynamicJsonDocument json(128);
JsonObject root = json.to<JsonObject>();
root["topic"] = String(topic);
bool limitAbs = false;
if(len > 0) {

2
src/web/RestApi.h

@ -1158,9 +1158,7 @@ class RestApi {
mConfig->plugin.zeroExport.groups[group].Ki = jsonIn[F("Ki")];
mConfig->plugin.zeroExport.groups[group].Kd = jsonIn[F("Kd")];
// Global
mConfig->plugin.zeroExport.groups[group].stateLast = zeroExportState::INIT;
mConfig->plugin.zeroExport.groups[group].state = zeroExportState::INIT;
mConfig->plugin.zeroExport.groups[group].stateNext = zeroExportState::INIT;
mApp->saveSettings(false); // without reboot
}
#endif

Loading…
Cancel
Save