diff --git a/CMakeLists.txt b/CMakeLists.txt index cae14e7..d1a5dcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,10 @@ file(GLOB SOURCES add_library(libhoymiles STATIC ${SOURCES}) add_subdirectory(src/libmodbus) -target_link_libraries(libhoymiles INTERFACE libmodbus) +target_link_libraries(libhoymiles libmodbus) + +add_executable(libhoymiles_example src/main.cpp) +target_link_libraries(libhoymiles_example libhoymiles) if(WIN32) diff --git a/inc/microinverter.h b/inc/microinverter.h index 0eaf563..beba6e5 100644 --- a/inc/microinverter.h +++ b/inc/microinverter.h @@ -13,7 +13,7 @@ class Microinverter { private: modbus_t *modbus; - Sunspec sunspec; + // Sunspec sunspec; int startAddress; diff --git a/src/dtu.cpp b/src/dtu.cpp index a19fec1..484fbb1 100644 --- a/src/dtu.cpp +++ b/src/dtu.cpp @@ -20,6 +20,8 @@ Dtu::Dtu(const char *address, int id, bool rtu, bool tcp) { modbus_rtu_set_serial_mode(this->modbus, MODBUS_RTU_RS485); } + modbus_set_debug(this->modbus, 1); + this->connected = false; if (modbus_connect(this->modbus) == -1) { std::cerr << "NOT CONNECTED" << std::endl; @@ -41,13 +43,21 @@ Dtu::~Dtu() { void Dtu::populateMicroinverters() { int portStartAddress = 0x4000; - uint16_t registers[19]; + int registersToRead{19}; + uint16_t registers[registersToRead]; + + bool lastSuccesful{true}; while (portStartAddress <= (0x4000 + (0x0019 * 99))) { - int registerCount; - registerCount = modbus_read_registers(this->modbus, portStartAddress, 19, registers); + int registerCount{-1}; + int timesTried{0}; + while((timesTried < 3) && (lastSuccesful && registerCount == -1)) { + registerCount = modbus_read_registers(this->modbus, portStartAddress, registersToRead, registers); + timesTried++; + } portStartAddress += 0x0019; - if (registers[0] == 12) { + if (registers[0] == 12 && registerCount != -1) { + lastSuccesful = true; Port port{portStartAddress}; port.setParametersFromMicroinverterArray(registers, 0); @@ -56,10 +66,24 @@ void Dtu::populateMicroinverters() { this->microinverters.push_back(microinverter); } - this->getMicroinverterBySerialNumber(port.getParameterByName("microinverterSerialNumber").first.get()->getValue().first.i).first->ports.push_back(port); + Microinverter* microinverter = this->getMicroinverterBySerialNumber(port.getParameterByName("microinverterSerialNumber").first.get()->getValue().first.i).first; + std::vector::iterator portsIterator = microinverter->ports.begin(); + bool valueExists{false}; + while(portsIterator != microinverter->ports.end() && !valueExists) { + if(portsIterator->getParameterByName("portNumber").first.get()->getValue().first.i == port.getParameterByName("portNumber").first.get()->getValue().first.i) { + valueExists = true; + } + portsIterator++; + } + if(!valueExists) { + microinverter->ports.push_back(port); + } + } + else{ + lastSuccesful = false; } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); } } diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fa82526 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,7 @@ +#include "dtu.h" + +int main() { + Dtu dtu{"/dev/ttyUSB0", 101, true, false}; + + return 0; +} \ No newline at end of file diff --git a/src/microinverter.cpp b/src/microinverter.cpp index a6542a2..cd3ff2c 100644 --- a/src/microinverter.cpp +++ b/src/microinverter.cpp @@ -8,7 +8,7 @@ #include "port.h" #include "sunspec.h" -Microinverter::Microinverter(modbus_t *modbus, int startAddress, long long serialNumber) : sunspec(40000, modbus) { +Microinverter::Microinverter(modbus_t *modbus, int startAddress, long long serialNumber) { this->modbus = modbus; this->startAddress = startAddress; this->serialNumber = serialNumber; diff --git a/src/sunspec.cpp b/src/sunspec.cpp index 3ad2f64..b475c6d 100644 --- a/src/sunspec.cpp +++ b/src/sunspec.cpp @@ -16,10 +16,10 @@ Sunspec::Sunspec(int address, modbus_t *modbus) { } void Sunspec::setValues() { - uint16_t registers[70]; + uint16_t registers[2]; int registerCount; - registerCount = modbus_read_registers(this->modbus, this->sunspecAddress, 70, registers); + registerCount = modbus_read_registers(this->modbus, this->sunspecAddress, 2, registers); std::vector>::iterator parametersIterator = this->parameters.begin(); while(parametersIterator != this->parameters.end()) {