Skip to content

Commit

Permalink
restructure MqttHandleVedirect
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreasBoehm committed Dec 13, 2024
1 parent 3d55498 commit e23be05
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 95 deletions.
32 changes: 0 additions & 32 deletions include/MqttHandleVedirect.h

This file was deleted.

2 changes: 2 additions & 0 deletions include/solarcharger/Provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace SolarChargers {

class Stats;
class HassIntegration;

class Provider {
Expand All @@ -13,6 +14,7 @@ class Provider {
virtual bool init(bool verboseLogging) = 0;
virtual void deinit() = 0;
virtual void loop() = 0;
virtual std::shared_ptr<Stats> getStats() const = 0;
virtual HassIntegration const& getHassIntegration() const = 0;

// TODO(andreasboehm): below methods are taken from VictronMppt to start abstracting
Expand Down
23 changes: 23 additions & 0 deletions include/solarcharger/Stats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include <Arduino.h>

namespace SolarChargers {

class Stats {
public:
void mqttLoop();

// the interval at which all data will be re-published, even
// if they did not change. used to calculate Home Assistent expiration.
virtual uint32_t getMqttFullPublishIntervalMs() const;

protected:
virtual void mqttPublish() const;

private:
uint32_t _lastMqttPublish = 0;
};

} // namespace SolarChargers
3 changes: 3 additions & 0 deletions include/solarcharger/victron/Provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <Configuration.h>
#include <solarcharger/Provider.h>
#include <solarcharger/victron/HassIntegration.h>
#include <solarcharger/victron/Stats.h>
#include <VeDirectMpptController.h>

namespace SolarChargers::Victron {
Expand All @@ -20,6 +21,7 @@ class Provider : public ::SolarChargers::Provider {
bool init(bool verboseLogging) final;
void deinit() final;
void loop() final;
std::shared_ptr<::SolarChargers::Stats> getStats() const final { return _stats; }
::SolarChargers::HassIntegration const& getHassIntegration() const final { return _hassIntegration; }

bool isDataValid() const final;
Expand Down Expand Up @@ -68,6 +70,7 @@ class Provider : public ::SolarChargers::Provider {
using controller_t = std::unique_ptr<VeDirectMpptController>;
std::vector<controller_t> _controllers;
std::vector<String> _serialPortOwners;
std::shared_ptr<Stats> _stats = std::make_shared<Stats>();
HassIntegration _hassIntegration;

bool initController(int8_t rx, int8_t tx, bool logging,
Expand Down
29 changes: 29 additions & 0 deletions include/solarcharger/victron/Stats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include <solarcharger/Stats.h>
#include <VeDirectMpptController.h>
#include <map>

namespace SolarChargers::Victron {

class Stats : public ::SolarChargers::Stats {
public:
void mqttPublish() const final;

private:
mutable std::map<std::string, VeDirectMpptController::data_t> _kvFrames;

// point of time in millis() when updated values will be published
mutable uint32_t _nextPublishUpdatesOnly = 0;

// point of time in millis() when all values will be published
mutable uint32_t _nextPublishFull = 1;

mutable bool _PublishFull;

void publish_mppt_data(const VeDirectMpptController::data_t &mpptData,
const VeDirectMpptController::data_t &frame) const;
};

} // namespace SolarChargers::Victron
2 changes: 0 additions & 2 deletions src/WebApi_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "MqttHandleInverter.h"
#include "MqttHandleHuawei.h"
#include "MqttHandlePowerLimiter.h"
#include "MqttHandleVedirect.h"
#include "MqttSettings.h"
#include "WebApi.h"
#include "WebApi_errors.h"
Expand Down Expand Up @@ -339,7 +338,6 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
MqttHandlePowerLimiter.forceUpdate();

SolarCharger.updateSettings();
MqttHandleVedirect.forceUpdate();
}

String WebApiMqttClass::getTlsCertInfo(const char* cert)
Expand Down
2 changes: 0 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "MqttHandleBatteryHass.h"
#include "MqttHandleInverter.h"
#include "MqttHandleInverterTotal.h"
#include "MqttHandleVedirect.h"
#include "MqttHandleHuawei.h"
#include "MqttHandlePowerLimiter.h"
#include "MqttHandlePowerLimiterHass.h"
Expand Down Expand Up @@ -135,7 +134,6 @@ void setup()
MqttHandleDtu.init(scheduler);
MqttHandleInverter.init(scheduler);
MqttHandleInverterTotal.init(scheduler);
MqttHandleVedirect.init(scheduler);
MqttHandleHass.init(scheduler);
MqttHandleBatteryHass.init(scheduler);
MqttHandleHuawei.init(scheduler);
Expand Down
8 changes: 5 additions & 3 deletions src/solarcharger/Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ void Controller::loop()
{
std::lock_guard<std::mutex> lock(_mutex);

if (_upProvider) {
_upProvider->loop();
}
if (!_upProvider) { return; }

_upProvider->loop();

_upProvider->getStats()->mqttLoop();

auto const& config = Configuration.get();
if (!config.Mqtt.Hass.Enabled) { return; }
Expand Down
33 changes: 33 additions & 0 deletions src/solarcharger/Stats.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <solarcharger/Stats.h>
#include <Configuration.h>
#include <MqttSettings.h>

namespace SolarChargers {

void Stats::mqttLoop()
{
auto& config = Configuration.get();

if (!MqttSettings.getConnected()
|| (millis() - _lastMqttPublish) < (config.Mqtt.PublishInterval * 1000)) {
return;
}

mqttPublish();

_lastMqttPublish = millis();
}

uint32_t Stats::getMqttFullPublishIntervalMs() const
{
auto& config = Configuration.get();

// this is the default interval, see mqttLoop(). mqttPublish()
// implementations in derived classes may choose to publish some values
// with a lower frequency and hence implement this method with a different
// return value.
return config.Mqtt.PublishInterval * 1000;
}

} // namespace SolarChargers
68 changes: 12 additions & 56 deletions src/MqttHandleVedirect.cpp → src/solarcharger/victron/Stats.cpp
Original file line number Diff line number Diff line change
@@ -1,61 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2022 Helge Erbe and others
*/
#include "MqttHandleVedirect.h"
#include "MqttSettings.h"
#include "MessageOutput.h"
#include <Configuration.h>
#include <MqttSettings.h>
#include <MessageOutput.h>
#include <solarcharger/Controller.h>
#include <solarcharger/victron/Stats.h>

MqttHandleVedirectClass MqttHandleVedirect;
namespace SolarChargers::Victron {

// #define MQTTHANDLEVEDIRECT_DEBUG

void MqttHandleVedirectClass::init(Scheduler& scheduler)
{
scheduler.addTask(_loopTask);
_loopTask.setCallback([this] { loop(); });
_loopTask.setIterations(TASK_FOREVER);
_loopTask.enable();

// initially force a full publish
this->forceUpdate();
}

void MqttHandleVedirectClass::forceUpdate()
void Stats::mqttPublish() const
{
// initially force a full publish
_nextPublishUpdatesOnly = 0;
_nextPublishFull = 1;
}


void MqttHandleVedirectClass::loop()
{
auto const& config = Configuration.get();
if (!MqttSettings.getConnected()
|| !config.SolarCharger.Enabled
|| config.SolarCharger.Provider != SolarChargerProviderType::VEDIRECT) {
return;
}

if ((millis() >= _nextPublishFull) || (millis() >= _nextPublishUpdatesOnly)) {
auto const& config = Configuration.get();

// determine if this cycle should publish full values or updates only
if (_nextPublishFull <= _nextPublishUpdatesOnly) {
_PublishFull = true;
} else {
_PublishFull = !config.SolarCharger.PublishUpdatesOnly;
}

#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

for (int idx = 0; idx < SolarCharger.controllerAmount(); ++idx) {
std::optional<VeDirectMpptController::data_t> optMpptData = SolarCharger.getData(idx);
if (!optMpptData.has_value()) { continue; }
Expand All @@ -68,7 +31,7 @@ void MqttHandleVedirectClass::loop()
}

// now calculate next points of time to publish
_nextPublishUpdatesOnly = millis() + (config.Mqtt.PublishInterval * 1000);
_nextPublishUpdatesOnly = millis() + ::SolarChargers::Stats::getMqttFullPublishIntervalMs();

if (_PublishFull) {
// when Home Assistant MQTT-Auto-Discovery is active,
Expand All @@ -77,24 +40,15 @@ void MqttHandleVedirectClass::loop()
if ((config.SolarCharger.PublishUpdatesOnly) && (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
}
}

void MqttHandleVedirectClass::publish_mppt_data(const VeDirectMpptController::data_t &currentData,
void Stats::publish_mppt_data(const VeDirectMpptController::data_t &currentData,
const VeDirectMpptController::data_t &previousData) const {
String value;
String topic = "victron/";
Expand Down Expand Up @@ -146,3 +100,5 @@ void MqttHandleVedirectClass::publish_mppt_data(const VeDirectMpptController::da
PUBLISH_OPT(SmartBatterySenseTemperatureMilliCelsius, "SmartBatterySenseTemperature", currentData.SmartBatterySenseTemperatureMilliCelsius.second / 1000.0);
#undef PUBLILSH_OPT
}

}; // namespace SolarChargers::Victron

0 comments on commit e23be05

Please sign in to comment.