|
@ -12,7 +12,6 @@ template <class HMSYSTEM> |
|
|
class ZeroExport { |
|
|
class ZeroExport { |
|
|
public: |
|
|
public: |
|
|
ZeroExport() { } |
|
|
ZeroExport() { } |
|
|
float mililine; |
|
|
|
|
|
|
|
|
|
|
|
void setup(cfgzeroExport_t *cfg, HMSYSTEM *sys, settings_t *config) { |
|
|
void setup(cfgzeroExport_t *cfg, HMSYSTEM *sys, settings_t *config) { |
|
|
mCfg = cfg; |
|
|
mCfg = cfg; |
|
@ -24,7 +23,6 @@ class ZeroExport { |
|
|
//DPRINTLN(DBG_INFO, (F("tickerSecond()")));
|
|
|
//DPRINTLN(DBG_INFO, (F("tickerSecond()")));
|
|
|
if (millis() - mCfg->lastTime < mCfg->count_avg * 1000UL) { |
|
|
if (millis() - mCfg->lastTime < mCfg->count_avg * 1000UL) { |
|
|
zero(); // just refresh when it is needed. To get cpu load low.
|
|
|
zero(); // just refresh when it is needed. To get cpu load low.
|
|
|
//DPRINTLN(DBG_INFO, (F("zero()")));
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -47,104 +45,63 @@ class ZeroExport { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
HTTPClient http; |
|
|
HTTPClient httpClient; |
|
|
|
|
|
|
|
|
// TODO: Need to improve here. 2048 for a JSON Obj is to big!?
|
|
|
// TODO: Need to improve here. 2048 for a JSON Obj is to big!?
|
|
|
void zero() { |
|
|
bool zero() |
|
|
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
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Shelly() |
|
|
|
|
|
{ |
|
|
{ |
|
|
http.begin(String(mCfg->monitor_ip), 80, "/status"); |
|
|
if (!httpClient.begin(mCfg->monitor_url)) { |
|
|
|
|
|
DPRINTLN(DBG_INFO, "httpClient.begin failed"); |
|
|
int httpResponseCode = http.GET(); |
|
|
httpClient.end(); |
|
|
if (httpResponseCode > 0 && httpResponseCode < 400) |
|
|
return false; |
|
|
{ |
|
|
|
|
|
DynamicJsonDocument json(2048); |
|
|
|
|
|
DeserializationError err = deserializeJson(json, http.getString()); |
|
|
|
|
|
|
|
|
|
|
|
// Parse succeeded?
|
|
|
|
|
|
if (err) { |
|
|
|
|
|
DPRINTLN(DBG_INFO, (F("Shelly() returned: "))); |
|
|
|
|
|
DPRINTLN(DBG_INFO, String(err.f_str())); |
|
|
|
|
|
return 2; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
mCfg->total_power = (double)json[F("total_power")]; |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
if (httpResponseCode >= 400) |
|
|
|
|
|
{ |
|
|
|
|
|
DPRINTLN(DBG_INFO, "Shelly(): Error " + String(httpResponseCode)); |
|
|
|
|
|
} |
|
|
} |
|
|
return 2; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Hichi() |
|
|
httpClient.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); |
|
|
{ |
|
|
httpClient.setUserAgent("Ahoy-Agent"); |
|
|
http.begin(String(mCfg->monitor_ip), 80, "/cm?cmnd=status%208"); |
|
|
httpClient.setConnectTimeout(1000); |
|
|
String hName = String(mCfg->HICHI_PowerName); |
|
|
httpClient.setTimeout(1000); |
|
|
|
|
|
httpClient.addHeader("Content-Type", "application/json"); |
|
|
|
|
|
httpClient.addHeader("Accept", "application/json"); |
|
|
|
|
|
|
|
|
int httpResponseCode = http.GET(); |
|
|
int httpCode = httpClient.GET(); |
|
|
if (httpResponseCode > 0 && httpResponseCode < 400) |
|
|
if (httpCode == HTTP_CODE_OK) |
|
|
{ |
|
|
{ |
|
|
|
|
|
String responseBody = httpClient.getString(); |
|
|
DynamicJsonDocument json(2048); |
|
|
DynamicJsonDocument json(2048); |
|
|
DeserializationError err = deserializeJson(json, http.getString()); |
|
|
DeserializationError err = deserializeJson(json, responseBody); |
|
|
|
|
|
|
|
|
// Parse succeeded?
|
|
|
// Parse succeeded?
|
|
|
if (err) { |
|
|
if (err) { |
|
|
DPRINT(DBG_INFO, (F("Hichi() returned: "))); |
|
|
DPRINTLN(DBG_INFO, (F("ZeroExport() JSON error returned: "))); |
|
|
DPRINTLN(DBG_INFO, String(err.f_str())); |
|
|
DPRINTLN(DBG_INFO, String(err.f_str())); |
|
|
return 0; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int count = 0; |
|
|
// check if it HICHI
|
|
|
for (uint8_t i = 0; i < strlen(hName.c_str()); i++) |
|
|
if(json.containsKey(F("StatusSNS")) ) { |
|
|
if (hName[i] == ']') count++; |
|
|
int index = responseBody.indexOf(String(mCfg->json_path)); // find first match position
|
|
|
|
|
|
responseBody = responseBody.substring(index); // cut it and store it in value
|
|
|
for (uint8_t i = 0; i < count; i++) |
|
|
index = responseBody.indexOf(","); // find the first seperation - Bingo!?
|
|
|
{ |
|
|
|
|
|
uint8_t l_index = hName.indexOf(']') - 1; |
|
|
mCfg->total_power = responseBody.substring(0, index - 1).toDouble(); |
|
|
json = json[hName.substring(1, l_index)]; |
|
|
} else if(json.containsKey(F("emeters"))) { |
|
|
|
|
|
mCfg->total_power = (double)json[F("total_power")]; |
|
|
|
|
|
} else { |
|
|
String output; |
|
|
DPRINTLN(DBG_INFO, (F("ZeroExport() json error: cant find value in this query: ") + responseBody)); |
|
|
serializeJson(json, output); |
|
|
return false; |
|
|
DPRINTLN(DBG_INFO, output); |
|
|
|
|
|
hName = hName.substring(l_index); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
DPRINTLN(DBG_INFO, String(json[0])); |
|
|
|
|
|
mCfg->total_power = (double)json[0]; |
|
|
|
|
|
return 2; |
|
|
|
|
|
} |
|
|
} |
|
|
if (httpResponseCode >= 400) |
|
|
else |
|
|
{ |
|
|
{ |
|
|
DPRINTLN(DBG_INFO, "HICHI(): Error " + String(httpResponseCode)); |
|
|
DPRINTLN(DBG_INFO, F("ZeroExport(): Error ") + String(httpCode)); |
|
|
|
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
return true; |
|
|
return 0; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// private member variables
|
|
|
// private member variables
|
|
|
const char *mVersion; |
|
|
|
|
|
cfgzeroExport_t *mCfg; |
|
|
cfgzeroExport_t *mCfg; |
|
|
|
|
|
|
|
|
settings_t *mConfig; |
|
|
settings_t *mConfig; |
|
|
HMSYSTEM *mSys; |
|
|
HMSYSTEM *mSys; |
|
|
uint16_t mRefreshCycle; |
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
#endif /*__ZEROEXPORT__*/ |
|
|
#endif /*__ZEROEXPORT__*/ |
|
|