diff --git a/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp b/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp index 6682a8226..c06894fc4 100644 --- a/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp +++ b/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp @@ -198,6 +198,19 @@ bool VeDirectFrameHandler::hexRxEvent(uint8_t inbyte) { return true; // stubbed out for future } +bool VeDirectFrameHandler::isDataValid() { + if (veMap.empty()) { + return false; + } + if ((millis() - getLastUpdate()) / 1000 > _pollInterval * 5) { + return false; + } + if (veMap.find("SER") == veMap.end()) { + return false; + } + return true; +} + unsigned long VeDirectFrameHandler::getLastUpdate() { return _lastPoll; diff --git a/lib/VeDirectFrameHandler/VeDirectFrameHandler.h b/lib/VeDirectFrameHandler/VeDirectFrameHandler.h index fefbb639c..0facdd8e7 100644 --- a/lib/VeDirectFrameHandler/VeDirectFrameHandler.h +++ b/lib/VeDirectFrameHandler/VeDirectFrameHandler.h @@ -33,6 +33,7 @@ class VeDirectFrameHandler { void setPollInterval(unsigned long interval); // set poll intervall in seconds void loop(); // main loop to read ve.direct data unsigned long getLastUpdate(); // timestamp of last successful frame read + bool isDataValid(); // return true if data valid and not outdated String getPidAsString(const char* pid); // product id as string String getCsAsString(const char* cs); // current state as string String getErrAsString(const char* err); // errer state as string diff --git a/src/MqttHandlVedirectHass.cpp b/src/MqttHandlVedirectHass.cpp index e2e8a2497..931d30bc4 100644 --- a/src/MqttHandlVedirectHass.cpp +++ b/src/MqttHandlVedirectHass.cpp @@ -50,7 +50,7 @@ void MqttHandleVedirectHassClass::publishConfig() return; } // ensure data is revieved from victron - if (VeDirect.veMap.find("SER") == VeDirect.veMap.end()) { + if (!VeDirect.isDataValid()) { return; } diff --git a/src/MqttHandleVedirect.cpp b/src/MqttHandleVedirect.cpp index b8ab99a91..0501c486f 100644 --- a/src/MqttHandleVedirect.cpp +++ b/src/MqttHandleVedirect.cpp @@ -24,26 +24,17 @@ void MqttHandleVedirectClass::loop() return; } - String serial; - auto pos = VeDirect.veMap.find("SER"); - if (pos == VeDirect.veMap.end()) { - MessageOutput.printf("No VeDirect Data\r\n"); + if (!VeDirect.isDataValid()) { + MessageOutput.printf("VeDirect Data not valid: Stopping publishing. Last read before %lu seconds\r\n", (millis() - VeDirect.getLastUpdate()) / 1000); return; - } - else { - serial = pos->second; } if (millis() - _lastPublish > (config.Mqtt_PublishInterval * 1000)) { - if ((millis() - VeDirect.getLastUpdate()) / 1000 > config.Vedirect_PollInterval * 5) { // same as age critical in live view - MessageOutput.printf("VeDirect Data too old: Stopping publishing. Last read before %lu seconds\r\n", (millis() - VeDirect.getLastUpdate()) / 1000); - return; - } - String key; String value; String mapedValue; bool bChanged = false; + String serial = VeDirect.veMap["SER"]; String topic = ""; for (auto it = VeDirect.veMap.begin(); it != VeDirect.veMap.end(); ++it) { @@ -61,7 +52,6 @@ void MqttHandleVedirectClass::loop() } } - // publish only changed key, values pairs if (!config.Vedirect_UpdatesOnly || (bChanged && config.Vedirect_UpdatesOnly)) { topic = "victron/" + serial + "/"; diff --git a/src/WebApi_ws_vedirect_live.cpp b/src/WebApi_ws_vedirect_live.cpp index f7ee21ced..e836c42f6 100644 --- a/src/WebApi_ws_vedirect_live.cpp +++ b/src/WebApi_ws_vedirect_live.cpp @@ -80,40 +80,40 @@ void WebApiWsVedirectLiveClass::loop() void WebApiWsVedirectLiveClass::generateJsonResponse(JsonVariant& root) { // device info - root[F("data_age")] = (millis() - VeDirect.getLastUpdate() ) / 1000; - root[F("age_critical")] = ((millis() - VeDirect.getLastUpdate()) / 1000) > Configuration.get().Vedirect_PollInterval * 5; - root[F("PID")] = VeDirect.getPidAsString(VeDirect.veMap["PID"].c_str()); - root[F("SER")] = VeDirect.veMap["SER"]; - root[F("FW")] = VeDirect.veMap["FW"]; - root[F("LOAD")] = VeDirect.veMap["LOAD"]; - root[F("CS")] = VeDirect.getCsAsString(VeDirect.veMap["CS"].c_str()); - root[F("ERR")] = VeDirect.getErrAsString(VeDirect.veMap["ERR"].c_str()); - root[F("OR")] = VeDirect.getOrAsString(VeDirect.veMap["OR"].c_str()); - root[F("MPPT")] = VeDirect.getMpptAsString(VeDirect.veMap["MPPT"].c_str()); - root[F("HSDS")]["v"] = VeDirect.veMap["HSDS"].toInt(); - root[F("HSDS")]["u"] = "Days"; + root["data_age"] = (millis() - VeDirect.getLastUpdate() ) / 1000; + root["age_critical"] = VeDirect.isDataValid(); + root["PID"] = VeDirect.getPidAsString(VeDirect.veMap["PID"].c_str()); + root["SER"] = VeDirect.veMap["SER"]; + root["FW"] = VeDirect.veMap["FW"]; + root["LOAD"] = VeDirect.veMap["LOAD"]; + root["CS"] = VeDirect.getCsAsString(VeDirect.veMap["CS"].c_str()); + root["ERR"] = VeDirect.getErrAsString(VeDirect.veMap["ERR"].c_str()); + root["OR"] = VeDirect.getOrAsString(VeDirect.veMap["OR"].c_str()); + root["MPPT"] = VeDirect.getMpptAsString(VeDirect.veMap["MPPT"].c_str()); + root["HSDS"]["v"] = VeDirect.veMap["HSDS"].toInt(); + root["HSDS"]["u"] = "Days"; // battery info - root[F("V")]["v"] = round(VeDirect.veMap["V"].toDouble() / 10.0) / 100.0; - root[F("V")]["u"] = "V"; - root[F("I")]["v"] = round(VeDirect.veMap["I"].toDouble() / 10.0) / 100.0; - root[F("I")]["u"] = "A"; + root["V"]["v"] = round(VeDirect.veMap["V"].toDouble() / 10.0) / 100.0; + root["V"]["u"] = "V"; + root["I"]["v"] = round(VeDirect.veMap["I"].toDouble() / 10.0) / 100.0; + root["I"]["u"] = "A"; // panel info - root[F("VPV")]["v"] = round(VeDirect.veMap["VPV"].toDouble() / 10.0) / 100.0; - root[F("VPV")]["u"] = "V"; - root[F("PPV")]["v"] = VeDirect.veMap["PPV"].toInt(); - root[F("PPV")]["u"] = "W"; - root[F("H19")]["v"] = VeDirect.veMap["H19"].toDouble() / 100.0; - root[F("H19")]["u"] = "kWh"; - root[F("H20")]["v"] = VeDirect.veMap["H20"].toDouble() / 100.0; - root[F("H20")]["u"] = "kWh"; - root[F("H21")]["v"] = VeDirect.veMap["H21"].toInt(); - root[F("H21")]["u"] = "W"; - root[F("H22")]["v"] = VeDirect.veMap["H22"].toDouble() / 100.0; - root[F("H22")]["u"] = "kWh"; - root[F("H23")]["v"] = VeDirect.veMap["H23"].toInt(); - root[F("H23")]["u"] = "W"; + root["VPV"]["v"] = round(VeDirect.veMap["VPV"].toDouble() / 10.0) / 100.0; + root["VPV"]["u"] = "V"; + root["PPV"]["v"] = VeDirect.veMap["PPV"].toInt(); + root["PPV"]["u"] = "W"; + root["H19"]["v"] = VeDirect.veMap["H19"].toDouble() / 100.0; + root["H19"]["u"] = "kWh"; + root["H20"]["v"] = VeDirect.veMap["H20"].toDouble() / 100.0; + root["H20"]["u"] = "kWh"; + root["H21"]["v"] = VeDirect.veMap["H21"].toInt(); + root["H21"]["u"] = "W"; + root["H22"]["v"] = VeDirect.veMap["H22"].toDouble() / 100.0; + root["H22"]["u"] = "kWh"; + root["H23"]["v"] = VeDirect.veMap["H23"].toInt(); + root["H23"]["u"] = "W"; if (VeDirect.getLastUpdate() > _newestVedirectTimestamp) { _newestVedirectTimestamp = VeDirect.getLastUpdate();