diff --git a/include/BatteryStats.h b/include/BatteryStats.h index ebdca11fd..6dc816a8c 100644 --- a/include/BatteryStats.h +++ b/include/BatteryStats.h @@ -95,4 +95,6 @@ class JkBmsBatteryStats : public BatteryStats { private: JkBms::DataPointContainer _dataPoints; + mutable uint32_t _lastMqttPublish = 0; + mutable uint32_t _lastFullMqttPublish = 0; }; diff --git a/src/BatteryStats.cpp b/src/BatteryStats.cpp index 0698b162b..fb1d2f2de 100644 --- a/src/BatteryStats.cpp +++ b/src/BatteryStats.cpp @@ -2,6 +2,7 @@ #include #include #include "BatteryStats.h" +#include "Configuration.h" #include "MqttSettings.h" #include "JkBmsDataPoints.h" @@ -156,13 +157,25 @@ void JkBmsBatteryStats::mqttPublish() const Label::BatterySoCPercent // already published by base class }; + CONFIG_T& config = Configuration.get(); + + // publish all topics every minute, unless the retain flag is enabled + bool fullPublish = _lastFullMqttPublish + 60 * 1000 < millis(); + fullPublish &= !config.Mqtt_Retain; + for (auto iter = _dataPoints.cbegin(); iter != _dataPoints.cend(); ++iter) { + // skip data points that did not change since last published + if (!fullPublish && iter->second.getTimestamp() < _lastMqttPublish) { continue; } + auto skipMatch = std::find(mqttSkip.begin(), mqttSkip.end(), iter->first); if (skipMatch != mqttSkip.end()) { continue; } String topic((std::string("battery/") + iter->second.getLabelText()).c_str()); MqttSettings.publish(topic, iter->second.getValueText().c_str()); } + + _lastMqttPublish = millis(); + if (fullPublish) { _lastFullMqttPublish = _lastMqttPublish; } } void JkBmsBatteryStats::updateFrom(JkBms::DataPointContainer const& dp)