From 216ceca3e18d105c88612527bca530451e17aa32 Mon Sep 17 00:00:00 2001 From: trabus322 Date: Fri, 15 Mar 2024 11:46:44 +0100 Subject: [PATCH] Trying to make inheritance work, not worky :c --- inc/hoymiles.h | 102 ++++++++++++++++++++++++++++++--------------- src/hoymiles.cpp | 105 ++++++++++++++++++++++++++++++++--------------- src/main.cpp | 12 ++++-- 3 files changed, 148 insertions(+), 71 deletions(-) diff --git a/inc/hoymiles.h b/inc/hoymiles.h index 8d5aec0..6fd10df 100644 --- a/inc/hoymiles.h +++ b/inc/hoymiles.h @@ -2,64 +2,98 @@ #define HOYMILES_H #include -#include #include +#include +#include struct _modbus; typedef _modbus modbus_t; -class MicroinverterParameter { - public: - std::string name; +class PortParameter { + protected: + uint16_t addressOffset; - int valueInt; - float valueFloat; + int registerSize; - int age; + void setValue(uint16_t *readArray, int registerCount); - uint16_t addressOffset; - int registerSize; + public: + PortParameter(std::string name, uint16_t addressOffset, int registerSize); - MicroinverterParameter(std::string name, uint16_t addressOffset, int registerSize); + std::string name; + int age; + int value; - void updateValue(modbus_t *modbus_context, uint16_t microinverterAddress); + virtual void updateValue(modbus_t *modbus_context, uint16_t portStartAddress); }; -class Microinverter{ - private: - modbus_t *modbus_context; - uint16_t address; +class PortParameterSerialNumber : public PortParameter { + private: + void setValue(uint16_t *readArray, int registerCount); - std::vector parameters; + public: + PortParameterSerialNumber(); +}; + +class PortParameterFloat : public PortParameter { + private: + int decimalPlaces; + + void setValue(uint16_t *readArray, int registerCount); + + public: + PortParameterFloat(std::string name, uint16_t addressOffset, int registerSize, int decimalPlaces); + + float value; +}; + +class Port { + private: + modbus_t *modbus_context; + uint16_t portStartAddress; + + std::vector> parameters; + + void populateParameters(); public: - Microinverter(modbus_t *modbus_t, uint16_t address); + Port(modbus_t *modbus_context, uint16_t portStartAddress); void updateParameters(); - - void updateParameterByIndex(int i); - - void updateParameterByName(std::string name); - - MicroinverterParameter getParameterByIndex(int i); - - MicroinverterParameter getParameterByName(std::string name); }; -class Dtu{ - private: - modbus_t *modbus_context; +class Microinverter { + private: + modbus_t *modbus_context; - std::vector microinverters; + std::vector ports; - void populateMicroinverters(); + void populatePorts(); - public: - Dtu(const char *ip_address, int port); + public: + Microinverter(modbus_t *modbus_t); - void updateMicroinverters(); + void updatePorts(); - ~Dtu(); + void updatePort(int i); + + Port getPort(int i); +}; + +class Dtu { + private: + modbus_t *modbus_context; + + std::vector microinverters; + + void populateMicroinverters(); + + public: + Dtu(const char *ip_address, int port); + + void updateMicroinverters(); + + ~Dtu(); }; #endif \ No newline at end of file diff --git a/src/hoymiles.cpp b/src/hoymiles.cpp index de7c25d..56bf5b9 100644 --- a/src/hoymiles.cpp +++ b/src/hoymiles.cpp @@ -1,8 +1,8 @@ #include "hoymiles.h" #include "modbus.h" +#include #include -#include Dtu::Dtu(const char *ip_address, int port) { this->modbus_context = modbus_new_tcp(ip_address, port); @@ -22,67 +22,106 @@ Dtu::~Dtu() { void Dtu::populateMicroinverters() { uint16_t address{0x1000}; - Microinverter microinverter{this->modbus_context, address}; + Microinverter microinverter{this->modbus_context}; this->microinverters.push_back(microinverter); } void Dtu::updateMicroinverters() { std::vector::iterator microinvertersIterator = this->microinverters.begin(); - while(microinvertersIterator != this->microinverters.end()){ - microinvertersIterator->updateParameters(); + while (microinvertersIterator != this->microinverters.end()) { + microinvertersIterator->updatePorts(); microinvertersIterator++; } } -MicroinverterParameter::MicroinverterParameter(std::string name, uint16_t addressOffset, int registerSize) { +void PortParameter::setValue(uint16_t *readArray, int registerCount) { + this->value = readArray[0]; +} + +PortParameter::PortParameter(std::string name, uint16_t addressOffset, int registerSize) { this->name = name; this->addressOffset = addressOffset; this->registerSize = registerSize; + + this->value = 0; } -void MicroinverterParameter::updateValue(modbus_t *modbus_context, uint16_t microinverterAddress) { +void PortParameter::updateValue(modbus_t *modbus_context, uint16_t microinverterAddress) { uint16_t readArray[this->registerSize]; int registerCount; registerCount = modbus_read_registers(modbus_context, microinverterAddress + this->addressOffset, this->registerSize, readArray); - if(registerCount == -1){ + registerCount = 2; + readArray[0] = 2309; + readArray[1] = 4354; + if (registerCount == -1) { this->age++; - } - else{ - for(int i{0}; iregisterSize; i++){ - this->valueInt = readArray[i]; - } + } else { + this->setValue(readArray, registerCount); this->age = 0; } } -Microinverter::Microinverter(modbus_t *modbus_t, uint16_t address) { - this->modbus_context = modbus_t; - this->address = address; +void Microinverter::populatePorts() { + Port port{this->modbus_context, 0x1000}; - MicroinverterParameter microinverterParameter{"gridVoltage", 0x0001, 6}; - - this->parameters.push_back(microinverterParameter); + this->ports.push_back(port); } -void Microinverter::updateParameters() { - std::vector::iterator parametersIterator = this->parameters.begin(); - while(parametersIterator != this->parameters.end()) { - parametersIterator->updateValue(this->modbus_context, this->address); +void Microinverter::updatePorts() { + for(Port port : this->ports){ + port.updateParameters(); + } +} + +Microinverter::Microinverter(modbus_t *modbus_context) { + this->modbus_context = modbus_context; + + this->populatePorts(); +} + +void Port::populateParameters() { + PortParameterFloat portParameter{"gridVoltage", 0x0034, 2, 1}; + + this->parameters.push_back(std::make_shared(portParameter)); +} + +void Port::updateParameters() { + std::vector>::iterator parametersIterator{this->parameters.begin()}; + while(parametersIterator != this->parameters.end()){ + parametersIterator->get()->updateValue(this->modbus_context, this->portStartAddress); parametersIterator++; } } -void Microinverter::updateParameterByIndex(int i){ - uint16_t readArray[2]; - int registerCount; - registerCount = modbus_read_registers(this->modbus_context, this->address + this->parameters.at(i).addressOffset, this->parameters.at(i).registerSize, readArray); - if(registerCount == -1){ - this->parameters.at(i).age++; - } - else{ - this->parameters.at(i).valueInt = readArray[0]; - this->parameters.at(i).valueInt = readArray[1]; - this->parameters.at(i).age = 0; +Port::Port(modbus_t *modbus_context, uint16_t portStartAddress) { + this->modbus_context = modbus_context; + this->portStartAddress = portStartAddress; + + this->populateParameters(); +} + +PortParameterFloat::PortParameterFloat(std::string name, uint16_t addressOffset, int registerSize, int decimalPlaces) : PortParameter(name, addressOffset, registerSize) { + this->decimalPlaces = decimalPlaces; + this->value = 0; +} + +void PortParameterFloat::setValue(uint16_t *readArray, int registerCount) { + uint16_t readValue{readArray[0]}; + + this->value = readValue / std::pow(10, this->decimalPlaces); +} + +PortParameterSerialNumber::PortParameterSerialNumber() : PortParameter("serialNumber", 0x0001, 6){}; + +void PortParameterSerialNumber::setValue(uint16_t *readArray, int registerCount) { + uint16_t readValue; + int registerCountCorrected = std::min(3, registerCount); + for(int i{0}; ivalue+= readValue * std::pow(10, (registerCountCorrected-i)*2); + + readValue = readArray[i] & 0x00FF; + this->value+= readValue * std::pow(10, ((registerCountCorrected-i)*2)-1); } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 8566d46..d112b9b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,10 +12,14 @@ int main(){ std::string ip_address {"192.168.31.136"}; int port {502}; - Dtu dtu {ip_address.c_str(), port}; - while(true) { - dtu.updateMicroinverters(); - } + // Dtu dtu {ip_address.c_str(), port}; + // while(true) { + // dtu.updateMicroinverters(); + // } + + Port hoymilesPort{modbus_new_tcp(ip_address.c_str(), port), 0x1000}; + + hoymilesPort.updateParameters(); return 0; } \ No newline at end of file