OpenDTU-old/lib/VeDirectFrameHandler/VeDirectMpptController.h
Bernhard Kirchen 6b8c93d2e6 polish VE.Direct HEX support
* show charge controller temperature in live view
* send hex requests right after decoding a frame. this seems to have the
  best chance of getting an answer to all requests.
* deem 0xFFFFFFFF value of network total DC power as invalid indicator.
  neither network state, nor network info, nor network mode seem to
  indicate that the charge controller is part of a VE.Smart network. for
  that reason, we revert to always querying the network total DC power
  value, but testing it for max(uin32_t) value, which seems to indicate
  that the charge controller is not part of a VE.Smart network.
* improve (verbose) logging, e.g., use _logId, and print names of
  response codes and known registers, always print error messages,
  add additional tests to prevent overly verbose messages.
* move hex protocol definitions to VeDirectData.h header
  and use enum classes
* define register addresses in enum class
* move values retrieved through hex protocol into main MPPT data struct
* do not send HEX requests if the serial interface cannot send data
* detect whether smart battery sense temperature is available
* web app: make all VE.Direct sub-cards iterable. this makes addind more
  values much simpler and saves a bunch of code in the web app.
* make VeDirectFrameHandler state a type-safe enum class
* unindent MPPT controller loop()
* whitespace cleanup
2024-04-03 16:33:15 +02:00

55 lines
1.2 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;
}
float getAverage() const {
if (_count == 0) { return 0.0; }
return static_cast<float>(_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;
void loop() final;
private:
bool hexDataHandler(VeDirectHexData const &data) final;
bool processTextDataDerived(std::string const& name, std::string const& value) final;
void frameValidEvent() final;
MovingAverage<float, 5> _efficiency;
};