OpenDTU-old/src/VictronMppt.cpp
2024-01-05 23:02:26 +01:00

140 lines
3.1 KiB
C++

// 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<std::mutex> 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<VeDirectMpptController>();
upController->init(rx, tx, &MessageOutput, config.Vedirect.VerboseLogging);
_controllers.push_back(std::move(upController));
}
void VictronMpptClass::loop()
{
std::lock_guard<std::mutex> lock(_mutex);
for (auto const& upController : _controllers) {
upController->loop();
}
}
bool VictronMpptClass::isDataValid() const
{
std::lock_guard<std::mutex> lock(_mutex);
for (auto const& upController : _controllers) {
if (!upController->isDataValid()) { return false; }
}
return !_controllers.empty();
}
uint32_t VictronMpptClass::getDataAgeMillis() const
{
std::lock_guard<std::mutex> 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<uint32_t>(age, now - (*iter)->getLastUpdate());
++iter;
}
return age;
}
VeDirectMpptController::spData_t VictronMpptClass::getData(size_t idx) const
{
std::lock_guard<std::mutex> 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<VeDirectMpptController::veMpptStruct>();
}
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;
}