From f3f1aa390301b6985d4facacad82795b78013d98 Mon Sep 17 00:00:00 2001 From: trabus322 Date: Sat, 16 Mar 2024 22:51:32 +0100 Subject: [PATCH] It's asking but need to tweek setting values from registers --- CMakeLists.txt | 4 +- inc/hoymiles/port.h | 52 +----------- inc/hoymiles/portParameters/portParameters.h | 84 +++++++++++++++++++ .../portParameters/portParametersGeneric.h | 66 +++++++++++++++ src/hoymiles/port.cpp | 81 +++++++----------- .../portParameters/portParameters.cpp | 39 +++++++++ .../portParameters/portParametersGeneric.cpp | 80 ++++++++++++++++++ src/main.cpp | 12 +-- 8 files changed, 309 insertions(+), 109 deletions(-) create mode 100644 inc/hoymiles/portParameters/portParameters.h create mode 100644 inc/hoymiles/portParameters/portParametersGeneric.h create mode 100644 src/hoymiles/portParameters/portParameters.cpp create mode 100644 src/hoymiles/portParameters/portParametersGeneric.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5afdd8d..a202ef5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,9 @@ project(hoymilesClient VERSION 0.1.0 LANGUAGES C CXX) include(CTest) enable_testing() -include_directories(inc inc/libmodbus inc/hoymiles) +include_directories(inc inc/libmodbus inc/hoymiles inc/hoymiles/portParameters) -file(GLOB SOURCES src/*.cpp src/libmodbus/*.c src/hoymiles/*.cpp) +file(GLOB SOURCES src/*.cpp src/libmodbus/*.c src/hoymiles/*.cpp src/hoymiles/portParameters/*.cpp) add_executable(hoymilesClient_exec ${SOURCES}) diff --git a/inc/hoymiles/port.h b/inc/hoymiles/port.h index 922f006..b51effe 100644 --- a/inc/hoymiles/port.h +++ b/inc/hoymiles/port.h @@ -6,59 +6,11 @@ #include #include +#include "portParametersGeneric.h" + struct _modbus; typedef _modbus modbus_t; -class PortParameter { - protected: - uint16_t parameterAddressOffset; - int registerSize; - - virtual void setValueFromRegisters(uint16_t *readArray, int registerCount); - - public: - PortParameter(std::string name, uint16_t parameterAddressOffset, int registerSize); - - virtual ~PortParameter(); - - enum PortParameterValueType { Int, Float }; - - union PortParameterValue { - int i; - float f; - }; - - protected: - PortParameterValueType valueType; - PortParameterValue value; - - public: - std::string name; - - std::pair getValue(); - - virtual std::string getOutputValue(); - - void updateValue(modbus_t *modbus_context, uint16_t portStartAddress); -}; - -class PortParameterFloat : public PortParameter { - protected: - int decimalPlaces; - - void setValueFromRegisters(uint16_t *readArray, int registerCount); - - public: - PortParameterFloat(std::string name, int decimalPlaces, uint16_t parameterAddressOffset, int registerSize); - - virtual std::string getOutputValue(); -}; - -class PortParameterInt : public PortParameter { - protected: - void setValueFromRegisters() -}; - class Port { private: modbus_t *modbus_context; diff --git a/inc/hoymiles/portParameters/portParameters.h b/inc/hoymiles/portParameters/portParameters.h new file mode 100644 index 0000000..dd3e6b8 --- /dev/null +++ b/inc/hoymiles/portParameters/portParameters.h @@ -0,0 +1,84 @@ +#ifndef PORTPARAMETERS_H +#define PORTPARAMETERS_H + +#include "portParametersGeneric.h" + +class PortParameterMicroinverterSerialNumber : public PortParameterInt { + public: + PortParameterMicroinverterSerialNumber(); +}; + +class PortParameterPortNumber : public PortParameterInt { + private: + void setValueFromRegisters(uint16_t *readArray, int registerCount); + + public: + PortParameterPortNumber(); +}; + +class PortParameterPvVoltage : public PortParameterFloat { + public: + PortParameterPvVoltage(); +}; + +class PortParameterPvCurrentMi : public PortParameterFloat { + public: + PortParameterPvCurrentMi(); +}; + +class PortParameterPvCurrentHm : public PortParameterFloat { + public: + PortParameterPvCurrentHm(); +}; + +class PortParameterGridVoltage : public PortParameterFloat { + public: + PortParameterGridVoltage(); +}; + +class PortParameterGridFrequency : public PortParameterFloat { + public: + PortParameterGridFrequency(); +}; + +class PortParameterPvPower : public PortParameterFloat { + public: + PortParameterPvPower(); +}; + +class PortParameterTodayProduction : public PortParameterInt { + public: + PortParameterTodayProduction(); +}; + +class PortParameterTotalProduction : public PortParameterInt { + public: + PortParameterTotalProduction(); +}; + +class PortParameterTemperature : public PortParameterFloat { + public: + PortParameterTemperature(); +}; + +class PortParameterOperatingStatus : public PortParameterInt { + public: + PortParameterOperatingStatus(); +}; + +class PortParameterAlarmCode : public PortParameterInt { + public: + PortParameterAlarmCode(); +}; + +class PortParameterAlarmCount : public PortParameterInt { + public: + PortParameterAlarmCount(); +}; + +class PortParameterLinkStatus : public PortParameterInt { + public: + PortParameterLinkStatus(); +}; + +#endif \ No newline at end of file diff --git a/inc/hoymiles/portParameters/portParametersGeneric.h b/inc/hoymiles/portParameters/portParametersGeneric.h new file mode 100644 index 0000000..ed66367 --- /dev/null +++ b/inc/hoymiles/portParameters/portParametersGeneric.h @@ -0,0 +1,66 @@ +#ifndef PORTPARAMETERSGENERIC_H +#define PORTPARAMETERSGENERIC_H + +#include +#include + +struct _modbus; +typedef _modbus modbus_t; + +class PortParameter { + protected: + uint16_t parameterAddressOffset; + int registerSize; + + virtual void setValueFromRegisters(uint16_t *readArray, int registerCount); + + public: + PortParameter(std::string name, uint16_t parameterAddressOffset, int registerSize); + + virtual ~PortParameter(); + + enum PortParameterValueType { Int, Float }; + + union PortParameterValue { + long i; + float f; + }; + + protected: + PortParameterValueType valueType; + PortParameterValue value; + + public: + std::string name; + int age; + + std::pair getValue(); + + virtual std::string getOutputValue(); + + void updateValue(modbus_t *modbus_context, uint16_t portStartAddress); +}; + +class PortParameterFloat : virtual public PortParameter { + protected: + int decimalPlaces; + + virtual void setValueFromRegisters(uint16_t *readArray, int registerCount); + + public: + PortParameterFloat(std::string name, int decimalPlaces, uint16_t parameterAddressOffset, int registerSize); + + std::string getOutputValue(); +}; + +class PortParameterInt : virtual public PortParameter { + protected: + virtual void setValueFromRegisters(uint16_t *readArray, int registerCount); + + public: + PortParameterInt(std::string name, uint16_t parameterAddressOffset, int registerSize); + + std::string getOutputValue(); +}; + +#endif \ No newline at end of file diff --git a/src/hoymiles/port.cpp b/src/hoymiles/port.cpp index 249ad4d..13a8b24 100644 --- a/src/hoymiles/port.cpp +++ b/src/hoymiles/port.cpp @@ -7,6 +7,7 @@ #include "modbus.h" #include "port.h" +#include "portParameters.h" Port::Port(modbus_t *modbus_context, uint16_t portStartAddress) { this->modbus_context = modbus_context; @@ -16,8 +17,35 @@ Port::Port(modbus_t *modbus_context, uint16_t portStartAddress) { } void Port::populateParameters() { - PortParameterFloat portParameterFloat{"gridVoltage", 1, 0x001a, 2}; - this->parameters.push_back(std::make_shared(portParameterFloat)); + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); + + this->parameters.push_back(std::make_shared()); } void Port::updateParameters() { @@ -26,53 +54,4 @@ void Port::updateParameters() { parametersIterator->get()->updateValue(this->modbus_context, this->portStartAddress); parametersIterator++; } -} - -PortParameter::PortParameter(std::string name, uint16_t parameterAddressOffset, int registerSize) { - this->name = name; - - this->parameterAddressOffset = parameterAddressOffset; - this->registerSize = registerSize; -} - -PortParameter::~PortParameter() {} - -void PortParameter::setValueFromRegisters(uint16_t *readArray, int registerCount) {} - -std::pair PortParameter::getValue() { - return std::pair(this->value, this->valueType); -} - -std::string PortParameter::getOutputValue() {} - -void PortParameter::updateValue(modbus_t *modbus_context, uint16_t portStartAddress) { - uint16_t readArray[this->registerSize]; - int registerCount; - registerCount = modbus_read_registers(modbus_context, portStartAddress + this->parameterAddressOffset, this->registerSize, readArray); - - registerCount = 2; - readArray[0] = 2312; - readArray[1] = 5432; - - if(registerCount == -1){ - std::cerr << "read_error"; - return; - } - else{ - this->setValueFromRegisters(readArray, registerCount); - } -} - -PortParameterFloat::PortParameterFloat(std::string name, int decimalPlaces, uint16_t parameterAddressOffset, int registerSize) : PortParameter(name, parameterAddressOffset, registerSize) { - this->decimalPlaces = decimalPlaces; - - this->valueType = Float; -} - -void PortParameterFloat::setValueFromRegisters(uint16_t *readArray, int registerCount) { - this->value.f = readArray[0] / std::pow(10, this->decimalPlaces); -} - -std::string PortParameterFloat::getOutputValue() { - return std::to_string(this->value.f); } \ No newline at end of file diff --git a/src/hoymiles/portParameters/portParameters.cpp b/src/hoymiles/portParameters/portParameters.cpp new file mode 100644 index 0000000..777c68f --- /dev/null +++ b/src/hoymiles/portParameters/portParameters.cpp @@ -0,0 +1,39 @@ +#include + +#include "portParameters.h" + +PortParameterMicroinverterSerialNumber::PortParameterMicroinverterSerialNumber() : PortParameterInt("microinverterSerialNumber", 0x0001, 6), PortParameter("microinverterSerialNumber", 0x1001, 6) {} + +PortParameterPortNumber::PortParameterPortNumber() : PortParameterInt("portNumber", 0x0007, 1), PortParameter("portNumber", 0x007, 1) {} + +void PortParameterPortNumber::setValueFromRegisters(uint16_t *readArray, int registerCount) { + if (registerCount > 0) { + this->value.i = readArray[0]; + } +} + +PortParameterPvVoltage::PortParameterPvVoltage() : PortParameterFloat("pvVoltage", 1, 0x0008, 2), PortParameter("pvVoltage", 0x0008, 2) {} + +PortParameterPvCurrentMi::PortParameterPvCurrentMi() : PortParameterFloat("pvCurrent", 1, 0x000a, 2), PortParameter("pvCurrent", 0x000a, 2) {} + +PortParameterPvCurrentHm::PortParameterPvCurrentHm() : PortParameterFloat("pvCurrent", 2, 0x000a, 2), PortParameter("pvCurrent", 0x000a, 2) {} + +PortParameterGridVoltage::PortParameterGridVoltage() : PortParameterFloat("gridVoltage", 1, 0x000c, 2), PortParameter("gridVoltage", 0x000c, 2) {} + +PortParameterGridFrequency::PortParameterGridFrequency() : PortParameterFloat("gridFrequency", 2, 0x000e, 2), PortParameter("gridFrequency", 0x000e, 2) {} + +PortParameterPvPower::PortParameterPvPower() : PortParameterFloat("pvPower", 1, 0x0010, 2), PortParameter("pvPower", 0x0010, 2) {} + +PortParameterTodayProduction::PortParameterTodayProduction() : PortParameterInt("todayProduction", 0x0012, 2), PortParameter("todayProduction", 0x0012, 2) {} + +PortParameterTotalProduction::PortParameterTotalProduction() : PortParameterInt("totalProduction", 0x0014, 4), PortParameter("totalProduction", 0x0014, 4) {} + +PortParameterTemperature::PortParameterTemperature() : PortParameterFloat("temperature", 1, 0x0018, 2), PortParameter("temperature", 0x0018, 2) {} + +PortParameterOperatingStatus::PortParameterOperatingStatus() : PortParameterInt("operatingStatus", 0x001a, 2), PortParameter("operatingStatus", 0x001a, 2) {} + +PortParameterAlarmCode::PortParameterAlarmCode() : PortParameterInt("alarmCode", 0x001c, 2), PortParameter("alarmCode", 0x001c, 2) {} + +PortParameterAlarmCount::PortParameterAlarmCount() : PortParameterInt("alarmCount", 0x001e, 2), PortParameter("alarmCount", 0x001e, 2) {} + +PortParameterLinkStatus::PortParameterLinkStatus() : PortParameterInt("linkStatus", 0x020, 2), PortParameter("linkStatus", 0x020, 2) {} \ No newline at end of file diff --git a/src/hoymiles/portParameters/portParametersGeneric.cpp b/src/hoymiles/portParameters/portParametersGeneric.cpp new file mode 100644 index 0000000..07f3834 --- /dev/null +++ b/src/hoymiles/portParameters/portParametersGeneric.cpp @@ -0,0 +1,80 @@ +#include + +#include "modbus.h" + +#include "portParametersGeneric.h" + +struct _modbus; +typedef _modbus modbus_t; + +PortParameter::PortParameter(std::string name, uint16_t parameterAddressOffset, int registerSize) { + this->name = name; + + this->parameterAddressOffset = parameterAddressOffset; + this->registerSize = registerSize; + + this->age = 0; +} + +PortParameter::~PortParameter() {} + +void PortParameter::setValueFromRegisters(uint16_t *readArray, int registerCount) {} + +std::pair PortParameter::getValue() { + return std::pair(this->value, this->valueType); +} + +std::string PortParameter::getOutputValue() {} + +void PortParameter::updateValue(modbus_t *modbus_context, uint16_t portStartAddress) { + uint16_t readArray[this->registerSize]; + int registerCount; + registerCount = modbus_read_registers(modbus_context, portStartAddress + this->parameterAddressOffset, this->registerSize, readArray); + + if(registerCount == -1){ + this->age++; + } + else{ + this->setValueFromRegisters(readArray, registerCount); + this->age = 0; + } +} + +PortParameterFloat::PortParameterFloat(std::string name, int decimalPlaces, uint16_t parameterAddressOffset, int registerSize) : PortParameter(name, parameterAddressOffset, registerSize) { + this->decimalPlaces = decimalPlaces; + + this->valueType = Float; + + this->value.f = 0; +} + +void PortParameterFloat::setValueFromRegisters(uint16_t *readArray, int registerCount) { + float temp = readArray[0]; + temp = temp / std::pow(10, this->decimalPlaces); + this->value.f = temp; +} + +std::string PortParameterFloat::getOutputValue() { + return std::to_string(this->value.f); +} + +PortParameterInt::PortParameterInt(std::string name, uint16_t parameterAddressOffset, int registerSize) : PortParameter(name, parameterAddressOffset, registerSize) { + this->valueType = Int; + + this->value.i = 0; +} + +void PortParameterInt::setValueFromRegisters(uint16_t *readArray, int registerCount) { + uint16_t readValue; + for (int i{0}; i < registerCount; i++) { + readValue = (readArray[i] & 0xFF00); + this->value.i += readValue * std::pow(10, ((registerCount * 2) - ((registerCount - i) * 2))); + + readValue = readArray[i] & 0x00FF; + this->value.i += readValue * std::pow(10, ((registerCount * 2) - ((registerCount - i) * 2))); + } +} + +std::string PortParameterInt::getOutputValue() { + return std::to_string(this->value.i); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b0d0e95..4899d30 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,14 +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}; + // Port hoymilesPort{modbus_new_tcp(ip_address.c_str(), port), 0x1000}; - hoymilesPort.updateParameters(); + // hoymilesPort.updateParameters(); return 0; } \ No newline at end of file