// SPDX-License-Identifier: GPL-2.0-or-later #include "VictronMppt.h" #include "Configuration.h" #include "PinMapping.h" #include "MessageOutput.h" VictronMpptClass VictronMppt; void VictronMpptClass::init(Scheduler& scheduler) { scheduler.addTask(_loopTask); _loopTask.setCallback(std::bind(&VictronMpptClass::loop, this)); _loopTask.setIterations(TASK_FOREVER); _loopTask.enable(); this->updateSettings(); } void VictronMpptClass::updateSettings() { std::lock_guard lock(_mutex); _controllers.clear(); CONFIG_T& config = Configuration.get(); if (!config.Vedirect.Enabled) { return; } const PinMapping_t& pin = PinMapping.get(); int8_t rx = pin.victron_rx; int8_t tx = pin.victron_tx; MessageOutput.printf("[VictronMppt] rx = %d, tx = %d\r\n", rx, tx); if (rx < 0) { MessageOutput.println("[VictronMppt] invalid pin config"); return; } auto upController = std::make_unique(); upController->init(rx, tx, &MessageOutput, config.Vedirect.VerboseLogging); _controllers.push_back(std::move(upController)); } void VictronMpptClass::loop() { std::lock_guard lock(_mutex); for (auto const& upController : _controllers) { upController->loop(); } } bool VictronMpptClass::isDataValid() const { std::lock_guard lock(_mutex); for (auto const& upController : _controllers) { if (!upController->isDataValid()) { return false; } } return !_controllers.empty(); } uint32_t VictronMpptClass::getDataAgeMillis() const { std::lock_guard lock(_mutex); if (_controllers.empty()) { return 0; } auto now = millis(); auto iter = _controllers.cbegin(); uint32_t age = now - (*iter)->getLastUpdate(); ++iter; while (iter != _controllers.end()) { age = std::min(age, now - (*iter)->getLastUpdate()); ++iter; } return age; } VeDirectMpptController::spData_t VictronMpptClass::getData(size_t idx) const { std::lock_guard lock(_mutex); if (_controllers.empty() || idx >= _controllers.size()) { MessageOutput.printf("ERROR: MPPT controller index %d is out of bounds (%d controllers)\r\n", idx, _controllers.size()); return std::make_shared(); } return _controllers[idx]->getData(); } int32_t VictronMpptClass::getPowerOutputWatts() const { int32_t sum = 0; for (const auto& upController : _controllers) { sum += upController->getData()->P; } return sum; } int32_t VictronMpptClass::getPanelPowerWatts() const { int32_t sum = 0; for (const auto& upController : _controllers) { sum += upController->getData()->PPV; } return sum; } double VictronMpptClass::getYieldTotal() const { double sum = 0; for (const auto& upController : _controllers) { sum += upController->getData()->H19; } return sum; } double VictronMpptClass::getYieldDay() const { double sum = 0; for (const auto& upController : _controllers) { sum += upController->getData()->H20; } return sum; }