diff --git a/inc/hoymiles/dtu.h b/inc/hoymiles/dtu.h index 14a7c77..294f4dd 100644 --- a/inc/hoymiles/dtu.h +++ b/inc/hoymiles/dtu.h @@ -19,6 +19,8 @@ class Dtu { void populateMicroinverters(); + std::pair getMicroinverterBySerialNumber(long serialNumber); + public: Dtu(const char *ip_address, int port); diff --git a/inc/hoymiles/microinverter.h b/inc/hoymiles/microinverter.h index c92c95a..b6b9c58 100644 --- a/inc/hoymiles/microinverter.h +++ b/inc/hoymiles/microinverter.h @@ -15,12 +15,14 @@ class Microinverter { std::shared_ptr modbus_context; std::mutex *modbus_context_mutex; - std::vector ports; - - void populatePorts(); + public: - Microinverter(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex); + Microinverter(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex, long serialNumber); + + long serialNumber; + + std::vector ports; void updatePorts(); diff --git a/src/hoymiles/dtu.cpp b/src/hoymiles/dtu.cpp index 6499593..2acd69a 100644 --- a/src/hoymiles/dtu.cpp +++ b/src/hoymiles/dtu.cpp @@ -1,11 +1,14 @@ #include #include +#include #include "modbus.h" #include "dtu.h" #include "microinverter.h" +#include "portParameters.h" + struct _modbus; typedef _modbus modbus_t; @@ -27,15 +30,61 @@ Dtu::~Dtu() { } void Dtu::populateMicroinverters() { - uint16_t address{0x1000}; - Microinverter microinverter{this->modbus_context, &this->modbus_context_mutex}; - this->microinverters.push_back(microinverter); + uint16_t portStartAddress = 0x1000; + uint16_t readArray[1]; + + 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 }; + + PortParameterMicroinverterSerialNumber portParameterMicroinverterSerialNumber{}; + portParameterMicroinverterSerialNumber.updateValue(this->modbus_context, &this->modbus_context_mutex, portStartAddress); + long serialNumber = portParameterMicroinverterSerialNumber.getValue().first.i; + + std::pair getMicroinverterBySerialNumber = this->getMicroinverterBySerialNumber(serialNumber); + if(getMicroinverterBySerialNumber.first) { + getMicroinverterBySerialNumber.second->ports.push_back(port); + } + else { + Microinverter microinverter{ this->modbus_context, &this->modbus_context_mutex, serialNumber }; + this->microinverters.push_back(microinverter); + this->microinverters.back().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(); + } +} + +std::pair Dtu::getMicroinverterBySerialNumber(long serialNumber) { + std::vector::iterator microinvertersIterator = this->microinverters.begin(); + while(microinvertersIterator != this->microinverters.end()) { + if(microinvertersIterator->serialNumber == serialNumber) { + return std::pair(true, &*microinvertersIterator); + } + else{ + microinvertersIterator++; + } + } + return std::pair(false, &*microinvertersIterator); } void Dtu::updateMicroinverters() { + std::vector updateThreads; + std::vector::iterator microinvertersIterator = this->microinverters.begin(); while (microinvertersIterator != this->microinverters.end()) { - microinvertersIterator->updatePorts(); + updateThreads.push_back(std::thread(&Microinverter::updatePorts, microinvertersIterator)); microinvertersIterator++; } + + std::vector::iterator updateThreadsIterator = updateThreads.begin(); + while(updateThreadsIterator != updateThreads.end()) { + updateThreadsIterator->join(); + updateThreadsIterator++; + } } \ No newline at end of file diff --git a/src/hoymiles/microinverter.cpp b/src/hoymiles/microinverter.cpp index 6a636ed..c336609 100644 --- a/src/hoymiles/microinverter.cpp +++ b/src/hoymiles/microinverter.cpp @@ -8,28 +8,11 @@ struct _modbus; typedef _modbus modbus_t; -Microinverter::Microinverter(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex) { +Microinverter::Microinverter(std::shared_ptr modbus_context, std::mutex *modbus_context_mutex, long serialNumber) { this->modbus_context = modbus_context; this->modbus_context_mutex = modbus_context_mutex; - this->populatePorts(); -} - -void Microinverter::populatePorts() { - uint16_t portStartAddress = 0x1000; - uint16_t readArray[1]; - - 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(); - } + this->serialNumber = serialNumber; } void Microinverter::updatePorts() { diff --git a/src/hoymiles/port.cpp b/src/hoymiles/port.cpp index d12e634..66edaa7 100644 --- a/src/hoymiles/port.cpp +++ b/src/hoymiles/port.cpp @@ -55,5 +55,6 @@ void Port::updateParameters() { while (parametersIterator != this->parameters.end()) { parametersIterator->get()->updateValue(this->modbus_context, this->modbus_context_mutex, this->portStartAddress); parametersIterator++; + break; } } \ No newline at end of file