From 8e96ba70644b6a85dbe394bb67c30bedcbc7ebb7 Mon Sep 17 00:00:00 2001 From: trabus322 Date: Wed, 13 Mar 2024 19:51:10 +0100 Subject: [PATCH] Made "multithreading" xX --- inc/hoymiles.h | 57 +++++++--- src/hoymiles.cpp | 280 +++++++++++++++++++++++++++++++++++++++++++---- src/main.cpp | 8 +- 3 files changed, 302 insertions(+), 43 deletions(-) diff --git a/inc/hoymiles.h b/inc/hoymiles.h index dc56e08..bdab100 100644 --- a/inc/hoymiles.h +++ b/inc/hoymiles.h @@ -7,27 +7,34 @@ struct _modbus; typedef _modbus modbus_t; -class Dtu{ - private: - modbus_t *modbus_t; - - std::vector microinverters; - - public: - Dtu(const char *ip_address, int port); - - void readTest(uint16_t address, int registers); - - ~Dtu(); -}; - class Microinverter{ private: - uint16_t readArray[33]; + modbus_t *modbus_context; uint16_t address; + void updatePortNumber(); + + void updatePlantVoltage(); + void updatePlantCurrent(); + + void updateGridVoltage(); + void updateGridFrequency(); + + void updatePlantPower(); + + void updateTodayProduction(); + void updateTotalProduction(); + + void updateTemperature(); + + void updateOperatingStatus(); + void updateAlarmCode(); + void updateAlarmCount(); + + void updateLinkStatus(); + public: - const int serialNumber; + int serialNumber; std::pair portNumber; std::pair plantVoltage; @@ -49,9 +56,25 @@ class Microinverter{ std::pair linkStatus; - Microinverter(uint16_t address); + Microinverter(modbus_t *modbus_t, uint16_t address); void updateValues(); }; +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 e5bed85..69e5d12 100644 --- a/src/hoymiles.cpp +++ b/src/hoymiles.cpp @@ -2,30 +2,270 @@ #include "modbus.h" #include +#include Dtu::Dtu(const char *ip_address, int port) { - this->modbus_t = modbus_new_tcp(ip_address, port); - if(modbus_connect(this->modbus_t) == -1){ - std::cerr << "conn_error"; - modbus_free(this->modbus_t); - abort(); - } -} - -void Dtu::readTest(uint16_t address, int registers) { - uint16_t readArray[registers]; - int registerCount; - registerCount = modbus_read_registers(this->modbus_t, address, registers, readArray); - if(registerCount == -1){ - std::cerr << "read_error"; - return; - } - for (int i{0}; i < registerCount; i++) { - std::clog << readArray[i] << std::endl; + 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_t); - modbus_free(this->modbus_t); + modbus_close(this->modbus_context); + modbus_free(this->modbus_context); +} + +void Dtu::populateMicroinverters() { + uint16_t address{0x1000}; + Microinverter microinverter{this->modbus_context, address}; + this->microinverters.push_back(microinverter); +} + +void Dtu::updateMicroinverters() { + std::vector::iterator microinvertersIterator{this->microinverters.begin()}; + std::vector updateThreads; + while (microinvertersIterator != this->microinverters.end()) { + updateThreads.push_back(std::thread{&Microinverter::updateValues, *microinvertersIterator}); + microinvertersIterator++; + } + std::vector::iterator updateThreadsIterator{updateThreads.begin()}; + while (updateThreadsIterator != updateThreads.end()) { + updateThreadsIterator->join(); + updateThreadsIterator++; + } + int numberOfInverters = this->microinverters.size(); +} + +Microinverter::Microinverter(modbus_t *modbus_context, uint16_t address) { + this->modbus_context = modbus_context; + this->address = address; + + uint16_t serialNumberReadArray[5]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 2, 5, serialNumberReadArray); + + this->serialNumber = 0; + for (int i{0}; i < registerCount; i++) { + serialNumber += serialNumberReadArray[i]; + } +} + +void Microinverter::updateValues() { + std::thread updatePortNumberThread{&Microinverter::updatePortNumber, this}; + + std::thread updatePlantVoltageThread{&Microinverter::updatePlantVoltage, this}; + std::thread updatePlantCurrentThread{&Microinverter::updatePlantCurrent, this}; + + std::thread updateGridVoltageThread{&Microinverter::updateGridVoltage, this}; + std::thread updateGridFrequencyThread{&Microinverter::updateGridFrequency, this}; + + std::thread updatePlantPowerThread{&Microinverter::updatePlantPower, this}; + + std::thread updateTodayProductionThread{&Microinverter::updateTodayProduction, this}; + std::thread updateTotalProductionThread{&Microinverter::updateTotalProduction, this}; + + std::thread updateTemperatureThread{&Microinverter::updateTemperature, this}; + + std::thread updateOperatingStatus{&Microinverter::updateOperatingStatus, this}; + std::thread updateAlarmCodeThread{&Microinverter::updateAlarmCode, this}; + std::thread updateAlarmCountThread{&Microinverter::updateAlarmCount, this}; + + std::thread updateLinkStatusThread{&Microinverter::updateLinkStatus, this}; + + + updatePortNumberThread.join(); + + updatePlantVoltageThread.join(); + updatePlantCurrentThread.join(); + + updateGridVoltageThread.join(); + updateGridFrequencyThread.join(); + + updatePlantPowerThread.join(); + + updateTodayProductionThread.join(); + updateTotalProductionThread.join(); + + updateTemperatureThread.join(); + + updateOperatingStatus.join(); + updateAlarmCodeThread.join(); + updateAlarmCountThread.join(); + + updateLinkStatusThread.join(); +} + +void Microinverter::updatePortNumber() { + uint16_t readArray[1]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 7, 1, readArray); + if (registerCount == -1) { + this->portNumber.second++; + } else { + this->portNumber.first = readArray[0]; + this->portNumber.second = 0; + } +} + +void Microinverter::updatePlantVoltage() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 8, 2, readArray); + if (registerCount == -1) { + this->plantVoltage.second++; + } else { + this->plantVoltage.first = readArray[0]; + this->plantVoltage.first += readArray[1]; + this->plantVoltage.second = 0; + } +} + +void Microinverter::updatePlantCurrent() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 10, 2, readArray); + if (registerCount == -1) { + this->plantCurrent.second++; + } else { + this->plantCurrent.first = readArray[0]; + this->plantCurrent.first += readArray[1]; + this->plantCurrent.second = 0; + } +} + +void Microinverter::updateGridVoltage() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 12, 2, readArray); + if (registerCount == -1) { + this->gridVoltage.second++; + } else { + this->gridVoltage.first = readArray[0]; + this->gridVoltage.first += readArray[1]; + this->gridVoltage.second = 0; + } +} + +void Microinverter::updateGridFrequency() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 14, 2, readArray); + if (registerCount == -1) { + this->gridFrequency.second++; + } else { + this->gridFrequency.first = readArray[0]; + this->gridFrequency.first += readArray[1]; + this->gridFrequency.second = 0; + } +} + +void Microinverter::updatePlantPower() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 16, 2, readArray); + if (registerCount == -1) { + this->plantPower.second++; + } else { + this->plantPower.first = readArray[0]; + this->plantPower.first += readArray[1]; + this->plantPower.second = 0; + } +} + +void Microinverter::updateTodayProduction() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 18, 2, readArray); + if (registerCount == -1) { + this->todayProduction.second++; + } else { + this->todayProduction.first = readArray[0]; + this->todayProduction.first += readArray[1]; + this->todayProduction.second = 0; + } +} + +void Microinverter::updateTotalProduction() { + uint16_t readArray[4]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 20, 4, readArray); + if (registerCount == -1) { + this->totalProduction.second++; + } else { + this->totalProduction.first = readArray[0]; + this->totalProduction.first += readArray[1]; + this->totalProduction.first += readArray[2]; + this->totalProduction.first += readArray[3]; + this->totalProduction.second = 0; + } +} + +void Microinverter::updateTemperature() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 24, 2, readArray); + if (registerCount == -1) { + this->temperature.second++; + } else { + this->temperature.first = readArray[0]; + this->temperature.first += readArray[1]; + this->temperature.second = 0; + } +} + +void Microinverter::updateOperatingStatus() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 26, 2, readArray); + if (registerCount == -1) { + this->operatingStatus.second++; + } else { + this->operatingStatus.first = readArray[0]; + this->operatingStatus.first += readArray[1]; + this->operatingStatus.second = 0; + } +} + +void Microinverter::updateAlarmCode() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 28, 2, readArray); + if (registerCount == -1) { + this->alarmCode.second++; + } else { + this->alarmCode.first = readArray[0]; + this->alarmCode.first += readArray[1]; + this->alarmCode.second = 0; + } +} + +void Microinverter::updateAlarmCount() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 30, 2, readArray); + if (registerCount == -1) { + this->alarmCount.second++; + } else { + this->alarmCount.first = readArray[0]; + this->alarmCount.first += readArray[1]; + this->alarmCount.second = 0; + } +} + +void Microinverter::updateLinkStatus() { + uint16_t readArray[2]; + int registerCount; + registerCount = modbus_read_registers(this->modbus_context, this->address + 32, 2, readArray); + if (registerCount == -1) { + this->linkStatus.second++; + } else { + this->linkStatus.first = readArray[0]; + this->linkStatus.first += readArray[1]; + this->linkStatus.second = 0; + } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 20c856c..8566d46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,12 +13,8 @@ int main(){ int port {502}; Dtu dtu {ip_address.c_str(), port}; - - bool buttonPressed{false}; - for(int i{0}; i<10; i++){ - dtu.readTest(0x1034, 2); - std::clog << std::endl; - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + while(true) { + dtu.updateMicroinverters(); } return 0;