Browse Source

add new properties to make more settings

pull/1155/head
DanielR92 2 years ago
parent
commit
7a7fab2c66
  1. 9
      src/app.cpp
  2. 31
      src/config/settings.h
  3. 64
      src/plugins/zeroExport/zeroExport.h
  4. 14
      src/web/RestApi.h
  5. 7
      src/web/html/setup.html
  6. 2
      src/web/web.h

9
src/app.cpp

@ -594,19 +594,20 @@ void app::updateLed(void) {
#if defined(ESP32)
void app::zeroexport() {
if (!mConfig->plugin.zexport.enabled) return;
if (!mConfig->plugin.zexport.rdytoSend) return;
DynamicJsonDocument doc(512);
JsonObject object = doc.to<JsonObject>();
object["path"] = "ctrl";
object["id"] = 0;
object["val"] = round(mzExport.sum());
object["id"] = mConfig->plugin.zexport.Iv;
object["val"] = round(mzExport.getPowertoSetnewValue());
object["cmd"] = "limit_nonpersistent_absolute";
/*String data;
String data;
serializeJsonPretty(object, data);
DPRINTLN(DBG_INFO, data);*/
DPRINTLN(DBG_INFO, data);
mApi.ctrlRequest(object);
}

31
src/config/settings.h

@ -138,18 +138,15 @@ typedef struct {
/* Zero Export section */
#if defined(ESP32)
typedef struct {
float power;
float pf;
float current;
float voltage;
} cfgShellyEM3_t;
typedef struct {
char monitor_ip[ZEXPORT_ADDR_LEN];
uint8_t device; // save the monitor device (1 - Shelly; 2 - Hichi;)
uint8_t Iv; // saves the inverter that is used for regulation
bool enabled;
bool rdytoSend; // indicate to send new value
float power_avg;
uint8_t count_avg;
cfgShellyEM3_t PHASE[3];
double total_power;
} cfgzeroExport_t;
#endif
@ -458,8 +455,11 @@ class settings {
#if defined(ESP32)
snprintf(mCfg.plugin.zexport.monitor_ip, ZEXPORT_ADDR_LEN, "%s", DEF_ZEXPORT);
mCfg.plugin.zexport.enabled = false;
mCfg.plugin.zexport.rdytoSend = false;
mCfg.plugin.zexport.count_avg = 10;
mCfg.plugin.zexport.power_avg = 10;
mCfg.plugin.zexport.device = 0;
mCfg.plugin.zexport.Iv = 0;
#endif
mCfg.inst.rstYieldMidNight = false;
@ -658,24 +658,19 @@ class settings {
if(set) {
obj[F("en_zeroexport")] = (bool) mCfg.plugin.zexport.enabled;
obj[F("monitor_ipAddr")] = mCfg.plugin.zexport.monitor_ip;
obj[F("Iv")] = mCfg.plugin.zexport.Iv;
obj[F("power_avg")] = mCfg.plugin.zexport.power_avg;
obj[F("count_avg")] = mCfg.plugin.zexport.count_avg;
if(!mCfg.plugin.zexport.PHASE) return;
for (size_t i = 0; i < sizeof(mCfg.plugin.zexport.PHASE); i++)
{
char str[10];
sprintf(str, "phase_%d", i + 1);
obj[str][F("power")] = mCfg.plugin.zexport.PHASE[i].power;
obj[str][F("pf")] = mCfg.plugin.zexport.PHASE[i].pf;
obj[str][F("current")] = mCfg.plugin.zexport.PHASE[i].current;
obj[str][F("voltage")] = mCfg.plugin.zexport.PHASE[i].voltage;
}
obj[F("total_power")] = mCfg.plugin.zexport.total_power;
}
else
{
getVal<bool>(obj, F("en_zeroexport"), &mCfg.plugin.zexport.enabled);
getChar(obj, F("monitor_ipAddr"), mCfg.plugin.zexport.monitor_ip, ZEXPORT_ADDR_LEN);
getVal<uint8_t>(obj, F("Iv"), &mCfg.plugin.zexport.Iv);
getVal<float>(obj, F("power_avg"), &mCfg.plugin.zexport.power_avg);
getVal<uint8_t>(obj, F("count_avg"), &mCfg.plugin.zexport.count_avg);
getVal<double>(obj, F("total_power"), &mCfg.plugin.zexport.total_power);
}
}
#endif

64
src/plugins/zeroExport/zeroExport.h

@ -21,12 +21,12 @@ class ZeroExport {
}
void payloadEventListener(uint8_t cmd) {
mNewPayload = true;
mCfg->rdytoSend = false;
}
void tickerSecond() {
if (mNewPayload || ((++mLoopCnt % 10) == 0)) {
mNewPayload = false;
if (!mCfg->rdytoSend || ((++mLoopCnt % mCfg->count_avg) == 0)) {
mCfg->rdytoSend = true;
mLoopCnt = 0;
zero();
}
@ -34,7 +34,7 @@ class ZeroExport {
// Sums up the power values ​​of all phases and returns them.
// If the value is negative, all power values ​​from the inverter are taken into account
double sum()
double getPowertoSetnewValue()
{
float ivPower = 0;
Inverter<> *iv;
@ -47,51 +47,59 @@ class ZeroExport {
ivPower += iv->getChannelFieldValue(CH0, FLD_PAC, rec);
}
double em3_power = mCfg->PHASE[0].power + mCfg->PHASE[1].power + mCfg->PHASE[2].power;
return ((unsigned)(em3_power - mCfg->power_avg) >= mCfg->power_avg) ? ivPower + em3_power : ivPower - em3_power;
return ((unsigned)(mCfg->total_power - mCfg->power_avg) >= mCfg->power_avg) ? ivPower + mCfg->total_power : ivPower - mCfg->total_power;
}
private:
HTTPClient http;
void loop() { }
// TODO: Need to improve here. 2048 for a JSON Obj is to big!?
void zero() {
sendReq(0);
sendReq(1);
sendReq(2);
switch (mCfg->device) {
case 0:
case 1:
mCfg->device = Shelly();
break;
case 2:
mCfg->device = Hichi();
break;
default:
// Statement(s)
break; // Wird nicht benötigt, wenn Statement(s) vorhanden sind
}
}
void sendReq(int index)
int Shelly()
{
http.begin(String(mCfg->monitor_ip), 80, "/emeter/" + String(index));
http.begin(String(mCfg->monitor_ip), 80, "/status");
int httpResponseCode = http.GET();
if (httpResponseCode > 0)
{
DynamicJsonDocument json(128);
deserializeJson(json, getData());
mCfg->PHASE[index].power = (float)json[F("power")];
mCfg->PHASE[index].pf = (float)json[F("pf")];
mCfg->PHASE[index].current = (float)json[F("current")];
mCfg->PHASE[index].voltage = (float)json[F("voltage")];
DynamicJsonDocument json(2048);
DeserializationError err = deserializeJson(json, http.getString());
mCfg->total_power = (double)json[F("total_power")];
// Parse succeeded?
if (err) {
DPRINTLN(DBG_INFO, (F("Shelly() returned: ")));
DPRINTLN(DBG_INFO, String(err.f_str()));
return 0;
}
return 1;
}
else
{
DPRINT(DBG_INFO, "Error code: ");
DPRINTLN(DBG_INFO, String(httpResponseCode));
}
return 0;
}
String getData()
int Hichi()
{
String payload = http.getString();
int x = payload.indexOf("{", 0);
return payload.substring(x, payload.length());
return 0;
}
// private member variables
bool mNewPayload;
uint8_t mLoopCnt;
const char *mVersion;
cfgzeroExport_t *mCfg;

14
src/web/RestApi.h

@ -486,18 +486,10 @@ class RestApi {
obj[F("en_zeroexport")] = (bool) mConfig->plugin.zexport.enabled;
obj[F("monitor_ipAddr")] = String(mConfig->plugin.zexport.monitor_ip);
obj[F("count_avg")] = (uint8_t)mConfig->plugin.zexport.count_avg;
obj[F("Iv")] = (uint8_t)mConfig->plugin.zexport.Iv;
obj[F("power_avg")] = (float)mConfig->plugin.zexport.power_avg;
for (size_t i = 0; i < 3; i++)
{
char str[10];
sprintf(str, "phase_%d", i);
JsonObject phases = obj.createNestedObject(str);
phases[F("power")] = mConfig->plugin.zexport.PHASE[i].power;
phases[F("pf")] = mConfig->plugin.zexport.PHASE[i].pf;
phases[F("current")] = mConfig->plugin.zexport.PHASE[i].current;
phases[F("voltage")] = mConfig->plugin.zexport.PHASE[i].voltage;
}
obj[F("total_power")] = (double)mConfig->plugin.zexport.total_power;
//obj[F("device")] = (uint8_t)mCfg.plugin.zexport.device;
}
#endif

7
src/web/html/setup.html

@ -335,9 +335,7 @@
<div class="col-12 col-sm-3 my-2">Refresh rate (sec.)<input type="number" name="count_avg" min="0" max="255"></div>
<div class="col-12 col-sm-3 my-2">Power tolerances (Watt)<input type="number" name="power_avg" min="0" max="255"></div>
</div>
<p name="phase_1">L1: n/a</p>
<p name="phase_2">L2: n/a</p>
<p name="phase_3">L3: n/a</p>
<p name="total_power">Total: n/a</p>
</fieldset>
</div>
@ -967,7 +965,8 @@
if(null != obj[i[1]])
document.getElementsByName(i[0])[0].value = obj[i[1]];
for (let i = 0; i < 3; i++) document.getElementsByName("phase_" + (i + 1))[0].innerHTML = "L" + (i + 1) + ": " + obj["phase_" + i]["power"].toFixed(2) + "W";
document.getElementsByName("total_power")[0].innerHTML = obj["total_power"].toFixed(2) + "W";
document.getElementById("Inv_ID").selectedIndex = obj["Iv"];
}
function parseZeroIv(root)

2
src/web/web.h

@ -604,8 +604,10 @@ class Web {
// zero-export
#if defined(ESP32)
mConfig->plugin.zexport.enabled = (request->arg("en_zeroexport") == "on");
mConfig->plugin.zexport.Iv = request->arg("Iv").toInt();
mConfig->plugin.zexport.count_avg = request->arg("count_avg").toInt();
mConfig->plugin.zexport.power_avg = request->arg("power_avg").toFloat();
mConfig->plugin.zexport.total_power = request->arg("total_power").toDouble();
if (request->arg("monitor_ipAddr") != "") {
String addr = request->arg("monitor_ipAddr");

Loading…
Cancel
Save