diff --git a/include/SolarCharger.h b/include/solarcharger/Controller.h similarity index 79% rename from include/SolarCharger.h rename to include/solarcharger/Controller.h index 74b2d31cd..06eeedf4d 100644 --- a/include/SolarCharger.h +++ b/include/solarcharger/Controller.h @@ -4,10 +4,12 @@ #include #include #include -#include "SolarChargerProvider.h" -#include "VeDirectMpptController.h" +#include +#include -class SolarChargerClass { +namespace SolarChargers { + +class Controller { public: void init(Scheduler&); void updateSettings(); @@ -42,7 +44,10 @@ class SolarChargerClass { Task _loopTask; mutable std::mutex _mutex; - std::unique_ptr _upProvider = nullptr; + std::unique_ptr _upProvider = nullptr; + bool _publishSensors = false; }; -extern SolarChargerClass SolarCharger; +} // namespace SolarChargers + +extern SolarChargers::Controller SolarCharger; diff --git a/include/solarcharger/HassIntegration.h b/include/solarcharger/HassIntegration.h new file mode 100644 index 000000000..54662b11c --- /dev/null +++ b/include/solarcharger/HassIntegration.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include +#include + +namespace SolarChargers { + +class HassIntegration { +public: + virtual void publishSensors() const; + +protected: + void publish(const String& subtopic, const String& payload) const; +}; + +} // namespace SolarChargers diff --git a/include/SolarChargerProvider.h b/include/solarcharger/Provider.h similarity index 86% rename from include/SolarChargerProvider.h rename to include/solarcharger/Provider.h index 77321412b..3bbbf25a1 100644 --- a/include/SolarChargerProvider.h +++ b/include/solarcharger/Provider.h @@ -1,14 +1,19 @@ // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#include "VeDirectMpptController.h" +#include -class SolarChargerProvider { +namespace SolarChargers { + +class HassIntegration; + +class Provider { public: // returns true if the provider is ready for use, false otherwise virtual bool init(bool verboseLogging) = 0; virtual void deinit() = 0; virtual void loop() = 0; + virtual HassIntegration const& getHassIntegration() const = 0; // TODO(andreasboehm): below methods are taken from VictronMppt to start abstracting // solar chargers without breaking everything. @@ -34,3 +39,5 @@ class SolarChargerProvider { virtual bool isDataValid() const = 0; }; + +} // namespace SolarChargers diff --git a/include/MqttHandleVedirectHass.h b/include/solarcharger/victron/HassIntegration.h similarity index 64% rename from include/MqttHandleVedirectHass.h rename to include/solarcharger/victron/HassIntegration.h index b8ea4534b..5d83530a1 100644 --- a/include/MqttHandleVedirectHass.h +++ b/include/solarcharger/victron/HassIntegration.h @@ -2,32 +2,26 @@ #pragma once #include +#include #include "VeDirectMpptController.h" -#include -class MqttHandleVedirectHassClass { +namespace SolarChargers::Victron { + +class HassIntegration : public ::SolarChargers::HassIntegration { public: - void init(Scheduler& scheduler); - void forceUpdate(); + void publishSensors() const final; private: - void loop(); - void publishConfig(); - void publish(const String& subtopic, const String& payload); void publishBinarySensor(const char *caption, const char *icon, const char *subTopic, const char *payload_on, const char *payload_off, - const VeDirectMpptController::data_t &mpptData); + const VeDirectMpptController::data_t &mpptData) const; void publishSensor(const char *caption, const char *icon, const char *subTopic, const char *deviceClass, const char *stateClass, const char *unitOfMeasurement, - const VeDirectMpptController::data_t &mpptData); + const VeDirectMpptController::data_t &mpptData) const; void createDeviceInfo(JsonObject &object, - const VeDirectMpptController::data_t &mpptData); - - Task _loopTask; + const VeDirectMpptController::data_t &mpptData) const; - bool _wasConnected = false; - bool _updateForced = false; }; -extern MqttHandleVedirectHassClass MqttHandleVedirectHass; +} // namespace SolarChargers diff --git a/include/VictronMppt.h b/include/solarcharger/victron/Provider.h similarity index 73% rename from include/VictronMppt.h rename to include/solarcharger/victron/Provider.h index 11f4840c1..72e6756ff 100644 --- a/include/VictronMppt.h +++ b/include/solarcharger/victron/Provider.h @@ -5,18 +5,22 @@ #include #include -#include "SolarChargerProvider.h" -#include "VeDirectMpptController.h" -#include "Configuration.h" +#include +#include +#include +#include -class VictronMppt : public SolarChargerProvider { +namespace SolarChargers::Victron { + +class Provider : public ::SolarChargers::Provider { public: - VictronMppt() = default; - ~VictronMppt() = default; + Provider() = default; + ~Provider() = default; bool init(bool verboseLogging) final; void deinit() final; void loop() final; + ::SolarChargers::HassIntegration const& getHassIntegration() const final { return _hassIntegration; } bool isDataValid() const final; @@ -55,16 +59,19 @@ class VictronMppt : public SolarChargerProvider { std::optional getVoltage(MPPTVoltage kindOf) const; private: - VictronMppt(VictronMppt const& other) = delete; - VictronMppt(VictronMppt&& other) = delete; - VictronMppt& operator=(VictronMppt const& other) = delete; - VictronMppt& operator=(VictronMppt&& other) = delete; + Provider(Provider const& other) = delete; + Provider(Provider&& other) = delete; + Provider& operator=(Provider const& other) = delete; + Provider& operator=(Provider&& other) = delete; mutable std::mutex _mutex; using controller_t = std::unique_ptr; std::vector _controllers; - std::vector _serialPortOwners; + HassIntegration _hassIntegration; + bool initController(int8_t rx, int8_t tx, bool logging, uint8_t instance); }; + +} // namespace SolarChargers::Victron diff --git a/src/MqttHandleVedirect.cpp b/src/MqttHandleVedirect.cpp index ce2cf76a4..04bb634b5 100644 --- a/src/MqttHandleVedirect.cpp +++ b/src/MqttHandleVedirect.cpp @@ -5,7 +5,7 @@ #include "MqttHandleVedirect.h" #include "MqttSettings.h" #include "MessageOutput.h" -#include "SolarCharger.h" +#include MqttHandleVedirectClass MqttHandleVedirect; diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index 81707593c..f40edd96a 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -16,7 +16,7 @@ #include #include #include "SunPosition.h" -#include "SolarCharger.h" +#include static auto sBatteryPoweredFilter = [](PowerLimiterInverter const& inv) { return !inv.isSolarPowered(); diff --git a/src/WebApi_mqtt.cpp b/src/WebApi_mqtt.cpp index 1d0c2ab15..658f4e821 100644 --- a/src/WebApi_mqtt.cpp +++ b/src/WebApi_mqtt.cpp @@ -10,7 +10,6 @@ #include "MqttHandleInverter.h" #include "MqttHandleHuawei.h" #include "MqttHandlePowerLimiter.h" -#include "MqttHandleVedirectHass.h" #include "MqttHandleVedirect.h" #include "MqttSettings.h" #include "WebApi.h" @@ -19,6 +18,7 @@ #include "PowerLimiter.h" #include "PowerMeter.h" #include +#include void WebApiMqttClass::init(AsyncWebServer& server, Scheduler& scheduler) { @@ -334,10 +334,11 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) MqttHandleBatteryHass.forceUpdate(); MqttHandleHass.forceUpdate(); MqttHandlePowerLimiterHass.forceUpdate(); - MqttHandleVedirectHass.forceUpdate(); MqttHandleHuawei.forceUpdate(); MqttHandlePowerLimiter.forceUpdate(); + + SolarCharger.updateSettings(); MqttHandleVedirect.forceUpdate(); } diff --git a/src/WebApi_powermeter.cpp b/src/WebApi_powermeter.cpp index e691ad79d..35fc04dcd 100644 --- a/src/WebApi_powermeter.cpp +++ b/src/WebApi_powermeter.cpp @@ -6,7 +6,6 @@ #include "ArduinoJson.h" #include "AsyncJson.h" #include "Configuration.h" -#include "MqttHandleVedirectHass.h" #include "MqttHandleHass.h" #include "MqttSettings.h" #include "PowerLimiter.h" diff --git a/src/WebApi_solar_charger.cpp b/src/WebApi_solar_charger.cpp index fcdb8aeba..8cbc08a2e 100644 --- a/src/WebApi_solar_charger.cpp +++ b/src/WebApi_solar_charger.cpp @@ -7,7 +7,7 @@ #include "WebApi_errors.h" #include "helper.h" #include "MqttHandlePowerLimiterHass.h" -#include "SolarCharger.h" +#include void WebApiSolarChargerlass::init(AsyncWebServer& server, Scheduler& scheduler) { diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp index e731081b4..b9adbc4dd 100644 --- a/src/WebApi_ws_live.cpp +++ b/src/WebApi_ws_live.cpp @@ -11,7 +11,7 @@ #include "Huawei_can.h" #include "PowerMeter.h" #include "defaults.h" -#include "SolarCharger.h" +#include #include WebApiWsLiveClass::WebApiWsLiveClass() diff --git a/src/WebApi_ws_solarcharger_live.cpp b/src/WebApi_ws_solarcharger_live.cpp index ed5595314..c0fb2173d 100644 --- a/src/WebApi_ws_solarcharger_live.cpp +++ b/src/WebApi_ws_solarcharger_live.cpp @@ -10,7 +10,7 @@ #include "WebApi.h" #include "defaults.h" #include "PowerLimiter.h" -#include "SolarCharger.h" +#include WebApiWsSolarChargerLiveClass::WebApiWsSolarChargerLiveClass() : _ws("/solarchargerlivedata") diff --git a/src/main.cpp b/src/main.cpp index 383568ff1..377476b87 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,6 @@ #include "Huawei_can.h" #include "MqttHandleDtu.h" #include "MqttHandleHass.h" -#include "MqttHandleVedirectHass.h" #include "MqttHandleBatteryHass.h" #include "MqttHandleInverter.h" #include "MqttHandleInverterTotal.h" @@ -34,7 +33,7 @@ #include "PowerMeter.h" #include "PowerLimiter.h" #include "defaults.h" -#include "SolarCharger.h" +#include #include #include #include @@ -138,7 +137,6 @@ void setup() MqttHandleInverterTotal.init(scheduler); MqttHandleVedirect.init(scheduler); MqttHandleHass.init(scheduler); - MqttHandleVedirectHass.init(scheduler); MqttHandleBatteryHass.init(scheduler); MqttHandleHuawei.init(scheduler); MqttHandlePowerLimiter.init(scheduler); diff --git a/src/SolarCharger.cpp b/src/solarcharger/Controller.cpp similarity index 67% rename from src/SolarCharger.cpp rename to src/solarcharger/Controller.cpp index ba2a56945..f1b580434 100644 --- a/src/SolarCharger.cpp +++ b/src/solarcharger/Controller.cpp @@ -1,22 +1,25 @@ // SPDX-License-Identifier: GPL-2.0-or-later -#include "SolarCharger.h" #include #include -#include +#include +#include +#include -SolarChargerClass SolarCharger; +SolarChargers::Controller SolarCharger; -void SolarChargerClass::init(Scheduler& scheduler) +namespace SolarChargers { + +void Controller::init(Scheduler& scheduler) { scheduler.addTask(_loopTask); - _loopTask.setCallback(std::bind(&SolarChargerClass::loop, this)); + _loopTask.setCallback(std::bind(&Controller::loop, this)); _loopTask.setIterations(TASK_FOREVER); _loopTask.enable(); this->updateSettings(); } -void SolarChargerClass::updateSettings() +void Controller::updateSettings() { std::lock_guard lock(_mutex); @@ -32,7 +35,7 @@ void SolarChargerClass::updateSettings() switch (config.SolarCharger.Provider) { case SolarChargerProviderType::VEDIRECT: - _upProvider = std::make_unique(); + _upProvider = std::make_unique<::SolarChargers::Victron::Provider>(); break; default: MessageOutput.printf("[SolarCharger] Unknown provider: %d\r\n", config.SolarCharger.Provider); @@ -40,18 +43,36 @@ void SolarChargerClass::updateSettings() } if (!_upProvider->init(verboseLogging)) { _upProvider = nullptr; } + + _publishSensors = true; } -void SolarChargerClass::loop() +void Controller::loop() { std::lock_guard lock(_mutex); if (_upProvider) { _upProvider->loop(); } + + auto const& config = Configuration.get(); + if (!config.Mqtt.Hass.Enabled) { return; } + + // TODO(schlimmchen): this cannot make sure that transient + // connection problems are actually always noticed. + if (!MqttSettings.getConnected()) { + _publishSensors = true; + return; + } + + if (!_publishSensors) { return; } + + _upProvider->getHassIntegration().publishSensors(); + + _publishSensors = false; } -size_t SolarChargerClass::controllerAmount() +size_t Controller::controllerAmount() { std::lock_guard lock(_mutex); @@ -62,7 +83,7 @@ size_t SolarChargerClass::controllerAmount() return 0; } -bool SolarChargerClass::isDataValid() +bool Controller::isDataValid() { std::lock_guard lock(_mutex); @@ -73,7 +94,7 @@ bool SolarChargerClass::isDataValid() return false; } -uint32_t SolarChargerClass::getDataAgeMillis() +uint32_t Controller::getDataAgeMillis() { std::lock_guard lock(_mutex); @@ -84,7 +105,7 @@ uint32_t SolarChargerClass::getDataAgeMillis() return 0; } -uint32_t SolarChargerClass::getDataAgeMillis(size_t idx) +uint32_t Controller::getDataAgeMillis(size_t idx) { std::lock_guard lock(_mutex); @@ -97,7 +118,7 @@ uint32_t SolarChargerClass::getDataAgeMillis(size_t idx) // total output of all MPPT charge controllers in Watts -int32_t SolarChargerClass::getOutputPowerWatts() +int32_t Controller::getOutputPowerWatts() { std::lock_guard lock(_mutex); @@ -109,7 +130,7 @@ int32_t SolarChargerClass::getOutputPowerWatts() } // total panel input power of all MPPT charge controllers in Watts -int32_t SolarChargerClass::getPanelPowerWatts() +int32_t Controller::getPanelPowerWatts() { std::lock_guard lock(_mutex); @@ -121,7 +142,7 @@ int32_t SolarChargerClass::getPanelPowerWatts() } // sum of total yield of all MPPT charge controllers in kWh -float SolarChargerClass::getYieldTotal() +float Controller::getYieldTotal() { std::lock_guard lock(_mutex); @@ -133,7 +154,7 @@ float SolarChargerClass::getYieldTotal() } // sum of today's yield of all MPPT charge controllers in kWh -float SolarChargerClass::getYieldDay() +float Controller::getYieldDay() { std::lock_guard lock(_mutex); @@ -145,7 +166,7 @@ float SolarChargerClass::getYieldDay() } // minimum of all MPPT charge controllers' output voltages in V -float SolarChargerClass::getOutputVoltage() +float Controller::getOutputVoltage() { std::lock_guard lock(_mutex); @@ -156,7 +177,7 @@ float SolarChargerClass::getOutputVoltage() return 0; } -std::optional SolarChargerClass::getData(size_t idx) +std::optional Controller::getData(size_t idx) { std::lock_guard lock(_mutex); @@ -166,3 +187,5 @@ std::optional SolarChargerClass::getData(size_t return std::nullopt; } + +} // namespace SolarChargers diff --git a/src/solarcharger/HassIntegration.cpp b/src/solarcharger/HassIntegration.cpp new file mode 100644 index 000000000..241ca68e3 --- /dev/null +++ b/src/solarcharger/HassIntegration.cpp @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include <__compiled_constants.h> + +namespace SolarChargers { + +void HassIntegration::publish(const String& subtopic, const String& payload) const +{ + String topic = Configuration.get().Mqtt.Hass.Topic; + topic += subtopic; + MqttSettings.publishGeneric(topic.c_str(), payload.c_str(), Configuration.get().Mqtt.Hass.Retain); +} + +} // namespace SolarChargers diff --git a/src/MqttHandleVedirectHass.cpp b/src/solarcharger/victron/HassIntegration.cpp similarity index 81% rename from src/MqttHandleVedirectHass.cpp rename to src/solarcharger/victron/HassIntegration.cpp index 251bf93b8..9d17d4c6f 100644 --- a/src/MqttHandleVedirectHass.cpp +++ b/src/solarcharger/victron/HassIntegration.cpp @@ -2,7 +2,6 @@ /* * Copyright (C) 2022 Thomas Basler and others */ -#include "MqttHandleVedirectHass.h" #include "Configuration.h" #include "MqttSettings.h" #include "MqttHandleHass.h" @@ -10,52 +9,13 @@ #include "MessageOutput.h" #include "Utils.h" #include "__compiled_constants.h" -#include "SolarCharger.h" +#include +#include -MqttHandleVedirectHassClass MqttHandleVedirectHass; +namespace SolarChargers::Victron { -void MqttHandleVedirectHassClass::init(Scheduler& scheduler) +void HassIntegration::publishSensors() const { - scheduler.addTask(_loopTask); - _loopTask.setCallback([this] { loop(); }); - _loopTask.setIterations(TASK_FOREVER); - _loopTask.enable(); -} - -void MqttHandleVedirectHassClass::loop() -{ - if (!Configuration.get().Mqtt.Hass.Enabled - || !Configuration.get().SolarCharger.Enabled - || Configuration.get().SolarCharger.Provider != SolarChargerProviderType::VEDIRECT) { - return; - } - - if (_updateForced) { - publishConfig(); - _updateForced = false; - } - - if (MqttSettings.getConnected() && !_wasConnected) { - // Connection established - _wasConnected = true; - publishConfig(); - } else if (!MqttSettings.getConnected() && _wasConnected) { - // Connection lost - _wasConnected = false; - } -} - -void MqttHandleVedirectHassClass::forceUpdate() -{ - _updateForced = true; -} - -void MqttHandleVedirectHassClass::publishConfig() -{ - if (!MqttSettings.getConnected()) { - return; - } - // device info for (int idx = 0; idx < SolarCharger.controllerAmount(); ++idx) { auto optMpptData = SolarCharger.getData(idx); @@ -120,10 +80,10 @@ void MqttHandleVedirectHassClass::publishConfig() yield(); } -void MqttHandleVedirectHassClass::publishSensor(const char *caption, const char *icon, const char *subTopic, +void HassIntegration::publishSensor(const char *caption, const char *icon, const char *subTopic, const char *deviceClass, const char *stateClass, const char *unitOfMeasurement, - const VeDirectMpptController::data_t &mpptData) + const VeDirectMpptController::data_t &mpptData) const { String serial = mpptData.serialNr_SER; @@ -179,9 +139,9 @@ void MqttHandleVedirectHassClass::publishSensor(const char *caption, const char publish(configTopic, buffer); } -void MqttHandleVedirectHassClass::publishBinarySensor(const char *caption, const char *icon, const char *subTopic, +void HassIntegration::publishBinarySensor(const char *caption, const char *icon, const char *subTopic, const char *payload_on, const char *payload_off, - const VeDirectMpptController::data_t &mpptData) + const VeDirectMpptController::data_t &mpptData) const { String serial = mpptData.serialNr_SER; @@ -224,8 +184,8 @@ void MqttHandleVedirectHassClass::publishBinarySensor(const char *caption, const publish(configTopic, buffer); } -void MqttHandleVedirectHassClass::createDeviceInfo(JsonObject &object, - const VeDirectMpptController::data_t &mpptData) +void HassIntegration::createDeviceInfo(JsonObject &object, + const VeDirectMpptController::data_t &mpptData) const { String serial = mpptData.serialNr_SER; object["name"] = "Victron(" + serial + ")"; @@ -237,9 +197,4 @@ void MqttHandleVedirectHassClass::createDeviceInfo(JsonObject &object, object["via_device"] = MqttHandleHass.getDtuUniqueId(); } -void MqttHandleVedirectHassClass::publish(const String& subtopic, const String& payload) -{ - String topic = Configuration.get().Mqtt.Hass.Topic; - topic += subtopic; - MqttSettings.publishGeneric(topic.c_str(), payload.c_str(), Configuration.get().Mqtt.Hass.Retain); -} +} // namespace SolarChargers::Victron diff --git a/src/VictronMppt.cpp b/src/solarcharger/victron/Provider.cpp similarity index 88% rename from src/VictronMppt.cpp rename to src/solarcharger/victron/Provider.cpp index a6bc4f7a0..61af54361 100644 --- a/src/VictronMppt.cpp +++ b/src/solarcharger/victron/Provider.cpp @@ -1,11 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-or-later -#include "VictronMppt.h" +#include #include "Configuration.h" #include "PinMapping.h" #include "MessageOutput.h" #include "SerialPortManager.h" -bool VictronMppt::init(bool verboseLogging) +namespace SolarChargers::Victron { + +bool Provider::init(bool verboseLogging) { const PinMapping_t& pin = PinMapping.get(); auto controllerCount = 0; @@ -25,7 +27,7 @@ bool VictronMppt::init(bool verboseLogging) return controllerCount > 0; } -void VictronMppt::deinit() +void Provider::deinit() { std::lock_guard lock(_mutex); @@ -36,7 +38,7 @@ void VictronMppt::deinit() _serialPortOwners.clear(); } -bool VictronMppt::initController(int8_t rx, int8_t tx, bool logging, +bool Provider::initController(int8_t rx, int8_t tx, bool logging, uint8_t instance) { MessageOutput.printf("[VictronMppt Instance %d] rx = %d, tx = %d\r\n", @@ -60,7 +62,7 @@ bool VictronMppt::initController(int8_t rx, int8_t tx, bool logging, return true; } -void VictronMppt::loop() +void Provider::loop() { std::lock_guard lock(_mutex); @@ -73,7 +75,7 @@ void VictronMppt::loop() * isDataValid() * return: true = if at least one of the MPPT controllers delivers valid data */ -bool VictronMppt::isDataValid() const +bool Provider::isDataValid() const { std::lock_guard lock(_mutex); @@ -84,7 +86,7 @@ bool VictronMppt::isDataValid() const return false; } -uint32_t VictronMppt::getDataAgeMillis() const +uint32_t Provider::getDataAgeMillis() const { std::lock_guard lock(_mutex); @@ -104,7 +106,7 @@ uint32_t VictronMppt::getDataAgeMillis() const return age; } -uint32_t VictronMppt::getDataAgeMillis(size_t idx) const +uint32_t Provider::getDataAgeMillis(size_t idx) const { std::lock_guard lock(_mutex); @@ -113,7 +115,7 @@ uint32_t VictronMppt::getDataAgeMillis(size_t idx) const return millis() - _controllers[idx]->getLastUpdate(); } -std::optional VictronMppt::getData(size_t idx) const +std::optional Provider::getData(size_t idx) const { std::lock_guard lock(_mutex); @@ -128,7 +130,7 @@ std::optional VictronMppt::getData(size_t idx) c return _controllers[idx]->getData(); } -int32_t VictronMppt::getOutputPowerWatts() const +int32_t Provider::getOutputPowerWatts() const { int32_t sum = 0; @@ -151,7 +153,7 @@ int32_t VictronMppt::getOutputPowerWatts() const return sum; } -int32_t VictronMppt::getPanelPowerWatts() const +int32_t Provider::getPanelPowerWatts() const { int32_t sum = 0; @@ -172,7 +174,7 @@ int32_t VictronMppt::getPanelPowerWatts() const return sum; } -float VictronMppt::getYieldTotal() const +float Provider::getYieldTotal() const { float sum = 0; @@ -184,7 +186,7 @@ float VictronMppt::getYieldTotal() const return sum; } -float VictronMppt::getYieldDay() const +float Provider::getYieldDay() const { float sum = 0; @@ -196,7 +198,7 @@ float VictronMppt::getYieldDay() const return sum; } -float VictronMppt::getOutputVoltage() const +float Provider::getOutputVoltage() const { float min = -1; @@ -210,7 +212,7 @@ float VictronMppt::getOutputVoltage() const return min; } -std::optional VictronMppt::getStateOfOperation() const +std::optional Provider::getStateOfOperation() const { for (const auto& upController : _controllers) { if (upController->isDataValid()) { @@ -221,7 +223,7 @@ std::optional VictronMppt::getStateOfOperation() const return std::nullopt; } -std::optional VictronMppt::getVoltage(MPPTVoltage kindOf) const +std::optional Provider::getVoltage(MPPTVoltage kindOf) const { for (const auto& upController : _controllers) { switch (kindOf) { @@ -245,3 +247,5 @@ std::optional VictronMppt::getVoltage(MPPTVoltage kindOf) const return std::nullopt; } + +} // namespace SolarChargers::Victron