aboutsummaryrefslogtreecommitdiff
path: root/src/p18
diff options
context:
space:
mode:
Diffstat (limited to 'src/p18')
-rw-r--r--src/p18/client.cc229
-rw-r--r--src/p18/client.h31
-rw-r--r--src/p18/commands.cc457
-rw-r--r--src/p18/commands.h35
-rw-r--r--src/p18/defines.cc262
-rw-r--r--src/p18/defines.h32
-rw-r--r--src/p18/exceptions.h22
-rw-r--r--src/p18/functions.cc12
-rw-r--r--src/p18/functions.h12
-rw-r--r--src/p18/response.cc815
-rw-r--r--src/p18/response.h511
-rw-r--r--src/p18/types.h174
12 files changed, 0 insertions, 2592 deletions
diff --git a/src/p18/client.cc b/src/p18/client.cc
deleted file mode 100644
index 1798be9..0000000
--- a/src/p18/client.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#include <memory>
-#include <utility>
-#include <sstream>
-#include <iomanip>
-#include <cmath>
-#include <stdexcept>
-
-#include "client.h"
-#include "types.h"
-#include "defines.h"
-#include "exceptions.h"
-#include "response.h"
-#include "../voltronic/crc.h"
-
-#define MKRESPONSE(type) std::shared_ptr<response_type::BaseResponse>(new response_type::type(raw, rawSize))
-
-#define RESPONSE_CASE(type) \
- case CommandType::Get ## type: \
- response = MKRESPONSE(type); \
- break; \
-
-
-namespace p18 {
-
-void Client::setDevice(std::shared_ptr<voltronic::Device> device) {
- device_ = std::move(device);
-}
-
-std::shared_ptr<response_type::BaseResponse> Client::execute(p18::CommandType commandType, std::vector<std::string>& arguments) {
- std::ostringstream buf;
- buf << std::setfill('0');
-
- int iCommandType = static_cast<int>(commandType);
- bool isSetCommand = iCommandType >= 100;
-
- auto pos = raw_commands.find(commandType);
- if (pos == raw_commands.end())
- throw std::runtime_error("packedCommand " + std::to_string(iCommandType) + " not found");
-
- std::string packedCommand = pos->second;
- std::string packedArguments = packArguments(commandType, arguments);
-
- size_t len = sizeof(voltronic::CRC) + 1 + packedCommand.size() + packedArguments.size();
-
- buf << "^";
- buf << (isSetCommand ? "S" : "P");
- buf << std::setw(3) << len;
- buf << packedCommand;
- buf << packedArguments;
-
- std::string packed = buf.str();
-
- auto result = runOnDevice(packed);
- std::shared_ptr<response_type::BaseResponse> response;
-
- const auto raw = result.first;
- const auto rawSize = result.second;
-
- switch (commandType) {
- RESPONSE_CASE(ProtocolID)
- RESPONSE_CASE(CurrentTime)
- RESPONSE_CASE(TotalGenerated)
- RESPONSE_CASE(YearGenerated)
- RESPONSE_CASE(MonthGenerated)
- RESPONSE_CASE(DayGenerated)
- RESPONSE_CASE(SeriesNumber)
- RESPONSE_CASE(CPUVersion)
- RESPONSE_CASE(RatedInformation)
- RESPONSE_CASE(GeneralStatus)
- RESPONSE_CASE(WorkingMode)
- RESPONSE_CASE(FaultsAndWarnings)
- RESPONSE_CASE(FlagsAndStatuses)
- RESPONSE_CASE(Defaults)
- RESPONSE_CASE(AllowedChargingCurrents)
- RESPONSE_CASE(AllowedACChargingCurrents)
- RESPONSE_CASE(ParallelRatedInformation)
- RESPONSE_CASE(ParallelGeneralStatus)
- RESPONSE_CASE(ACChargingTimeBucket)
- RESPONSE_CASE(ACLoadsSupplyTimeBucket)
-
- case CommandType::SetLoads:
- case CommandType::SetFlag:
- case CommandType::SetDefaults:
- case CommandType::SetBatteryMaxChargingCurrent:
- case CommandType::SetBatteryMaxACChargingCurrent:
- case CommandType::SetACOutputFreq:
- case CommandType::SetBatteryMaxChargingVoltage:
- case CommandType::SetACOutputRatedVoltage:
- case CommandType::SetOutputSourcePriority:
- case CommandType::SetBatteryChargingThresholds:
- case CommandType::SetChargingSourcePriority:
- case CommandType::SetSolarPowerPriority:
- case CommandType::SetACInputVoltageRange:
- case CommandType::SetBatteryType:
- case CommandType::SetOutputModel:
- case CommandType::SetBatteryCutOffVoltage:
- case CommandType::SetSolarConfig:
- case CommandType::ClearGenerated:
- case CommandType::SetDateTime:
- case CommandType::SetACChargingTimeBucket:
- case CommandType::SetACLoadsSupplyTimeBucket:
- response = MKRESPONSE(SetResponse);
- break;
- }
-
- if (!response->validate())
- throw InvalidResponseError("validate() failed");
-
- response->unpack();
- return std::move(response);
-}
-
-std::pair<std::shared_ptr<char>, size_t> Client::runOnDevice(std::string& raw) {
- size_t bufSize = 256;
- std::shared_ptr<char> buf(new char[bufSize]);
- size_t responseSize = device_->run(
- (const u8*)raw.c_str(), raw.size(),
- (u8*)buf.get(), bufSize);
-
- return std::pair<std::shared_ptr<char>, size_t>(buf, responseSize);
-}
-
-std::string Client::packArguments(p18::CommandType commandType, std::vector<std::string>& arguments) {
- std::ostringstream buf;
- buf << std::setfill('0');
-
- switch (commandType) {
- case CommandType::GetYearGenerated:
- case CommandType::SetOutputSourcePriority:
- case CommandType::SetSolarPowerPriority:
- case CommandType::SetACInputVoltageRange:
- case CommandType::SetBatteryType:
- case CommandType::SetLoads:
- buf << arguments[0];
- break;
-
- case CommandType::GetMonthGenerated:
- case CommandType::GetDayGenerated:
- buf << arguments[0];
- for (int i = 1; i <= (commandType == CommandType::GetMonthGenerated ? 1 : 2); i++)
- buf << std::setw(2) << std::stoi(arguments[i]);
- break;
-
- case CommandType::GetParallelGeneralStatus:
- case CommandType::GetParallelRatedInformation:
- buf << std::stoi(arguments[0]);
- break;
-
- case CommandType::SetFlag:
- buf << (arguments[1] == "1" ? "E" : "D");
- buf << arguments[0];
- break;
-
- case CommandType::SetBatteryMaxChargingCurrent:
- case CommandType::SetBatteryMaxACChargingCurrent:
- buf << arguments[0] << ",";
- buf << std::setw(3) << std::stoi(arguments[1]);
- break;
-
- case CommandType::SetACOutputFreq:
- buf << std::setw(2) << std::stoi(arguments[0]);
- break;
-
- case CommandType::SetBatteryMaxChargingVoltage:
- case CommandType::SetBatteryChargingThresholds: {
- for (int i = 0; i < 2; i++) {
- double val = std::stod(arguments[i]);
- buf << std::setw(3) << (int)round(val*10);
- if (i == 0)
- buf << ",";
- }
- break;
- }
-
- case CommandType::SetACOutputRatedVoltage: {
- buf << std::setw(4) << (std::stoi(arguments[0])*10);
- break;
- }
-
- case CommandType::SetChargingSourcePriority:
- case CommandType::SetOutputModel:
- buf << arguments[0] << "," << arguments[1];
- break;
-
- case CommandType::SetBatteryCutOffVoltage: {
- double v = std::stod(arguments[0]);
- buf << std::setw(3) << ((int)round(v*10));
- break;
- }
-
- case CommandType::SetSolarConfig: {
- size_t len = arguments[0].size();
- buf << std::setw(2) << len << arguments[0];
- if (len < 20) {
- for (int i = 0; i < 20-len; i++)
- buf << "0";
- }
- break;
- }
-
- case CommandType::SetDateTime: {
- for (int i = 0; i < 6; i++) {
- int val = std::stoi(arguments[i]);
- if (i == 0)
- val -= 2000;
- buf << std::setw(2) << val;
- }
- break;
- }
-
- case CommandType::SetACChargingTimeBucket:
- case CommandType::SetACLoadsSupplyTimeBucket:
- for (int i = 0; i < 4; i++) {
- buf << std::setw(2) << std::stoi(arguments[i]);
- if (i == 1)
- buf << ",";
- }
- break;
-
- default:
- break;
- }
-
- return buf.str();
-}
-
-} \ No newline at end of file
diff --git a/src/p18/client.h b/src/p18/client.h
deleted file mode 100644
index 8307bbb..0000000
--- a/src/p18/client.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef INVERTER_TOOLS_P18_CLIENT_H_
-#define INVERTER_TOOLS_P18_CLIENT_H_
-
-#include "../voltronic/device.h"
-#include "types.h"
-#include "response.h"
-
-#include <memory>
-#include <vector>
-#include <string>
-
-
-namespace p18 {
-
-class Client {
-private:
- std::shared_ptr<voltronic::Device> device_;
- static std::string packArguments(p18::CommandType commandType, std::vector<std::string>& arguments);
-
-public:
- void setDevice(std::shared_ptr<voltronic::Device> device);
- std::shared_ptr<response_type::BaseResponse> execute(p18::CommandType commandType, std::vector<std::string>& arguments);
- std::pair<std::shared_ptr<char>, size_t> runOnDevice(std::string& raw);
-};
-
-}
-
-
-#endif //INVERTER_TOOLS_P18_CLIENT_H_
diff --git a/src/p18/commands.cc b/src/p18/commands.cc
deleted file mode 100644
index 5060d49..0000000
--- a/src/p18/commands.cc
+++ /dev/null
@@ -1,457 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#include <stdexcept>
-#include <sstream>
-#include <vector>
-#include <string>
-
-#ifdef INVERTERCTL
-#include <getopt.h>
-#endif
-
-#include "commands.h"
-#include "defines.h"
-#include "functions.h"
-#include "../util.h"
-#include "../logging.h"
-
-namespace p18 {
-
-const std::map<std::string, p18::CommandType> client_commands = {
- {"get-protocol-id", p18::CommandType::GetProtocolID},
- {"get-date-time", p18::CommandType::GetCurrentTime},
- {"get-total-generated", p18::CommandType::GetTotalGenerated},
- {"get-year-generated", p18::CommandType::GetYearGenerated},
- {"get-month-generated", p18::CommandType::GetMonthGenerated},
- {"get-day-generated", p18::CommandType::GetDayGenerated},
- {"get-series-number", p18::CommandType::GetSeriesNumber},
- {"get-cpu-version", p18::CommandType::GetCPUVersion},
- {"get-rated", p18::CommandType::GetRatedInformation},
- {"get-status", p18::CommandType::GetGeneralStatus},
- {"get-mode", p18::CommandType::GetWorkingMode},
- {"get-errors", p18::CommandType::GetFaultsAndWarnings},
- {"get-flags", p18::CommandType::GetFlagsAndStatuses},
- {"get-rated-defaults", p18::CommandType::GetDefaults},
- {"get-allowed-charging-currents", p18::CommandType::GetAllowedChargingCurrents},
- {"get-allowed-ac-charging-currents", p18::CommandType::GetAllowedACChargingCurrents},
- {"get-p-rated", p18::CommandType::GetParallelRatedInformation},
- {"get-p-status", p18::CommandType::GetParallelGeneralStatus},
- {"get-ac-charging-time", p18::CommandType::GetACChargingTimeBucket},
- {"get-ac-loads-supply-time", p18::CommandType::GetACLoadsSupplyTimeBucket},
- {"set-loads-supply", p18::CommandType::SetLoads},
- {"set-flag", p18::CommandType::SetFlag},
- {"set-rated-defaults", p18::CommandType::SetDefaults},
- {"set-max-charging-current", p18::CommandType::SetBatteryMaxChargingCurrent},
- {"set-max-ac-charging-current", p18::CommandType::SetBatteryMaxACChargingCurrent},
- {"set-ac-output-freq", p18::CommandType::SetACOutputFreq},
- {"set-max-charging-voltage", p18::CommandType::SetBatteryMaxChargingVoltage},
- {"set-ac-output-voltage", p18::CommandType::SetACOutputRatedVoltage},
- {"set-output-source-priority", p18::CommandType::SetOutputSourcePriority},
- {"set-charging-thresholds", p18::CommandType::SetBatteryChargingThresholds}, /* Battery re-charging and re-discharging voltage when utility is available */
- {"set-charging-source-priority", p18::CommandType::SetChargingSourcePriority},
- {"set-solar-power-priority", p18::CommandType::SetSolarPowerPriority},
- {"set-ac-input-voltage-range", p18::CommandType::SetACInputVoltageRange},
- {"set-battery-type", p18::CommandType::SetBatteryType},
- {"set-output-model", p18::CommandType::SetOutputModel},
- {"set-battery-cut-off-voltage", p18::CommandType::SetBatteryCutOffVoltage},
- {"set-solar-configuration", p18::CommandType::SetSolarConfig},
- {"clear-generated-data", p18::CommandType::ClearGenerated},
- {"set-date-time", p18::CommandType::SetDateTime},
- {"set-ac-charging-time", p18::CommandType::SetACChargingTimeBucket},
- {"set-ac-loads-supply-time", p18::CommandType::SetACLoadsSupplyTimeBucket},
-};
-
-static void validate_date_args(const std::string* ys, const std::string* ms, const std::string* ds) {
- static const std::string err_year = "invalid year";
- static const std::string err_month = "invalid month";
- static const std::string err_day = "invalid day";
-
- int y, m = 0, d = 0;
-
- // validate year
- if (!is_numeric(*ys) || ys->size() != 4)
- throw std::invalid_argument(err_year);
-
- y = std::stoi(*ys);
- if (y < 2000 || y > 2099)
- throw std::invalid_argument(err_year);
-
- // validate month
- if (ms != nullptr) {
- if (!is_numeric(*ms) || ms->size() > 2)
- throw std::invalid_argument(err_month);
-
- m = std::stoi(*ms);
- if (m < 1 || m > 12)
- throw std::invalid_argument(err_month);
- }
-
- // validate day
- if (ds != nullptr) {
- if (!is_numeric(*ds) || ds->size() > 2)
- throw std::invalid_argument(err_day);
-
- d = std::stoi(*ds);
- if (d < 1 || d > 31)
- throw std::invalid_argument(err_day);
- }
-
- if (y != 0 && m != 0 && d != 0) {
- if (!is_date_valid(y, m, d))
- throw std::invalid_argument("invalid date");
- }
-}
-
-static void validate_time_args(const std::string* hs, const std::string* ms, const std::string* ss) {
- static const std::string err_hour = "invalid hour";
- static const std::string err_minute = "invalid minute";
- static const std::string err_second = "invalid second";
-
- unsigned h, m, s;
-
- if (!is_numeric(*hs) || hs->size() > 2)
- throw std::invalid_argument(err_hour);
-
- h = static_cast<unsigned>(std::stoul(*hs));
- if (h > 23)
- throw std::invalid_argument(err_hour);
-
- if (!is_numeric(*ms) || ms->size() > 2)
- throw std::invalid_argument(err_minute);
-
- m = static_cast<unsigned>(std::stoul(*ms));
- if (m > 59)
- throw std::invalid_argument(err_minute);
-
- if (!is_numeric(*ss) || ss->size() > 2)
- throw std::invalid_argument(err_second);
-
- s = static_cast<unsigned>(std::stoul(*ss));
- if (s > 59)
- throw std::invalid_argument(err_second);
-}
-
-
-#define GET_ARGS(__len__) get_args((CommandInput*)input, arguments, (__len__))
-
-#ifdef INVERTERCTL
-static void get_args(CommandInput* input,
- std::vector<std::string>& arguments,
- size_t count) {
- for (size_t i = 0; i < count; i++) {
- if (optind < input->argc && *input->argv[optind] != '-')
- arguments.emplace_back(input->argv[optind++]);
- else {
- std::ostringstream error;
- error << "this command requires " << count << " argument";
- if (count > 1)
- error << "s";
- throw std::invalid_argument(error.str());
- }
- }
-}
-#endif
-
-#ifdef INVERTERD
-static void get_args(CommandInput* input,
- std::vector<std::string>& arguments,
- size_t count) {
- if (input->argv->size() < count) {
- std::ostringstream error;
- error << "this command requires " << count << " argument";
- if (count > 1)
- error << "s";
- throw std::invalid_argument(error.str());
- }
-
- for (size_t i = 0; i < count; i++)
- arguments.emplace_back((*input->argv)[i]);
-}
-#endif
-
-p18::CommandType validate_input(std::string& command,
- std::vector<std::string>& arguments,
- void* input) {
- auto it = p18::client_commands.find(command);
- if (it == p18::client_commands.end())
- throw std::invalid_argument("invalid command");
-
- auto commandType = it->second;
- switch (commandType) {
- case p18::CommandType::GetYearGenerated:
- GET_ARGS(1);
- validate_date_args(&arguments[0], nullptr, nullptr);
- break;
-
- case p18::CommandType::GetMonthGenerated:
- GET_ARGS(2);
- validate_date_args(&arguments[0], &arguments[1], nullptr);
- break;
-
- case p18::CommandType::GetDayGenerated:
- GET_ARGS(3);
- validate_date_args(&arguments[0], &arguments[1], &arguments[2]);
- break;
-
- case p18::CommandType::GetParallelRatedInformation:
- case p18::CommandType::GetParallelGeneralStatus:
- GET_ARGS(1);
- if (!is_numeric(arguments[0]) || arguments[0].size() > 1)
- throw std::invalid_argument("invalid argument");
- break;
-
- case p18::CommandType::SetLoads: {
- GET_ARGS(1);
- std::string &arg = arguments[0];
- if (arg != "0" && arg != "1")
- throw std::invalid_argument("invalid argument, only 0 or 1 allowed");
- break;
- }
-
- case p18::CommandType::SetFlag: {
- GET_ARGS(2);
-
- bool match_found = false;
- for (auto const& item: p18::flags) {
- if (arguments[0] == item.flag) {
- arguments[0] = item.letter;
- match_found = true;
- break;
- }
- }
-
- if (!match_found)
- throw std::invalid_argument("invalid flag");
-
- if (arguments[1] != "0" && arguments[1] != "1")
- throw std::invalid_argument("invalid flag state, only 0 or 1 allowed");
-
- break;
- }
-
- case p18::CommandType::SetBatteryMaxChargingCurrent:
- case p18::CommandType::SetBatteryMaxACChargingCurrent: {
- GET_ARGS(2);
-
- auto id = static_cast<unsigned>(std::stoul(arguments[0]));
- auto amps = static_cast<unsigned>(std::stoul(arguments[1]));
-
- if (!p18::is_valid_parallel_id(id))
- throw std::invalid_argument("invalid id");
-
- // 3 characters max
- if (amps > 999)
- throw std::invalid_argument("invalid amps");
-
- break;
- }
-
- case p18::CommandType::SetACOutputFreq: {
- GET_ARGS(1);
- std::string &freq = arguments[0];
- if (freq != "50" && freq != "60")
- throw std::invalid_argument("invalid frequency, only 50 or 60 allowed");
- break;
- }
-
- case p18::CommandType::SetBatteryMaxChargingVoltage: {
- GET_ARGS(2);
-
- float cv = std::stof(arguments[0]);
- float fv = std::stof(arguments[1]);
-
- if (cv < 48.0 || cv > 58.4)
- throw std::invalid_argument("invalid CV");
-
- if (fv < 48.0 || fv > 58.4)
- throw std::invalid_argument("invalid FV");
-
- break;
- }
-
- case p18::CommandType::SetACOutputRatedVoltage: {
- GET_ARGS(1);
-
- auto v = static_cast<unsigned>(std::stoul(arguments[0]));
-
- bool matchFound = false;
- for (const auto &item: p18::ac_output_rated_voltages) {
- if (v == item) {
- matchFound = true;
- break;
- }
- }
-
- if (!matchFound)
- throw std::invalid_argument("invalid voltage");
-
- break;
- }
-
- case p18::CommandType::SetOutputSourcePriority: {
- GET_ARGS(1);
-
- std::array<std::string, 2> priorities({"SUB", "SBU"});
-
- long index = index_of(priorities, arguments[0]);
- if (index == -1)
- throw std::invalid_argument("invalid argument");
-
- arguments[0] = std::to_string(index);
- break;
- }
-
- case p18::CommandType::SetBatteryChargingThresholds: {
- GET_ARGS(2);
-
- float cv = std::stof(arguments[0]);
- float dv = std::stof(arguments[1]);
-
- if (index_of(p18::bat_ac_recharging_voltages_12v, cv) == -1 &&
- index_of(p18::bat_ac_recharging_voltages_24v, cv) == -1 &&
- index_of(p18::bat_ac_recharging_voltages_48v, cv) == -1)
- throw std::invalid_argument("invalid CV");
-
- if (index_of(p18::bat_ac_redischarging_voltages_12v, dv) == -1 &&
- index_of(p18::bat_ac_redischarging_voltages_24v, dv) == -1 &&
- index_of(p18::bat_ac_redischarging_voltages_48v, dv) == -1)
- throw std::invalid_argument("invalid DV");
-
- break;
- }
-
- case p18::CommandType::SetChargingSourcePriority: {
- GET_ARGS(2);
-
- auto id = static_cast<unsigned>(std::stoul(arguments[0]));
- if (!p18::is_valid_parallel_id(id))
- throw std::invalid_argument("invalid id");
-
- std::array<std::string, 3> priorities({"SF", "SU", "S"});
- long index = index_of(priorities, arguments[1]);
- if (index == -1)
- throw std::invalid_argument("invalid argument");
-
- arguments[1] = std::to_string(index);
- break;
- }
-
- case p18::CommandType::SetSolarPowerPriority: {
- GET_ARGS(1);
-
- std::array<std::string, 2> allowed({"BLU", "LBU"});
- long index = index_of(allowed, arguments[0]);
- if (index == -1)
- throw std::invalid_argument("invalid priority");
-
- arguments[0] = std::to_string(index);
- break;
- }
-
- case p18::CommandType::SetACInputVoltageRange: {
- GET_ARGS(1);
- std::array<std::string, 2> allowed({"APPLIANCE", "UPS"});
- long index = index_of(allowed, arguments[0]);
- if (index == -1)
- throw std::invalid_argument("invalid argument");
- arguments[0] = std::to_string(index);
- break;
- }
-
- case p18::CommandType::SetBatteryType: {
- GET_ARGS(1);
-
- std::array<std::string, 3> allowed({"AGM", "FLOODED", "USER"});
- long index = index_of(allowed, arguments[0]);
- if (index == -1)
- throw std::invalid_argument("invalid type");
- arguments[0] = std::to_string(index);
-
- break;
- }
-
- case p18::CommandType::SetOutputModel: {
- GET_ARGS(2);
-
- auto id = static_cast<unsigned>(std::stoul(arguments[0]));
- if (!p18::is_valid_parallel_id(id))
- throw std::invalid_argument("invalid id");
-
- std::array<std::string, 5> allowed({"SM", "P", "P1", "P2", "P3"});
- long index = index_of(allowed, arguments[1]);
- if (index == -1)
- throw std::invalid_argument("invalid model");
- arguments[1] = std::to_string(index);
-
- break;
- }
-
- case p18::CommandType::SetBatteryCutOffVoltage: {
- GET_ARGS(1);
-
- float v = std::stof(arguments[0]);
- if (v < 40.0 || v > 48.0)
- throw std::invalid_argument("invalid voltage");
-
- break;
- }
-
- case p18::CommandType::SetSolarConfig: {
- GET_ARGS(1);
-
- if (!is_numeric(arguments[0]) || arguments[0].size() > 20)
- throw std::invalid_argument("invalid argument");
-
- break;
- }
-
- case p18::CommandType::SetDateTime: {
- GET_ARGS(6);
-
- validate_date_args(&arguments[0], &arguments[1], &arguments[2]);
- validate_time_args(&arguments[3], &arguments[4], &arguments[5]);
-
- break;
- }
-
- case p18::CommandType::SetACChargingTimeBucket:
- case p18::CommandType::SetACLoadsSupplyTimeBucket: {
- GET_ARGS(2);
-
- std::vector<std::string> start = split(arguments[0], ':');
- if (start.size() != 2)
- throw std::invalid_argument("invalid start time");
-
- std::vector<std::string> end = split(arguments[1], ':');
- if (end.size() != 2)
- throw std::invalid_argument("invalid end time");
-
- auto startHour = static_cast<unsigned short>(std::stoul(start[0]));
- auto startMinute = static_cast<unsigned short>(std::stoul(start[1]));
- if (startHour > 23 || startMinute > 59)
- throw std::invalid_argument("invalid start time");
-
- auto endHour = static_cast<unsigned short>(std::stoul(end[0]));
- auto endMinute = static_cast<unsigned short>(std::stoul(end[1]));
- if (endHour > 23 || endMinute > 59)
- throw std::invalid_argument("invalid end time");
-
- arguments.clear();
-
- arguments.emplace_back(std::to_string(startHour));
- arguments.emplace_back(std::to_string(startMinute));
-
- arguments.emplace_back(std::to_string(endHour));
- arguments.emplace_back(std::to_string(endMinute));
-
- break;
- }
-
- default:
- break;
- }
-
- return commandType;
-}
-
-} \ No newline at end of file
diff --git a/src/p18/commands.h b/src/p18/commands.h
deleted file mode 100644
index 0b597e9..0000000
--- a/src/p18/commands.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef INVERTER_TOOLS_P18_COMMANDS_H
-#define INVERTER_TOOLS_P18_COMMANDS_H
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "types.h"
-
-namespace p18 {
-
-#ifdef INVERTERCTL
-struct CommandInput {
- int argc;
- char** argv;
-};
-#endif
-
-#ifdef INVERTERD
-struct CommandInput {
- std::vector<std::string>* argv;
-};
-#endif
-
-extern const std::map<std::string, p18::CommandType> client_commands;
-
-static void validate_date_args(const std::string* ys, const std::string* ms, const std::string* ds);
-static void validate_time_args(const std::string* hs, const std::string* ms, const std::string* ss);
-CommandType validate_input(std::string& command, std::vector<std::string>& arguments, void* input);
-
-}
-
-#endif //INVERTER_TOOLS_P18_COMMANDS_H
diff --git a/src/p18/defines.cc b/src/p18/defines.cc
deleted file mode 100644
index 999f81a..0000000
--- a/src/p18/defines.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#include <iostream>
-
-#include "defines.h"
-#include "types.h"
-
-namespace p18 {
-
-const std::map<CommandType, std::string> raw_commands = {
- {CommandType::GetProtocolID, "PI"},
- {CommandType::GetCurrentTime, "T"},
- {CommandType::GetTotalGenerated, "ET"},
- {CommandType::GetYearGenerated, "EY"},
- {CommandType::GetMonthGenerated, "EM"},
- {CommandType::GetDayGenerated, "ED"},
- {CommandType::GetSeriesNumber, "ID"},
- {CommandType::GetCPUVersion, "VFW"},
- {CommandType::GetRatedInformation, "PIRI"},
- {CommandType::GetGeneralStatus, "GS"},
- {CommandType::GetWorkingMode, "MOD"},
- {CommandType::GetFaultsAndWarnings, "FWS"},
- {CommandType::GetFlagsAndStatuses, "FLAG"},
- {CommandType::GetDefaults, "DI"},
- {CommandType::GetAllowedChargingCurrents, "MCHGCR"},
- {CommandType::GetAllowedACChargingCurrents, "MUCHGCR"},
- {CommandType::GetParallelRatedInformation, "PRI"},
- {CommandType::GetParallelGeneralStatus, "PGS"},
- {CommandType::GetACChargingTimeBucket, "ACCT"},
- {CommandType::GetACLoadsSupplyTimeBucket, "ACLT"},
- {CommandType::SetLoads, "LON"},
- {CommandType::SetFlag, "P"},
- {CommandType::SetDefaults, "PF"},
- {CommandType::SetBatteryMaxChargingCurrent, "MCHGC"},
- {CommandType::SetBatteryMaxACChargingCurrent, "MUCHGC"},
- /* The protocol documentation defines two commands, "F50" and "F60",
- but it's identical as if there were just one "F" command with an argument. */
- {CommandType::SetACOutputFreq, "F"},
- {CommandType::SetBatteryMaxChargingVoltage, "MCHGV"},
- {CommandType::SetACOutputRatedVoltage, "V"},
- {CommandType::SetOutputSourcePriority, "POP"},
- {CommandType::SetBatteryChargingThresholds, "BUCD"},
- {CommandType::SetChargingSourcePriority, "PCP"},
- {CommandType::SetSolarPowerPriority, "PSP"},
- {CommandType::SetACInputVoltageRange, "PGR"},
- {CommandType::SetBatteryType, "PBT"},
- {CommandType::SetOutputModel, "POPM"},
- {CommandType::SetBatteryCutOffVoltage, "PSDV"},
- {CommandType::SetSolarConfig, "ID"},
- {CommandType::ClearGenerated, "CLE"},
- {CommandType::SetDateTime, "DAT"},
- {CommandType::SetACChargingTimeBucket, "ACCT"},
- {CommandType::SetACLoadsSupplyTimeBucket, "ACLT"},
-};
-
-const std::array<int, 5> ac_output_rated_voltages = {202, 208, 220, 230, 240};
-
-const std::array<float, 8> bat_ac_recharging_voltages_12v = {11, 11.3, 11.5, 11.8, 12, 12.3, 12.5, 12.8};
-const std::array<float, 8> bat_ac_recharging_voltages_24v = {22, 22.5, 23, 23.5, 24, 24.5, 25, 25.5};
-const std::array<float, 8> bat_ac_recharging_voltages_48v = {44, 45, 46, 47, 48, 49, 50, 51};
-
-const std::array<float, 12> bat_ac_redischarging_voltages_12v = {0, 12, 12.3, 12.5, 12.8, 13, 13.3, 13.5, 13.8, 14, 14.3, 14.5};
-const std::array<float, 12> bat_ac_redischarging_voltages_24v = {0, 24, 24.5, 25, 25.5, 26, 26.5, 27, 27.5, 28, 28.5, 29};
-const std::array<float, 12> bat_ac_redischarging_voltages_48v = {0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58};
-
-const std::map<int, std::string> fault_codes = {
- {1, "Fan is locked"},
- {2, "Over temperature"},
- {3, "Battery voltage is too high"},
- {4, "Battery voltage is too low"},
- {5, "Output short circuited or Over temperature"},
- {6, "Output voltage is too high"},
- {7, "Over load time out"},
- {8, "Bus voltage is too high"},
- {9, "Bus soft start failed"},
- {11, "Main relay failed"},
- {51, "Over current inverter"},
- {52, "Bus soft start failed"},
- {53, "Inverter soft start failed"},
- {54, "Self-test failed"},
- {55, "Over DC voltage on output of inverter"},
- {56, "Battery connection is open"},
- {57, "Current sensor failed"},
- {58, "Output voltage is too low"},
- {60, "Inverter negative power"},
- {71, "Parallel version different"},
- {72, "Output circuit failed"},
- {80, "CAN communication failed"},
- {81, "Parallel host line lost"},
- {82, "Parallel synchronized signal lost"},
- {83, "Parallel battery voltage detect different"},
- {84, "Parallel LINE voltage or frequency detect different"},
- {85, "Parallel LINE input current unbalanced"},
- {86, "Parallel output setting different"},
-};
-
-const std::array<Flag, 9> flags = {{
- {"BUZZ", 'A', "Silence buzzer or open buzzer"},
- {"OLBP", 'B', "Overload bypass function"},
- {"LCDE", 'C', "LCD display escape to default page after 1min timeout"},
- {"OLRS", 'D', "Overload restart"},
- {"OTRS", 'E', "Overload temperature restart"},
- {"BLON", 'F', "Backlight on"},
- {"ALRM", 'G', "Alarm on primary source interrupt"},
- {"FTCR", 'H', "Fault code record"},
- {"MTYP", 'I', "Machine type (1=Grid-Tie, 0=Off-Grid-Tie)"},
-}};
-
-ENUM_STR(BatteryType) {
- switch (val) {
- case BatteryType::AGM: return os << "AGM" ;
- case BatteryType::Flooded: return os << "Flooded";
- case BatteryType::User: return os << "User";
- };
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(InputVoltageRange) {
- switch (val) {
- case InputVoltageRange::Appliance: return os << "Appliance";
- case InputVoltageRange::USP: return os << "USP";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(OutputSourcePriority) {
- switch (val) {
- case OutputSourcePriority::SolarUtilityBattery:
- return os << "Solar-Utility-Battery";
- case OutputSourcePriority::SolarBatteryUtility:
- return os << "Solar-Battery-Utility";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(ChargerSourcePriority) {
- switch (val) {
- case ChargerSourcePriority::SolarFirst:
- return os << "Solar-First";
- case ChargerSourcePriority::SolarAndUtility:
- return os << "Solar-and-Utility";
- case ChargerSourcePriority::SolarOnly:
- return os << "Solar-only";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(MachineType) {
- switch (val) {
- case MachineType::OffGridTie: return os << "Off-Grid-Tie";
- case MachineType::GridTie: return os << "Grid-Tie";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(Topology) {
- switch (val) {
- case Topology::TransformerLess: return os << "Transformer-less";
- case Topology::Transformer: return os << "Transformer";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(OutputModelSetting) {
- switch (val) {
- case OutputModelSetting::SingleModule:
- return os << "Single module";
- case OutputModelSetting::ParallelOutput:
- return os << "Parallel output";
- case OutputModelSetting::Phase1OfThreePhaseOutput:
- return os << "Phase 1 of three phase output";
- case OutputModelSetting::Phase2OfThreePhaseOutput:
- return os << "Phase 2 of three phase output";
- case OutputModelSetting::Phase3OfThreePhaseOutput:
- return os << "Phase 3 of three phase";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(SolarPowerPriority) {
- switch (val) {
- case SolarPowerPriority::BatteryLoadUtility:
- return os << "Battery-Load-Utility";
- case SolarPowerPriority::LoadBatteryUtility:
- return os << "Load-Battery-Utility";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(MPPTChargerStatus) {
- switch (val) {
- case MPPTChargerStatus::Abnormal: return os << "Abnormal";
- case MPPTChargerStatus::NotCharging: return os << "Not charging";
- case MPPTChargerStatus::Charging: return os << "Charging";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(BatteryPowerDirection) {
- switch (val) {
- case BatteryPowerDirection::DoNothing: return os << "Do nothing";
- case BatteryPowerDirection::Charge: return os << "Charge";
- case BatteryPowerDirection::Discharge: return os << "Discharge";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(DC_AC_PowerDirection) {
- switch (val) {
- case DC_AC_PowerDirection::DoNothing: return os << "Do nothing";
- case DC_AC_PowerDirection::AC_DC: return os << "AC/DC";
- case DC_AC_PowerDirection::DC_AC: return os << "DC/AC";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(LinePowerDirection) {
- switch (val) {
- case LinePowerDirection::DoNothing: return os << "Do nothing";
- case LinePowerDirection::Input: return os << "Input";
- case LinePowerDirection::Output: return os << "Output";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(WorkingMode) {
- switch (val) {
- case WorkingMode::PowerOnMode: return os << "Power on mode";
- case WorkingMode::StandbyMode: return os << "Standby mode";
- case WorkingMode::BypassMode: return os << "Bypass mode";
- case WorkingMode::BatteryMode: return os << "Battery mode";
- case WorkingMode::FaultMode: return os << "Fault mode";
- case WorkingMode::HybridMode: return os << "Hybrid mode";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(ParallelConnectionStatus) {
- switch (val) {
- case ParallelConnectionStatus::NotExistent: return os << "Non-existent";
- case ParallelConnectionStatus::Existent: return os << "Existent";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(LoadConnectionStatus) {
- switch (val) {
- case LoadConnectionStatus::Disconnected: return os << "Disconnected";
- case LoadConnectionStatus::Connected: return os << "Connected";
- }
- ENUM_STR_DEFAULT;
-}
-
-ENUM_STR(ConfigurationStatus) {
- switch (val) {
- case ConfigurationStatus::Default: return os << "Default";
- case ConfigurationStatus::Changed: return os << "Changed";
- }
- ENUM_STR_DEFAULT;
-}
-
-} \ No newline at end of file
diff --git a/src/p18/defines.h b/src/p18/defines.h
deleted file mode 100644
index 83728f8..0000000
--- a/src/p18/defines.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef INVERTER_TOOLS_P18_DEFINES_H
-#define INVERTER_TOOLS_P18_DEFINES_H
-
-#include <map>
-#include <string>
-#include <array>
-
-#include "types.h"
-
-namespace p18 {
-
-extern const std::map<CommandType, std::string> raw_commands;
-
-extern const std::array<int, 5> ac_output_rated_voltages;
-
-extern const std::array<float, 8> bat_ac_recharging_voltages_12v;
-extern const std::array<float, 8> bat_ac_recharging_voltages_24v;
-extern const std::array<float, 8> bat_ac_recharging_voltages_48v;
-
-extern const std::array<float, 12> bat_ac_redischarging_voltages_12v;
-extern const std::array<float, 12> bat_ac_redischarging_voltages_24v;
-extern const std::array<float, 12> bat_ac_redischarging_voltages_48v;
-
-extern const std::map<int, std::string> fault_codes;
-
-extern const std::array<Flag, 9> flags;
-
-}
-
-#endif //INVERTER_TOOLS_P18_DEFINES_H
diff --git a/src/p18/exceptions.h b/src/p18/exceptions.h
deleted file mode 100644
index 9b79082..0000000
--- a/src/p18/exceptions.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef INFINISOLAR_TOOLS_P18_EXCEPTIONS_H
-#define INFINISOLAR_TOOLS_P18_EXCEPTIONS_H
-
-#include <stdexcept>
-
-namespace p18 {
-
-class InvalidResponseError : public std::runtime_error {
-public:
- using std::runtime_error::runtime_error;
-};
-
-class ParseError : public InvalidResponseError {
-public:
- using InvalidResponseError::InvalidResponseError;
-};
-
-}
-
-#endif //INFINISOLAR_TOOLS_P18_EXCEPTIONS_H
diff --git a/src/p18/functions.cc b/src/p18/functions.cc
deleted file mode 100644
index 9799fc0..0000000
--- a/src/p18/functions.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#include "functions.h"
-
-namespace p18 {
-
-bool is_valid_parallel_id(unsigned id)
-{
- return id >= 0 && id <= 6;
-}
-
-} \ No newline at end of file
diff --git a/src/p18/functions.h b/src/p18/functions.h
deleted file mode 100644
index c372242..0000000
--- a/src/p18/functions.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef INFINISOLAR_TOOLS_P18_FUNCTIONS_H
-#define INFINISOLAR_TOOLS_P18_FUNCTIONS_H
-
-namespace p18 {
-
-bool is_valid_parallel_id(unsigned id);
-
-}
-
-#endif //INFINISOLAR_TOOLS_P18_FUNCTIONS_H
diff --git a/src/p18/response.cc b/src/p18/response.cc
deleted file mode 100644
index e2cd9f4..0000000
--- a/src/p18/response.cc
+++ /dev/null
@@ -1,815 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#include <utility>
-#include <cstring>
-#include <sstream>
-#include <iomanip>
-#include <typeinfo>
-
-#include "response.h"
-#include "exceptions.h"
-
-#define RETURN_TABLE(...) \
- return std::shared_ptr<formatter::Table<VariantHolder>>( \
- new formatter::Table<VariantHolder>(format, __VA_ARGS__) \
- );
-
-#define RETURN_STATUS(...) \
- return std::shared_ptr<formatter::Status>( \
- new formatter::Status(format, __VA_ARGS__) \
- );
-
-
-namespace p18::response_type {
-
-typedef formatter::TableItem<VariantHolder> LINE;
-
-using formatter::Unit;
-
-
-/**
- * Helpers
- */
-std::ostream& operator<<(std::ostream& os, FieldLength fl) {
- if (fl.min_ == fl.max_)
- os << fl.min_;
- else
- os << "[" << fl.min_ << ", " << fl.max_ << "]";
- return os;
-}
-
-
-/**
- * Base responses
- */
-
-BaseResponse::BaseResponse(std::shared_ptr<char> raw, size_t rawSize)
- : raw_(std::move(raw)), rawSize_(rawSize) {}
-
-bool GetResponse::validate() {
- if (rawSize_ < 5)
- return false;
-
- const char* raw = raw_.get();
- if (raw[0] != '^' || raw[1] != 'D')
- return false;
-
- char lenbuf[4];
- memcpy(lenbuf, &raw[2], 3);
- lenbuf[3] = '\0';
-
- auto len = static_cast<size_t>(std::stoul(lenbuf));
- return rawSize_ >= len-5 /* exclude ^Dxxx*/;
-}
-
-const char* GetResponse::getData() const {
- return raw_.get() + 5;
-}
-
-size_t GetResponse::getDataSize() const {
- return rawSize_ - 5;
-}
-
-std::vector<std::string> GetResponse::getList(std::vector<FieldLength> itemLengths, int expectAtLeast) const {
- std::string buf(getData(), getDataSize());
- auto list = ::split(buf, ',');
-
- if (expectAtLeast == -1)
- expectAtLeast = (int)itemLengths.size();
-
- if (!itemLengths.empty()) {
- // check list length
- if (list.size() < expectAtLeast) {
- std::ostringstream error;
- error << "while parsing " << demangle_type_name(typeid(*this).name());
- error << ": list is expected to be " << expectAtLeast << " items long, ";
- error << "got only " << list.size() << " items";
- throw ParseError(error.str());
- }
-
- // check each item's length
- for (int i = 0; i < list.size(); i++) {
- if (!itemLengths[i].validate(list[i].size())) {
- std::ostringstream error;
- error << "while parsing " << demangle_type_name(typeid(*this).name());
- error << ": item " << i << " is expected to be " << itemLengths[i] << " characters long, ";
- error << "got " << list[i].size() << " characters";
- throw ParseError(error.str());
- }
- }
- }
-
- return list;
-}
-
-bool SetResponse::validate() {
- if (rawSize_ < 2)
- return false;
-
- const char* raw = raw_.get();
- return raw[0] == '^' && (raw[1] == '0' || raw[1] == '1');
-}
-
-bool SetResponse::get() {
- return raw_.get()[1] == '1';
-}
-
-void SetResponse::unpack() {}
-
-formattable_ptr SetResponse::format(formatter::Format format) {
- RETURN_STATUS(get(), "");
-}
-
-formattable_ptr ErrorResponse::format(formatter::Format format) {
- return std::shared_ptr<formatter::Status>(
- new formatter::Status(format, false, error_)
- );
-}
-
-
-/**
- * Actual typed responses
- */
-
-void ProtocolID::unpack() {
- auto data = getData();
-
- char s[4];
- strncpy(s, data, 2);
- s[2] = '\0';
-
- id = stou(s);
-}
-
-formattable_ptr ProtocolID::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("id", "Protocol ID", id),
- });
-}
-
-
-void CurrentTime::unpack() {
- auto data = getData();
-
- std::string buf;
- buf = std::string(data, 4);
-
- year = stou(buf);
-
- for (int i = 0; i < 5; i++) {
- buf = std::string(data + 4 + (i * 2), 2);
- auto n = stou(buf);
-
- switch (i) {
- case 0:
- month = n;
- break;
-
- case 1:
- day = n;
- break;
-
- case 2:
- hour = n;
- break;
-
- case 3:
- minute = n;
- break;
-
- case 4:
- second = n;
- break;
-
- default:
- std::ostringstream error;
- error << "unexpected value while parsing CurrentTime (i = " << i << ")";
- throw ParseError(error.str());
- }
- }
-}
-
-formattable_ptr CurrentTime::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("year", "Year", year),
- LINE("month", "Month", month),
- LINE("day", "Day", day),
- LINE("hour", "Hour", hour),
- LINE("minute", "Minute", minute),
- LINE("second", "Second", second),
- });
-}
-
-
-void TotalGenerated::unpack() {
- auto data = getData();
-
- std::string buf(data, 8);
- wh = stou(buf);
-}
-
-formattable_ptr TotalGenerated::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("wh", "Wh", wh)
- });
-}
-
-
-void SeriesNumber::unpack() {
- auto data = getData();
-
- std::string buf(data, 2);
- size_t len = std::stoul(buf);
-
- id = std::string(data+2, len);
-}
-
-formattable_ptr SeriesNumber::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("sn", "Series number", id)
- });
-}
-
-
-void CPUVersion::unpack() {
- auto list = getList({5, 5, 5});
-
- main_cpu_version = list[0];
- slave1_cpu_version = list[1];
- slave2_cpu_version = list[2];
-}
-
-formattable_ptr CPUVersion::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("main_v", "Main CPU version", main_cpu_version),
- LINE("slave1_v", "Slave 1 CPU version", slave1_cpu_version),
- LINE("slave2_v", "Slave 2 CPU version", slave2_cpu_version)
- });
-}
-
-
-void RatedInformation::unpack() {
- auto list = getList({
- 4, // AAAA
- 3, // BBB
- 4, // CCCC
- 3, // DDD
- 3, // EEE
- 4, // FFFF
- 4, // GGGG
- 3, // HHH
- 3, // III
- 3, // JJJ
- 3, // KKK
- 3, // LLL
- 3, // MMM
- 1, // N
- 2, // OO
- 3, // PPP
- 1, // O
- 1, // R
- 1, // S
- 1, // T
- 1, // U
- 1, // V
- 1, // W
- 1, // Z
- 1, // a
- });
-
- ac_input_rating_voltage = stou(list[0]);
- ac_input_rating_current = stou(list[1]);
- ac_output_rating_voltage = stou(list[2]);
- ac_output_rating_freq = stou(list[3]);
- ac_output_rating_current = stou(list[4]);
- ac_output_rating_apparent_power = stou(list[5]);
- ac_output_rating_active_power = stou(list[6]);
- battery_rating_voltage = stou(list[7]);
- battery_recharge_voltage = stou(list[8]);
- battery_redischarge_voltage = stou(list[9]);
- battery_under_voltage = stou(list[10]);
- battery_bulk_voltage = stou(list[11]);
- battery_float_voltage = stou(list[12]);
- battery_type = static_cast<BatteryType>(stou(list[13]));
- max_ac_charging_current = stou(list[14]);
- max_charging_current = stou(list[15]);
- input_voltage_range = static_cast<InputVoltageRange>(stou(list[16]));
- output_source_priority = static_cast<OutputModelSetting>(stou(list[17]));
- charger_source_priority = static_cast<ChargerSourcePriority>(stou(list[18]));
- parallel_max_num = stou(list[19]);
- machine_type = static_cast<MachineType>(stou(list[20]));
- topology = static_cast<Topology>(stou(list[21]));
- output_model_setting = static_cast<OutputModelSetting>(stou(list[22]));
- solar_power_priority = static_cast<SolarPowerPriority>(stou(list[23]));
- mppt = list[24];
-}
-
-formattable_ptr RatedInformation::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("ac_input_rating_voltage", "AC input rating voltage", ac_input_rating_voltage / 10.0, Unit::V),
- LINE("ac_input_rating_current", "AC input rating current", ac_input_rating_current / 10.0, Unit::A),
- LINE("ac_output_rating_voltage", "AC output rating voltage", ac_output_rating_voltage / 10.0, Unit::V),
- LINE("ac_output_rating_freq", "AC output rating frequency", ac_output_rating_freq / 10.0, Unit::Hz),
- LINE("ac_output_rating_current", "AC output rating current", ac_output_rating_current / 10.0, Unit::A),
- LINE("ac_output_rating_apparent_power", "AC output rating apparent power", ac_output_rating_apparent_power, Unit::VA),
- LINE("ac_output_rating_active_power", "AC output rating active power", ac_output_rating_active_power, Unit::Wh),
- LINE("battery_rating_voltage", "Battery rating voltage", battery_rating_voltage / 10.0, Unit::V),
- LINE("battery_recharge_voltage", "Battery re-charge voltage", battery_recharge_voltage / 10.0, Unit::V),
- LINE("battery_redischarge_voltage", "Battery re-discharge voltage", battery_redischarge_voltage / 10.0, Unit::V),
- LINE("battery_under_voltage", "Battery under voltage", battery_under_voltage / 10.0, Unit::V),
- LINE("battery_bulk_voltage", "Battery bulk voltage", battery_bulk_voltage / 10.0, Unit::V),
- LINE("battery_float_voltage", "Battery float voltage", battery_float_voltage / 10.0, Unit::V),
- LINE("battery_type", "Battery type", battery_type),
- LINE("max_charging_current", "Max charging current", max_charging_current, Unit::A),
- LINE("max_ac_charging_current", "Max AC charging current", max_ac_charging_current, Unit::A),
- LINE("input_voltage_range", "Input voltage range", input_voltage_range),
- LINE("output_source_priority", "Output source priority", output_source_priority),
- LINE("charge_source_priority", "Charge source priority", charger_source_priority),
- LINE("parallel_max_num", "Parallel max num", parallel_max_num),
- LINE("machine_type", "Machine type", machine_type),
- LINE("topology", "Topology", topology),
- LINE("output_model_setting", "Output model setting", output_model_setting),
- LINE("solar_power_priority", "Solar power priority", solar_power_priority),
- LINE("mppt", "MPPT string", mppt)
- });
-}
-
-
-void GeneralStatus::unpack() {
- auto list = getList({
- 4, // AAAA
- 3, // BBB
- 4, // CCCC
- 3, // DDD
- 4, // EEEE
- 4, // FFFF
- 3, // GGG
- 3, // HHH
- 3, // III
- 3, // JJJ
- 3, // KKK
- 3, // LLL
- 3, // MMM
- 3, // NNN
- 3, // OOO
- 3, // PPP
- 4, // QQQQ
- 4, // RRRR
- 4, // SSSS
- 4, // TTTT
- 1, // U
- 1, // V
- 1, // W
- 1, // X
- 1, // Y
- 1, // Z
- 1, // a
- 1, // b
- });
-
- grid_voltage = stou(list[0]);
- grid_freq = stou(list[1]);
- ac_output_voltage = stou(list[2]);
- ac_output_freq = stou(list[3]);
- ac_output_apparent_power = stou(list[4]);
- ac_output_active_power = stou(list[5]);
- output_load_percent = stou(list[6]);
- battery_voltage = stou(list[7]);
- battery_voltage_scc = stou(list[8]);
- battery_voltage_scc2 = stou(list[9]);
- battery_discharge_current = stou(list[10]);
- battery_charging_current = stou(list[11]);
- battery_capacity = stou(list[12]);
- inverter_heat_sink_temp = stou(list[13]);
- mppt1_charger_temp = stou(list[14]);
- mppt2_charger_temp = stou(list[15]);
- pv1_input_power = stou(list[16]);
- pv2_input_power = stou(list[17]);
- pv1_input_voltage = stou(list[18]);
- pv2_input_voltage = stou(list[19]);
- configuration_status = static_cast<ConfigurationStatus>(stou(list[20]));
- mppt1_charger_status = static_cast<MPPTChargerStatus>(stou(list[21]));
- mppt2_charger_status = static_cast<MPPTChargerStatus>(stou(list[22]));
- load_connected = static_cast<LoadConnectionStatus>(stou(list[23]));
- battery_power_direction = static_cast<BatteryPowerDirection>(stou(list[24]));
- dc_ac_power_direction = static_cast<DC_AC_PowerDirection>(stou(list[25]));
- line_power_direction = static_cast<LinePowerDirection>(stou(list[26]));
- local_parallel_id = stou(list[27]);
-}
-
-formattable_ptr GeneralStatus::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("grid_voltage", "Grid voltage", grid_voltage / 10.0, Unit::V),
- LINE("grid_freq", "Grid frequency", grid_freq / 10.0, Unit::Hz),
- LINE("ac_output_voltage", "AC output voltage", ac_output_voltage / 10.0, Unit::V),
- LINE("ac_output_freq", "AC output frequency", ac_output_freq / 10.0, Unit::Hz),
- LINE("ac_output_apparent_power", "AC output apparent power", ac_output_apparent_power, Unit::VA),
- LINE("ac_output_active_power", "AC output active power", ac_output_active_power, Unit::Wh),
- LINE("output_load_percent", "Output load percent", output_load_percent, Unit::Percentage),
- LINE("battery_voltage", "Battery voltage", battery_voltage / 10.0, Unit::V),
- LINE("battery_voltage_scc", "Battery voltage from SCC", battery_voltage_scc / 10.0, Unit::V),
- LINE("battery_voltage_scc2", "Battery voltage from SCC2", battery_voltage_scc2 / 10.0, Unit::V),
- LINE("battery_discharging_current", "Battery discharging current", battery_discharge_current, Unit::A),
- LINE("battery_charging_current", "Battery charging current", battery_charging_current, Unit::A),
- LINE("battery_capacity", "Battery capacity", battery_capacity, Unit::Percentage),
- LINE("inverter_heat_sink_temp", "Inverter heat sink temperature", inverter_heat_sink_temp, Unit::Celsius),
- LINE("mppt1_charger_temp", "MPPT1 charger temperature", mppt1_charger_temp, Unit::Celsius),
- LINE("mppt2_charger_temp", "MPPT2 charger temperature", mppt2_charger_temp, Unit::Celsius),
- LINE("pv1_input_power", "PV1 input power", pv1_input_power, Unit::Wh),
- LINE("pv2_input_power", "PV2 input power", pv2_input_power, Unit::Wh),
- LINE("pv1_input_voltage", "PV1 input voltage", pv1_input_voltage / 10.0, Unit::V),
- LINE("pv2_input_voltage", "PV2 input voltage", pv2_input_voltage / 10.0, Unit::V),
- LINE("configuration_status", "Configuration state", configuration_status),
- LINE("mppt1_charger_status", "MPPT1 charger status", mppt1_charger_status),
- LINE("mppt2_charger_status", "MPPT2 charger status", mppt2_charger_status),
- LINE("load_connected", "Load connection", load_connected),
- LINE("battery_power_direction", "Battery power direction", battery_power_direction),
- LINE("dc_ac_power_direction", "DC/AC power direction", dc_ac_power_direction),
- LINE("line_power_direction", "Line power direction", line_power_direction),
- LINE("local_parallel_id", "Local parallel ID", local_parallel_id),
- });
-}
-
-
-void WorkingMode::unpack() {
- auto data = getData();
- mode = static_cast<p18::WorkingMode>(stou(std::string(data, 2)));
-}
-
-formattable_ptr WorkingMode::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("mode", "Working mode", mode)
- })
-}
-
-
-void FaultsAndWarnings::unpack() {
- auto list = getList({2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1});
-
- fault_code = stou(list[0]);
- line_fail = stou(list[1]) > 0;
- output_circuit_short = stou(list[2]) > 0;
- inverter_over_temperature = stou(list[3]) > 0;
- fan_lock = stou(list[4]) > 0;
- battery_voltage_high = stou(list[5]) > 0;
- battery_low = stou(list[6]) > 0;
- battery_under = stou(list[7]) > 0;
- over_load = stou(list[8]) > 0;
- eeprom_fail = stou(list[9]) > 0;
- power_limit = stou(list[10]) > 0;
- pv1_voltage_high = stou(list[11]) > 0;
- pv2_voltage_high = stou(list[12]) > 0;
- mppt1_overload_warning = stou(list[13]) > 0;
- mppt2_overload_warning = stou(list[14]) > 0;
- battery_too_low_to_charge_for_scc1 = stou(list[15]) > 0;
- battery_too_low_to_charge_for_scc2 = stou(list[16]) > 0;
-}
-
-formattable_ptr FaultsAndWarnings::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("fault_code", "Fault code", fault_code),
- LINE("line_fail", "Line fail", line_fail),
- LINE("output_circuit_short", "Output circuit short", output_circuit_short),
- LINE("inverter_over_temperature", "Inverter over temperature", inverter_over_temperature),
- LINE("fan_lock", "Fan lock", fan_lock),
- LINE("battery_voltage_high", "Battery voltage high", battery_voltage_high),
- LINE("battery_low", "Battery low", battery_low),
- LINE("battery_under", "Battery under", battery_under),
- LINE("over_load", "Over load", over_load),
- LINE("eeprom_fail", "EEPROM fail", eeprom_fail),
- LINE("power_limit", "Power limit", power_limit),
- LINE("pv1_voltage_high", "PV1 voltage high", pv1_voltage_high),
- LINE("pv2_voltage_high", "PV2 voltage high", pv2_voltage_high),
- LINE("mppt1_overload_warning", "MPPT1 overload warning", mppt1_overload_warning),
- LINE("mppt2_overload_warning", "MPPT2 overload warning", mppt2_overload_warning),
- LINE("battery_too_low_to_charge_for_scc1", "Battery too low to charge for SCC1", battery_too_low_to_charge_for_scc1),
- LINE("battery_too_low_to_charge_for_scc2", "Battery too low to charge for SCC2", battery_too_low_to_charge_for_scc2),
- })
-}
-
-
-void FlagsAndStatuses::unpack() {
- auto list = getList({1, 1, 1, 1, 1, 1, 1, 1, 1});
-
- buzzer = stou(list[0]) > 0;
- overload_bypass = stou(list[1]) > 0;
- lcd_escape_to_default_page_after_1min_timeout = stou(list[2]) > 0;
- overload_restart = stou(list[3]) > 0;
- over_temp_restart = stou(list[4]) > 0;
- backlight_on = stou(list[5]) > 0;
- alarm_on_primary_source_interrupt = stou(list[6]) > 0;
- fault_code_record = stou(list[7]) > 0;
- reserved = *list[8].c_str();
-}
-
-formattable_ptr FlagsAndStatuses::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("buzzer",
- "Buzzer",
- buzzer),
-
- LINE("overload_bypass",
- "Overload bypass function",
- overload_bypass),
-
- LINE("escape_to_default_screen_after_1min_timeout",
- "Escape to default screen after 1min timeout",
- lcd_escape_to_default_page_after_1min_timeout),
-
- LINE("overload_restart",
- "Overload restart",
- overload_restart),
-
- LINE("over_temp_restart",
- "Over temperature restart",
- over_temp_restart),
-
- LINE("backlight_on",
- "Backlight on",
- backlight_on),
-
- LINE("alarm_on_on_primary_source_interrupt",
- "Alarm on on primary source interrupt",
- alarm_on_primary_source_interrupt),
-
- LINE("fault_code_record",
- "Fault code record",
- fault_code_record)
- })
-}
-
-
-void Defaults::unpack() {
- auto list = getList({
- 4, // AAAA
- 3, // BBB
- 1, // C
- 3, // DDD
- 3, // EEE
- 3, // FFF
- 3, // GGG
- 3, // HHH
- 3, // III
- 2, // JJ
- 1, // K
- 1, // L
- 1, // M
- 1, // N
- 1, // O
- 1, // P
- 1, // S
- 1, // T
- 1, // U
- 1, // V
- 1, // W
- 1, // X
- 1, // Y
- 1, // Z
- });
-
- ac_output_voltage = stou(list[0]);
- ac_output_freq = stou(list[1]);
- ac_input_voltage_range = static_cast<InputVoltageRange>(stou(list[2]));
- battery_under_voltage = stou(list[3]);
- charging_float_voltage = stou(list[4]);
- charging_bulk_voltage = stou(list[5]);
- battery_recharge_voltage = stou(list[6]);
- battery_redischarge_voltage = stou(list[7]);
- max_charging_current = stou(list[8]);
- max_ac_charging_current = stou(list[9]);
- battery_type = static_cast<BatteryType>(stou(list[10]));
- output_source_priority = static_cast<OutputSourcePriority>(stou(list[11]));
- charger_source_priority = static_cast<ChargerSourcePriority>(stou(list[12]));
- solar_power_priority = static_cast<SolarPowerPriority>(stou(list[13]));
- machine_type = static_cast<MachineType>(stou(list[14]));
- output_model_setting = static_cast<OutputModelSetting>(stou(list[15]));
- flag_buzzer = stou(list[16]) > 0;
- flag_overload_restart = stou(list[17]) > 0;
- flag_over_temp_restart = stou(list[18]) > 0;
- flag_backlight_on = stou(list[19]) > 0;
- flag_alarm_on_primary_source_interrupt = stou(list[20]) > 0;
- flag_fault_code_record = stou(list[21]) > 0;
- flag_overload_bypass = stou(list[22]) > 0;
- flag_lcd_escape_to_default_page_after_1min_timeout = stou(list[23]) > 0;
-}
-
-formattable_ptr Defaults::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("ac_output_voltage", "AC output voltage", ac_output_voltage / 10.0, Unit::V),
- LINE("ac_output_freq", "AC output frequency", ac_output_freq / 10.0, Unit::Hz),
- LINE("ac_input_voltage_range", "AC input voltage range", ac_input_voltage_range),
- LINE("battery_under_voltage", "Battery under voltage", battery_under_voltage / 10.0, Unit::V),
- LINE("battery_bulk_voltage", "Charging bulk voltage", charging_bulk_voltage / 10.0, Unit::V),
- LINE("battery_float_voltage", "Charging float voltage", charging_float_voltage / 10.0, Unit::V),
- LINE("battery_recharging_voltage", "Battery re-charging voltage", battery_recharge_voltage / 10.0, Unit::V),
- LINE("battery_redischarging_voltage", "Battery re-discharging voltage", battery_redischarge_voltage / 10.0, Unit::V),
- LINE("max_charging_current", "Max charging current", max_charging_current, Unit::A),
- LINE("max_ac_charging_current", "Max AC charging current", max_ac_charging_current, Unit::A),
- LINE("battery_type", "Battery type", battery_type),
- LINE("output_source_priority", "Output source priority", output_source_priority),
- LINE("charger_source_priority", "Charger source priority", charger_source_priority),
- LINE("solar_power_priority", "Solar power priority", solar_power_priority),
- LINE("machine_type", "Machine type", machine_type),
- LINE("output_model_setting", "Output model setting", output_model_setting),
- LINE("buzzer_flag", "Buzzer flag", flag_buzzer),
- LINE("overload_bypass_flag", "Overload bypass function flag", flag_overload_bypass),
- LINE("escape_to_default_screen_after_1min_timeout_flag", "Escape to default screen after 1min timeout flag", flag_lcd_escape_to_default_page_after_1min_timeout),
- LINE("overload_restart_flag", "Overload restart flag", flag_overload_restart),
- LINE("over_temp_restart_flag", "Over temperature restart flag", flag_over_temp_restart),
- LINE("backlight_on_flag", "Backlight on flag", flag_backlight_on),
- LINE("alarm_on_on_primary_source_interrupt_flag", "Alarm on on primary source interrupt flag", flag_alarm_on_primary_source_interrupt),
- LINE("fault_code_record_flag", "Fault code record flag", flag_fault_code_record),
- })
-}
-
-void AllowedChargingCurrents::unpack() {
- auto list = getList({});
- for (const std::string& i: list) {
- amps.emplace_back(stou(i));
- }
-}
-
-formattable_ptr AllowedChargingCurrents::format(formatter::Format format) {
- std::vector<formatter::ListItem<VariantHolder>> v;
- for (const auto& n: amps)
- v.emplace_back(n);
-
- return std::shared_ptr<formatter::List<VariantHolder>>(
- new formatter::List<VariantHolder>(format, v)
- );
-}
-
-
-void ParallelRatedInformation::unpack() {
- auto list = getList({
- 1, // A
- 2, // BB
- 20, // CCCCCCCCCCCCCCCCCCCC
- 1, // D
- 3, // EEE
-
- // FF
- // note: protocol documentation says that the following field is 2 bytes long,
- // but actual tests of the 6kw unit shows it can be 3 bytes long
- FieldLength(2, 3),
-
- 1 // G
- });
-
- parallel_id_connection_status = static_cast<ParallelConnectionStatus>(stou(list[0]));
- serial_number_valid_length = stou(list[1]);
- serial_number = std::string(list[2], 0, serial_number_valid_length);
- charger_source_priority = static_cast<ChargerSourcePriority>(stou(list[3]));
- max_charging_current = stou(list[4]);
- max_ac_charging_current = stou(list[5]);
- output_model_setting = static_cast<OutputModelSetting>(stou(list[6]));
-}
-
-formattable_ptr ParallelRatedInformation::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("parallel_id_connection_status", "Parallel ID connection status", parallel_id_connection_status),
- LINE("serial_number", "Serial number", serial_number),
- LINE("charger_source_priority", "Charger source priority", charger_source_priority),
- LINE("max_charging_current", "Max charging current", max_charging_current, Unit::A),
- LINE("max_ac_charging_current", "Max AC charging current", max_ac_charging_current, Unit::A),
- LINE("output_model_setting", "Output model setting", output_model_setting),
- })
-}
-
-
-void ParallelGeneralStatus::unpack() {
- auto list = getList({
- 1, // A
- 1, // B
- 2, // CC
- 4, // DDDD
- 3, // EEE
- 4, // FFFF
- 3, // GGG
- 4, // HHHH
- 4, // IIII
- 5, // JJJJJ
- 5, // KKKKK
- 3, // LLL
- 3, // MMM
- 3, // NNN
- 3, // OOO
- 3, // PPP
- 3, // QQQ
- 3, // MMM. It's not my mistake, it's per the doc.
- 4, // RRRR
- 4, // SSSS
- 4, // TTTT
- 4, // UUUU
- 1, // V
- // FIXME: marked red in the docs
- 1, // W
- // FIXME: marked red in the docs
- 1, // X
- 1, // Y
- 1, // Z
- 1, // a
- 3, // bbb. Note: this one is marked in red in the doc. Apparently it means
- // that it may be missing on some models, see
- // https://github.com/gch1p/inverter-tools/issues/1#issuecomment-981158688
- }, 28);
-
- parallel_id_connection_status = static_cast<ParallelConnectionStatus>(stou(list[0]));
- work_mode = static_cast<p18::WorkingMode>(stou(list[1]));
- fault_code = stou(list[2]);
- grid_voltage = stou(list[3]);
- grid_freq = stou(list[4]);
- ac_output_voltage = stou(list[5]);
- ac_output_freq = stou(list[6]);
- ac_output_apparent_power = stou(list[7]);
- ac_output_active_power = stou(list[8]);
- total_ac_output_apparent_power = stou(list[9]);
- total_ac_output_active_power = stou(list[10]);
- output_load_percent = stou(list[11]);
- total_output_load_percent = stou(list[12]);
- battery_voltage = stou(list[13]);
- battery_discharge_current = stou(list[14]);
- battery_charging_current = stou(list[15]);
- total_battery_charging_current = stou(list[16]);
- battery_capacity = stou(list[17]);
- pv1_input_power = stou(list[18]);
- pv2_input_power = stou(list[19]);
- pv1_input_voltage = stou(list[20]);
- pv2_input_voltage = stou(list[21]);
- mppt1_charger_status = static_cast<MPPTChargerStatus>(stou(list[22]));
- mppt2_charger_status = static_cast<MPPTChargerStatus>(stou(list[23]));
- load_connected = static_cast<LoadConnectionStatus>(stou(list[24]));
- battery_power_direction = static_cast<BatteryPowerDirection>(stou(list[25]));
- dc_ac_power_direction = static_cast<DC_AC_PowerDirection>(stou(list[26]));
- line_power_direction = static_cast<LinePowerDirection>(stou(list[27]));
- if (list.size() >= 29) {
- max_temp_present = true;
- max_temp = stou(list[28]);
- }
-}
-
-formattable_ptr ParallelGeneralStatus::format(formatter::Format format) {
- auto table = new formatter::Table<VariantHolder>(format, {
- LINE("parallel_id_connection_status", "Parallel ID connection status", parallel_id_connection_status),
- LINE("mode", "Working mode", work_mode),
- LINE("fault_code", "Fault code", fault_code),
- LINE("grid_voltage", "Grid voltage", grid_voltage / 10.0, Unit::V),
- LINE("grid_freq", "Grid frequency", grid_freq / 10.0, Unit::Hz),
- LINE("ac_output_voltage", "AC output voltage", ac_output_voltage / 10.0, Unit::V),
- LINE("ac_output_freq", "AC output frequency", ac_output_freq / 10.0, Unit::Hz),
- LINE("ac_output_apparent_power", "AC output apparent power", ac_output_apparent_power, Unit::VA),
- LINE("ac_output_active_power", "AC output active power", ac_output_active_power, Unit::Wh),
- LINE("total_ac_output_apparent_power", "Total AC output apparent power", total_ac_output_apparent_power, Unit::VA),
- LINE("total_ac_output_active_power", "Total AC output active power", total_ac_output_active_power, Unit::Wh),
- LINE("output_load_percent", "Output load percent", output_load_percent, Unit::Percentage),
- LINE("total_output_load_percent", "Total output load percent", total_output_load_percent, Unit::Percentage),
- LINE("battery_voltage", "Battery voltage", battery_voltage / 10.0, Unit::V),
- LINE("battery_discharge_current", "Battery discharge current", battery_discharge_current, Unit::A),
- LINE("battery_charging_current", "Battery charging current", battery_charging_current, Unit::A),
- LINE("pv1_input_power", "PV1 Input power", pv1_input_power, Unit::Wh),
- LINE("pv2_input_power", "PV2 Input power", pv2_input_power, Unit::Wh),
- LINE("pv1_input_voltage", "PV1 Input voltage", pv1_input_voltage / 10.0, Unit::V),
- LINE("pv2_input_voltage", "PV2 Input voltage", pv2_input_voltage / 10.0, Unit::V),
- LINE("mppt1_charger_status", "MPPT1 charger status", mppt1_charger_status),
- LINE("mppt2_charger_status", "MPPT2 charger status", mppt2_charger_status),
- LINE("load_connected", "Load connection", load_connected),
- LINE("battery_power_direction", "Battery power direction", battery_power_direction),
- LINE("dc_ac_power_direction", "DC/AC power direction", dc_ac_power_direction),
- LINE("line_power_direction", "Line power direction", line_power_direction),
- });
-
- if (max_temp_present) {
- table->push(
- LINE("max_temp", "Max. temperature", max_temp)
- );
- }
-
- return std::shared_ptr<formatter::Table<VariantHolder>>(table);
-}
-
-
-void ACChargingTimeBucket::unpack() {
- auto list = getList({4 /* AAAA */, 4 /* BBBB */});
-
- start_h = stouh(list[0].substr(0, 2));
- start_m = stouh(list[0].substr(2, 2));
-
- end_h = stouh(list[1].substr(0, 2));
- end_m = stouh(list[1].substr(2, 2));
-}
-
-static inline std::string get_time(unsigned short h, unsigned short m) {
- std::ostringstream buf;
- buf << std::setfill('0');
- buf << std::setw(2) << h << ":" << std::setw(2) << m;
- return buf.str();
-}
-
-formattable_ptr ACChargingTimeBucket::format(formatter::Format format) {
- RETURN_TABLE({
- LINE("start_time", "Start time", get_time(start_h, start_m)),
- LINE("end_time", "End time", get_time(end_h, end_m)),
- })
-}
-
-} \ No newline at end of file
diff --git a/src/p18/response.h b/src/p18/response.h
deleted file mode 100644
index 3ffc6d4..0000000
--- a/src/p18/response.h
+++ /dev/null
@@ -1,511 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef INVERTER_TOOLS_P18_RESPONSE_H
-#define INVERTER_TOOLS_P18_RESPONSE_H
-
-#include <string>
-#include <vector>
-#include <memory>
-#include <variant>
-#include <nlohmann/json.hpp>
-
-#include "types.h"
-#include "src/formatter/formatter.h"
-
-namespace p18::response_type {
-
-using nlohmann::json;
-
-typedef std::shared_ptr<formatter::Formattable> formattable_ptr;
-
-
-/**
- * Value holder for the formatter module
- */
-
-typedef std::variant<
- unsigned,
- unsigned short,
- unsigned long,
- bool,
- double,
- std::string,
- p18::BatteryType,
- p18::BatteryPowerDirection,
- p18::ChargerSourcePriority,
- p18::DC_AC_PowerDirection,
- p18::InputVoltageRange,
- p18::LinePowerDirection,
- p18::MachineType,
- p18::MPPTChargerStatus,
- p18::Topology,
- p18::OutputSourcePriority,
- p18::OutputModelSetting,
- p18::ParallelConnectionStatus,
- p18::SolarPowerPriority,
- p18::WorkingMode,
- p18::LoadConnectionStatus,
- p18::ConfigurationStatus
-> Variant;
-
-class VariantHolder {
-private:
- Variant v_;
-
-public:
- // implicit conversion constructors
- VariantHolder(unsigned v) : v_(v) {}
- VariantHolder(unsigned short v) : v_(v) {}
- VariantHolder(unsigned long v) : v_(v) {}
- VariantHolder(bool v) : v_(v) {}
- VariantHolder(double v) : v_(v) {}
- VariantHolder(std::string v) : v_(v) {}
- VariantHolder(p18::BatteryType v) : v_(v) {}
- VariantHolder(p18::BatteryPowerDirection v) : v_(v) {}
- VariantHolder(p18::ChargerSourcePriority v) : v_(v) {}
- VariantHolder(p18::DC_AC_PowerDirection v) : v_(v) {}
- VariantHolder(p18::InputVoltageRange v) : v_(v) {}
- VariantHolder(p18::LinePowerDirection v) : v_(v) {}
- VariantHolder(p18::MachineType v) : v_(v) {}
- VariantHolder(p18::MPPTChargerStatus v) : v_(v) {}
- VariantHolder(p18::Topology v) : v_(v) {}
- VariantHolder(p18::OutputSourcePriority v) : v_(v) {}
- VariantHolder(p18::OutputModelSetting v) : v_(v) {}
- VariantHolder(p18::ParallelConnectionStatus v) : v_(v) {}
- VariantHolder(p18::SolarPowerPriority v) : v_(v) {}
- VariantHolder(p18::WorkingMode v) : v_(v) {}
- VariantHolder(p18::LoadConnectionStatus v) : v_(v) {}
- VariantHolder(p18::ConfigurationStatus v) : v_(v) {}
-
- friend std::ostream &operator<<(std::ostream &os, VariantHolder const& ref) {
- std::visit([&os](const auto& elem) {
- os << elem;
- }, ref.v_);
- return os;
- }
-
- inline json toJSON() const {
- json j;
- bool isEnum =
- std::holds_alternative<p18::BatteryType>(v_) ||
- std::holds_alternative<p18::BatteryPowerDirection>(v_) ||
- std::holds_alternative<p18::ChargerSourcePriority>(v_) ||
- std::holds_alternative<p18::DC_AC_PowerDirection>(v_) ||
- std::holds_alternative<p18::InputVoltageRange>(v_) ||
- std::holds_alternative<p18::LinePowerDirection>(v_) ||
- std::holds_alternative<p18::MachineType>(v_) ||
- std::holds_alternative<p18::MPPTChargerStatus>(v_) ||
- std::holds_alternative<p18::Topology>(v_) ||
- std::holds_alternative<p18::OutputSourcePriority>(v_) ||
- std::holds_alternative<p18::OutputModelSetting>(v_) ||
- std::holds_alternative<p18::ParallelConnectionStatus>(v_) ||
- std::holds_alternative<p18::SolarPowerPriority>(v_) ||
- std::holds_alternative<p18::WorkingMode>(v_) ||
- std::holds_alternative<p18::LoadConnectionStatus>(v_) ||
- std::holds_alternative<p18::ConfigurationStatus>(v_);
-
- std::visit([&j, &isEnum](const auto& elem) {
- if (isEnum)
- j = formatter::to_str(elem);
- else
- j = elem;
- }, v_);
-
- return j;
- }
-
- inline json toSimpleJSON() const {
- json j;
- std::visit([&j](const auto& elem) {
- j = elem;
- }, v_);
- return j;
- }
-};
-
-
-/**
- * Some helpers
- */
-class FieldLength {
-protected:
- size_t min_;
- size_t max_;
-
-public:
- FieldLength(size_t n) : min_(n), max_(n) {}
- FieldLength(size_t min, size_t max) : min_(min), max_(max) {}
-
- [[nodiscard]] bool validate(size_t len) const {
- return len >= min_ && len <= max_;
- }
-
- friend std::ostream& operator<<(std::ostream& os, FieldLength fl);
-};
-
-
-/**
- * Base responses
- */
-
-class BaseResponse {
-protected:
- std::shared_ptr<char> raw_;
- size_t rawSize_;
-
-public:
- BaseResponse(std::shared_ptr<char> raw, size_t rawSize);
- virtual ~BaseResponse() = default;
- virtual bool validate() = 0;
- virtual void unpack() = 0;
- virtual formattable_ptr format(formatter::Format format) = 0;
-};
-
-class GetResponse : public BaseResponse {
-protected:
- const char* getData() const;
- size_t getDataSize() const;
- std::vector<std::string> getList(std::vector<FieldLength> itemLengths, int expectAtLeast = -1) const;
-
-public:
- using BaseResponse::BaseResponse;
- bool validate() override;
-// virtual void output() = 0;
-};
-
-class SetResponse : public BaseResponse {
-public:
- using BaseResponse::BaseResponse;
- void unpack() override;
- bool validate() override;
- formattable_ptr format(formatter::Format format) override;
- bool get();
-};
-
-class ErrorResponse : public BaseResponse {
-private:
- std::string error_;
-
-public:
- explicit ErrorResponse(std::string error)
- : BaseResponse(nullptr, 0), error_(std::move(error)) {}
-
- bool validate() override {
- return true;
- }
- void unpack() override {}
- formattable_ptr format(formatter::Format format) override;
-};
-
-
-/**
- * Actual typed responses
- */
-
-class ProtocolID : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- unsigned id = 0;
-};
-
-class CurrentTime : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- unsigned year = 0;
- unsigned short month = 0;
- unsigned short day = 0;
- unsigned short hour = 0;
- unsigned short minute = 0;
- unsigned short second = 0;
-};
-
-class TotalGenerated : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- unsigned long wh = 0;
-};
-
-class YearGenerated : public TotalGenerated {
-public:
- using TotalGenerated::TotalGenerated;
-};
-
-class MonthGenerated : public TotalGenerated {
-public:
- using TotalGenerated::TotalGenerated;
-};
-
-class DayGenerated : public TotalGenerated {
-public:
- using TotalGenerated::TotalGenerated;
-};
-
-class SeriesNumber : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- std::string id;
-};
-
-class CPUVersion : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- std::string main_cpu_version;
- std::string slave1_cpu_version;
- std::string slave2_cpu_version;
-};
-
-class RatedInformation : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- unsigned ac_input_rating_voltage; /* unit: 0.1V */
- unsigned ac_input_rating_current; /* unit: 0.1A */
- unsigned ac_output_rating_voltage; /* unit: 0.1A */
- unsigned ac_output_rating_freq; /* unit: 0.1Hz */
- unsigned ac_output_rating_current; /* unit: 0.1A */
- unsigned ac_output_rating_apparent_power; /* unit: VA */
- unsigned ac_output_rating_active_power; /* unit: W */
- unsigned battery_rating_voltage; /* unit: 0.1V */
- unsigned battery_recharge_voltage; /* unit: 0.1V */
- unsigned battery_redischarge_voltage; /* unit: 0.1V */
- unsigned battery_under_voltage; /* unit: 0.1V */
- unsigned battery_bulk_voltage; /* unit: 0.1V */
- unsigned battery_float_voltage; /* unit: 0.1V */
- p18::BatteryType battery_type;
- unsigned max_ac_charging_current; /* unit: A */
- unsigned max_charging_current; /* unit: A */
- p18::InputVoltageRange input_voltage_range;
- p18::OutputModelSetting output_source_priority;
- p18::ChargerSourcePriority charger_source_priority;
- unsigned parallel_max_num;
- p18::MachineType machine_type;
- p18::Topology topology;
- p18::OutputModelSetting output_model_setting;
- p18::SolarPowerPriority solar_power_priority;
- std::string mppt;
-};
-
-class GeneralStatus : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- unsigned grid_voltage; /* unit: 0.1V */
- unsigned grid_freq; /* unit: 0.1Hz */
- unsigned ac_output_voltage; /* unit: 0.1V */
- unsigned ac_output_freq; /* unit: 0.1Hz */
- unsigned ac_output_apparent_power; /* unit: VA */
- unsigned ac_output_active_power; /* unit: W */
- unsigned output_load_percent; /* unit: % */
- unsigned battery_voltage; /* unit: 0.1V */
- unsigned battery_voltage_scc; /* unit: 0.1V */
- unsigned battery_voltage_scc2; /* unit: 0.1V */
- unsigned battery_discharge_current; /* unit: A */
- unsigned battery_charging_current; /* unit: A */
- unsigned battery_capacity; /* unit: % */
- unsigned inverter_heat_sink_temp; /* unit: C */
- unsigned mppt1_charger_temp; /* unit: C */
- unsigned mppt2_charger_temp; /* unit: C */
- unsigned pv1_input_power; /* unit: W */
- unsigned pv2_input_power; /* unit: W */
- unsigned pv1_input_voltage; /* unit: 0.1V */
- unsigned pv2_input_voltage; /* unit: 0.1V */
- p18::ConfigurationStatus configuration_status;
- p18::MPPTChargerStatus mppt1_charger_status;
- p18::MPPTChargerStatus mppt2_charger_status;
- p18::LoadConnectionStatus load_connected;
- p18::BatteryPowerDirection battery_power_direction;
- p18::DC_AC_PowerDirection dc_ac_power_direction;
- p18::LinePowerDirection line_power_direction;
- unsigned local_parallel_id; /* 0 .. (parallel number - 1) */
-};
-
-class WorkingMode : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- p18::WorkingMode mode = static_cast<p18::WorkingMode>(0);
-};
-
-class FaultsAndWarnings : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- unsigned fault_code = 0;
- bool line_fail = false;
- bool output_circuit_short = false;
- bool inverter_over_temperature = false;
- bool fan_lock = false;
- bool battery_voltage_high = false;
- bool battery_low = false;
- bool battery_under = false;
- bool over_load = false;
- bool eeprom_fail = false;
- bool power_limit = false;
- bool pv1_voltage_high = false;
- bool pv2_voltage_high = false;
- bool mppt1_overload_warning = false;
- bool mppt2_overload_warning = false;
- bool battery_too_low_to_charge_for_scc1 = false;
- bool battery_too_low_to_charge_for_scc2 = false;
-};
-
-class FlagsAndStatuses : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- bool buzzer = false;
- bool overload_bypass = false;
- bool lcd_escape_to_default_page_after_1min_timeout = false;
- bool overload_restart = false;
- bool over_temp_restart = false;
- bool backlight_on = false;
- bool alarm_on_primary_source_interrupt = false;
- bool fault_code_record = false;
- char reserved = '0';
-};
-
-class Defaults : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- unsigned ac_output_voltage = 0; /* unit: 0.1V */
- unsigned ac_output_freq = 0;
- p18::InputVoltageRange ac_input_voltage_range = static_cast<InputVoltageRange>(0);
- unsigned battery_under_voltage = 0;
- unsigned charging_float_voltage = 0;
- unsigned charging_bulk_voltage = 0;
- unsigned battery_recharge_voltage = 0;
- unsigned battery_redischarge_voltage = 0;
- unsigned max_charging_current = 0;
- unsigned max_ac_charging_current = 0;
- p18::BatteryType battery_type = static_cast<BatteryType>(0);
- p18::OutputSourcePriority output_source_priority = static_cast<OutputSourcePriority>(0);
- p18::ChargerSourcePriority charger_source_priority = static_cast<ChargerSourcePriority>(0);
- p18::SolarPowerPriority solar_power_priority = static_cast<SolarPowerPriority>(0);
- p18::MachineType machine_type = static_cast<MachineType>(0);
- p18::OutputModelSetting output_model_setting = static_cast<OutputModelSetting>(0);
- bool flag_buzzer = false;
- bool flag_overload_restart = false;
- bool flag_over_temp_restart = false;
- bool flag_backlight_on = false;
- bool flag_alarm_on_primary_source_interrupt = false;
- bool flag_fault_code_record = false;
- bool flag_overload_bypass = false;
- bool flag_lcd_escape_to_default_page_after_1min_timeout = false;
-};
-
-class AllowedChargingCurrents : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- std::vector<unsigned> amps;
-};
-
-class AllowedACChargingCurrents : public AllowedChargingCurrents {
-public:
- using AllowedChargingCurrents::AllowedChargingCurrents;
-};
-
-class ParallelRatedInformation : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- p18::ParallelConnectionStatus parallel_id_connection_status = static_cast<ParallelConnectionStatus>(0);
- unsigned serial_number_valid_length = 0;
- std::string serial_number;
- p18::ChargerSourcePriority charger_source_priority = static_cast<ChargerSourcePriority>(0);
- unsigned max_ac_charging_current = 0; // unit: A
- unsigned max_charging_current = 0; // unit: A
- p18::OutputModelSetting output_model_setting = static_cast<OutputModelSetting>(0);
-};
-
-class ParallelGeneralStatus : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- p18::ParallelConnectionStatus parallel_id_connection_status;
- p18::WorkingMode work_mode;
- unsigned fault_code;
- unsigned grid_voltage; /* unit: 0.1V */
- unsigned grid_freq; /* unit: 0.1Hz */
- unsigned ac_output_voltage; /* unit: 0.1V */
- unsigned ac_output_freq; /* unit: 0.1Hz */
- unsigned ac_output_apparent_power; /* unit: VA */
- unsigned ac_output_active_power; /* unit: W */
- unsigned total_ac_output_apparent_power; /* unit: VA */
- unsigned total_ac_output_active_power; /* unit: W */
- unsigned output_load_percent; /* unit: % */
- unsigned total_output_load_percent; /* unit: % */
- unsigned battery_voltage; /* unit: 0.1V */
- unsigned battery_discharge_current; /* unit: A */
- unsigned battery_charging_current; /* unit: A */
- unsigned total_battery_charging_current; /* unit: A */
- unsigned battery_capacity; /* unit: % */
- unsigned pv1_input_power; /* unit: W */
- unsigned pv2_input_power; /* unit: W */
- unsigned pv1_input_voltage; /* unit: 0.1V */
- unsigned pv2_input_voltage; /* unit: 0.1V */
- p18::MPPTChargerStatus mppt1_charger_status;
- p18::MPPTChargerStatus mppt2_charger_status;
- p18::LoadConnectionStatus load_connected;
- p18::BatteryPowerDirection battery_power_direction;
- p18::DC_AC_PowerDirection dc_ac_power_direction;
- p18::LinePowerDirection line_power_direction;
-
- bool max_temp_present = false;
- unsigned max_temp; /* unit: C */
-};
-
-class ACChargingTimeBucket : public GetResponse {
-public:
- using GetResponse::GetResponse;
- void unpack() override;
- formattable_ptr format(formatter::Format format) override;
-
- unsigned short start_h = 0;
- unsigned short start_m = 0;
- unsigned short end_h = 0;
- unsigned short end_m = 0;
-};
-
-class ACLoadsSupplyTimeBucket : public ACChargingTimeBucket {
-public:
- using ACChargingTimeBucket::ACChargingTimeBucket;
-};
-
-} // namespace p18
-
-#endif //INVERTER_TOOLS_P18_RESPONSE_H
diff --git a/src/p18/types.h b/src/p18/types.h
deleted file mode 100644
index bcabd7c..0000000
--- a/src/p18/types.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef INVERTER_TOOLS_P18_TYPES_H
-#define INVERTER_TOOLS_P18_TYPES_H
-
-#include <string>
-
-#define ENUM_STR(enum_type) std::ostream& operator<< (std::ostream& os, enum_type val)
-#define ENUM_STR_DEFAULT return os << val
-
-namespace p18 {
-
-enum class CommandType {
- GetProtocolID = 0,
- GetCurrentTime,
- GetTotalGenerated,
- GetYearGenerated,
- GetMonthGenerated,
- GetDayGenerated,
- GetSeriesNumber,
- GetCPUVersion,
- GetRatedInformation,
- GetGeneralStatus,
- GetWorkingMode,
- GetFaultsAndWarnings,
- GetFlagsAndStatuses,
- GetDefaults,
- GetAllowedChargingCurrents,
- GetAllowedACChargingCurrents,
- GetParallelRatedInformation,
- GetParallelGeneralStatus,
- GetACChargingTimeBucket,
- GetACLoadsSupplyTimeBucket,
- SetLoads = 100,
- SetFlag,
- SetDefaults,
- SetBatteryMaxChargingCurrent,
- SetBatteryMaxACChargingCurrent,
- SetACOutputFreq,
- SetBatteryMaxChargingVoltage,
- SetACOutputRatedVoltage,
- SetOutputSourcePriority,
- SetBatteryChargingThresholds, /* Battery re-charging and re-discharing voltage when utility is available */
- SetChargingSourcePriority,
- SetSolarPowerPriority,
- SetACInputVoltageRange,
- SetBatteryType,
- SetOutputModel,
- SetBatteryCutOffVoltage,
- SetSolarConfig,
- ClearGenerated,
- SetDateTime,
- SetACChargingTimeBucket,
- SetACLoadsSupplyTimeBucket,
-};
-
-enum class BatteryType {
- AGM = 0,
- Flooded = 1,
- User = 2,
-};
-ENUM_STR(BatteryType);
-
-enum class InputVoltageRange {
- Appliance = 0,
- USP = 1,
-};
-ENUM_STR(InputVoltageRange);
-
-enum class OutputSourcePriority {
- SolarUtilityBattery = 0,
- SolarBatteryUtility = 1,
-};
-ENUM_STR(OutputSourcePriority);
-
-enum class ChargerSourcePriority {
- SolarFirst = 0,
- SolarAndUtility = 1,
- SolarOnly = 2,
-};
-ENUM_STR(ChargerSourcePriority);
-
-enum class MachineType {
- OffGridTie = 0,
- GridTie = 1,
-};
-ENUM_STR(MachineType);
-
-enum class Topology {
- TransformerLess = 0,
- Transformer = 1,
-};
-ENUM_STR(Topology);
-
-enum class OutputModelSetting {
- SingleModule = 0,
- ParallelOutput = 1,
- Phase1OfThreePhaseOutput = 2,
- Phase2OfThreePhaseOutput = 3,
- Phase3OfThreePhaseOutput = 4,
-};
-ENUM_STR(OutputModelSetting);
-
-enum class SolarPowerPriority {
- BatteryLoadUtility = 0,
- LoadBatteryUtility = 1,
-};
-ENUM_STR(SolarPowerPriority);
-
-enum class MPPTChargerStatus {
- Abnormal = 0,
- NotCharging = 1,
- Charging = 2,
-};
-ENUM_STR(MPPTChargerStatus);
-
-enum class BatteryPowerDirection {
- DoNothing = 0,
- Charge = 1,
- Discharge = 2,
-};
-ENUM_STR(BatteryPowerDirection);
-
-enum class DC_AC_PowerDirection {
- DoNothing = 0,
- AC_DC = 1,
- DC_AC = 2,
-};
-ENUM_STR(DC_AC_PowerDirection);
-
-enum class LinePowerDirection {
- DoNothing = 0,
- Input = 1,
- Output = 2,
-};
-ENUM_STR(LinePowerDirection);
-
-enum class WorkingMode {
- PowerOnMode = 0,
- StandbyMode = 1,
- BypassMode = 2,
- BatteryMode = 3,
- FaultMode = 4,
- HybridMode = 5,
-};
-ENUM_STR(WorkingMode);
-
-enum class ParallelConnectionStatus {
- NotExistent = 0,
- Existent = 1,
-};
-ENUM_STR(ParallelConnectionStatus);
-
-enum class LoadConnectionStatus {
- Disconnected = 0,
- Connected = 1,
-};
-ENUM_STR(LoadConnectionStatus);
-
-enum class ConfigurationStatus {
- Default = 0,
- Changed = 1,
-};
-ENUM_STR(ConfigurationStatus);
-
-struct Flag {
- std::string flag;
- char letter;
- std::string description;
-};
-
-}
-
-#endif //INVERTER_TOOLS_P18_TYPES_H