diff --git a/src/config/settings.h b/src/config/settings.h index 7795e420..0a34ed1f 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -134,11 +134,23 @@ typedef struct { uint16_t interval; } cfgMqtt_t; +typedef struct { + float power; + float pf; + float current; + float voltage; + bool is_valid; + uint16_t total; + uint16_t total_returned; +} cfgShellyEM3_t; + typedef struct { char monitor_ip[ZEXPORT_ADDR_LEN]; bool enabled; + cfgShellyEM3_t PHASE[3]; } cfgzeroExport_t; + typedef struct { bool enabled; char name[MAX_NAME_LENGTH]; @@ -433,8 +445,9 @@ class settings { snprintf(mCfg.mqtt.topic, MQTT_TOPIC_LEN, "%s", DEF_MQTT_TOPIC); mCfg.mqtt.interval = 0; // off + // Zero-Export snprintf(mCfg.plugin.zexport.monitor_ip, ZEXPORT_ADDR_LEN, "%s", DEF_ZEXPORT); - mCfg.plugin.zexport.enabled = false; + mCfg.plugin.zexport.enabled = false; mCfg.inst.rstYieldMidNight = false; mCfg.inst.rstValsNotAvail = false; @@ -621,6 +634,20 @@ class settings { if(set) { obj[F("en_zeroexport")] = (bool) mCfg.plugin.zexport.enabled; obj[F("monitor_ipAddr")] = mCfg.plugin.zexport.monitor_ip; + + 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); + 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[str][F("is_valid")] = mCfg.plugin.zexport.PHASE[i].is_valid; + obj[str][F("total")] = mCfg.plugin.zexport.PHASE[i].total; + obj[str][F("total_returned")] = mCfg.plugin.zexport.PHASE[i].total_returned; + } } else { diff --git a/src/plugins/zeroExport/zeroExport.h b/src/plugins/zeroExport/zeroExport.h index 03fc9fd0..aab4e60b 100644 --- a/src/plugins/zeroExport/zeroExport.h +++ b/src/plugins/zeroExport/zeroExport.h @@ -2,17 +2,20 @@ #define __ZEROEXPORT__ #include +#include +#include "AsyncJson.h" template class ZeroExport { public: ZeroExport() { } + float mililine; void setup(cfgzeroExport_t *cfg, HMSYSTEM *sys, settings_t *config) { - mCfg = cfg; - mSys = sys; - mConfig = config; + mCfg = cfg; + mSys = sys; + mConfig = config; } void payloadEventListener(uint8_t cmd) { @@ -27,47 +30,76 @@ class ZeroExport { } } - void tickerMinute() { - zero(); + uint8_t sum(int a, int b, int c) + { + return a + b + c; } private: + WiFiClient client; + int status = WL_IDLE_STATUS; + const uint16_t httpPort = 80; + const String url = "/emeter/"; + char msgBuffer[256] = {'\0'}; + + const String serverIp = "192.168.5.30"; + + void loop() { } void zero() { - char meter[] = "192.168.5.30/emeter/0"; + sendReq(0); + sendReq(1); + sendReq(2); + } - WiFiClient client; - HTTPClient http; + // TODO: change int to u_short + void sendReq(int index) { + if (!client.connect(serverIp, httpPort)) { + delay(1000); + DPRINTLN(DBG_INFO, F("connection failed")); + } - DPRINTLN(DBG_INFO, meter); + strcpy ( msgBuffer, "GET "); + strcat ( msgBuffer, url.c_str()); - http.begin(client, meter); // HTTPS - http.GET(); + char str[10]; + sprintf(str, "%d", index); - // Parse response - DynamicJsonDocument doc(2048); - deserializeJson(doc, http.getStream()); + strcat ( msgBuffer, str); + strcat ( msgBuffer, "\r\nHTTP/1.1\r\n\r\n" ); + client.print(msgBuffer); - // Read values - DPRINTLN(DBG_INFO, doc["power"].as()); + DynamicJsonDocument json(128); + String raw = getData(); + deserializeJson(json, raw); - // httpCode will be negative on error - /*if (httpCode > 0) { - // file found at server - if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { - String payload = http.getString(); - DPRINTLN(DBG_INFO, payload); - } - } else { - DPRINTLN(DBG_INFO, http.errorToString(httpCode).c_str()); - }*/ + DPRINTLN(DBG_INFO, raw); - http.end(); + mCfg->PHASE[index].power = json[F("power")]; + mCfg->PHASE[index].pf = json[F("pf")]; + mCfg->PHASE[index].current = json[F("current")]; + mCfg->PHASE[index].voltage = json[F("voltage")]; + mCfg->PHASE[index].is_valid = json[F("is_valid")]; + mCfg->PHASE[index].total = json[F("total")]; + mCfg->PHASE[index].total_returned = json[F("total_returned")]; + } + + String getData() { + while (client.connected()) { + //TODO: what if available is not true? It will stuck here then... + while (client.available()) + { + String raw = client.readString(); + int x = raw.indexOf("{", 0); + client.stop(); + return raw.substring(x, raw.length()); + } + } + return F("error"); } // private member variables bool mNewPayload; uint8_t mLoopCnt; - uint32_t *mUtcTs; const char *mVersion; cfgzeroExport_t *mCfg; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index e8213633..042e6327 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -468,6 +468,20 @@ class RestApi { void getzeroExport(JsonObject obj) { obj[F("en_zeroexport")] = (bool) mConfig->plugin.zexport.enabled; obj[F("monitor_ipAddr")] = String(mConfig->plugin.zexport.monitor_ip); + 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; + phases[F("is_valid")] = mConfig->plugin.zexport.PHASE[i].is_valid; + phases[F("total")] = mConfig->plugin.zexport.PHASE[i].total; + phases[F("total_returned")] = mConfig->plugin.zexport.PHASE[i].total_returned; + } } void getNtp(JsonObject obj) { diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 80c3115c..3b72e011 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -328,7 +328,7 @@
-
Monitor IP:
+
Shelly EM3 IP:
@@ -925,9 +925,11 @@ } function parsezeroExport(obj) { - for(var i of [["monitor_ipAddr", "monitor_ipAddr"], ["en_zeroexport", "en_zeroexport"]]) + for(var i of [["monitor_ipAddr", "monitor_ipAddr"],["phase_1", "phase_1"],["phase_2", "phase_2"],["phase_3", "phase_3"],["sum", "sum"]]) if(null != obj[i[1]]) document.getElementsByName(i[0])[0].value = obj[i[1]]; + + document.getElementsByName("en_zeroexport")[0].checked = obj["en_zeroexport"]; } function parse(root) { diff --git a/src/web/html/visualization.html b/src/web/html/visualization.html index 03ff4083..4136bd50 100644 --- a/src/web/html/visualization.html +++ b/src/web/html/visualization.html @@ -10,6 +10,7 @@
+

Every seconds the values are updated

diff --git a/src/web/web.h b/src/web/web.h index 09ad0742..30127408 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -604,11 +604,11 @@ class Web { mConfig->mqtt.interval = request->arg("mqttInterval").toInt(); // zero-export + mConfig->plugin.zexport.enabled = (request->arg("en_zeroexport") == "on"); if (request->arg("monitor_ipAddr") != "") { String addr = request->arg("monitor_ipAddr"); addr.trim(); addr.toCharArray(mConfig->plugin.zexport.monitor_ip, ZEXPORT_ADDR_LEN); - mConfig->plugin.zexport.enabled = (request->arg("en_zeroexport") == "on"); } else mConfig->plugin.zexport.monitor_ip[0] = '\0';