From 9c3ed916b569dd82647559148eb740133d8e3ff9 Mon Sep 17 00:00:00 2001 From: trabus322 Date: Sun, 17 Mar 2024 21:33:21 +0100 Subject: [PATCH] Managed to implement some stuff, need to rewrite reading from DTU --- inc/hoymiles/dtu.h | 5 ++- inc/hoymiles/microinverter.h | 7 ++-- inc/hoymiles/port.h | 7 ++-- inc/hoymiles/portParameters/portParameters.h | 3 ++ .../portParameters/portParametersGeneric.h | 4 ++- src/hoymiles/dtu.cpp | 13 +++---- src/hoymiles/microinverter.cpp | 34 ++++++++++++++++--- src/hoymiles/port.cpp | 6 ++-- .../portParameters/portParameters.cpp | 19 +++++++++-- .../portParameters/portParametersGeneric.cpp | 19 +++++++---- 10 files changed, 90 insertions(+), 27 deletions(-) diff --git a/inc/hoymiles/dtu.h b/inc/hoymiles/dtu.h index e6e3027..14a7c77 100644 --- a/inc/hoymiles/dtu.h +++ b/inc/hoymiles/dtu.h @@ -2,6 +2,8 @@ #define DTU_H #include +#include +#include #include "microinverter.h" @@ -10,7 +12,8 @@ typedef _modbus modbus_t; class Dtu { private: - modbus_t *modbus_context; + std::shared_ptr modbus_context; + std::mutex modbus_context_mutex; std::vector microinverters; diff --git a/inc/hoymiles/microinverter.h b/inc/hoymiles/microinverter.h index 5672983..c92c95a 100644 --- a/inc/hoymiles/microinverter.h +++ b/inc/hoymiles/microinverter.h @@ -2,6 +2,8 @@ #define MICROINVERTER_H #include +#include +#include #include "port.h" @@ -10,14 +12,15 @@ typedef _modbus modbus_t; class Microinverter { private: - modbus_t *modbus_context; + std::shared_ptr modbus_context; + std::mutex *modbus_context_mutex; std::vector ports; void populatePorts(); public: - Microinverter(modbus_t *modbus_t); + Microinverter(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex); void updatePorts(); diff --git a/inc/hoymiles/port.h b/inc/hoymiles/port.h index b51effe..cd7cb79 100644 --- a/inc/hoymiles/port.h +++ b/inc/hoymiles/port.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "portParametersGeneric.h" @@ -13,7 +14,9 @@ typedef _modbus modbus_t; class Port { private: - modbus_t *modbus_context; + std::shared_ptr modbus_context; + std::mutex *modbus_context_mutex; + uint16_t portStartAddress; std::vector> parameters; @@ -21,7 +24,7 @@ class Port { void populateParameters(); public: - Port(modbus_t *modbus_context, uint16_t portStartAddress); + Port(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex, uint16_t portStartAddress); void updateParameters(); }; diff --git a/inc/hoymiles/portParameters/portParameters.h b/inc/hoymiles/portParameters/portParameters.h index dd3e6b8..83dcd85 100644 --- a/inc/hoymiles/portParameters/portParameters.h +++ b/inc/hoymiles/portParameters/portParameters.h @@ -4,6 +4,9 @@ #include "portParametersGeneric.h" class PortParameterMicroinverterSerialNumber : public PortParameterInt { + protected: + void setValueFromRegisters(uint16_t *readArray, int registerCount); + public: PortParameterMicroinverterSerialNumber(); }; diff --git a/inc/hoymiles/portParameters/portParametersGeneric.h b/inc/hoymiles/portParameters/portParametersGeneric.h index ed66367..b9578bd 100644 --- a/inc/hoymiles/portParameters/portParametersGeneric.h +++ b/inc/hoymiles/portParameters/portParametersGeneric.h @@ -3,6 +3,8 @@ #include #include +#include +#include struct _modbus; typedef _modbus modbus_t; @@ -38,7 +40,7 @@ class PortParameter { virtual std::string getOutputValue(); - void updateValue(modbus_t *modbus_context, uint16_t portStartAddress); + void updateValue(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex, uint16_t portStartAddress); }; class PortParameterFloat : virtual public PortParameter { diff --git a/src/hoymiles/dtu.cpp b/src/hoymiles/dtu.cpp index 82dbb73..6499593 100644 --- a/src/hoymiles/dtu.cpp +++ b/src/hoymiles/dtu.cpp @@ -10,10 +10,11 @@ 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) { + this->modbus_context = std::make_shared(modbus_new_tcp(ip_address, port)); + + if (modbus_connect(*this->modbus_context.get()) == -1) { std::cerr << "conn_error"; - modbus_free(this->modbus_context); + modbus_free(*this->modbus_context.get()); abort(); } @@ -21,13 +22,13 @@ Dtu::Dtu(const char *ip_address, int port) { } Dtu::~Dtu() { - modbus_close(this->modbus_context); - modbus_free(this->modbus_context); + modbus_close(*this->modbus_context.get()); + modbus_free(*this->modbus_context.get()); } void Dtu::populateMicroinverters() { uint16_t address{0x1000}; - Microinverter microinverter{this->modbus_context}; + Microinverter microinverter{this->modbus_context, &this->modbus_context_mutex}; this->microinverters.push_back(microinverter); } diff --git a/src/hoymiles/microinverter.cpp b/src/hoymiles/microinverter.cpp index cdda4eb..6a636ed 100644 --- a/src/hoymiles/microinverter.cpp +++ b/src/hoymiles/microinverter.cpp @@ -1,20 +1,46 @@ +#include + +#include "modbus.h" + #include "microinverter.h" #include "port.h" -Microinverter::Microinverter(modbus_t *modbus_context) { +struct _modbus; +typedef _modbus modbus_t; + +Microinverter::Microinverter(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex) { this->modbus_context = modbus_context; + this->modbus_context_mutex = modbus_context_mutex; this->populatePorts(); } void Microinverter::populatePorts() { - Port port{this->modbus_context, 0x1000}; + uint16_t portStartAddress = 0x1000; + uint16_t readArray[1]; - this->ports.push_back(port); + int registerCount; + registerCount = modbus_read_registers(*this->modbus_context.get(), portStartAddress + 0x0021, 1, readArray); + while(registerCount != -1 && readArray[0] == 0x700) { + Port port{ this->modbus_context, this->modbus_context_mutex, portStartAddress }; + this->ports.push_back(port); + portStartAddress += 0x0028; + + this->modbus_context_mutex->lock(); + registerCount = modbus_read_registers(*this->modbus_context.get(), portStartAddress + 0x0021, 1, readArray); + this->modbus_context_mutex->unlock(); + } } void Microinverter::updatePorts() { + std::vector updateThreads; for(Port port : this->ports){ - port.updateParameters(); + updateThreads.push_back(std::thread(&Port::updateParameters, port)); + // port.updateParameters(); + } + std::vector::iterator updateThreadsIterator = updateThreads.begin(); + while(updateThreadsIterator != updateThreads.end()) { + updateThreadsIterator->join(); + updateThreadsIterator++; } } \ No newline at end of file diff --git a/src/hoymiles/port.cpp b/src/hoymiles/port.cpp index 13a8b24..d12e634 100644 --- a/src/hoymiles/port.cpp +++ b/src/hoymiles/port.cpp @@ -9,8 +9,10 @@ #include "port.h" #include "portParameters.h" -Port::Port(modbus_t *modbus_context, uint16_t portStartAddress) { +Port::Port(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex, uint16_t portStartAddress) { this->modbus_context = modbus_context; + this->modbus_context_mutex = modbus_context_mutex; + this->portStartAddress = portStartAddress; this->populateParameters(); @@ -51,7 +53,7 @@ void Port::populateParameters() { void Port::updateParameters() { std::vector>::iterator parametersIterator{this->parameters.begin()}; while (parametersIterator != this->parameters.end()) { - parametersIterator->get()->updateValue(this->modbus_context, this->portStartAddress); + parametersIterator->get()->updateValue(this->modbus_context, this->modbus_context_mutex, this->portStartAddress); parametersIterator++; } } \ No newline at end of file diff --git a/src/hoymiles/portParameters/portParameters.cpp b/src/hoymiles/portParameters/portParameters.cpp index 777c68f..98f86e6 100644 --- a/src/hoymiles/portParameters/portParameters.cpp +++ b/src/hoymiles/portParameters/portParameters.cpp @@ -1,10 +1,25 @@ #include +#include +#include #include "portParameters.h" -PortParameterMicroinverterSerialNumber::PortParameterMicroinverterSerialNumber() : PortParameterInt("microinverterSerialNumber", 0x0001, 6), PortParameter("microinverterSerialNumber", 0x1001, 6) {} +PortParameterMicroinverterSerialNumber::PortParameterMicroinverterSerialNumber() : PortParameterInt("microinverterSerialNumber", 0x0001, 6), PortParameter("microinverterSerialNumber", 0x0001, 6) {} -PortParameterPortNumber::PortParameterPortNumber() : PortParameterInt("portNumber", 0x0007, 1), PortParameter("portNumber", 0x007, 1) {} +void PortParameterMicroinverterSerialNumber::setValueFromRegisters(uint16_t *readArray, int registerCount) { + uint16_t readValue; + std::string readValueString = ""; + registerCount = std::ceil(registerCount/2); + for (int i{0}; i < registerCount; i++) { + readValue = readArray[i]; + std::stringstream readValueStringStream; + readValueStringStream << std::hex << readValue; + readValueString.append(readValueStringStream.str()); + } + this->value.i = std::stol(readValueString); +} + +PortParameterPortNumber::PortParameterPortNumber() : PortParameterInt("portNumber", 0x0007, 1), PortParameter("portNumber", 0x0007, 1) {} void PortParameterPortNumber::setValueFromRegisters(uint16_t *readArray, int registerCount) { if (registerCount > 0) { diff --git a/src/hoymiles/portParameters/portParametersGeneric.cpp b/src/hoymiles/portParameters/portParametersGeneric.cpp index 07f3834..000da08 100644 --- a/src/hoymiles/portParameters/portParametersGeneric.cpp +++ b/src/hoymiles/portParameters/portParametersGeneric.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "modbus.h" @@ -26,10 +28,13 @@ std::pair modbus_context, std::mutex *modbus_context_mutex, uint16_t portStartAddress) { uint16_t readArray[this->registerSize]; int registerCount; - registerCount = modbus_read_registers(modbus_context, portStartAddress + this->parameterAddressOffset, this->registerSize, readArray); + + modbus_context_mutex->lock(); + registerCount = modbus_read_registers(*modbus_context.get(), portStartAddress + this->parameterAddressOffset, this->registerSize, readArray); + modbus_context_mutex->unlock(); if(registerCount == -1){ this->age++; @@ -66,13 +71,13 @@ PortParameterInt::PortParameterInt(std::string name, uint16_t parameterAddressOf void PortParameterInt::setValueFromRegisters(uint16_t *readArray, int registerCount) { uint16_t readValue; + std::string readValueString = ""; + registerCount = std::ceil(registerCount/2); 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))); + readValue = readArray[i]; + readValueString.append(std::to_string(readValue)); } + this->value.i = std::stol(readValueString); } std::string PortParameterInt::getOutputValue() {