fix: Home Assistant MQTT-Auto-Discovery with VE.Direct (#297)
In Home Assistant, when Home Assistant MQTT-Auto-Discovery is active, almost all Sensors of the auto-discovered Victron device in Home Assistant become "unavailable" after a short time - except those Sensors with frequent changes like battery voltage or panel voltage. This patch introduces regular mqtt updates for all VE.Direct sensors when MQTT-Auto-Discovery is enabled. Signed-off-by: Martin Dummer <martin.dummer@gmx.net>
This commit is contained in:
parent
23ff4ef22a
commit
cdf5c85510
@ -19,7 +19,14 @@ public:
|
|||||||
void loop();
|
void loop();
|
||||||
private:
|
private:
|
||||||
veStruct _kvFrame{};
|
veStruct _kvFrame{};
|
||||||
uint32_t _lastPublish;
|
|
||||||
|
// point of time in millis() when updated values will be published
|
||||||
|
uint32_t _nextPublishUpdatesOnly = 0;
|
||||||
|
|
||||||
|
// point of time in millis() when all values will be published
|
||||||
|
uint32_t _nextPublishFull = 1;
|
||||||
|
|
||||||
|
bool _PublishFull;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MqttHandleVedirectClass MqttHandleVedirect;
|
extern MqttHandleVedirectClass MqttHandleVedirect;
|
||||||
@ -12,8 +12,13 @@
|
|||||||
|
|
||||||
MqttHandleVedirectClass MqttHandleVedirect;
|
MqttHandleVedirectClass MqttHandleVedirect;
|
||||||
|
|
||||||
|
// #define MQTTHANDLEVEDIRECT_DEBUG
|
||||||
|
|
||||||
void MqttHandleVedirectClass::init()
|
void MqttHandleVedirectClass::init()
|
||||||
{
|
{
|
||||||
|
// initially force a full publish
|
||||||
|
_nextPublishUpdatesOnly = 0;
|
||||||
|
_nextPublishFull = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttHandleVedirectClass::loop()
|
void MqttHandleVedirectClass::loop()
|
||||||
@ -28,71 +33,111 @@ void MqttHandleVedirectClass::loop()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (millis() - _lastPublish > (config.Mqtt_PublishInterval * 1000)) {
|
if ((millis() >= _nextPublishFull) || (millis() >= _nextPublishUpdatesOnly)) {
|
||||||
|
// determine if this cycle should publish full values or updates only
|
||||||
|
if (_nextPublishFull <= _nextPublishUpdatesOnly) {
|
||||||
|
_PublishFull = true;
|
||||||
|
} else {
|
||||||
|
_PublishFull = !config.Vedirect_UpdatesOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MQTTHANDLEVEDIRECT_DEBUG
|
||||||
|
MessageOutput.printf("\r\n\r\nMqttHandleVedirectClass::loop millis %lu _nextPublishUpdatesOnly %u _nextPublishFull %u\r\n", millis(), _nextPublishUpdatesOnly, _nextPublishFull);
|
||||||
|
if (_PublishFull) {
|
||||||
|
MessageOutput.println("MqttHandleVedirectClass::loop publish full");
|
||||||
|
} else {
|
||||||
|
MessageOutput.println("MqttHandleVedirectClass::loop publish updates only");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
String value;
|
String value;
|
||||||
String topic = "victron/";
|
String topic = "victron/";
|
||||||
topic.concat(VeDirect.veFrame.SER);
|
topic.concat(VeDirect.veFrame.SER);
|
||||||
topic.concat("/");
|
topic.concat("/");
|
||||||
|
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.PID != _kvFrame.PID)
|
if (_PublishFull || VeDirect.veFrame.PID != _kvFrame.PID)
|
||||||
MqttSettings.publish(topic + "PID", VeDirect.getPidAsString(VeDirect.veFrame.PID));
|
MqttSettings.publish(topic + "PID", VeDirect.getPidAsString(VeDirect.veFrame.PID));
|
||||||
if (!config.Vedirect_UpdatesOnly || strcmp(VeDirect.veFrame.SER, _kvFrame.SER) != 0)
|
if (_PublishFull || strcmp(VeDirect.veFrame.SER, _kvFrame.SER) != 0)
|
||||||
MqttSettings.publish(topic + "SER", VeDirect.veFrame.SER );
|
MqttSettings.publish(topic + "SER", VeDirect.veFrame.SER );
|
||||||
if (!config.Vedirect_UpdatesOnly || strcmp(VeDirect.veFrame.FW, _kvFrame.FW) != 0)
|
if (_PublishFull || strcmp(VeDirect.veFrame.FW, _kvFrame.FW) != 0)
|
||||||
MqttSettings.publish(topic + "FW", VeDirect.veFrame.FW);
|
MqttSettings.publish(topic + "FW", VeDirect.veFrame.FW);
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.LOAD != _kvFrame.LOAD)
|
if (_PublishFull || VeDirect.veFrame.LOAD != _kvFrame.LOAD)
|
||||||
MqttSettings.publish(topic + "LOAD", VeDirect.veFrame.LOAD == true ? "ON": "OFF");
|
MqttSettings.publish(topic + "LOAD", VeDirect.veFrame.LOAD == true ? "ON": "OFF");
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.CS != _kvFrame.CS)
|
if (_PublishFull || VeDirect.veFrame.CS != _kvFrame.CS)
|
||||||
MqttSettings.publish(topic + "CS", VeDirect.getCsAsString(VeDirect.veFrame.CS));
|
MqttSettings.publish(topic + "CS", VeDirect.getCsAsString(VeDirect.veFrame.CS));
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.ERR != _kvFrame.ERR)
|
if (_PublishFull || VeDirect.veFrame.ERR != _kvFrame.ERR)
|
||||||
MqttSettings.publish(topic + "ERR", VeDirect.getErrAsString(VeDirect.veFrame.ERR));
|
MqttSettings.publish(topic + "ERR", VeDirect.getErrAsString(VeDirect.veFrame.ERR));
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.OR != _kvFrame.OR)
|
if (_PublishFull || VeDirect.veFrame.OR != _kvFrame.OR)
|
||||||
MqttSettings.publish(topic + "OR", VeDirect.getOrAsString(VeDirect.veFrame.OR));
|
MqttSettings.publish(topic + "OR", VeDirect.getOrAsString(VeDirect.veFrame.OR));
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.MPPT != _kvFrame.MPPT)
|
if (_PublishFull || VeDirect.veFrame.MPPT != _kvFrame.MPPT)
|
||||||
MqttSettings.publish(topic + "MPPT", VeDirect.getMpptAsString(VeDirect.veFrame.MPPT));
|
MqttSettings.publish(topic + "MPPT", VeDirect.getMpptAsString(VeDirect.veFrame.MPPT));
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.HSDS != _kvFrame.HSDS) {
|
if (_PublishFull || VeDirect.veFrame.HSDS != _kvFrame.HSDS) {
|
||||||
value = VeDirect.veFrame.HSDS;
|
value = VeDirect.veFrame.HSDS;
|
||||||
MqttSettings.publish(topic + "HSDS", value);
|
MqttSettings.publish(topic + "HSDS", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.V != _kvFrame.V) {
|
if (_PublishFull || VeDirect.veFrame.V != _kvFrame.V) {
|
||||||
value = VeDirect.veFrame.V;
|
value = VeDirect.veFrame.V;
|
||||||
MqttSettings.publish(topic + "V", value);
|
MqttSettings.publish(topic + "V", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.I != _kvFrame.I) {
|
if (_PublishFull || VeDirect.veFrame.I != _kvFrame.I) {
|
||||||
value = VeDirect.veFrame.I;
|
value = VeDirect.veFrame.I;
|
||||||
MqttSettings.publish(topic + "I", value);
|
MqttSettings.publish(topic + "I", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.VPV != _kvFrame.VPV) {
|
if (_PublishFull || VeDirect.veFrame.VPV != _kvFrame.VPV) {
|
||||||
value = VeDirect.veFrame.VPV;
|
value = VeDirect.veFrame.VPV;
|
||||||
MqttSettings.publish(topic + "VPV", value);
|
MqttSettings.publish(topic + "VPV", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.PPV != _kvFrame.PPV) {
|
if (_PublishFull || VeDirect.veFrame.PPV != _kvFrame.PPV) {
|
||||||
value = VeDirect.veFrame.PPV;
|
value = VeDirect.veFrame.PPV;
|
||||||
MqttSettings.publish(topic + "PPV", value);
|
MqttSettings.publish(topic + "PPV", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.H19 != _kvFrame.H19) {
|
if (_PublishFull || VeDirect.veFrame.H19 != _kvFrame.H19) {
|
||||||
value = VeDirect.veFrame.H19;
|
value = VeDirect.veFrame.H19;
|
||||||
MqttSettings.publish(topic + "H19", value);
|
MqttSettings.publish(topic + "H19", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.H20 != _kvFrame.H20) {
|
if (_PublishFull || VeDirect.veFrame.H20 != _kvFrame.H20) {
|
||||||
value = VeDirect.veFrame.H20;
|
value = VeDirect.veFrame.H20;
|
||||||
MqttSettings.publish(topic + "H20", value);
|
MqttSettings.publish(topic + "H20", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.H21 != _kvFrame.H21) {
|
if (_PublishFull || VeDirect.veFrame.H21 != _kvFrame.H21) {
|
||||||
value = VeDirect.veFrame.H21;
|
value = VeDirect.veFrame.H21;
|
||||||
MqttSettings.publish(topic + "H21", value);
|
MqttSettings.publish(topic + "H21", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.H22 != _kvFrame.H22) {
|
if (_PublishFull || VeDirect.veFrame.H22 != _kvFrame.H22) {
|
||||||
value = VeDirect.veFrame.H22;
|
value = VeDirect.veFrame.H22;
|
||||||
MqttSettings.publish(topic + "H22", value);
|
MqttSettings.publish(topic + "H22", value);
|
||||||
}
|
}
|
||||||
if (!config.Vedirect_UpdatesOnly || VeDirect.veFrame.H23 != _kvFrame.H23) {
|
if (_PublishFull || VeDirect.veFrame.H23 != _kvFrame.H23) {
|
||||||
value = VeDirect.veFrame.H23;
|
value = VeDirect.veFrame.H23;
|
||||||
MqttSettings.publish(topic + "H23", value);
|
MqttSettings.publish(topic + "H23", value);
|
||||||
}
|
}
|
||||||
if (config.Vedirect_UpdatesOnly){
|
if (!_PublishFull) {
|
||||||
_kvFrame= VeDirect.veFrame;
|
_kvFrame= VeDirect.veFrame;
|
||||||
}
|
}
|
||||||
_lastPublish = millis();
|
|
||||||
|
// now calculate next points of time to publish
|
||||||
|
_nextPublishUpdatesOnly = millis() + (config.Mqtt_PublishInterval * 1000);
|
||||||
|
|
||||||
|
if (_PublishFull) {
|
||||||
|
// when Home Assistant MQTT-Auto-Discovery is active,
|
||||||
|
// and "enable expiration" is active, all values must be published at
|
||||||
|
// least once before the announced expiry interval is reached
|
||||||
|
if ((config.Vedirect_UpdatesOnly) && (config.Mqtt_Hass_Enabled) && (config.Mqtt_Hass_Expire)) {
|
||||||
|
_nextPublishFull = millis() + (((config.Mqtt_PublishInterval * 3) - 1) * 1000);
|
||||||
|
|
||||||
|
#ifdef MQTTHANDLEVEDIRECT_DEBUG
|
||||||
|
uint32_t _tmpNextFullSeconds = (config.Mqtt_PublishInterval * 3) - 1;
|
||||||
|
MessageOutput.printf("MqttHandleVedirectClass::loop _tmpNextFullSeconds %u - _nextPublishFull %u \r\n", _tmpNextFullSeconds, _nextPublishFull);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// no future publish full needed
|
||||||
|
_nextPublishFull = UINT32_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MQTTHANDLEVEDIRECT_DEBUG
|
||||||
|
MessageOutput.printf("MqttHandleVedirectClass::loop _nextPublishUpdatesOnly %u _nextPublishFull %u\r\n", _nextPublishUpdatesOnly, _nextPublishFull);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,6 +6,7 @@
|
|||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "MqttHandleHass.h"
|
#include "MqttHandleHass.h"
|
||||||
#include "MqttHandleVedirectHass.h"
|
#include "MqttHandleVedirectHass.h"
|
||||||
|
#include "MqttHandleVedirect.h"
|
||||||
#include "MqttSettings.h"
|
#include "MqttSettings.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "WebApi_errors.h"
|
#include "WebApi_errors.h"
|
||||||
@ -333,6 +334,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
|||||||
MqttSettings.performReconnect();
|
MqttSettings.performReconnect();
|
||||||
MqttHandleHass.forceUpdate();
|
MqttHandleHass.forceUpdate();
|
||||||
MqttHandleVedirectHass.forceUpdate();
|
MqttHandleVedirectHass.forceUpdate();
|
||||||
|
MqttHandleVedirect.init();
|
||||||
PowerMeter.init();
|
PowerMeter.init();
|
||||||
PowerLimiter.init();
|
PowerLimiter.init();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user