diff --git a/CMakeLists.txt b/CMakeLists.txt index 55a22f3..5afdd8d 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) +include_directories(inc inc/libmodbus inc/hoymiles) -file(GLOB SOURCES src/*.cpp src/libmodbus/*.c) +file(GLOB SOURCES src/*.cpp src/libmodbus/*.c src/hoymiles/*.cpp) add_executable(hoymilesClient_exec ${SOURCES}) diff --git a/inc/hoymiles.h b/inc/hoymiles.h deleted file mode 100644 index bf7d1d4..0000000 --- a/inc/hoymiles.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef HOYMILES_H -#define HOYMILES_H - -#include -#include -#include -#include - -struct _modbus; -typedef _modbus modbus_t; - -class PortParameter { - protected: - uint16_t addressOffset; - int registerSize; - - virtual void setValue(uint16_t *readArray, int registerCount); - - public: - PortParameter(std::string name, uint16_t addressOffset, int registerSize); - - std::string name; - - int age; - - virtual void updateValue(modbus_t *modbus_context, uint16_t portStartAddress); -}; - - - -template -class PortParameterTemplate : virtual public PortParameter { - public: - PortParameterTemplate(std::string name, uint16_t addressOffset, int registerSize); - - Type value; - - Type getValue(); -}; - -class PortParameterInt : public PortParameterTemplate { - private: - void setValue(uint16_t *readArray, int registerCount); - - public: - PortParameterInt(); -}; - - - -class PortParameterSerialNumber : public PortParameterTemplate { - private: - void setValue(uint16_t *readArray, int registerCount); - - public: - PortParameterSerialNumber(); -}; - - - -class PortParameterFloat : public PortParameterTemplate { - 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: - Port(modbus_t *modbus_context, uint16_t portStartAddress); - - void updateParameters(); - - std::shared_ptr getParameterById(int i); - - std::shared_ptr getParameterByName(std::string name); -}; - - - -class Microinverter { - private: - modbus_t *modbus_context; - - std::vector ports; - - void populatePorts(); - - public: - Microinverter(modbus_t *modbus_t); - - void updatePorts(); - - 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/inc/hoymiles/dtu.h b/inc/hoymiles/dtu.h new file mode 100644 index 0000000..e6e3027 --- /dev/null +++ b/inc/hoymiles/dtu.h @@ -0,0 +1,27 @@ +#ifndef DTU_H +#define DTU_H + +#include + +#include "microinverter.h" + +struct _modbus; +typedef _modbus modbus_t; + +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/inc/hoymiles/microinverter.h b/inc/hoymiles/microinverter.h new file mode 100644 index 0000000..5672983 --- /dev/null +++ b/inc/hoymiles/microinverter.h @@ -0,0 +1,29 @@ +#ifndef MICROINVERTER_H +#define MICROINVERTER_H + +#include + +#include "port.h" + +struct _modbus; +typedef _modbus modbus_t; + +class Microinverter { + private: + modbus_t *modbus_context; + + std::vector ports; + + void populatePorts(); + + public: + Microinverter(modbus_t *modbus_t); + + void updatePorts(); + + void updatePort(int i); + + Port getPort(int i); +}; + +#endif \ No newline at end of file diff --git a/inc/hoymiles/port.h b/inc/hoymiles/port.h new file mode 100644 index 0000000..922f006 --- /dev/null +++ b/inc/hoymiles/port.h @@ -0,0 +1,77 @@ +#ifndef PORT_H +#define PORT_H + +#include +#include +#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 { + 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; + uint16_t portStartAddress; + + std::vector> parameters; + + void populateParameters(); + + public: + Port(modbus_t *modbus_context, uint16_t portStartAddress); + + void updateParameters(); +}; + +#endif \ No newline at end of file diff --git a/src/hoymiles.cpp b/src/hoymiles.cpp deleted file mode 100644 index c544790..0000000 --- a/src/hoymiles.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#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); - if (modbus_connect(this->modbus_context) == -1) { - std::cerr << "conn_error"; - modbus_free(this->modbus_context); - abort(); - } - - this->populateMicroinverters(); -} - -Dtu::~Dtu() { - modbus_close(this->modbus_context); - modbus_free(this->modbus_context); -} - -void Dtu::populateMicroinverters() { - uint16_t address{0x1000}; - 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->updatePorts(); - microinvertersIterator++; - } -} - - - -void Microinverter::populatePorts() { - Port port{this->modbus_context, 0x1000}; - - this->ports.push_back(port); -} - -void Microinverter::updatePorts() { - for(Port port : this->ports){ - port.updateParameters(); - } -} - -Microinverter::Microinverter(modbus_t *modbus_context) { - this->modbus_context = modbus_context; - - this->populatePorts(); -} - - - -Port::Port(modbus_t *modbus_context, uint16_t portStartAddress) { - this->modbus_context = modbus_context; - this->portStartAddress = portStartAddress; - - this->populateParameters(); -} - -void Port::populateParameters() { - PortParameterFloat portParameterFloat{"gridVoltage", 0x0034, 2, 1}; - this->parameters.push_back(std::make_shared(portParameterFloat)); - - PortParameterSerialNumber portParameterSerialNumber{}; - this->parameters.push_back(std::make_shared(portParameterSerialNumber)); -} - -void Port::updateParameters() { - std::vector>::iterator parametersIterator{this->parameters.begin()}; - while(parametersIterator != this->parameters.end()){ - parametersIterator->get()->updateValue(this->modbus_context, this->portStartAddress); - parametersIterator++; - } -} - -std::shared_ptr Port::getParameterById(int i) { - return this->parameters.at(i); -} - - - -PortParameter::PortParameter(std::string name, uint16_t addressOffset, int registerSize) { - this->name = name; - - this->addressOffset = addressOffset; - this->registerSize = registerSize; -} - -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); - registerCount = 2; - readArray[0] = 2309; - readArray[1] = 4354; - if (registerCount == -1) { - this->age++; - } else { - this->setValue(readArray, registerCount); - this->age = 0; - } -} - -void PortParameter::setValue(uint16_t *readArray, int registerCount) {} - - - -template -PortParameterTemplate::PortParameterTemplate(std::string name, uint16_t addressOffset, int registerSize) : PortParameter(name, addressOffset, registerSize) {} - - - -PortParameterFloat::PortParameterFloat(std::string name, uint16_t addressOffset, int registerSize, int decimalPlaces) : PortParameterTemplate(name, addressOffset, registerSize), 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); -} - -template -Type PortParameterTemplate::getValue() { - return this->value; -} - - - -PortParameterSerialNumber::PortParameterSerialNumber() : PortParameterTemplate("serialNumber", 0x0001, 6), 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/hoymiles/dtu.cpp b/src/hoymiles/dtu.cpp new file mode 100644 index 0000000..82dbb73 --- /dev/null +++ b/src/hoymiles/dtu.cpp @@ -0,0 +1,40 @@ +#include +#include + +#include "modbus.h" + +#include "dtu.h" +#include "microinverter.h" + +struct _modbus; +typedef _modbus modbus_t; + +Dtu::Dtu(const char *ip_address, int port) { + this->modbus_context = modbus_new_tcp(ip_address, port); + if (modbus_connect(this->modbus_context) == -1) { + std::cerr << "conn_error"; + modbus_free(this->modbus_context); + abort(); + } + + this->populateMicroinverters(); +} + +Dtu::~Dtu() { + modbus_close(this->modbus_context); + modbus_free(this->modbus_context); +} + +void Dtu::populateMicroinverters() { + uint16_t address{0x1000}; + 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->updatePorts(); + microinvertersIterator++; + } +} \ No newline at end of file diff --git a/src/hoymiles/microinverter.cpp b/src/hoymiles/microinverter.cpp new file mode 100644 index 0000000..cdda4eb --- /dev/null +++ b/src/hoymiles/microinverter.cpp @@ -0,0 +1,20 @@ +#include "microinverter.h" +#include "port.h" + +Microinverter::Microinverter(modbus_t *modbus_context) { + this->modbus_context = modbus_context; + + this->populatePorts(); +} + +void Microinverter::populatePorts() { + Port port{this->modbus_context, 0x1000}; + + this->ports.push_back(port); +} + +void Microinverter::updatePorts() { + for(Port port : this->ports){ + port.updateParameters(); + } +} \ No newline at end of file diff --git a/src/hoymiles/port.cpp b/src/hoymiles/port.cpp new file mode 100644 index 0000000..249ad4d --- /dev/null +++ b/src/hoymiles/port.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include + +#include "modbus.h" + +#include "port.h" + +Port::Port(modbus_t *modbus_context, uint16_t portStartAddress) { + this->modbus_context = modbus_context; + this->portStartAddress = portStartAddress; + + this->populateParameters(); +} + +void Port::populateParameters() { + PortParameterFloat portParameterFloat{"gridVoltage", 1, 0x001a, 2}; + this->parameters.push_back(std::make_shared(portParameterFloat)); +} + +void Port::updateParameters() { + std::vector>::iterator parametersIterator{this->parameters.begin()}; + while (parametersIterator != this->parameters.end()) { + 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/main.cpp b/src/main.cpp index 77d7c10..b0d0e95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,8 +4,8 @@ #include #include -#include "hoymiles.h" #include "modbus.h" +#include "dtu.h" int main(){ @@ -21,7 +21,5 @@ int main(){ hoymilesPort.updateParameters(); - std::shared_ptr temp{hoymilesPort.getParameterById(0)}; - float temp2 = temp.get()->getValue(); return 0; } \ No newline at end of file