OpenDTU-old/lib/VeDirectFrameHandler/VeDirectMpptController.h
Bernhard Kirchen ad125ea804 Fix: properly handle fragmented VE.Direct messages
queue every text event until the frame was checked by it checksum. then
process the data directly into the buffer struct. do not clear the
buffer struct, so it will always include the most recent value of a
particular data point.
2024-04-02 21:05:59 +02:00

55 lines
1.3 KiB
C++

#pragma once
#include <Arduino.h>
#include "VeDirectData.h"
#include "VeDirectFrameHandler.h"
template<typename T, size_t WINDOW_SIZE>
class MovingAverage {
public:
MovingAverage()
: _sum(0)
, _index(0)
, _count(0) { }
void addNumber(T num) {
if (_count < WINDOW_SIZE) {
_count++;
} else {
_sum -= _window[_index];
}
_window[_index] = num;
_sum += num;
_index = (_index + 1) % WINDOW_SIZE;
}
double getAverage() const {
if (_count == 0) { return 0.0; }
return static_cast<double>(_sum) / _count;
}
private:
std::array<T, WINDOW_SIZE> _window;
T _sum;
size_t _index;
size_t _count;
};
class VeDirectMpptController : public VeDirectFrameHandler<veMpptStruct> {
public:
VeDirectMpptController() = default;
void init(int8_t rx, int8_t tx, Print* msgOut, bool verboseLogging, uint16_t hwSerialPort);
using data_t = veMpptStruct;
using spData_t = std::shared_ptr<data_t const>;
spData_t getData() const { return _spData; }
private:
bool processTextDataDerived(std::string const& name, std::string const& value) final;
void frameValidEvent() final;
spData_t _spData = nullptr;
MovingAverage<double, 5> _efficiency;
};