Compare commits
4 commits
0381c3c334
...
128fadf77d
| Author | SHA1 | Date | |
|---|---|---|---|
| 128fadf77d | |||
| a78599ea02 | |||
| c24e6c7d06 | |||
| 79f8ee4944 |
7 changed files with 151 additions and 16 deletions
|
|
@ -14,6 +14,10 @@ class Dtu {
|
|||
|
||||
std::vector<Microinverter> microinverters;
|
||||
|
||||
Port dtuPort;
|
||||
|
||||
int rtuId;
|
||||
|
||||
bool connected;
|
||||
|
||||
void populateMicroinverters();
|
||||
|
|
@ -21,6 +25,8 @@ class Dtu {
|
|||
public:
|
||||
Dtu(const char *address, int id, bool rtu, bool tcp);
|
||||
|
||||
Dtu(modbus_t *modbus, int id);
|
||||
|
||||
std::pair<Microinverter *, bool> getMicroinverterBySerialNumber(long long serialNumber);
|
||||
|
||||
bool isConnected();
|
||||
|
|
@ -35,6 +41,15 @@ class Dtu {
|
|||
|
||||
void listOfMicroinverters();
|
||||
|
||||
float getCurrentPower();
|
||||
|
||||
int getCurrentOnOff();
|
||||
|
||||
void turnOffMicroinverters();
|
||||
void turnOnMicroinverters();
|
||||
|
||||
void limitMicroinverters(uint16_t limit);
|
||||
|
||||
~Dtu();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class Microinverter {
|
|||
private:
|
||||
modbus_t *modbus;
|
||||
|
||||
Sunspec sunspec;
|
||||
// Sunspec sunspec;
|
||||
|
||||
int startAddress;
|
||||
|
||||
|
|
@ -43,6 +43,10 @@ class Microinverter {
|
|||
void setStatus(std::vector<std::pair<int, uint16_t>> portsToSet, std::string statusName);
|
||||
|
||||
void setStatusWholeMicroinverter(uint16_t value, std::string statusName);
|
||||
|
||||
float getCurrentPower();
|
||||
|
||||
int getCurrentOnOff();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
#include "portParameters.h"
|
||||
|
||||
Dtu::Dtu(const char *address, int id, bool rtu, bool tcp) {
|
||||
Dtu::Dtu(const char *address, int id, bool rtu, bool tcp) : dtuPort(0) {
|
||||
dtuPort.statusPortStartAddress = 0xd000;
|
||||
if (tcp) {
|
||||
this->modbus = modbus_new_tcp(address, id);
|
||||
}
|
||||
|
|
@ -22,7 +23,7 @@ Dtu::Dtu(const char *address, int id, bool rtu, bool tcp) {
|
|||
|
||||
this->connected = false;
|
||||
if (modbus_connect(this->modbus) == -1) {
|
||||
std::cerr << "NOT CONNECTED" << std::endl;
|
||||
std::cerr << "[" << id << "] NOT_CONNECTED" << std::endl;
|
||||
} else {
|
||||
this->connected = true;
|
||||
if (rtu) {
|
||||
|
|
@ -32,6 +33,24 @@ Dtu::Dtu(const char *address, int id, bool rtu, bool tcp) {
|
|||
}
|
||||
}
|
||||
|
||||
Dtu::Dtu(modbus_t *modbus, int id = -1) : dtuPort(0) {
|
||||
dtuPort.statusPortStartAddress = 0xd000;
|
||||
|
||||
this->modbus = modbus;
|
||||
this->rtuId = id;
|
||||
|
||||
this->connected = false;
|
||||
if (modbus_connect(this->modbus) == -1) {
|
||||
std::cerr << "[" << id << "] NOT_CONNECTED" << std::endl;
|
||||
} else {
|
||||
this->connected = true;
|
||||
if (id != -1) {
|
||||
modbus_set_slave(this->modbus, rtuId);
|
||||
}
|
||||
this->populateMicroinverters();
|
||||
}
|
||||
}
|
||||
|
||||
bool Dtu::isConnected() { return this->connected; }
|
||||
|
||||
Dtu::~Dtu() {
|
||||
|
|
@ -40,14 +59,32 @@ Dtu::~Dtu() {
|
|||
}
|
||||
|
||||
void Dtu::populateMicroinverters() {
|
||||
if(this->rtuId != -1) {
|
||||
modbus_set_slave(this->modbus, this->rtuId);
|
||||
}
|
||||
|
||||
int portStartAddress = 0x4000;
|
||||
uint16_t registers[19];
|
||||
int registersToRead{19};
|
||||
uint16_t registers[registersToRead];
|
||||
|
||||
bool lastSuccesful{true};
|
||||
|
||||
int addressToSkip{-1};
|
||||
|
||||
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) && portStartAddress != addressToSkip)) {
|
||||
registerCount = modbus_read_registers(this->modbus, portStartAddress, registersToRead, registers);
|
||||
timesTried++;
|
||||
}
|
||||
portStartAddress += 0x0019;
|
||||
if (registers[0] == 12) {
|
||||
if ((registers[0] == 12 && registerCount != -1) && portStartAddress != addressToSkip) {
|
||||
if (!lastSuccesful) {
|
||||
addressToSkip = portStartAddress;
|
||||
portStartAddress -= 2 * 0x0019;
|
||||
}
|
||||
lastSuccesful = true;
|
||||
Port port{portStartAddress};
|
||||
port.setParametersFromMicroinverterArray(registers, 0);
|
||||
|
||||
|
|
@ -56,10 +93,23 @@ 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<Port>::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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +126,9 @@ std::pair<Microinverter *, bool> Dtu::getMicroinverterBySerialNumber(long long s
|
|||
}
|
||||
|
||||
void Dtu::updateMicroinverters(std::vector<std::string> ¶metersToGet, bool allParameters, std::vector<long long> µinvertersToGet) {
|
||||
if(this->rtuId != -1) {
|
||||
modbus_set_slave(this->modbus, this->rtuId);
|
||||
}
|
||||
if (microinvertersToGet.empty()) {
|
||||
std::vector<Microinverter>::iterator microinvertersIterator = this->microinverters.begin();
|
||||
while (microinvertersIterator != this->microinverters.end()) {
|
||||
|
|
@ -156,3 +209,38 @@ void Dtu::listOfMicroinverters() {
|
|||
microinvertersIterator++;
|
||||
}
|
||||
}
|
||||
|
||||
float Dtu::getCurrentPower() {
|
||||
std::vector<Microinverter>::iterator microinvertersIterator = this->microinverters.begin();
|
||||
float currentPower{0};
|
||||
while (microinvertersIterator != this->microinverters.end()) {
|
||||
currentPower += microinvertersIterator->getCurrentPower();
|
||||
microinvertersIterator++;
|
||||
}
|
||||
return currentPower;
|
||||
}
|
||||
|
||||
int Dtu::getCurrentOnOff() {
|
||||
if(this->microinverters.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
std::vector<Microinverter>::iterator microinvertersIterator = this->microinverters.begin();
|
||||
int currentOn{0};
|
||||
while(microinvertersIterator != this->microinverters.end()) {
|
||||
currentOn += microinvertersIterator->getCurrentOnOff();
|
||||
microinvertersIterator++;
|
||||
}
|
||||
float balance = currentOn / this->microinverters.size();
|
||||
if(balance >= 0.5) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Dtu::turnOffMicroinverters() { this->dtuPort.getStatusByName("onOff").first.get()->writeValue(0, this->modbus, this->dtuPort.statusPortStartAddress); }
|
||||
|
||||
void Dtu::turnOnMicroinverters() { this->dtuPort.getStatusByName("onOff").first.get()->writeValue(1, this->modbus, this->dtuPort.statusPortStartAddress); }
|
||||
|
||||
void Dtu::limitMicroinverters(uint16_t limit) { this->dtuPort.getStatusByName("limitActivePower").first.get()->writeValue(limit, this->modbus, this->dtuPort.statusPortStartAddress); }
|
||||
|
|
@ -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;
|
||||
|
|
@ -137,3 +137,29 @@ void Microinverter::setStatusWholeMicroinverter(uint16_t value, std::string stat
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
float Microinverter::getCurrentPower() {
|
||||
std::vector<Port>::iterator portsIterator = this->ports.begin();
|
||||
float currentPower{0};
|
||||
while(portsIterator != this->ports.end()) {
|
||||
currentPower += portsIterator->getParameterByName("pvPower").first.get()->getValue().first.f;
|
||||
portsIterator++;
|
||||
}
|
||||
return currentPower;
|
||||
}
|
||||
|
||||
int Microinverter::getCurrentOnOff() {
|
||||
std::vector<Port>::iterator portsIterator = this->ports.begin();
|
||||
int currentOn{0};
|
||||
while(portsIterator != this->ports.end()) {
|
||||
currentOn += portsIterator->getStatusByName("onOff").first.get()->getValue().first.i;
|
||||
portsIterator++;
|
||||
}
|
||||
float balance = currentOn / this->ports.size();
|
||||
if(balance >= 0.5) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<std::shared_ptr<SunspecParameter>>::iterator parametersIterator = this->parameters.begin();
|
||||
while(parametersIterator != this->parameters.end()) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ SunspecParameter::SunspecParameter(std::string name, int registerAddressOffset,
|
|||
|
||||
void SunspecParameter::getValueFromRegisters(uint16_t *registers, int addressOffset) {}
|
||||
|
||||
std::pair<SunspecParameter::SunspecValue, SunspecParameter::SunspecValueType> SunspecParameter::getValue() {}
|
||||
std::pair<SunspecParameter::SunspecValue, SunspecParameter::SunspecValueType> SunspecParameter::getValue() {
|
||||
return {this->value, this->valueType};
|
||||
}
|
||||
|
||||
SunspecParameterString32::SunspecParameterString32(std::string name, int registerAddressOffset, int registerSize) : SunspecParameter(name, registerAddressOffset, registerSize) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ int main(int argc, char **argv) {
|
|||
signal(SIGTERM, sigHandler);
|
||||
signal(SIGABRT, sigHandler);
|
||||
|
||||
std::string version{"v2.4h"};
|
||||
std::string version{"v2.5"};
|
||||
std::cout << version << std::endl;
|
||||
|
||||
CLI::App hoymilesClient{"Client for DTU-Pro/DTU-ProS"};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue