Release v2.2w #17
8 changed files with 88 additions and 17 deletions
|
|
@ -31,6 +31,8 @@ class Dtu {
|
||||||
|
|
||||||
void printMicroinverters(std::vector<std::string> ¶metersToGet, bool allParameters, std::vector<long long> µinvertersToGet, bool shortNames, bool printTodayProduction, bool printTotalProduction);
|
void printMicroinverters(std::vector<std::string> ¶metersToGet, bool allParameters, std::vector<long long> µinvertersToGet, bool shortNames, bool printTodayProduction, bool printTotalProduction);
|
||||||
|
|
||||||
|
void setStatusMicroinverters(uint16_t value, std::string statusName, std::vector<long long>& microinvertersToSet);
|
||||||
|
|
||||||
~Dtu();
|
~Dtu();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ class Microinverter {
|
||||||
long long getTotalProduction();
|
long long getTotalProduction();
|
||||||
|
|
||||||
void setStatus(std::vector<std::pair<int, uint16_t>> portsToSet, std::string statusName);
|
void setStatus(std::vector<std::pair<int, uint16_t>> portsToSet, std::string statusName);
|
||||||
|
|
||||||
|
void setStatusWholeMicroinverter(uint16_t value, std::string statusName);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -123,3 +123,22 @@ void Dtu::printMicroinverters(std::vector<std::string> ¶metersToGet, bool al
|
||||||
microinvertersToGetIterator++;
|
microinvertersToGetIterator++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Dtu::setStatusMicroinverters(uint16_t value, std::string statusName, std::vector<long long>& microinvertersToSet) {
|
||||||
|
if (microinvertersToSet.empty()) {
|
||||||
|
std::vector<Microinverter>::iterator microinvertersIterator = this->microinverters.begin();
|
||||||
|
while (microinvertersIterator != this->microinverters.end()) {
|
||||||
|
microinvertersToSet.push_back(microinvertersIterator->serialNumber);
|
||||||
|
microinvertersIterator++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<long long>::iterator microinvertersToSetIterator = microinvertersToSet.begin();
|
||||||
|
while(microinvertersToSetIterator != microinvertersToSet.end()) {
|
||||||
|
std::pair<Microinverter *, bool> microinverterPair = this->getMicroinverterBySerialNumber(*microinvertersToSetIterator);
|
||||||
|
if(microinverterPair.second) {
|
||||||
|
microinverterPair.first->setStatusWholeMicroinverter(value, statusName);
|
||||||
|
}
|
||||||
|
microinvertersToSetIterator++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ void Microinverter::updateStatusParameters() {
|
||||||
int portsRead = 0;
|
int portsRead = 0;
|
||||||
while (portsRead < this->ports.size()) {
|
while (portsRead < this->ports.size()) {
|
||||||
int portsToRead = 0;
|
int portsToRead = 0;
|
||||||
while (portsToRead * 6 < (10 - 6) && (portsToRead + portsRead) < this->ports.size()) {
|
while (portsToRead * 6 < (128 - 6) && (portsToRead + portsRead) < this->ports.size()) {
|
||||||
portsToRead++;
|
portsToRead++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,6 +70,9 @@ void Microinverter::updateStatusParameters() {
|
||||||
this->age++;
|
this->age++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
this->age = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i{0}; i < portsToRead; i++) {
|
for (int i{0}; i < portsToRead; i++) {
|
||||||
this->ports.at(i + portsRead).setStatusesFromMicroinverterArray(registers, i * 6);
|
this->ports.at(i + portsRead).setStatusesFromMicroinverterArray(registers, i * 6);
|
||||||
|
|
@ -115,7 +118,22 @@ long long Microinverter::getTotalProduction() {
|
||||||
void Microinverter::setStatus(std::vector<std::pair<int, uint16_t>> portsToSet, std::string statusName) {
|
void Microinverter::setStatus(std::vector<std::pair<int, uint16_t>> portsToSet, std::string statusName) {
|
||||||
std::vector<std::pair<int, uint16_t>>::iterator portsToSetIterator = portsToSet.begin();
|
std::vector<std::pair<int, uint16_t>>::iterator portsToSetIterator = portsToSet.begin();
|
||||||
while(portsToSetIterator != portsToSet.end()) {
|
while(portsToSetIterator != portsToSet.end()) {
|
||||||
this->ports.at(portsToSetIterator->first).getStatusByName(statusName).first.get()->writeValue(portsToSetIterator->second, *this->modbus, this->ports.at(portsToSetIterator->first).statusPortStartAddress);
|
try {
|
||||||
|
if(this->ports.at(portsToSetIterator->first).getStatusByName(statusName).second) {
|
||||||
|
this->ports.at(portsToSetIterator->first).getStatusByName(statusName).first->writeValue(portsToSetIterator->second, *this->modbus, this->statusStartAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(const std::out_of_range& outOfRange) {
|
||||||
|
std::cerr << outOfRange.what() << std::endl;
|
||||||
|
}
|
||||||
portsToSetIterator++;
|
portsToSetIterator++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Microinverter::setStatusWholeMicroinverter(uint16_t value, std::string statusName) {
|
||||||
|
if(this->ports.begin() != this->ports.end()) {
|
||||||
|
if(this->ports.begin()->getStatusByName(statusName).second) {
|
||||||
|
this->ports.begin()->getStatusByName(statusName).first.get()->writeValue(value, *this->modbus, this->ports.begin()->statusPortStartAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -50,7 +50,6 @@ void Port::populateParameters() {
|
||||||
|
|
||||||
this->parameters.push_back(std::make_shared<PortParameterLinkStatus>());
|
this->parameters.push_back(std::make_shared<PortParameterLinkStatus>());
|
||||||
|
|
||||||
|
|
||||||
this->statusParameters.push_back(std::make_shared<PortParameterOnOff>());
|
this->statusParameters.push_back(std::make_shared<PortParameterOnOff>());
|
||||||
|
|
||||||
this->statusParameters.push_back(std::make_shared<PortParameterLimitActivePower>());
|
this->statusParameters.push_back(std::make_shared<PortParameterLimitActivePower>());
|
||||||
|
|
@ -199,6 +198,18 @@ void Port::printParameters(std::vector<std::string> ¶metersToGet, bool allPa
|
||||||
}
|
}
|
||||||
parametersToGetIterator++;
|
parametersToGetIterator++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<PortParameter>>::iterator statusesToGetIterator = this->statusParameters.begin();
|
||||||
|
while (statusesToGetIterator != this->statusParameters.end()) {
|
||||||
|
std::cout << " ";
|
||||||
|
if (shortNames) {
|
||||||
|
std::cout << statusesToGetIterator->get()->shortName;
|
||||||
|
} else {
|
||||||
|
std::cout << statusesToGetIterator->get()->name;
|
||||||
|
}
|
||||||
|
std::cout << ": " << statusesToGetIterator->get()->getOutputValue() << " |";
|
||||||
|
statusesToGetIterator++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Port::turnOff(class modbus &modbus) { this->getStatusByName("onOff").first.get()->writeValue(0, modbus, this->statusPortStartAddress); }
|
void Port::turnOff(class modbus &modbus) { this->getStatusByName("onOff").first.get()->writeValue(0, modbus, this->statusPortStartAddress); }
|
||||||
|
|
@ -206,8 +217,7 @@ void Port::turnOff(class modbus &modbus) { this->getStatusByName("onOff").first.
|
||||||
bool Port::isOff(class modbus &modbus) {
|
bool Port::isOff(class modbus &modbus) {
|
||||||
if (this->getStatusByName("onOff").first.get()->getValue().first.i == 1) {
|
if (this->getStatusByName("onOff").first.get()->getValue().first.i == 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,4 +48,4 @@ PortParameterLinkStatus::PortParameterLinkStatus() : PortParameterInt("linkStatu
|
||||||
|
|
||||||
PortParameterOnOff::PortParameterOnOff() : PortParameterInt("onOff", "of", "", true, true, 0x0000, 1) {}
|
PortParameterOnOff::PortParameterOnOff() : PortParameterInt("onOff", "of", "", true, true, 0x0000, 1) {}
|
||||||
|
|
||||||
PortParameterLimitActivePower::PortParameterLimitActivePower() : PortParameterInt("limitActivePower", "lAP", "", true, true, 0x0001, 1) {}
|
PortParameterLimitActivePower::PortParameterLimitActivePower() : PortParameterInt("limitActivePower", "lAP", "%", true, true, 0x0001, 1) {}
|
||||||
|
|
@ -29,7 +29,8 @@ std::pair<PortParameter::PortParameterValue, PortParameter::PortParameterValueTy
|
||||||
}
|
}
|
||||||
|
|
||||||
PortParameter& PortParameter::writeValue(uint16_t value, class modbus& modbus, int portStartAddress) {
|
PortParameter& PortParameter::writeValue(uint16_t value, class modbus& modbus, int portStartAddress) {
|
||||||
modbus.modbus_write_register(this->parameterAddressOffset + portStartAddress, value);
|
int writeCount;
|
||||||
|
writeCount = modbus.modbus_write_register(this->parameterAddressOffset + portStartAddress, value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
37
src/main.cpp
37
src/main.cpp
|
|
@ -47,9 +47,9 @@ int main(int argc, char **argv) {
|
||||||
std::string shortNamesHelp{"Print short parameter names"};
|
std::string shortNamesHelp{"Print short parameter names"};
|
||||||
hoymilesClient.add_flag<bool>("-s,--short", shortNames, shortNamesHelp)->group("Parameters");
|
hoymilesClient.add_flag<bool>("-s,--short", shortNames, shortNamesHelp)->group("Parameters");
|
||||||
|
|
||||||
std::vector<long long> microinvertersToGet{};
|
std::vector<long long> microinvertersToChoose{};
|
||||||
std::string microinvertersToGetHelp{"List of microinverters to fetch, delimited by ','; if omitted, all are fetched"};
|
std::string microinvertersToChooseHelp{"List of microinverters to work on, delimited by ','; if omitted, all are selected"};
|
||||||
hoymilesClient.add_option<std::vector<long long>>("-m,--microinverters", microinvertersToGet, microinvertersToGetHelp)->delimiter(',')->group("Microinverters");
|
hoymilesClient.add_option<std::vector<long long>>("-m,--microinverters", microinvertersToChoose, microinvertersToChooseHelp)->delimiter(',')->group("Microinverters");
|
||||||
|
|
||||||
bool microinvertersGetTodayProduction{false};
|
bool microinvertersGetTodayProduction{false};
|
||||||
std::string microinvertersGetTodayProductionHelp{"Show today production for microinverters"};
|
std::string microinvertersGetTodayProductionHelp{"Show today production for microinverters"};
|
||||||
|
|
@ -63,6 +63,18 @@ int main(int argc, char **argv) {
|
||||||
std::string ignoreNotConnectedHelp{"Ignore conn_error"};
|
std::string ignoreNotConnectedHelp{"Ignore conn_error"};
|
||||||
hoymilesClient.add_flag<bool>("-I,--ignore_conn_error", ignoreNotConnected, ignoreNotConnectedHelp)->group("Debug");
|
hoymilesClient.add_flag<bool>("-I,--ignore_conn_error", ignoreNotConnected, ignoreNotConnectedHelp)->group("Debug");
|
||||||
|
|
||||||
|
bool writeMode = false;
|
||||||
|
std::string writeModeHelp{"Write instead of read"};
|
||||||
|
hoymilesClient.add_flag<bool>("-w,--write", writeMode, writeModeHelp)->group("Write");
|
||||||
|
|
||||||
|
uint16_t writeValue;
|
||||||
|
std::string writeValueHelp{"Value to write"};
|
||||||
|
hoymilesClient.add_option<uint16_t>("-V,--value", writeValue, writeModeHelp)->group("Write")->needs(hoymilesClient.get_option("-w"));
|
||||||
|
|
||||||
|
std::string writeStatusName{};
|
||||||
|
std::string writeStatusNameHelp{"Status to write"};
|
||||||
|
hoymilesClient.add_option<std::string>("-S,--status", writeStatusName, writeStatusName)->group("Write")->needs(hoymilesClient.get_option("-w"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
hoymilesClient.parse(argc, argv);
|
hoymilesClient.parse(argc, argv);
|
||||||
} catch (const CLI::ParseError &e) {
|
} catch (const CLI::ParseError &e) {
|
||||||
|
|
@ -76,26 +88,33 @@ int main(int argc, char **argv) {
|
||||||
std::cout << "DTU construction time: " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms" << std::endl;
|
std::cout << "DTU construction time: " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms" << std::endl;
|
||||||
std::cout << std::endl << std::endl;
|
std::cout << std::endl << std::endl;
|
||||||
|
|
||||||
while ((dtu.isConnected() || ignoreNotConnected) && (!parametersToGet.empty() || allParameters)) {
|
while (!writeMode && ((dtu.isConnected() || ignoreNotConnected) && (!parametersToGet.empty() || allParameters))) {
|
||||||
time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||||
|
|
||||||
startTime = std::chrono::high_resolution_clock::now();
|
startTime = std::chrono::high_resolution_clock::now();
|
||||||
dtu.updateMicroinverters(parametersToGet, allParameters, microinvertersToGet);
|
dtu.updateMicroinverters(parametersToGet, allParameters, microinvertersToChoose);
|
||||||
endTime = std::chrono::high_resolution_clock::now();
|
endTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
std::cout << "Pass time: " << std::put_time(localtime(&now), "%F %T") << std::endl;
|
std::cout << "Pass time: " << std::put_time(localtime(&now), "%F %T") << std::endl;
|
||||||
std::cout << "DTU update time: " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms" << std::endl;
|
std::cout << "DTU update time: " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms" << std::endl;
|
||||||
|
|
||||||
dtu.printMicroinverters(parametersToGet, allParameters, microinvertersToGet, shortNames, microinvertersGetTodayProduction, microinvertersGetTotalProduction);
|
dtu.printMicroinverters(parametersToGet, allParameters, microinvertersToChoose, shortNames, microinvertersGetTodayProduction, microinvertersGetTotalProduction);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::vector<std::pair<int, uint16_t>> portsToLimitActivePower{std::pair<int, uint16_t>(0, 69), std::pair<int, uint16_t>(1, 38), std::pair<int, uint16_t>(3, 3)};
|
|
||||||
dtu.getMicroinverterBySerialNumber(138273312349).first->setStatus(portsToLimitActivePower, "limitActivePower");
|
|
||||||
}
|
}
|
||||||
// if(dtu.modbusError()) {
|
// if(dtu.modbusError()) {
|
||||||
// std::cerr << dtu.modbusErrorMessage() << std::endl;
|
// std::cerr << dtu.modbusErrorMessage() << std::endl;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
if(writeMode) {
|
||||||
|
std::cout << "Starting DTU write" << std::endl;
|
||||||
|
|
||||||
|
startTime = std::chrono::high_resolution_clock::now();
|
||||||
|
dtu.setStatusMicroinverters(writeValue, writeStatusName, microinvertersToChoose);
|
||||||
|
endTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
std::cout << "DTU write time: " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue