From cca4f35f14c3c87e5cd78e8fa68f38f537420285 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 13:06:45 +0200 Subject: [PATCH 01/38] Use flash strings for sensor logger. --- components/victron/victron.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index e6a254a..514f90d 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -29,10 +29,10 @@ static const char *const OFF_REASONS[OFF_REASONS_SIZE] = { }; void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) - ESP_LOGCONFIG(TAG, "Victron:"); - LOG_BINARY_SENSOR(" ", "Load state", load_state_binary_sensor_); + ESP_LOGCONFIG(TAG, LOG_STR_LITERAL("Victron:")); + LOG_BINARY_SENSOR(" ", LOG_STR_LITERAL("Load state"), load_state_binary_sensor_); LOG_BINARY_SENSOR(" ", "Relay state", relay_state_binary_sensor_); - LOG_SENSOR(" ", "Max Power Yesterday", max_power_yesterday_sensor_); + LOG_SENSOR(" ", LOG_STR_LITERAL("Max Power Yesterday"), max_power_yesterday_sensor_); LOG_SENSOR(" ", "Max Power Today", max_power_today_sensor_); LOG_SENSOR(" ", "Yield Total", yield_total_sensor_); LOG_SENSOR(" ", "Yield Yesterday", yield_yesterday_sensor_); From 28827157aa422494a1e97119f045c86b81406713 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 13:58:24 +0200 Subject: [PATCH 02/38] Use string literals for logging in Victron component --- components/victron/victron.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 514f90d..7f5b579 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -29,7 +29,7 @@ static const char *const OFF_REASONS[OFF_REASONS_SIZE] = { }; void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) - ESP_LOGCONFIG(TAG, LOG_STR_LITERAL("Victron:")); + ESP_LOGCONFIG(TAG, "Victron:"); LOG_BINARY_SENSOR(" ", LOG_STR_LITERAL("Load state"), load_state_binary_sensor_); LOG_BINARY_SENSOR(" ", "Relay state", relay_state_binary_sensor_); LOG_SENSOR(" ", LOG_STR_LITERAL("Max Power Yesterday"), max_power_yesterday_sensor_); From 919115176c5d5b7003fa03d9358bd857416306c1 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 14:01:12 +0200 Subject: [PATCH 03/38] Replace string literals with flash strings in Victron component logging --- components/victron/victron.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 7f5b579..6f80808 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -30,9 +30,9 @@ static const char *const OFF_REASONS[OFF_REASONS_SIZE] = { void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) ESP_LOGCONFIG(TAG, "Victron:"); - LOG_BINARY_SENSOR(" ", LOG_STR_LITERAL("Load state"), load_state_binary_sensor_); + LOG_BINARY_SENSOR(" ", F("Load state"), load_state_binary_sensor_); LOG_BINARY_SENSOR(" ", "Relay state", relay_state_binary_sensor_); - LOG_SENSOR(" ", LOG_STR_LITERAL("Max Power Yesterday"), max_power_yesterday_sensor_); + LOG_SENSOR(" ", "Max Power Yesterday", max_power_yesterday_sensor_); LOG_SENSOR(" ", "Max Power Today", max_power_today_sensor_); LOG_SENSOR(" ", "Yield Total", yield_total_sensor_); LOG_SENSOR(" ", "Yield Yesterday", yield_yesterday_sensor_); From 2539492a76102656ae802f8af9dda8fc069cd49e Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 14:03:50 +0200 Subject: [PATCH 04/38] Replace string literals with flash strings in Victron component config dump --- components/victron/victron.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 6f80808..e6a254a 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -30,7 +30,7 @@ static const char *const OFF_REASONS[OFF_REASONS_SIZE] = { void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) ESP_LOGCONFIG(TAG, "Victron:"); - LOG_BINARY_SENSOR(" ", F("Load state"), load_state_binary_sensor_); + LOG_BINARY_SENSOR(" ", "Load state", load_state_binary_sensor_); LOG_BINARY_SENSOR(" ", "Relay state", relay_state_binary_sensor_); LOG_SENSOR(" ", "Max Power Yesterday", max_power_yesterday_sensor_); LOG_SENSOR(" ", "Max Power Today", max_power_today_sensor_); From 1ab9a89f9496b08fd6a3fa05d51f64a0307eece8 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 14:04:47 +0200 Subject: [PATCH 05/38] Refactor Victron component config dump to use a prefix for logging --- components/victron/victron.cpp | 105 +++++++++++++++++---------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index e6a254a..cb6f116 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -29,59 +29,60 @@ static const char *const OFF_REASONS[OFF_REASONS_SIZE] = { }; void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) +static const char *prefix = " "; ESP_LOGCONFIG(TAG, "Victron:"); - LOG_BINARY_SENSOR(" ", "Load state", load_state_binary_sensor_); - LOG_BINARY_SENSOR(" ", "Relay state", relay_state_binary_sensor_); - LOG_SENSOR(" ", "Max Power Yesterday", max_power_yesterday_sensor_); - LOG_SENSOR(" ", "Max Power Today", max_power_today_sensor_); - LOG_SENSOR(" ", "Yield Total", yield_total_sensor_); - LOG_SENSOR(" ", "Yield Yesterday", yield_yesterday_sensor_); - LOG_SENSOR(" ", "Yield Today", yield_today_sensor_); - LOG_SENSOR(" ", "Panel Voltage", panel_voltage_sensor_); - LOG_SENSOR(" ", "Panel Power", panel_power_sensor_); - LOG_SENSOR(" ", "Battery Voltage", battery_voltage_sensor_); - LOG_SENSOR(" ", "Battery Voltage 2", battery_voltage_2_sensor_); - LOG_SENSOR(" ", "Battery Voltage 3", battery_voltage_3_sensor_); - LOG_SENSOR(" ", "Battery Current", battery_current_sensor_); - LOG_SENSOR(" ", "Battery Current", battery_current_2_sensor_); - LOG_SENSOR(" ", "Battery Current", battery_current_3_sensor_); - LOG_SENSOR(" ", "AC Out Voltage", ac_out_voltage_sensor_); - LOG_SENSOR(" ", "AC Out Current", ac_out_current_sensor_); - LOG_SENSOR(" ", "Load Current", load_current_sensor_); - LOG_SENSOR(" ", "Day Number", day_number_sensor_); - LOG_SENSOR(" ", "Charging Mode ID", charging_mode_id_sensor_); - LOG_SENSOR(" ", "Error Code", error_code_sensor_); - LOG_SENSOR(" ", "Warning Code", warning_code_sensor_); - LOG_SENSOR(" ", "Tracking Mode ID", tracking_mode_id_sensor_); - LOG_SENSOR(" ", "Device Mode ID", device_mode_id_sensor_); - LOG_SENSOR(" ", "Off Reason Bitmask", off_reason_bitmask_sensor_); - LOG_TEXT_SENSOR(" ", "Charging Mode", charging_mode_text_sensor_); - LOG_TEXT_SENSOR(" ", "Error Text", error_text_sensor_); - LOG_TEXT_SENSOR(" ", "Warning Text", warning_text_sensor_); - LOG_TEXT_SENSOR(" ", "Tracking Mode", tracking_mode_text_sensor_); - LOG_TEXT_SENSOR(" ", "Device Mode", device_mode_text_sensor_); - LOG_TEXT_SENSOR(" ", "Firmware Version", firmware_version_text_sensor_); - LOG_TEXT_SENSOR(" ", "Firmware Version 24bit", firmware_version_24bit_text_sensor_); - LOG_TEXT_SENSOR(" ", "Device Type", device_type_text_sensor_); - LOG_TEXT_SENSOR(" ", "Off Reason", off_reason_text_sensor_); - - LOG_SENSOR(" ", "Battery Temperature ", battery_temperature_sensor_); - LOG_SENSOR(" ", "Instantaneous Power", instantaneous_power_sensor_); - LOG_SENSOR(" ", "Consumed Amp Hours", consumed_amp_hours_sensor_); - LOG_SENSOR(" ", "State Of Charge", state_of_charge_sensor_); - LOG_SENSOR(" ", "Time To Go", time_to_go_sensor_); - LOG_SENSOR(" ", "Depth Of The Deepest Discharge", depth_of_the_deepest_discharge_sensor_); - LOG_SENSOR(" ", "Depth Of The Last Discharge", depth_of_the_last_discharge_sensor_); - LOG_SENSOR(" ", "Number Of Charge Cycles", number_of_charge_cycles_sensor_); - LOG_SENSOR(" ", "Number Of Full Discharges", number_of_full_discharges_sensor_); - LOG_SENSOR(" ", "Min Battery Voltage", min_battery_voltage_sensor_); - LOG_SENSOR(" ", "Max Battery Voltage", max_battery_voltage_sensor_); - LOG_SENSOR(" ", "Last Full Charge", last_full_charge_sensor_); - LOG_SENSOR(" ", "Amount Of Discharged Energy", amount_of_discharged_energy_sensor_); - LOG_SENSOR(" ", "Amount Of Charged Energy", amount_of_charged_energy_sensor_); - LOG_TEXT_SENSOR(" ", "Alarm Condition Active", alarm_condition_active_text_sensor_); - LOG_TEXT_SENSOR(" ", "Alarm Reason", alarm_reason_text_sensor_); - LOG_TEXT_SENSOR(" ", "Model Description", model_description_text_sensor_); + LOG_BINARY_SENSOR(prefix, "Load state", load_state_binary_sensor_); + LOG_BINARY_SENSOR(prefix, "Relay state", relay_state_binary_sensor_); + LOG_SENSOR(prefix, "Max Power Yesterday", max_power_yesterday_sensor_); + LOG_SENSOR(prefix, "Max Power Today", max_power_today_sensor_); + LOG_SENSOR(prefix, "Yield Total", yield_total_sensor_); + LOG_SENSOR(prefix, "Yield Yesterday", yield_yesterday_sensor_); + LOG_SENSOR(prefix, "Yield Today", yield_today_sensor_); + LOG_SENSOR(prefix, "Panel Voltage", panel_voltage_sensor_); + LOG_SENSOR(prefix, "Panel Power", panel_power_sensor_); + LOG_SENSOR(prefix, "Battery Voltage", battery_voltage_sensor_); + LOG_SENSOR(prefix, "Battery Voltage 2", battery_voltage_2_sensor_); + LOG_SENSOR(prefix, "Battery Voltage 3", battery_voltage_3_sensor_); + LOG_SENSOR(prefix, "Battery Current", battery_current_sensor_); + LOG_SENSOR(prefix, "Battery Current", battery_current_2_sensor_); + LOG_SENSOR(prefix, "Battery Current", battery_current_3_sensor_); + LOG_SENSOR(prefix, "AC Out Voltage", ac_out_voltage_sensor_); + LOG_SENSOR(prefix, "AC Out Current", ac_out_current_sensor_); + LOG_SENSOR(prefix, "Load Current", load_current_sensor_); + LOG_SENSOR(prefix, "Day Number", day_number_sensor_); + LOG_SENSOR(prefix, "Charging Mode ID", charging_mode_id_sensor_); + LOG_SENSOR(prefix, "Error Code", error_code_sensor_); + LOG_SENSOR(prefix, "Warning Code", warning_code_sensor_); + LOG_SENSOR(prefix, "Tracking Mode ID", tracking_mode_id_sensor_); + LOG_SENSOR(prefix, "Device Mode ID", device_mode_id_sensor_); + LOG_SENSOR(prefix, "Off Reason Bitmask", off_reason_bitmask_sensor_); + LOG_TEXT_SENSOR(prefix, "Charging Mode", charging_mode_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Error Text", error_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Warning Text", warning_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Tracking Mode", tracking_mode_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Device Mode", device_mode_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Firmware Version", firmware_version_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Firmware Version 24bit", firmware_version_24bit_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Device Type", device_type_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Off Reason", off_reason_text_sensor_); + + LOG_SENSOR(prefix, "Battery Temperature ", battery_temperature_sensor_); + LOG_SENSOR(prefix, "Instantaneous Power", instantaneous_power_sensor_); + LOG_SENSOR(prefix, "Consumed Amp Hours", consumed_amp_hours_sensor_); + LOG_SENSOR(prefix, "State Of Charge", state_of_charge_sensor_); + LOG_SENSOR(prefix, "Time To Go", time_to_go_sensor_); + LOG_SENSOR(prefix, "Depth Of The Deepest Discharge", depth_of_the_deepest_discharge_sensor_); + LOG_SENSOR(prefix, "Depth Of The Last Discharge", depth_of_the_last_discharge_sensor_); + LOG_SENSOR(prefix, "Number Of Charge Cycles", number_of_charge_cycles_sensor_); + LOG_SENSOR(prefix, "Number Of Full Discharges", number_of_full_discharges_sensor_); + LOG_SENSOR(prefix, "Min Battery Voltage", min_battery_voltage_sensor_); + LOG_SENSOR(prefix, "Max Battery Voltage", max_battery_voltage_sensor_); + LOG_SENSOR(prefix, "Last Full Charge", last_full_charge_sensor_); + LOG_SENSOR(prefix, "Amount Of Discharged Energy", amount_of_discharged_energy_sensor_); + LOG_SENSOR(prefix, "Amount Of Charged Energy", amount_of_charged_energy_sensor_); + LOG_TEXT_SENSOR(prefix, "Alarm Condition Active", alarm_condition_active_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Alarm Reason", alarm_reason_text_sensor_); + LOG_TEXT_SENSOR(prefix, "Model Description", model_description_text_sensor_); check_uart_settings(19200); } From 886a5818448c642f42f72a364409b79f61f20e17 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 16:48:36 +0200 Subject: [PATCH 06/38] Use a const char to prevent memory fragmentation. --- components/victron/victron.cpp | 22 +++++++++++++++------- components/victron/victron.h | 2 ++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index cb6f116..ae69080 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -153,7 +153,7 @@ void VictronComponent::loop() { } } -static std::string charging_mode_text(int value) { +static const char *charging_mode_text(int value) { switch (value) { case 0: return "Off"; @@ -190,7 +190,7 @@ static std::string charging_mode_text(int value) { } } -static std::string error_code_text(int value) { +static const char *error_code_text(int value) { switch (value) { case 0: return "No error"; @@ -237,7 +237,7 @@ static std::string error_code_text(int value) { } } -static std::string warning_code_text(int value) { +static const char *warning_code_text(int value) { switch (value) { case 0: return "No warning"; @@ -270,7 +270,7 @@ static std::string warning_code_text(int value) { } } -static std::string tracking_mode_text(int value) { +static const char *tracking_mode_text(int value) { switch (value) { case 0: return "Off"; @@ -283,7 +283,7 @@ static std::string tracking_mode_text(int value) { } } -static std::string device_mode_text(int value) { +static const char *device_mode_text(int value) { switch (value) { case 0: return "Off"; @@ -341,7 +341,7 @@ static std::string dc_monitor_mode_text(int value) { } } -static std::string device_type_text(int value) { +static const char *device_type_text(int value) { switch (value) { case 0x203: return "BMV-700"; @@ -1121,13 +1121,21 @@ void VictronComponent::publish_state_(sensor::Sensor *sensor, float value) { } void VictronComponent::publish_state_(text_sensor::TextSensor *text_sensor, const std::string &state) { + publish_state_(text_sensor, state.c_str()); +} + +void VictronComponent::publish_state_once_(text_sensor::TextSensor *text_sensor, const std::string &state) { + publish_state_once_(text_sensor, state.c_str()); +} + +void VictronComponent::publish_state_(text_sensor::TextSensor *text_sensor, const char *state) { if (text_sensor == nullptr) return; text_sensor->publish_state(state); } -void VictronComponent::publish_state_once_(text_sensor::TextSensor *text_sensor, const std::string &state) { +void VictronComponent::publish_state_once_(text_sensor::TextSensor *text_sensor, const char *state) { if (text_sensor == nullptr) return; diff --git a/components/victron/victron.h b/components/victron/victron.h index 4f8c8c2..51d487f 100644 --- a/components/victron/victron.h +++ b/components/victron/victron.h @@ -214,6 +214,8 @@ class VictronComponent : public uart::UARTDevice, public Component { void publish_state_(sensor::Sensor *sensor, float value); void publish_state_(text_sensor::TextSensor *text_sensor, const std::string &state); void publish_state_once_(text_sensor::TextSensor *text_sensor, const std::string &state); + void publish_state_(text_sensor::TextSensor *text_sensor, const char *state); + void publish_state_once_(text_sensor::TextSensor *text_sensor, const char *state); binary_sensor::BinarySensor *load_state_binary_sensor_; binary_sensor::BinarySensor *relay_state_binary_sensor_; From 4cde222a86c5004c07849e24726609577568d646 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 16:57:10 +0200 Subject: [PATCH 07/38] Store OFF_REASONS in program memory to reduce RAM usage --- components/victron/victron.cpp | 56 ++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index ae69080..acc4688 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -2,6 +2,7 @@ #include "esphome/core/log.h" #include // std::min #include "esphome/core/helpers.h" +#include namespace esphome { namespace victron { @@ -9,23 +10,39 @@ namespace victron { static const char *const TAG = "victron"; static const uint8_t OFF_REASONS_SIZE = 16; -static const char *const OFF_REASONS[OFF_REASONS_SIZE] = { - "No input power", // 0000 0000 0000 0001 - "Switched off (power switch)", // 0000 0000 0000 0010 - "Switched off (device mode register)", // 0000 0000 0000 0100 - "Remote input", // 0000 0000 0000 1000 - "Protection active", // 0000 0000 0001 0000 - "Paygo", // 0000 0000 0010 0000 - "BMS", // 0000 0000 0100 0000 - "Engine shutdown detection", // 0000 0000 1000 0000 - "Analysing input voltage", // 0000 0001 0000 0000 - "Unknown: Bit 10", // 0000 0010 0000 0000 - "Unknown: Bit 11", // 0000 0100 0000 0000 - "Unknown: Bit 12", // 0000 1000 0000 0000 - "Unknown: Bit 13", // 0001 0000 0000 0000 - "Unknown: Bit 14", // 0010 0000 0000 0000 - "Unknown: Bit 15", // 0100 0000 0000 0000 - "Unknown: Bit 16", // 1000 0000 0000 0000 +static const char OFF_REASONS_0[] PROGMEM = "No input power"; +static const char OFF_REASONS_1[] PROGMEM = "Switched off (power switch)"; +static const char OFF_REASONS_2[] PROGMEM = "Switched off (device mode register)"; +static const char OFF_REASONS_3[] PROGMEM = "Remote input"; +static const char OFF_REASONS_4[] PROGMEM = "Protection active"; +static const char OFF_REASONS_5[] PROGMEM = "Paygo"; +static const char OFF_REASONS_6[] PROGMEM = "BMS"; +static const char OFF_REASONS_7[] PROGMEM = "Engine shutdown detection"; +static const char OFF_REASONS_8[] PROGMEM = "Analysing input voltage"; +static const char OFF_REASONS_9[] PROGMEM = "Unknown: Bit 10"; +static const char OFF_REASONS_10[] PROGMEM = "Unknown: Bit 11"; +static const char OFF_REASONS_11[] PROGMEM = "Unknown: Bit 12"; +static const char OFF_REASONS_12[] PROGMEM = "Unknown: Bit 13"; +static const char OFF_REASONS_13[] PROGMEM = "Unknown: Bit 14"; +static const char OFF_REASONS_14[] PROGMEM = "Unknown: Bit 15"; +static const char OFF_REASONS_15[] PROGMEM = "Unknown: Bit 16"; +static const char *const OFF_REASONS[OFF_REASONS_SIZE] PROGMEM = { + OFF_REASONS_0, + OFF_REASONS_1, + OFF_REASONS_2, + OFF_REASONS_3, + OFF_REASONS_4, + OFF_REASONS_5, + OFF_REASONS_6, + OFF_REASONS_7, + OFF_REASONS_8, + OFF_REASONS_9, + OFF_REASONS_10, + OFF_REASONS_11, + OFF_REASONS_12, + OFF_REASONS_13, + OFF_REASONS_14, + OFF_REASONS_15 }; void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) @@ -697,7 +714,7 @@ static const char *device_type_text(int value) { static std::string off_reason_text(uint32_t mask) { bool first = true; std::string value_list = ""; - + char buffer[48]; if (mask) { for (uint8_t i = 0; i < OFF_REASONS_SIZE; i++) { if (mask & (1 << i)) { @@ -706,7 +723,8 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - value_list.append(OFF_REASONS[i]); + strcpy_P(buffer, (PGM_P)pgm_read_ptr(&OFF_REASONS[i])); + value_list.append(buffer); } } } From 39dbd068a33eae68848148cf37866d3f031a9f6d Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 17:41:07 +0200 Subject: [PATCH 08/38] Store error and charging mode messages in program memory to reduce RAM usage --- components/victron/victron.cpp | 184 +++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 76 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index acc4688..0c776fc 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -45,6 +45,96 @@ static const char *const OFF_REASONS[OFF_REASONS_SIZE] PROGMEM = { OFF_REASONS_15 }; +static const char ERROR_CODE_0[] PROGMEM = "No error"; +static const char ERROR_CODE_2[] PROGMEM = "Battery voltage too high"; +static const char ERROR_CODE_17[] PROGMEM = "Charger temperature too high"; +static const char ERROR_CODE_18[] PROGMEM = "Charger over current"; +static const char ERROR_CODE_19[] PROGMEM = "Charger current reversed"; +static const char ERROR_CODE_20[] PROGMEM = "Bulk time limit exceeded"; +static const char ERROR_CODE_21[] PROGMEM = "Current sensor issue"; +static const char ERROR_CODE_26[] PROGMEM = "Terminals overheated"; +static const char ERROR_CODE_28[] PROGMEM = "Converter issue"; +static const char ERROR_CODE_33[] PROGMEM = "Input voltage too high (solar panel)"; +static const char ERROR_CODE_34[] PROGMEM = "Input current too high (solar panel)"; +static const char ERROR_CODE_38[] PROGMEM = "Input shutdown (excessive battery voltage)"; +static const char ERROR_CODE_39[] PROGMEM = "Input shutdown (due to current flow during off mode)"; +static const char ERROR_CODE_65[] PROGMEM = "Lost communication with one of devices"; +static const char ERROR_CODE_66[] PROGMEM = "Synchronised charging device configuration issue"; +static const char ERROR_CODE_67[] PROGMEM = "BMS connection lost"; +static const char ERROR_CODE_68[] PROGMEM = "Network misconfigured"; +static const char ERROR_CODE_116[] PROGMEM = "Factory calibration data lost"; +static const char ERROR_CODE_117[] PROGMEM = "Invalid/incompatible firmware"; +static const char ERROR_CODE_119[] PROGMEM = "User settings invalid"; +static const char ERROR_CODE_UNKNOWN[] PROGMEM = "Unknown"; + +struct ErrorCodeEntry { + int code; + const char *msg; +}; + +static const ErrorCodeEntry ERROR_CODE_TABLE[] PROGMEM = { + {0, ERROR_CODE_0}, + {2, ERROR_CODE_2}, + {17, ERROR_CODE_17}, + {18, ERROR_CODE_18}, + {19, ERROR_CODE_19}, + {20, ERROR_CODE_20}, + {21, ERROR_CODE_21}, + {26, ERROR_CODE_26}, + {28, ERROR_CODE_28}, + {33, ERROR_CODE_33}, + {34, ERROR_CODE_34}, + {38, ERROR_CODE_38}, + {39, ERROR_CODE_39}, + {65, ERROR_CODE_65}, + {66, ERROR_CODE_66}, + {67, ERROR_CODE_67}, + {68, ERROR_CODE_68}, + {116, ERROR_CODE_116}, + {117, ERROR_CODE_117}, + {119, ERROR_CODE_119} +}; + +static const char CHARGING_MODE_0[] PROGMEM = "Off"; +static const char CHARGING_MODE_1[] PROGMEM = "Low power"; +static const char CHARGING_MODE_2[] PROGMEM = "Fault"; +static const char CHARGING_MODE_3[] PROGMEM = "Bulk"; +static const char CHARGING_MODE_4[] PROGMEM = "Absorption"; +static const char CHARGING_MODE_5[] PROGMEM = "Float"; +static const char CHARGING_MODE_6[] PROGMEM = "Storage"; +static const char CHARGING_MODE_7[] PROGMEM = "Equalize (manual)"; +static const char CHARGING_MODE_9[] PROGMEM = "Inverting"; +static const char CHARGING_MODE_11[] PROGMEM = "Power supply"; +static const char CHARGING_MODE_245[] PROGMEM = "Starting-up"; +static const char CHARGING_MODE_246[] PROGMEM = "Repeated absorption"; +static const char CHARGING_MODE_247[] PROGMEM = "Auto equalize / Recondition"; +static const char CHARGING_MODE_248[] PROGMEM = "BatterySafe"; +static const char CHARGING_MODE_252[] PROGMEM = "External control"; +static const char CHARGING_MODE_UNKNOWN[] PROGMEM = "Unknown"; + +struct ChargingModeEntry { + int code; + const char *msg; +}; + +static const ChargingModeEntry CHARGING_MODE_TABLE[] PROGMEM = { + {0, CHARGING_MODE_0}, + {1, CHARGING_MODE_1}, + {2, CHARGING_MODE_2}, + {3, CHARGING_MODE_3}, + {4, CHARGING_MODE_4}, + {5, CHARGING_MODE_5}, + {6, CHARGING_MODE_6}, + {7, CHARGING_MODE_7}, + {9, CHARGING_MODE_9}, + {11, CHARGING_MODE_11}, + {245, CHARGING_MODE_245}, + {246, CHARGING_MODE_246}, + {247, CHARGING_MODE_247}, + {248, CHARGING_MODE_248}, + {252, CHARGING_MODE_252} +}; + void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) static const char *prefix = " "; ESP_LOGCONFIG(TAG, "Victron:"); @@ -171,87 +261,29 @@ void VictronComponent::loop() { } static const char *charging_mode_text(int value) { - switch (value) { - case 0: - return "Off"; - case 1: - return "Low power"; - case 2: - return "Fault"; - case 3: - return "Bulk"; - case 4: - return "Absorption"; - case 5: - return "Float"; - case 6: - return "Storage"; - case 7: - return "Equalize (manual)"; - case 9: - return "Inverting"; - case 11: - return "Power supply"; - case 245: - return "Starting-up"; - case 246: - return "Repeated absorption"; - case 247: - return "Auto equalize / Recondition"; - case 248: - return "BatterySafe"; - case 252: - return "External control"; - default: - return "Unknown"; +static char buffer[30]; + for (size_t i = 0; i < sizeof(CHARGING_MODE_TABLE) / sizeof(CHARGING_MODE_TABLE[0]); i++) { + int code = pgm_read_dword(&CHARGING_MODE_TABLE[i].code); + if (code == value) { + strcpy_P(buffer, (PGM_P)pgm_read_ptr(&CHARGING_MODE_TABLE[i].msg)); + return strdup(buffer); + } } + strcpy_P(buffer, CHARGING_MODE_UNKNOWN); + return buffer; } static const char *error_code_text(int value) { - switch (value) { - case 0: - return "No error"; - case 2: - return "Battery voltage too high"; - case 17: - return "Charger temperature too high"; - case 18: - return "Charger over current"; - case 19: - return "Charger current reversed"; - case 20: - return "Bulk time limit exceeded"; - case 21: - return "Current sensor issue"; - case 26: - return "Terminals overheated"; - case 28: - return "Converter issue"; - case 33: - return "Input voltage too high (solar panel)"; - case 34: - return "Input current too high (solar panel)"; - case 38: - return "Input shutdown (excessive battery voltage)"; - case 39: - return "Input shutdown (due to current flow during off mode)"; - case 65: - return "Lost communication with one of devices"; - case 66: - return "Synchronised charging device configuration issue"; - case 67: - return "BMS connection lost"; - case 68: - return "Network misconfigured"; - case 116: - return "Factory calibration data lost"; - case 117: - return "Invalid/incompatible firmware"; - case 119: - return "User settings invalid"; - default: - return "Unknown"; +static char buffer[55]; + for (size_t i = 0; i < sizeof(ERROR_CODE_TABLE) / sizeof(ERROR_CODE_TABLE[0]); i++) { + int code = pgm_read_dword(&ERROR_CODE_TABLE[i].code); + if (code == value) { + strcpy_P(buffer, (PGM_P)pgm_read_ptr(&ERROR_CODE_TABLE[i].msg)); + return strdup(buffer); + } } + strcpy_P(buffer, ERROR_CODE_UNKNOWN); + return buffer; } static const char *warning_code_text(int value) { From d9d43f2217b5b8b28df26ce06aff137c46c8cf9b Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Wed, 17 Sep 2025 17:58:23 +0200 Subject: [PATCH 09/38] Optimize memory usage by using static buffers for error and charging mode messages --- components/victron/victron.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 0c776fc..9d7d915 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -67,6 +67,8 @@ static const char ERROR_CODE_117[] PROGMEM = "Invalid/incompatible firmware"; static const char ERROR_CODE_119[] PROGMEM = "User settings invalid"; static const char ERROR_CODE_UNKNOWN[] PROGMEM = "Unknown"; +static char buffer_error_code[53]; + struct ErrorCodeEntry { int code; const char *msg; @@ -112,6 +114,8 @@ static const char CHARGING_MODE_248[] PROGMEM = "BatterySafe"; static const char CHARGING_MODE_252[] PROGMEM = "External control"; static const char CHARGING_MODE_UNKNOWN[] PROGMEM = "Unknown"; +static char buffer_charging_mode[30]; + struct ChargingModeEntry { int code; const char *msg; @@ -261,29 +265,29 @@ void VictronComponent::loop() { } static const char *charging_mode_text(int value) { -static char buffer[30]; +const char *result = CHARGING_MODE_UNKNOWN; + for (size_t i = 0; i < sizeof(CHARGING_MODE_TABLE) / sizeof(CHARGING_MODE_TABLE[0]); i++) { int code = pgm_read_dword(&CHARGING_MODE_TABLE[i].code); if (code == value) { - strcpy_P(buffer, (PGM_P)pgm_read_ptr(&CHARGING_MODE_TABLE[i].msg)); - return strdup(buffer); + result = CHARGING_MODE_TABLE[i].msg; + break; } } - strcpy_P(buffer, CHARGING_MODE_UNKNOWN); - return buffer; + strcpy_P(buffer_charging_mode, result); + return buffer_charging_mode; } static const char *error_code_text(int value) { -static char buffer[55]; for (size_t i = 0; i < sizeof(ERROR_CODE_TABLE) / sizeof(ERROR_CODE_TABLE[0]); i++) { int code = pgm_read_dword(&ERROR_CODE_TABLE[i].code); if (code == value) { - strcpy_P(buffer, (PGM_P)pgm_read_ptr(&ERROR_CODE_TABLE[i].msg)); - return strdup(buffer); + strcpy_P(buffer_error_code, (PGM_P)pgm_read_ptr(&ERROR_CODE_TABLE[i].msg)); + return buffer_error_code; } } - strcpy_P(buffer, ERROR_CODE_UNKNOWN); - return buffer; + strcpy_P(buffer_error_code, ERROR_CODE_UNKNOWN); + return buffer_error_code; } static const char *warning_code_text(int value) { @@ -746,7 +750,7 @@ static const char *device_type_text(int value) { static std::string off_reason_text(uint32_t mask) { bool first = true; std::string value_list = ""; - char buffer[48]; + char buffer[36]; if (mask) { for (uint8_t i = 0; i < OFF_REASONS_SIZE; i++) { if (mask & (1 << i)) { From fa4540b14eae16499f87a6ae19b9138197bab30e Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Thu, 18 Sep 2025 01:12:45 +0200 Subject: [PATCH 10/38] Remove obsolete lookup tables. --- components/victron/victron.cpp | 41 ---------------------------------- 1 file changed, 41 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 9d7d915..43a7a30 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -74,29 +74,6 @@ struct ErrorCodeEntry { const char *msg; }; -static const ErrorCodeEntry ERROR_CODE_TABLE[] PROGMEM = { - {0, ERROR_CODE_0}, - {2, ERROR_CODE_2}, - {17, ERROR_CODE_17}, - {18, ERROR_CODE_18}, - {19, ERROR_CODE_19}, - {20, ERROR_CODE_20}, - {21, ERROR_CODE_21}, - {26, ERROR_CODE_26}, - {28, ERROR_CODE_28}, - {33, ERROR_CODE_33}, - {34, ERROR_CODE_34}, - {38, ERROR_CODE_38}, - {39, ERROR_CODE_39}, - {65, ERROR_CODE_65}, - {66, ERROR_CODE_66}, - {67, ERROR_CODE_67}, - {68, ERROR_CODE_68}, - {116, ERROR_CODE_116}, - {117, ERROR_CODE_117}, - {119, ERROR_CODE_119} -}; - static const char CHARGING_MODE_0[] PROGMEM = "Off"; static const char CHARGING_MODE_1[] PROGMEM = "Low power"; static const char CHARGING_MODE_2[] PROGMEM = "Fault"; @@ -121,24 +98,6 @@ struct ChargingModeEntry { const char *msg; }; -static const ChargingModeEntry CHARGING_MODE_TABLE[] PROGMEM = { - {0, CHARGING_MODE_0}, - {1, CHARGING_MODE_1}, - {2, CHARGING_MODE_2}, - {3, CHARGING_MODE_3}, - {4, CHARGING_MODE_4}, - {5, CHARGING_MODE_5}, - {6, CHARGING_MODE_6}, - {7, CHARGING_MODE_7}, - {9, CHARGING_MODE_9}, - {11, CHARGING_MODE_11}, - {245, CHARGING_MODE_245}, - {246, CHARGING_MODE_246}, - {247, CHARGING_MODE_247}, - {248, CHARGING_MODE_248}, - {252, CHARGING_MODE_252} -}; - void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) static const char *prefix = " "; ESP_LOGCONFIG(TAG, "Victron:"); From 4110f9f0465f1c400459537223357a20e6906aec Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Thu, 18 Sep 2025 01:14:05 +0200 Subject: [PATCH 11/38] Remove the loop and use switch to improve performance. --- components/victron/victron.cpp | 56 +++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 43a7a30..f30a6b6 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -224,14 +224,56 @@ void VictronComponent::loop() { } static const char *charging_mode_text(int value) { -const char *result = CHARGING_MODE_UNKNOWN; - - for (size_t i = 0; i < sizeof(CHARGING_MODE_TABLE) / sizeof(CHARGING_MODE_TABLE[0]); i++) { - int code = pgm_read_dword(&CHARGING_MODE_TABLE[i].code); - if (code == value) { - result = CHARGING_MODE_TABLE[i].msg; + const char *result; + switch (value) { + case 0: + result = CHARGING_MODE_0; + break; + case 1: + result = CHARGING_MODE_1; + break; + case 2: + result = CHARGING_MODE_2; + break; + case 3: + result = CHARGING_MODE_3; + break; + case 4: + result = CHARGING_MODE_4; + break; + case 5: + result = CHARGING_MODE_5; + break; + case 6: + result = CHARGING_MODE_6; + break; + case 7: + result = CHARGING_MODE_7; + break; + case 9: + result = CHARGING_MODE_9; + break; + case 11: + result = CHARGING_MODE_11; + break; + case 245: + result = CHARGING_MODE_245; + break; + case 246: + result = CHARGING_MODE_246; + break; + case 247: + result = CHARGING_MODE_247; + break; + case 248: + result = CHARGING_MODE_248; + break; + case 252: + result = CHARGING_MODE_252; + break; + default: + result = CHARGING_MODE_UNKNOWN; break; - } } strcpy_P(buffer_charging_mode, result); return buffer_charging_mode; From 58115aec4a4da460e81cc431e3c9a9df56147847 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Thu, 18 Sep 2025 01:14:49 +0200 Subject: [PATCH 12/38] Remove the loop and use switch to improve performance. --- components/victron/victron.cpp | 79 ++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index f30a6b6..3d3a500 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -280,14 +280,73 @@ static const char *charging_mode_text(int value) { } static const char *error_code_text(int value) { - for (size_t i = 0; i < sizeof(ERROR_CODE_TABLE) / sizeof(ERROR_CODE_TABLE[0]); i++) { - int code = pgm_read_dword(&ERROR_CODE_TABLE[i].code); - if (code == value) { - strcpy_P(buffer_error_code, (PGM_P)pgm_read_ptr(&ERROR_CODE_TABLE[i].msg)); - return buffer_error_code; - } + const char *result; + switch (value) { + case 0: + result = ERROR_CODE_0; + break; + case 2: + result = ERROR_CODE_2; + break; + case 17: + result = ERROR_CODE_17; + break; + case 18: + result = ERROR_CODE_18; + break; + case 19: + result = ERROR_CODE_19; + break; + case 20: + result = ERROR_CODE_20; + break; + case 21: + result = ERROR_CODE_21; + break; + case 26: + result = ERROR_CODE_26; + break; + case 28: + result = ERROR_CODE_28; + break; + case 33: + result = ERROR_CODE_33; + break; + case 34: + result = ERROR_CODE_34; + break; + case 38: + result = ERROR_CODE_38; + break; + case 39: + result = ERROR_CODE_39; + break; + case 65: + result = ERROR_CODE_65; + break; + case 66: + result = ERROR_CODE_66; + break; + case 67: + result = ERROR_CODE_67; + break; + case 68: + result = ERROR_CODE_68; + break; + case 116: + result = ERROR_CODE_116; + break; + case 117: + result = ERROR_CODE_117; + break; + case 119: + result = ERROR_CODE_119; + break; + default: + result = ERROR_CODE_UNKNOWN; + break; } - strcpy_P(buffer_error_code, ERROR_CODE_UNKNOWN); + strcpy_P(buffer_error_code, result); return buffer_error_code; } @@ -743,9 +802,13 @@ static const char *device_type_text(int value) { return "SmartSolar MPPT RS 450/200"; case 0xA117: return "BlueSolar MPPT VE.Can 150|100"; + default: - return "Unknown"; + result = DEVICE_TYPE_UNKNOWN; + break; } + strcpy_P(buffer_device_type, result); + return buffer_device_type; } static std::string off_reason_text(uint32_t mask) { From a13b03f98d43329131b7c8cea207fa6e2314d805 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Thu, 18 Sep 2025 01:15:28 +0200 Subject: [PATCH 13/38] Partially refactor device_type. --- components/victron/victron.cpp | 579 +++++++++++++++++++++++++-------- 1 file changed, 436 insertions(+), 143 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 3d3a500..3514e1f 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -454,295 +454,588 @@ static std::string dc_monitor_mode_text(int value) { } } +// Device type strings in PROGMEM +static const char DEVICE_TYPE_BMV_700[] PROGMEM = "BMV-700"; +static const char DEVICE_TYPE_BMV_702[] PROGMEM = "BMV-702"; +static const char DEVICE_TYPE_BMV_700H[] PROGMEM = "BMV-700H"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_70_15[] PROGMEM = "BlueSolar MPPT 70|15"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_50[] PROGMEM = "BlueSolar MPPT 75|50"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_35[] PROGMEM = "BlueSolar MPPT 150|35"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15[] PROGMEM = "BlueSolar MPPT 75|15"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_15[] PROGMEM = "BlueSolar MPPT 100|15"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30[] PROGMEM = "BlueSolar MPPT 100|30"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50[] PROGMEM = "BlueSolar MPPT 100|50"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_70[] PROGMEM = "BlueSolar MPPT 150|70"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_100[] PROGMEM = "BlueSolar MPPT 150|100"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50_REV2[] PROGMEM = "BlueSolar MPPT 100|50 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30_REV2[] PROGMEM = "BlueSolar MPPT 100|30 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_35_REV2[] PROGMEM = "BlueSolar MPPT 150|35 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10[] PROGMEM = "BlueSolar MPPT 75|10"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45[] PROGMEM = "BlueSolar MPPT 150|45"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_60[] PROGMEM = "BlueSolar MPPT 150|60"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_85[] PROGMEM = "BlueSolar MPPT 150|85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_100[] PROGMEM = "SmartSolar MPPT 250|100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100[] PROGMEM = "SmartSolar MPPT 150|100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85[] PROGMEM = "SmartSolar MPPT 150|85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_15[] PROGMEM = "SmartSolar MPPT 75|15"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_15_REV2[] PROGMEM = "SmartSolar MPPT 75|15 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_10[] PROGMEM = "SmartSolar MPPT 75|10"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_10_REV2[] PROGMEM = "SmartSolar MPPT 75|10 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_15[] PROGMEM = "SmartSolar MPPT 100|15"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_30[] PROGMEM = "SmartSolar MPPT 100|30"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45_REV3[] PROGMEM = "SmartSolar MPPT 150|45 rev3"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_50[] PROGMEM = "SmartSolar MPPT 100|50"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_35[] PROGMEM = "SmartSolar MPPT 150|35"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100_REV2[] PROGMEM = "SmartSolar MPPT 150|100 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85_REV2[] PROGMEM = "SmartSolar MPPT 150|85 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_70[] PROGMEM = "SmartSolar MPPT 250|70"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_85[] PROGMEM = "SmartSolar MPPT 250|85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_60[] PROGMEM = "SmartSolar MPPT 250|60"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_45[] PROGMEM = "SmartSolar MPPT 250|45"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_20[] PROGMEM = "SmartSolar MPPT 100|20"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_20_48V[] PROGMEM = "SmartSolar MPPT 100|20 48V"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45[] PROGMEM = "SmartSolar MPPT 150|45"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_60[] PROGMEM = "SmartSolar MPPT 150|60"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_70[] PROGMEM = "SmartSolar MPPT 150|70"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_85_REV2[] PROGMEM = "SmartSolar MPPT 250|85 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_100_REV2[] PROGMEM = "SmartSolar MPPT 250|100 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_20[] PROGMEM = "BlueSolar MPPT 100|20"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_20_48V[] PROGMEM = "BlueSolar MPPT 100|20 48V"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_60_REV2[] PROGMEM = "SmartSolar MPPT 250|60 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_70_REV2[] PROGMEM = "SmartSolar MPPT 250|70 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45_REV2[] PROGMEM = "SmartSolar MPPT 150|45 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_60_REV2[] PROGMEM = "SmartSolar MPPT 150|60 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_70_REV2[] PROGMEM = "SmartSolar MPPT 150|70 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85_REV3[] PROGMEM = "SmartSolar MPPT 150|85 rev3"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100_REV3[] PROGMEM = "SmartSolar MPPT 150|100 rev3"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45_REV2[] PROGMEM = "BlueSolar MPPT 150|45 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_60_REV2[] PROGMEM = "BlueSolar MPPT 150|60 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_70_REV2[] PROGMEM = "BlueSolar MPPT 150|70 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15_REV3[] PROGMEM = "BlueSolar MPPT 75|15 rev3"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_70[] PROGMEM = "SmartSolar MPPT VE.Can 150/70"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_45[] PROGMEM = "SmartSolar MPPT VE.Can 150/45"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_60[] PROGMEM = "SmartSolar MPPT VE.Can 150/60"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_85[] PROGMEM = "SmartSolar MPPT VE.Can 150/85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_100[] PROGMEM = "SmartSolar MPPT VE.Can 150/100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_45[] PROGMEM = "SmartSolar MPPT VE.Can 250/45"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_60[] PROGMEM = "SmartSolar MPPT VE.Can 250/60"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_70[] PROGMEM = "SmartSolar MPPT VE.Can 250/70"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_85[] PROGMEM = "SmartSolar MPPT VE.Can 250/85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_100[] PROGMEM = "SmartSolar MPPT VE.Can 250/100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_70_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/70 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_85_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/85 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_100_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/100 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_150_100[] PROGMEM = "BlueSolar MPPT VE.Can 150/100"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_250_70[] PROGMEM = "BlueSolar MPPT VE.Can 250/70"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_250_100[] PROGMEM = "BlueSolar MPPT VE.Can 250/100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_70_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/70 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_100_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/100 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_85_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/85 rev2"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_230V[] PROGMEM = "Phoenix Inverter 12V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_230V[] PROGMEM = "Phoenix Inverter 24V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_230V[] PROGMEM = "Phoenix Inverter 48V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_230V[] PROGMEM = "Phoenix Inverter 12V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_230V[] PROGMEM = "Phoenix Inverter 24V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_230V[] PROGMEM = "Phoenix Inverter 48V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_230V[] PROGMEM = "Phoenix Inverter 12V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_230V[] PROGMEM = "Phoenix Inverter 24V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_230V[] PROGMEM = "Phoenix Inverter 48V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_230V[] PROGMEM = "Phoenix Inverter 12V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_230V[] PROGMEM = "Phoenix Inverter 24V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_230V[] PROGMEM = "Phoenix Inverter 48V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_120V[] PROGMEM = "Phoenix Inverter 12V 250VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_120V[] PROGMEM = "Phoenix Inverter 24V 250VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_120V[] PROGMEM = "Phoenix Inverter 48V 250VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_230V[] PROGMEM = "Phoenix Inverter 12V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_230V[] PROGMEM = "Phoenix Inverter 24V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_230V[] PROGMEM = "Phoenix Inverter 48V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_120V[] PROGMEM = "Phoenix Inverter 12V 375VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_120V[] PROGMEM = "Phoenix Inverter 24V 375VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_120V[] PROGMEM = "Phoenix Inverter 48V 375VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_230V[] PROGMEM = "Phoenix Inverter 12V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_230V[] PROGMEM = "Phoenix Inverter 24V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_230V[] PROGMEM = "Phoenix Inverter 48V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_120V[] PROGMEM = "Phoenix Inverter 12V 500VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_120V[] PROGMEM = "Phoenix Inverter 24V 500VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_120V[] PROGMEM = "Phoenix Inverter 48V 500VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230V[] PROGMEM = "Phoenix Inverter 12V 800VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230V[] PROGMEM = "Phoenix Inverter 24V 800VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230V[] PROGMEM = "Phoenix Inverter 48V 800VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120V[] PROGMEM = "Phoenix Inverter 12V 800VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120V[] PROGMEM = "Phoenix Inverter 24V 800VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120V[] PROGMEM = "Phoenix Inverter 48V 800VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230V[] PROGMEM = "Phoenix Inverter 12V 1200VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230V[] PROGMEM = "Phoenix Inverter 24V 1200VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230V[] PROGMEM = "Phoenix Inverter 48V 1200VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_120V[] PROGMEM = "Phoenix Inverter 12V 1200VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120V[] PROGMEM = "Phoenix Inverter 24V 1200VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120V[] PROGMEM = "Phoenix Inverter 48V 1200VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1600VA_230V[] PROGMEM = "Phoenix Inverter 12V 1600VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1600VA_230V[] PROGMEM = "Phoenix Inverter 24V 1600VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1600VA_230V[] PROGMEM = "Phoenix Inverter 48V 1600VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_2000VA_230V[] PROGMEM = "Phoenix Inverter 12V 2000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_2000VA_230V[] PROGMEM = "Phoenix Inverter 24V 2000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_2000VA_230V[] PROGMEM = "Phoenix Inverter 48V 2000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_3000VA_230V[] PROGMEM = "Phoenix Inverter 12V 3000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_3000VA_230V[] PROGMEM = "Phoenix Inverter 24V 3000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_3000VA_230V[] PROGMEM = "Phoenix Inverter 48V 3000VA 230V"; +static const char DEVICE_TYPE_BLUE_SMART_IP65_CHARGER_12_25[] PROGMEM = "Blue Smart IP65 Charger 12|25"; +static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_8[] PROGMEM = "Blue Smart IP22 Charger 24|8"; +static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_12[] PROGMEM = "Blue Smart IP22 Charger 24|12"; +static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_16[] PROGMEM = "Blue Smart IP22 Charger 24|16"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_50_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 12|50 (1+1)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_50_3[] PROGMEM = "Phoenix Smart IP43 Charger 12|50 (3)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_25_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 24|25 (1+1)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_25_3[] PROGMEM = "Phoenix Smart IP43 Charger 24|25 (3)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_30_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 12|30 (1+1)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_30_3[] PROGMEM = "Phoenix Smart IP43 Charger 12|30 (3)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_16_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 24|16 (1+1)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_16_3[] PROGMEM = "Phoenix Smart IP43 Charger 24|16 (3)"; +static const char DEVICE_TYPE_BMV_712_SMART[] PROGMEM = "BMV-712 Smart"; +static const char DEVICE_TYPE_BMV_710H_SMART[] PROGMEM = "BMV-710H Smart"; +static const char DEVICE_TYPE_BMV_712_SMART_REV2[] PROGMEM = "BMV-712 Smart Rev2"; +static const char DEVICE_TYPE_SMARTSHUNT_500A_50MV[] PROGMEM = "SmartShunt 500A/50mV"; +static const char DEVICE_TYPE_SMARTSHUNT_1000A_50MV[] PROGMEM = "SmartShunt 1000A/50mV"; +static const char DEVICE_TYPE_SMARTSHUNT_2000A_50MV[] PROGMEM = "SmartShunt 2000A/50mV"; +static const char DEVICE_TYPE_MULTI_RS_SOLAR_48V_6000VA_230V[] PROGMEM = "Multi RS Solar 48V 6000VA 230V"; +static const char DEVICE_TYPE_UNKNOWN[] PROGMEM = "Unknown"; + +static char buffer_device_type[48]; + static const char *device_type_text(int value) { + const char *result; switch (value) { case 0x203: - return "BMV-700"; + result = DEVICE_TYPE_BMV_700; + break; case 0x204: - return "BMV-702"; + result = DEVICE_TYPE_BMV_702; + break; case 0x205: - return "BMV-700H"; + result = DEVICE_TYPE_BMV_700H; + break; case 0x0300: - return "BlueSolar MPPT 70|15"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_70_15; + break; case 0xA040: - return "BlueSolar MPPT 75|50"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_75_50; + break; case 0xA041: - return "BlueSolar MPPT 150|35"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_35; + break; case 0xA042: - return "BlueSolar MPPT 75|15"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_75_15; + break; case 0xA043: - return "BlueSolar MPPT 100|15"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_15; + break; case 0xA044: - return "BlueSolar MPPT 100|30"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_30; + break; case 0xA045: - return "BlueSolar MPPT 100|50"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_50; + break; case 0xA046: - return "BlueSolar MPPT 150|70"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_70; + break; case 0xA047: - return "BlueSolar MPPT 150|100"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_100; + break; case 0xA049: - return "BlueSolar MPPT 100|50 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_50_REV2; + break; case 0xA04A: - return "BlueSolar MPPT 100|30 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_30_REV2; + break; case 0xA04B: - return "BlueSolar MPPT 150|35 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_35_REV2; + break; case 0xA04C: - return "BlueSolar MPPT 75|10"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_75_10; + break; case 0xA04D: - return "BlueSolar MPPT 150|45"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_45; + break; case 0xA04E: - return "BlueSolar MPPT 150|60"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_60; + break; case 0xA04F: - return "BlueSolar MPPT 150|85"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_85; + break; case 0xA050: - return "SmartSolar MPPT 250|100"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_100; + break; case 0xA051: - return "SmartSolar MPPT 150|100"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_100; + break; case 0xA052: - return "SmartSolar MPPT 150|85"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_85; + break; case 0xA053: - return "SmartSolar MPPT 75|15"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_75_15; + break; case 0xA075: - return "SmartSolar MPPT 75|15 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_75_15_REV2; + break; case 0xA054: - return "SmartSolar MPPT 75|10"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_75_10; + break; case 0xA074: - return "SmartSolar MPPT 75|10 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_75_10_REV2; + break; case 0xA055: - return "SmartSolar MPPT 100|15"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_100_15; + break; case 0xA056: - return "SmartSolar MPPT 100|30"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_100_30; + break; case 0xA073: - return "SmartSolar MPPT 150|45 rev3"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_45_REV3; + break; case 0xA057: - return "SmartSolar MPPT 100|50"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_100_50; + break; case 0xA058: - return "SmartSolar MPPT 150|35"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_35; + break; case 0xA059: - return "SmartSolar MPPT 150|100 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_100_REV2; + break; case 0xA05A: - return "SmartSolar MPPT 150|85 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_85_REV2; + break; case 0xA05B: - return "SmartSolar MPPT 250|70"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_70; + break; case 0xA05C: - return "SmartSolar MPPT 250|85"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_85; + break; case 0xA05D: - return "SmartSolar MPPT 250|60"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_60; + break; case 0xA05E: - return "SmartSolar MPPT 250|45"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_45; + break; case 0xA05F: - return "SmartSolar MPPT 100|20"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_100_20; + break; case 0xA060: - return "SmartSolar MPPT 100|20 48V"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_100_20_48V; + break; case 0xA061: - return "SmartSolar MPPT 150|45"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_45; + break; case 0xA062: - return "SmartSolar MPPT 150|60"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_60; + break; case 0xA063: - return "SmartSolar MPPT 150|70"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_70; + break; case 0xA064: - return "SmartSolar MPPT 250|85 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_85_REV2; + break; case 0xA065: - return "SmartSolar MPPT 250|100 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_100_REV2; + break; case 0xA066: - return "BlueSolar MPPT 100|20"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_20; + break; case 0xA067: - return "BlueSolar MPPT 100|20 48V"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_20_48V; + break; case 0xA068: - return "SmartSolar MPPT 250|60 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_60_REV2; + break; case 0xA069: - return "SmartSolar MPPT 250|70 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_250_70_REV2; + break; case 0xA06A: - return "SmartSolar MPPT 150|45 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_45_REV2; + break; case 0xA06B: - return "SmartSolar MPPT 150|60 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_60_REV2; + break; case 0xA06C: - return "SmartSolar MPPT 150|70 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_70_REV2; + break; case 0xA06D: - return "SmartSolar MPPT 150|85 rev3"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_85_REV3; + break; case 0xA06E: - return "SmartSolar MPPT 150|100 rev3"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_150_100_REV3; + break; case 0xA06F: - return "BlueSolar MPPT 150|45 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_45_REV2; + break; case 0xA070: - return "BlueSolar MPPT 150|60 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_60_REV2; + break; case 0xA071: - return "BlueSolar MPPT 150|70 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_70_REV2; + break; case 0xA07D: - return "BlueSolar MPPT 75|15 rev3"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_75_15_REV3; + break; case 0xA102: - return "SmartSolar MPPT VE.Can 150/70"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_70; + break; case 0xA103: - return "SmartSolar MPPT VE.Can 150/45"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_45; + break; case 0xA104: - return "SmartSolar MPPT VE.Can 150/60"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_60; + break; case 0xA105: - return "SmartSolar MPPT VE.Can 150/85"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_85; + break; case 0xA106: - return "SmartSolar MPPT VE.Can 150/100"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_100; + break; case 0xA107: - return "SmartSolar MPPT VE.Can 250/45"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_45; + break; case 0xA108: - return "SmartSolar MPPT VE.Can 250/60"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_60; + break; case 0xA109: - return "SmartSolar MPPT VE.Can 250/70"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_70; + break; case 0xA10A: - return "SmartSolar MPPT VE.Can 250/85"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_85; + break; case 0xA10B: - return "SmartSolar MPPT VE.Can 250/100"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_100; + break; case 0xA10C: - return "SmartSolar MPPT VE.Can 150/70 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_70_REV2; + break; case 0xA10D: - return "SmartSolar MPPT VE.Can 150/85 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_85_REV2; + break; case 0xA10E: - return "SmartSolar MPPT VE.Can 150/100 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_100_REV2; + break; case 0xA10F: - return "BlueSolar MPPT VE.Can 150/100"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_150_100; + break; case 0xA112: - return "BlueSolar MPPT VE.Can 250/70"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_250_70; + break; case 0xA113: - return "BlueSolar MPPT VE.Can 250/100"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_250_100; + break; case 0xA114: - return "SmartSolar MPPT VE.Can 250/70 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_70_REV2; + break; case 0xA115: - return "SmartSolar MPPT VE.Can 250/100 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_100_REV2; + break; case 0xA116: - return "SmartSolar MPPT VE.Can 250/85 rev2"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_85_REV2; + break; case 0xA201: - return "Phoenix Inverter 12V 250VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_230V; + break; case 0xA202: - return "Phoenix Inverter 24V 250VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_230V; + break; case 0xA204: - return "Phoenix Inverter 48V 250VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_230V; + break; case 0xA211: - return "Phoenix Inverter 12V 375VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_230V; + break; case 0xA212: - return "Phoenix Inverter 24V 375VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_230V; + break; case 0xA214: - return "Phoenix Inverter 48V 375VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_230V; + break; case 0xA221: - return "Phoenix Inverter 12V 500VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_230V; + break; case 0xA222: - return "Phoenix Inverter 24V 500VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_230V; + break; case 0xA224: - return "Phoenix Inverter 48V 500VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_230V; + break; case 0xA231: - return "Phoenix Inverter 12V 250VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_230V; + break; case 0xA232: - return "Phoenix Inverter 24V 250VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_230V; + break; case 0xA234: - return "Phoenix Inverter 48V 250VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_230V; + break; case 0xA239: - return "Phoenix Inverter 12V 250VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_120V; + break; case 0xA23A: - return "Phoenix Inverter 24V 250VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_120V; + break; case 0xA23C: - return "Phoenix Inverter 48V 250VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_120V; + break; case 0xA241: - return "Phoenix Inverter 12V 375VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_230V; + break; case 0xA242: - return "Phoenix Inverter 24V 375VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_230V; + break; case 0xA244: - return "Phoenix Inverter 48V 375VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_230V; + break; case 0xA249: - return "Phoenix Inverter 12V 375VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_120V; + break; case 0xA24A: - return "Phoenix Inverter 24V 375VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_120V; + break; case 0xA24C: - return "Phoenix Inverter 48V 375VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_120V; + break; case 0xA251: - return "Phoenix Inverter 12V 500VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_230V; + break; case 0xA252: - return "Phoenix Inverter 24V 500VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_230V; + break; case 0xA254: - return "Phoenix Inverter 48V 500VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_230V; + break; case 0xA259: - return "Phoenix Inverter 12V 500VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_120V; + break; case 0xA25A: - return "Phoenix Inverter 24V 500VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_120V; + break; case 0xA25C: - return "Phoenix Inverter 48V 500VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_120V; + break; case 0xA261: - return "Phoenix Inverter 12V 800VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230V; + break; case 0xA262: - return "Phoenix Inverter 24V 800VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230V; + break; case 0xA264: - return "Phoenix Inverter 48V 800VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230V; + break; case 0xA269: - return "Phoenix Inverter 12V 800VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120V; + break; case 0xA26A: - return "Phoenix Inverter 24V 800VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120V; + break; case 0xA26C: - return "Phoenix Inverter 48V 800VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120V; + break; case 0xA271: - return "Phoenix Inverter 12V 1200VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230V; + break; case 0xA272: - return "Phoenix Inverter 24V 1200VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230V; + break; case 0xA274: - return "Phoenix Inverter 48V 1200VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230V; + break; case 0xA279: case 0xA2F9: - return "Phoenix Inverter 12V 1200VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_120V; + break; case 0xA27A: - return "Phoenix Inverter 24V 1200VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120V; + break; case 0xA27C: - return "Phoenix Inverter 48V 1200VA 120V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120V; + break; case 0xA281: - return "Phoenix Inverter 12V 1600VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_1600VA_230V; + break; case 0xA282: - return "Phoenix Inverter 24V 1600VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_1600VA_230V; + break; case 0xA284: - return "Phoenix Inverter 48V 1600VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_1600VA_230V; + break; case 0xA291: - return "Phoenix Inverter 12V 2000VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_2000VA_230V; + break; case 0xA292: - return "Phoenix Inverter 24V 2000VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_2000VA_230V; + break; case 0xA294: - return "Phoenix Inverter 48V 2000VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_2000VA_230V; + break; case 0xA2A1: - return "Phoenix Inverter 12V 3000VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_3000VA_230V; + break; case 0xA2A2: - return "Phoenix Inverter 24V 3000VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_3000VA_230V; + break; case 0xA2A4: - return "Phoenix Inverter 48V 3000VA 230V"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_3000VA_230V; + break; case 0xA30A: - return "Blue Smart IP65 Charger 12|25"; + result = DEVICE_TYPE_BLUE_SMART_IP65_CHARGER_12_25; + break; case 0xA332: - return "Blue Smart IP22 Charger 24|8"; + result = DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_8; + break; case 0xA334: - return "Blue Smart IP22 Charger 24|12"; + result = DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_12; + break; case 0xA336: - return "Blue Smart IP22 Charger 24|16"; + result = DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_16; + break; case 0xA340: - return "Phoenix Smart IP43 Charger 12|50 (1+1)"; + result = DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_50_1_1; + break; case 0xA341: - return "Phoenix Smart IP43 Charger 12|50 (3)"; + result = DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_50_3; + break; case 0xA342: - return "Phoenix Smart IP43 Charger 24|25 (1+1)"; + result = DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_25_1_1; + break; case 0xA343: - return "Phoenix Smart IP43 Charger 24|25 (3)"; + result = DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_25_3; + break; case 0xA344: - return "Phoenix Smart IP43 Charger 12|30 (1+1)"; + result = DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_30_1_1; + break; case 0xA345: - return "Phoenix Smart IP43 Charger 12|30 (3)"; + result = DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_30_3; + break; case 0xA346: - return "Phoenix Smart IP43 Charger 24|16 (1+1)"; + result = DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_16_1_1; + break; case 0xA347: - return "Phoenix Smart IP43 Charger 24|16 (3)"; + result = DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_16_3; + break; case 0xA381: - return "BMV-712 Smart"; + result = DEVICE_TYPE_BMV_712_SMART; + break; case 0xA382: - return "BMV-710H Smart"; + result = DEVICE_TYPE_BMV_710H_SMART; + break; case 0xA383: - return "BMV-712 Smart Rev2"; + result = DEVICE_TYPE_BMV_712_SMART_REV2; + break; case 0xA389: - return "SmartShunt 500A/50mV"; + result = DEVICE_TYPE_SMARTSHUNT_500A_50MV; + break; case 0xA38A: - return "SmartShunt 1000A/50mV"; + result = DEVICE_TYPE_SMARTSHUNT_1000A_50MV; + break; case 0xA38B: - return "SmartShunt 2000A/50mV"; + result = DEVICE_TYPE_SMARTSHUNT_2000A_50MV; + break; case 0xA442: - return "Multi RS Solar 48V 6000VA 230V"; + result = DEVICE_TYPE_MULTI_RS_SOLAR_48V_6000VA_230V; + break; + // Additional PIDs mentioned in VE.Direct-HEX-Protocol specifications case 0xA2B1: return "Phoenix Inverter Smart 12V 5000VA 230Vac 64k"; From 2a9501ddf4a5866b7381a54c0bef38c8124a2200 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Thu, 18 Sep 2025 01:31:49 +0200 Subject: [PATCH 14/38] Remove duplicates and add missing ones. --- components/victron/victron.cpp | 127 +++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 38 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 3514e1f..10725b7 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -540,21 +540,13 @@ static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_230V[] PROGMEM = "Phoen static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_230V[] PROGMEM = "Phoenix Inverter 12V 500VA 230V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_230V[] PROGMEM = "Phoenix Inverter 24V 500VA 230V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_230V[] PROGMEM = "Phoenix Inverter 48V 500VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_230V[] PROGMEM = "Phoenix Inverter 12V 250VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_230V[] PROGMEM = "Phoenix Inverter 24V 250VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_230V[] PROGMEM = "Phoenix Inverter 48V 250VA 230V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_120V[] PROGMEM = "Phoenix Inverter 12V 250VA 120V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_120V[] PROGMEM = "Phoenix Inverter 24V 250VA 120V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_120V[] PROGMEM = "Phoenix Inverter 48V 250VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_230V[] PROGMEM = "Phoenix Inverter 12V 375VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_230V[] PROGMEM = "Phoenix Inverter 24V 375VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_230V[] PROGMEM = "Phoenix Inverter 48V 375VA 230V"; + static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_120V[] PROGMEM = "Phoenix Inverter 12V 375VA 120V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_120V[] PROGMEM = "Phoenix Inverter 24V 375VA 120V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_120V[] PROGMEM = "Phoenix Inverter 48V 375VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_230V[] PROGMEM = "Phoenix Inverter 12V 500VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_230V[] PROGMEM = "Phoenix Inverter 24V 500VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_230V[] PROGMEM = "Phoenix Inverter 48V 500VA 230V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_120V[] PROGMEM = "Phoenix Inverter 12V 500VA 120V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_120V[] PROGMEM = "Phoenix Inverter 24V 500VA 120V"; static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_120V[] PROGMEM = "Phoenix Inverter 48V 500VA 120V"; @@ -598,6 +590,36 @@ static const char DEVICE_TYPE_SMARTSHUNT_500A_50MV[] PROGMEM = "SmartShunt 500A/ static const char DEVICE_TYPE_SMARTSHUNT_1000A_50MV[] PROGMEM = "SmartShunt 1000A/50mV"; static const char DEVICE_TYPE_SMARTSHUNT_2000A_50MV[] PROGMEM = "SmartShunt 2000A/50mV"; static const char DEVICE_TYPE_MULTI_RS_SOLAR_48V_6000VA_230V[] PROGMEM = "Multi RS Solar 48V 6000VA 230V"; +// Add missing PROGMEM definitions for Phoenix Inverter Smart device types +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_12V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 12V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_24V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 24V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_48V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 48V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 1200VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 1200VA 120Vac 64k HS"; +static const char DEVICE_TYPE_ORION_XS_12V_12V_50A[] PROGMEM = "Orion XS 12V/12V-50A"; +static const char DEVICE_TYPE_ORION_XS_1400[] PROGMEM = "Orion XS 1400"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_50_REV2[] PROGMEM = "BlueSolar MPPT 75|50 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45_REV3[] PROGMEM = "BlueSolar MPPT 150|45 rev3"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30_REV3[] PROGMEM = "BlueSolar MPPT 100|30 rev3"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50_REV3[] PROGMEM = "BlueSolar MPPT 100|50 rev3"; + +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10_REV2[] PROGMEM = "BlueSolar MPPT 75|10 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15_REV2[] PROGMEM = "BlueSolar MPPT 75|15 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_15_REV2[] PROGMEM = "BlueSolar MPPT 100|15 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10_REV3[] PROGMEM = "BlueSolar MPPT 75/10 rev3"; +static const char DEVICE_TYPE_SMARTSOLAR_CHARGER_MPPT_100_30[] PROGMEM = "SmartSolar Charger MPPT 100/30"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_100[] PROGMEM = "SmartSolar MPPT RS 450/100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_200[] PROGMEM = "SmartSolar MPPT RS 450/200"; + static const char DEVICE_TYPE_UNKNOWN[] PROGMEM = "Unknown"; static char buffer_device_type[48]; @@ -1038,63 +1060,92 @@ static const char *device_type_text(int value) { // Additional PIDs mentioned in VE.Direct-HEX-Protocol specifications case 0xA2B1: - return "Phoenix Inverter Smart 12V 5000VA 230Vac 64k"; + result = DEVICE_TYPE_PHOENIX_INVERTER_SMART_12V_5000VA_230VAC_64K; + break; case 0xA2B2: - return "Phoenix Inverter Smart 24V 5000VA 230Vac 64k"; + result = DEVICE_TYPE_PHOENIX_INVERTER_SMART_24V_5000VA_230VAC_64K; + break; case 0xA2B4: - return "Phoenix Inverter Smart 48V 5000VA 230Vac 64k"; + result = DEVICE_TYPE_PHOENIX_INVERTER_SMART_48V_5000VA_230VAC_64K; + break; case 0xA2E1: - return "Phoenix Inverter 12V 800VA 230Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230VAC_64K_HS; + break; case 0xA2E2: - return "Phoenix Inverter 24V 800VA 230Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230VAC_64K_HS; + break; case 0xA2E4: - return "Phoenix Inverter 48V 800VA 230Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230VAC_64K_HS; + break; case 0xA2E9: - return "Phoenix Inverter 12V 800VA 120Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120VAC_64K_HS; + break; case 0xA2EA: - return "Phoenix Inverter 24V 800VA 120Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120VAC_64K_HS; + break; case 0xA2EC: - return "Phoenix Inverter 48V 800VA 120Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120VAC_64K_HS; + break; case 0xA2F1: - return "Phoenix Inverter 12V 1200VA 230Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230VAC_64K_HS; + break; case 0xA2F2: - return "Phoenix Inverter 24V 1200VA 230Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230VAC_64K_HS; + break; case 0xA2F4: - return "Phoenix Inverter 48V 1200VA 230Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230VAC_64K_HS; + break; case 0xA2FA: - return "Phoenix Inverter 24V 1200VA 120Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120VAC_64K_HS; + break; case 0xA2FC: - return "Phoenix Inverter 48V 1200VA 120Vac 64k HS"; + result = DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120VAC_64K_HS; + break; case 0xA3F0: - return "Orion XS 12V/12V-50A"; + result = DEVICE_TYPE_ORION_XS_12V_12V_50A; + break; case 0xA3F1: - return "Orion XS 1400"; + result = DEVICE_TYPE_ORION_XS_1400; + break; case 0xA048: - return "BlueSolar MPPT 75|50 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_75_50_REV2; + break; case 0xA072: - return "BlueSolar MPPT 150|45 rev3"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_45_REV3; + break; case 0xA076: - return "BlueSolar MPPT 100|30 rev3"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_30_REV3; + break; case 0xA077: - return "BlueSolar MPPT 100|50 rev3"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_50_REV3; + break; case 0xA078: - return "BlueSolar MPPT 150|35 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_150_35_REV2; + break; case 0xA079: - return "BlueSolar MPPT 75|10 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_75_10_REV2; + break; case 0xA07A: - return "BlueSolar MPPT 75|15 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_75_15_REV2; + break; case 0xA07B: - return "BlueSolar MPPT 100|15 rev2"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_100_15_REV2; + break; case 0xA07C: - return "BlueSolar MPPT 75/10 rev3"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_75_10_REV3; + break; case 0xA07E: - return "SmartSolar Charger MPPT 100/30"; + result = DEVICE_TYPE_SMARTSOLAR_CHARGER_MPPT_100_30; + break; case 0xA110: - return "SmartSolar MPPT RS 450/100"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_100; + break; case 0xA111: - return "SmartSolar MPPT RS 450/200"; + result = DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_200; + break; case 0xA117: - return "BlueSolar MPPT VE.Can 150|100"; + result = DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_150_100; + break; default: result = DEVICE_TYPE_UNKNOWN; From ded7960888762b588153f0267455e480034efca4 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 13:33:50 +0200 Subject: [PATCH 15/38] Move device type strings to flash. --- components/victron/victron.cpp | 347 ++++++++++++++++----------------- 1 file changed, 170 insertions(+), 177 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 10725b7..29a3cef 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -45,6 +45,8 @@ static const char *const OFF_REASONS[OFF_REASONS_SIZE] PROGMEM = { OFF_REASONS_15 }; +static char buffer_off_reason[36]; + static const char ERROR_CODE_0[] PROGMEM = "No error"; static const char ERROR_CODE_2[] PROGMEM = "Battery voltage too high"; static const char ERROR_CODE_17[] PROGMEM = "Charger temperature too high"; @@ -93,10 +95,172 @@ static const char CHARGING_MODE_UNKNOWN[] PROGMEM = "Unknown"; static char buffer_charging_mode[30]; -struct ChargingModeEntry { - int code; - const char *msg; -}; +// Device type strings in PROGMEM +static const char DEVICE_TYPE_BMV_700[] PROGMEM = "BMV-700"; +static const char DEVICE_TYPE_BMV_702[] PROGMEM = "BMV-702"; +static const char DEVICE_TYPE_BMV_700H[] PROGMEM = "BMV-700H"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_70_15[] PROGMEM = "BlueSolar MPPT 70|15"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_50[] PROGMEM = "BlueSolar MPPT 75|50"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_35[] PROGMEM = "BlueSolar MPPT 150|35"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15[] PROGMEM = "BlueSolar MPPT 75|15"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_15[] PROGMEM = "BlueSolar MPPT 100|15"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30[] PROGMEM = "BlueSolar MPPT 100|30"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50[] PROGMEM = "BlueSolar MPPT 100|50"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_70[] PROGMEM = "BlueSolar MPPT 150|70"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_100[] PROGMEM = "BlueSolar MPPT 150|100"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50_REV2[] PROGMEM = "BlueSolar MPPT 100|50 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30_REV2[] PROGMEM = "BlueSolar MPPT 100|30 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_35_REV2[] PROGMEM = "BlueSolar MPPT 150|35 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10[] PROGMEM = "BlueSolar MPPT 75|10"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45[] PROGMEM = "BlueSolar MPPT 150|45"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_60[] PROGMEM = "BlueSolar MPPT 150|60"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_85[] PROGMEM = "BlueSolar MPPT 150|85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_100[] PROGMEM = "SmartSolar MPPT 250|100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100[] PROGMEM = "SmartSolar MPPT 150|100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85[] PROGMEM = "SmartSolar MPPT 150|85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_15[] PROGMEM = "SmartSolar MPPT 75|15"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_15_REV2[] PROGMEM = "SmartSolar MPPT 75|15 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_10[] PROGMEM = "SmartSolar MPPT 75|10"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_10_REV2[] PROGMEM = "SmartSolar MPPT 75|10 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_15[] PROGMEM = "SmartSolar MPPT 100|15"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_30[] PROGMEM = "SmartSolar MPPT 100|30"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45_REV3[] PROGMEM = "SmartSolar MPPT 150|45 rev3"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_50[] PROGMEM = "SmartSolar MPPT 100|50"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_35[] PROGMEM = "SmartSolar MPPT 150|35"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100_REV2[] PROGMEM = "SmartSolar MPPT 150|100 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85_REV2[] PROGMEM = "SmartSolar MPPT 150|85 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_70[] PROGMEM = "SmartSolar MPPT 250|70"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_85[] PROGMEM = "SmartSolar MPPT 250|85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_60[] PROGMEM = "SmartSolar MPPT 250|60"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_45[] PROGMEM = "SmartSolar MPPT 250|45"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_20[] PROGMEM = "SmartSolar MPPT 100|20"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_20_48V[] PROGMEM = "SmartSolar MPPT 100|20 48V"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45[] PROGMEM = "SmartSolar MPPT 150|45"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_60[] PROGMEM = "SmartSolar MPPT 150|60"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_70[] PROGMEM = "SmartSolar MPPT 150|70"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_85_REV2[] PROGMEM = "SmartSolar MPPT 250|85 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_100_REV2[] PROGMEM = "SmartSolar MPPT 250|100 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_20[] PROGMEM = "BlueSolar MPPT 100|20"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_20_48V[] PROGMEM = "BlueSolar MPPT 100|20 48V"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_60_REV2[] PROGMEM = "SmartSolar MPPT 250|60 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_70_REV2[] PROGMEM = "SmartSolar MPPT 250|70 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45_REV2[] PROGMEM = "SmartSolar MPPT 150|45 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_60_REV2[] PROGMEM = "SmartSolar MPPT 150|60 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_70_REV2[] PROGMEM = "SmartSolar MPPT 150|70 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85_REV3[] PROGMEM = "SmartSolar MPPT 150|85 rev3"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100_REV3[] PROGMEM = "SmartSolar MPPT 150|100 rev3"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45_REV2[] PROGMEM = "BlueSolar MPPT 150|45 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_60_REV2[] PROGMEM = "BlueSolar MPPT 150|60 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_70_REV2[] PROGMEM = "BlueSolar MPPT 150|70 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15_REV3[] PROGMEM = "BlueSolar MPPT 75|15 rev3"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_70[] PROGMEM = "SmartSolar MPPT VE.Can 150/70"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_45[] PROGMEM = "SmartSolar MPPT VE.Can 150/45"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_60[] PROGMEM = "SmartSolar MPPT VE.Can 150/60"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_85[] PROGMEM = "SmartSolar MPPT VE.Can 150/85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_100[] PROGMEM = "SmartSolar MPPT VE.Can 150/100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_45[] PROGMEM = "SmartSolar MPPT VE.Can 250/45"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_60[] PROGMEM = "SmartSolar MPPT VE.Can 250/60"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_70[] PROGMEM = "SmartSolar MPPT VE.Can 250/70"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_85[] PROGMEM = "SmartSolar MPPT VE.Can 250/85"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_100[] PROGMEM = "SmartSolar MPPT VE.Can 250/100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_70_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/70 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_85_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/85 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_100_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/100 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_150_100[] PROGMEM = "BlueSolar MPPT VE.Can 150/100"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_250_70[] PROGMEM = "BlueSolar MPPT VE.Can 250/70"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_250_100[] PROGMEM = "BlueSolar MPPT VE.Can 250/100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_70_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/70 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_100_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/100 rev2"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_85_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/85 rev2"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_230V[] PROGMEM = "Phoenix Inverter 12V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_230V[] PROGMEM = "Phoenix Inverter 24V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_230V[] PROGMEM = "Phoenix Inverter 48V 250VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_230V[] PROGMEM = "Phoenix Inverter 12V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_230V[] PROGMEM = "Phoenix Inverter 24V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_230V[] PROGMEM = "Phoenix Inverter 48V 375VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_230V[] PROGMEM = "Phoenix Inverter 12V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_230V[] PROGMEM = "Phoenix Inverter 24V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_230V[] PROGMEM = "Phoenix Inverter 48V 500VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_120V[] PROGMEM = "Phoenix Inverter 12V 250VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_120V[] PROGMEM = "Phoenix Inverter 24V 250VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_120V[] PROGMEM = "Phoenix Inverter 48V 250VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_120V[] PROGMEM = "Phoenix Inverter 12V 375VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_120V[] PROGMEM = "Phoenix Inverter 24V 375VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_120V[] PROGMEM = "Phoenix Inverter 48V 375VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_120V[] PROGMEM = "Phoenix Inverter 12V 500VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_120V[] PROGMEM = "Phoenix Inverter 24V 500VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_120V[] PROGMEM = "Phoenix Inverter 48V 500VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230V[] PROGMEM = "Phoenix Inverter 12V 800VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230V[] PROGMEM = "Phoenix Inverter 24V 800VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230V[] PROGMEM = "Phoenix Inverter 48V 800VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120V[] PROGMEM = "Phoenix Inverter 12V 800VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120V[] PROGMEM = "Phoenix Inverter 24V 800VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120V[] PROGMEM = "Phoenix Inverter 48V 800VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230V[] PROGMEM = "Phoenix Inverter 12V 1200VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230V[] PROGMEM = "Phoenix Inverter 24V 1200VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230V[] PROGMEM = "Phoenix Inverter 48V 1200VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_120V[] PROGMEM = "Phoenix Inverter 12V 1200VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120V[] PROGMEM = "Phoenix Inverter 24V 1200VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120V[] PROGMEM = "Phoenix Inverter 48V 1200VA 120V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1600VA_230V[] PROGMEM = "Phoenix Inverter 12V 1600VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1600VA_230V[] PROGMEM = "Phoenix Inverter 24V 1600VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1600VA_230V[] PROGMEM = "Phoenix Inverter 48V 1600VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_2000VA_230V[] PROGMEM = "Phoenix Inverter 12V 2000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_2000VA_230V[] PROGMEM = "Phoenix Inverter 24V 2000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_2000VA_230V[] PROGMEM = "Phoenix Inverter 48V 2000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_3000VA_230V[] PROGMEM = "Phoenix Inverter 12V 3000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_3000VA_230V[] PROGMEM = "Phoenix Inverter 24V 3000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_3000VA_230V[] PROGMEM = "Phoenix Inverter 48V 3000VA 230V"; +static const char DEVICE_TYPE_BLUE_SMART_IP65_CHARGER_12_25[] PROGMEM = "Blue Smart IP65 Charger 12|25"; +static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_8[] PROGMEM = "Blue Smart IP22 Charger 24|8"; +static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_12[] PROGMEM = "Blue Smart IP22 Charger 24|12"; +static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_16[] PROGMEM = "Blue Smart IP22 Charger 24|16"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_50_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 12|50 (1+1)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_50_3[] PROGMEM = "Phoenix Smart IP43 Charger 12|50 (3)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_25_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 24|25 (1+1)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_25_3[] PROGMEM = "Phoenix Smart IP43 Charger 24|25 (3)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_30_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 12|30 (1+1)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_30_3[] PROGMEM = "Phoenix Smart IP43 Charger 12|30 (3)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_16_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 24|16 (1+1)"; +static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_16_3[] PROGMEM = "Phoenix Smart IP43 Charger 24|16 (3)"; +static const char DEVICE_TYPE_BMV_712_SMART[] PROGMEM = "BMV-712 Smart"; +static const char DEVICE_TYPE_BMV_710H_SMART[] PROGMEM = "BMV-710H Smart"; +static const char DEVICE_TYPE_BMV_712_SMART_REV2[] PROGMEM = "BMV-712 Smart Rev2"; +static const char DEVICE_TYPE_SMARTSHUNT_500A_50MV[] PROGMEM = "SmartShunt 500A/50mV"; +static const char DEVICE_TYPE_SMARTSHUNT_1000A_50MV[] PROGMEM = "SmartShunt 1000A/50mV"; +static const char DEVICE_TYPE_SMARTSHUNT_2000A_50MV[] PROGMEM = "SmartShunt 2000A/50mV"; +static const char DEVICE_TYPE_MULTI_RS_SOLAR_48V_6000VA_230V[] PROGMEM = "Multi RS Solar 48V 6000VA 230V"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_12V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 12V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_24V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 24V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_48V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 48V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 1200VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 1200VA 120Vac 64k HS"; +static const char DEVICE_TYPE_ORION_XS_12V_12V_50A[] PROGMEM = "Orion XS 12V/12V-50A"; +static const char DEVICE_TYPE_ORION_XS_1400[] PROGMEM = "Orion XS 1400"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_50_REV2[] PROGMEM = "BlueSolar MPPT 75|50 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45_REV3[] PROGMEM = "BlueSolar MPPT 150|45 rev3"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30_REV3[] PROGMEM = "BlueSolar MPPT 100|30 rev3"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50_REV3[] PROGMEM = "BlueSolar MPPT 100|50 rev3"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10_REV2[] PROGMEM = "BlueSolar MPPT 75|10 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15_REV2[] PROGMEM = "BlueSolar MPPT 75|15 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_15_REV2[] PROGMEM = "BlueSolar MPPT 100|15 rev2"; +static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10_REV3[] PROGMEM = "BlueSolar MPPT 75/10 rev3"; +static const char DEVICE_TYPE_SMARTSOLAR_CHARGER_MPPT_100_30[] PROGMEM = "SmartSolar Charger MPPT 100/30"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_100[] PROGMEM = "SmartSolar MPPT RS 450/100"; +static const char DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_200[] PROGMEM = "SmartSolar MPPT RS 450/200"; + +static const char DEVICE_TYPE_UNKNOWN[] PROGMEM = "Unknown"; + +static char buffer_device_type[48]; void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) static const char *prefix = " "; @@ -454,176 +618,6 @@ static std::string dc_monitor_mode_text(int value) { } } -// Device type strings in PROGMEM -static const char DEVICE_TYPE_BMV_700[] PROGMEM = "BMV-700"; -static const char DEVICE_TYPE_BMV_702[] PROGMEM = "BMV-702"; -static const char DEVICE_TYPE_BMV_700H[] PROGMEM = "BMV-700H"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_70_15[] PROGMEM = "BlueSolar MPPT 70|15"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_50[] PROGMEM = "BlueSolar MPPT 75|50"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_35[] PROGMEM = "BlueSolar MPPT 150|35"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15[] PROGMEM = "BlueSolar MPPT 75|15"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_15[] PROGMEM = "BlueSolar MPPT 100|15"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30[] PROGMEM = "BlueSolar MPPT 100|30"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50[] PROGMEM = "BlueSolar MPPT 100|50"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_70[] PROGMEM = "BlueSolar MPPT 150|70"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_100[] PROGMEM = "BlueSolar MPPT 150|100"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50_REV2[] PROGMEM = "BlueSolar MPPT 100|50 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30_REV2[] PROGMEM = "BlueSolar MPPT 100|30 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_35_REV2[] PROGMEM = "BlueSolar MPPT 150|35 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10[] PROGMEM = "BlueSolar MPPT 75|10"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45[] PROGMEM = "BlueSolar MPPT 150|45"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_60[] PROGMEM = "BlueSolar MPPT 150|60"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_85[] PROGMEM = "BlueSolar MPPT 150|85"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_100[] PROGMEM = "SmartSolar MPPT 250|100"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100[] PROGMEM = "SmartSolar MPPT 150|100"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85[] PROGMEM = "SmartSolar MPPT 150|85"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_15[] PROGMEM = "SmartSolar MPPT 75|15"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_15_REV2[] PROGMEM = "SmartSolar MPPT 75|15 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_10[] PROGMEM = "SmartSolar MPPT 75|10"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_75_10_REV2[] PROGMEM = "SmartSolar MPPT 75|10 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_15[] PROGMEM = "SmartSolar MPPT 100|15"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_30[] PROGMEM = "SmartSolar MPPT 100|30"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45_REV3[] PROGMEM = "SmartSolar MPPT 150|45 rev3"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_50[] PROGMEM = "SmartSolar MPPT 100|50"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_35[] PROGMEM = "SmartSolar MPPT 150|35"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100_REV2[] PROGMEM = "SmartSolar MPPT 150|100 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85_REV2[] PROGMEM = "SmartSolar MPPT 150|85 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_70[] PROGMEM = "SmartSolar MPPT 250|70"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_85[] PROGMEM = "SmartSolar MPPT 250|85"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_60[] PROGMEM = "SmartSolar MPPT 250|60"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_45[] PROGMEM = "SmartSolar MPPT 250|45"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_20[] PROGMEM = "SmartSolar MPPT 100|20"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_100_20_48V[] PROGMEM = "SmartSolar MPPT 100|20 48V"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45[] PROGMEM = "SmartSolar MPPT 150|45"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_60[] PROGMEM = "SmartSolar MPPT 150|60"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_70[] PROGMEM = "SmartSolar MPPT 150|70"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_85_REV2[] PROGMEM = "SmartSolar MPPT 250|85 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_100_REV2[] PROGMEM = "SmartSolar MPPT 250|100 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_20[] PROGMEM = "BlueSolar MPPT 100|20"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_20_48V[] PROGMEM = "BlueSolar MPPT 100|20 48V"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_60_REV2[] PROGMEM = "SmartSolar MPPT 250|60 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_250_70_REV2[] PROGMEM = "SmartSolar MPPT 250|70 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_45_REV2[] PROGMEM = "SmartSolar MPPT 150|45 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_60_REV2[] PROGMEM = "SmartSolar MPPT 150|60 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_70_REV2[] PROGMEM = "SmartSolar MPPT 150|70 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_85_REV3[] PROGMEM = "SmartSolar MPPT 150|85 rev3"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_150_100_REV3[] PROGMEM = "SmartSolar MPPT 150|100 rev3"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45_REV2[] PROGMEM = "BlueSolar MPPT 150|45 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_60_REV2[] PROGMEM = "BlueSolar MPPT 150|60 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_70_REV2[] PROGMEM = "BlueSolar MPPT 150|70 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15_REV3[] PROGMEM = "BlueSolar MPPT 75|15 rev3"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_70[] PROGMEM = "SmartSolar MPPT VE.Can 150/70"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_45[] PROGMEM = "SmartSolar MPPT VE.Can 150/45"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_60[] PROGMEM = "SmartSolar MPPT VE.Can 150/60"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_85[] PROGMEM = "SmartSolar MPPT VE.Can 150/85"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_100[] PROGMEM = "SmartSolar MPPT VE.Can 150/100"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_45[] PROGMEM = "SmartSolar MPPT VE.Can 250/45"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_60[] PROGMEM = "SmartSolar MPPT VE.Can 250/60"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_70[] PROGMEM = "SmartSolar MPPT VE.Can 250/70"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_85[] PROGMEM = "SmartSolar MPPT VE.Can 250/85"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_100[] PROGMEM = "SmartSolar MPPT VE.Can 250/100"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_70_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/70 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_85_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/85 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_150_100_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 150/100 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_150_100[] PROGMEM = "BlueSolar MPPT VE.Can 150/100"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_250_70[] PROGMEM = "BlueSolar MPPT VE.Can 250/70"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_VE_CAN_250_100[] PROGMEM = "BlueSolar MPPT VE.Can 250/100"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_70_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/70 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_100_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/100 rev2"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_VE_CAN_250_85_REV2[] PROGMEM = "SmartSolar MPPT VE.Can 250/85 rev2"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_230V[] PROGMEM = "Phoenix Inverter 12V 250VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_230V[] PROGMEM = "Phoenix Inverter 24V 250VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_230V[] PROGMEM = "Phoenix Inverter 48V 250VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_230V[] PROGMEM = "Phoenix Inverter 12V 375VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_230V[] PROGMEM = "Phoenix Inverter 24V 375VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_230V[] PROGMEM = "Phoenix Inverter 48V 375VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_230V[] PROGMEM = "Phoenix Inverter 12V 500VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_230V[] PROGMEM = "Phoenix Inverter 24V 500VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_230V[] PROGMEM = "Phoenix Inverter 48V 500VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_250VA_120V[] PROGMEM = "Phoenix Inverter 12V 250VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_250VA_120V[] PROGMEM = "Phoenix Inverter 24V 250VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_250VA_120V[] PROGMEM = "Phoenix Inverter 48V 250VA 120V"; - -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_375VA_120V[] PROGMEM = "Phoenix Inverter 12V 375VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_375VA_120V[] PROGMEM = "Phoenix Inverter 24V 375VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_375VA_120V[] PROGMEM = "Phoenix Inverter 48V 375VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_500VA_120V[] PROGMEM = "Phoenix Inverter 12V 500VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_500VA_120V[] PROGMEM = "Phoenix Inverter 24V 500VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_500VA_120V[] PROGMEM = "Phoenix Inverter 48V 500VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230V[] PROGMEM = "Phoenix Inverter 12V 800VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230V[] PROGMEM = "Phoenix Inverter 24V 800VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230V[] PROGMEM = "Phoenix Inverter 48V 800VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120V[] PROGMEM = "Phoenix Inverter 12V 800VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120V[] PROGMEM = "Phoenix Inverter 24V 800VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120V[] PROGMEM = "Phoenix Inverter 48V 800VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230V[] PROGMEM = "Phoenix Inverter 12V 1200VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230V[] PROGMEM = "Phoenix Inverter 24V 1200VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230V[] PROGMEM = "Phoenix Inverter 48V 1200VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_120V[] PROGMEM = "Phoenix Inverter 12V 1200VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120V[] PROGMEM = "Phoenix Inverter 24V 1200VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120V[] PROGMEM = "Phoenix Inverter 48V 1200VA 120V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1600VA_230V[] PROGMEM = "Phoenix Inverter 12V 1600VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1600VA_230V[] PROGMEM = "Phoenix Inverter 24V 1600VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1600VA_230V[] PROGMEM = "Phoenix Inverter 48V 1600VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_2000VA_230V[] PROGMEM = "Phoenix Inverter 12V 2000VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_2000VA_230V[] PROGMEM = "Phoenix Inverter 24V 2000VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_2000VA_230V[] PROGMEM = "Phoenix Inverter 48V 2000VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_3000VA_230V[] PROGMEM = "Phoenix Inverter 12V 3000VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_3000VA_230V[] PROGMEM = "Phoenix Inverter 24V 3000VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_3000VA_230V[] PROGMEM = "Phoenix Inverter 48V 3000VA 230V"; -static const char DEVICE_TYPE_BLUE_SMART_IP65_CHARGER_12_25[] PROGMEM = "Blue Smart IP65 Charger 12|25"; -static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_8[] PROGMEM = "Blue Smart IP22 Charger 24|8"; -static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_12[] PROGMEM = "Blue Smart IP22 Charger 24|12"; -static const char DEVICE_TYPE_BLUE_SMART_IP22_CHARGER_24_16[] PROGMEM = "Blue Smart IP22 Charger 24|16"; -static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_50_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 12|50 (1+1)"; -static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_50_3[] PROGMEM = "Phoenix Smart IP43 Charger 12|50 (3)"; -static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_25_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 24|25 (1+1)"; -static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_25_3[] PROGMEM = "Phoenix Smart IP43 Charger 24|25 (3)"; -static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_30_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 12|30 (1+1)"; -static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_12_30_3[] PROGMEM = "Phoenix Smart IP43 Charger 12|30 (3)"; -static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_16_1_1[] PROGMEM = "Phoenix Smart IP43 Charger 24|16 (1+1)"; -static const char DEVICE_TYPE_PHOENIX_SMART_IP43_CHARGER_24_16_3[] PROGMEM = "Phoenix Smart IP43 Charger 24|16 (3)"; -static const char DEVICE_TYPE_BMV_712_SMART[] PROGMEM = "BMV-712 Smart"; -static const char DEVICE_TYPE_BMV_710H_SMART[] PROGMEM = "BMV-710H Smart"; -static const char DEVICE_TYPE_BMV_712_SMART_REV2[] PROGMEM = "BMV-712 Smart Rev2"; -static const char DEVICE_TYPE_SMARTSHUNT_500A_50MV[] PROGMEM = "SmartShunt 500A/50mV"; -static const char DEVICE_TYPE_SMARTSHUNT_1000A_50MV[] PROGMEM = "SmartShunt 1000A/50mV"; -static const char DEVICE_TYPE_SMARTSHUNT_2000A_50MV[] PROGMEM = "SmartShunt 2000A/50mV"; -static const char DEVICE_TYPE_MULTI_RS_SOLAR_48V_6000VA_230V[] PROGMEM = "Multi RS Solar 48V 6000VA 230V"; -// Add missing PROGMEM definitions for Phoenix Inverter Smart device types -static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_12V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 12V 5000VA 230Vac 64k"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_24V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 24V 5000VA 230Vac 64k"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_48V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 48V 5000VA 230Vac 64k"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 800VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 800VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 800VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 800VA 120Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 800VA 120Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 800VA 120Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 1200VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 1200VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 1200VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 1200VA 120Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 1200VA 120Vac 64k HS"; -static const char DEVICE_TYPE_ORION_XS_12V_12V_50A[] PROGMEM = "Orion XS 12V/12V-50A"; -static const char DEVICE_TYPE_ORION_XS_1400[] PROGMEM = "Orion XS 1400"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_50_REV2[] PROGMEM = "BlueSolar MPPT 75|50 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_150_45_REV3[] PROGMEM = "BlueSolar MPPT 150|45 rev3"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_30_REV3[] PROGMEM = "BlueSolar MPPT 100|30 rev3"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_50_REV3[] PROGMEM = "BlueSolar MPPT 100|50 rev3"; - -static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10_REV2[] PROGMEM = "BlueSolar MPPT 75|10 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_15_REV2[] PROGMEM = "BlueSolar MPPT 75|15 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_100_15_REV2[] PROGMEM = "BlueSolar MPPT 100|15 rev2"; -static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_10_REV3[] PROGMEM = "BlueSolar MPPT 75/10 rev3"; -static const char DEVICE_TYPE_SMARTSOLAR_CHARGER_MPPT_100_30[] PROGMEM = "SmartSolar Charger MPPT 100/30"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_100[] PROGMEM = "SmartSolar MPPT RS 450/100"; -static const char DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_200[] PROGMEM = "SmartSolar MPPT RS 450/200"; - -static const char DEVICE_TYPE_UNKNOWN[] PROGMEM = "Unknown"; - -static char buffer_device_type[48]; - static const char *device_type_text(int value) { const char *result; switch (value) { @@ -1158,7 +1152,6 @@ static const char *device_type_text(int value) { static std::string off_reason_text(uint32_t mask) { bool first = true; std::string value_list = ""; - char buffer[36]; if (mask) { for (uint8_t i = 0; i < OFF_REASONS_SIZE; i++) { if (mask & (1 << i)) { @@ -1167,8 +1160,8 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - strcpy_P(buffer, (PGM_P)pgm_read_ptr(&OFF_REASONS[i])); - value_list.append(buffer); + strcpy_P(buffer_off_reason, (PGM_P)pgm_read_ptr(&OFF_REASONS[i])); + value_list.append(buffer_off_reason); } } } From b9953169c92491a9de1d9acf0029eddbcd82e098 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 13:58:49 +0200 Subject: [PATCH 16/38] Moving data from Flash to SRAM is expensive, so only copy strings if value has changed. --- components/victron/victron.cpp | 35 ++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 29a3cef..e4afa40 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1291,15 +1291,25 @@ void VictronComponent::handle_value_() { } if (label_ == "AR") { - this->publish_state_(alarm_reason_text_sensor_, error_code_text(atoi(value_.c_str()))); // NOLINT(cert-err34-c) + static uint16_t last_error = UINT16_MAX; + uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) + if( value != last_error ) { + last_error = value; + this->publish_state_(alarm_reason_text_sensor_, error_code_text(value)); // NOLINT(cert-err34-c) + } return; } if (label_ == "OR") { auto off_reason_bitmask = parse_hex(value_.substr(2, value_.size() - 2)); if (off_reason_bitmask) { + static uint32_t last_off_mask = UINT32_MAX; this->publish_state_(off_reason_bitmask_sensor_, *off_reason_bitmask); - this->publish_state_(off_reason_text_sensor_, off_reason_text(*off_reason_bitmask)); + // Load the string only if it has changed. + if (*off_reason_bitmask != last_off_mask){ + last_off_mask = *off_reason_bitmask; + this->publish_state_(off_reason_text_sensor_, off_reason_text(*off_reason_bitmask)); + } } return; } @@ -1453,16 +1463,24 @@ void VictronComponent::handle_value_() { } if (label_ == "ERR") { - value = atoi(value_.c_str()); // NOLINT(cert-err34-c) + static uint16_t last_error = UINT16_MAX; + uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(error_code_sensor_, value); - this->publish_state_(error_text_sensor_, error_code_text(value)); + if (value != last_error){ + last_error = value; + this->publish_state_(error_text_sensor_, error_code_text(value)); + } return; } if (label_ == "CS") { + static uint16_t last_charging_mode = 0; value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(charging_mode_id_sensor_, (float) value); - this->publish_state_(charging_mode_text_sensor_, charging_mode_text(value)); + if( value != last_charging_mode ){ + last_charging_mode = value; + this->publish_state_(charging_mode_text_sensor_, charging_mode_text(value)); + } return; } @@ -1496,7 +1514,12 @@ void VictronComponent::handle_value_() { } if (label_ == "PID") { - this->publish_state_once_(device_type_text_sensor_, device_type_text(strtol(value_.c_str(), nullptr, 0))); + static uint32_t last_pid = UINT32_MAX; + uint32_t value = strtol(value_.c_str(), nullptr, 0); + if (value != last_pid) { + last_pid = value; + this->publish_state_(device_type_text_sensor_, device_type_text(value)); + } return; } From f754c9cd19c9093772460cf09ebb758010f97bb6 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 14:21:50 +0200 Subject: [PATCH 17/38] Only update buffer on value change, send status every time. --- components/victron/victron.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index e4afa40..f566e96 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1151,7 +1151,7 @@ static const char *device_type_text(int value) { static std::string off_reason_text(uint32_t mask) { bool first = true; - std::string value_list = ""; + static std::string value_list = ""; if (mask) { for (uint8_t i = 0; i < OFF_REASONS_SIZE; i++) { if (mask & (1 << i)) { @@ -1293,10 +1293,12 @@ void VictronComponent::handle_value_() { if (label_ == "AR") { static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) + // Flash memory is slow, so only load the string if the value has changed. if( value != last_error ) { last_error = value; - this->publish_state_(alarm_reason_text_sensor_, error_code_text(value)); // NOLINT(cert-err34-c) + error_code_text(value); } + this->publish_state_(alarm_reason_text_sensor_, buffer_error_code); // NOLINT(cert-err34-c) return; } @@ -1304,12 +1306,14 @@ void VictronComponent::handle_value_() { auto off_reason_bitmask = parse_hex(value_.substr(2, value_.size() - 2)); if (off_reason_bitmask) { static uint32_t last_off_mask = UINT32_MAX; + static std::string last_off_text = ""; this->publish_state_(off_reason_bitmask_sensor_, *off_reason_bitmask); - // Load the string only if it has changed. + // Flash memory is slow, so only load the string if the value has changed. if (*off_reason_bitmask != last_off_mask){ last_off_mask = *off_reason_bitmask; - this->publish_state_(off_reason_text_sensor_, off_reason_text(*off_reason_bitmask)); + last_off_text = std::move(off_reason_text(*off_reason_bitmask)); } + this->publish_state_(off_reason_text_sensor_, last_off_text); } return; } @@ -1466,10 +1470,12 @@ void VictronComponent::handle_value_() { static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(error_code_sensor_, value); + // Flash memory is slow, so only load the string if the value has changed. if (value != last_error){ last_error = value; - this->publish_state_(error_text_sensor_, error_code_text(value)); + error_code_text(value); } + this->publish_state_(error_text_sensor_, buffer_error_code); return; } @@ -1477,10 +1483,12 @@ void VictronComponent::handle_value_() { static uint16_t last_charging_mode = 0; value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(charging_mode_id_sensor_, (float) value); + // Flash memory is slow, so only load the string if the value has changed. if( value != last_charging_mode ){ last_charging_mode = value; - this->publish_state_(charging_mode_text_sensor_, charging_mode_text(value)); + charging_mode_text(value); } + this->publish_state_(charging_mode_text_sensor_, buffer_charging_mode); return; } @@ -1516,10 +1524,12 @@ void VictronComponent::handle_value_() { if (label_ == "PID") { static uint32_t last_pid = UINT32_MAX; uint32_t value = strtol(value_.c_str(), nullptr, 0); + // Flash memory is slow, so only load the string if the value has changed. if (value != last_pid) { last_pid = value; - this->publish_state_(device_type_text_sensor_, device_type_text(value)); + device_type_text(value); } + this->publish_state_(device_type_text_sensor_, buffer_device_type); return; } From 1bfaf7dbc6751a1067ceed91243b328d22ddca37 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 14:22:00 +0200 Subject: [PATCH 18/38] Revert "Only update buffer on value change, send status every time." This reverts commit f754c9cd19c9093772460cf09ebb758010f97bb6. --- components/victron/victron.cpp | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index f566e96..e4afa40 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1151,7 +1151,7 @@ static const char *device_type_text(int value) { static std::string off_reason_text(uint32_t mask) { bool first = true; - static std::string value_list = ""; + std::string value_list = ""; if (mask) { for (uint8_t i = 0; i < OFF_REASONS_SIZE; i++) { if (mask & (1 << i)) { @@ -1293,12 +1293,10 @@ void VictronComponent::handle_value_() { if (label_ == "AR") { static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) - // Flash memory is slow, so only load the string if the value has changed. if( value != last_error ) { last_error = value; - error_code_text(value); + this->publish_state_(alarm_reason_text_sensor_, error_code_text(value)); // NOLINT(cert-err34-c) } - this->publish_state_(alarm_reason_text_sensor_, buffer_error_code); // NOLINT(cert-err34-c) return; } @@ -1306,14 +1304,12 @@ void VictronComponent::handle_value_() { auto off_reason_bitmask = parse_hex(value_.substr(2, value_.size() - 2)); if (off_reason_bitmask) { static uint32_t last_off_mask = UINT32_MAX; - static std::string last_off_text = ""; this->publish_state_(off_reason_bitmask_sensor_, *off_reason_bitmask); - // Flash memory is slow, so only load the string if the value has changed. + // Load the string only if it has changed. if (*off_reason_bitmask != last_off_mask){ last_off_mask = *off_reason_bitmask; - last_off_text = std::move(off_reason_text(*off_reason_bitmask)); + this->publish_state_(off_reason_text_sensor_, off_reason_text(*off_reason_bitmask)); } - this->publish_state_(off_reason_text_sensor_, last_off_text); } return; } @@ -1470,12 +1466,10 @@ void VictronComponent::handle_value_() { static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(error_code_sensor_, value); - // Flash memory is slow, so only load the string if the value has changed. if (value != last_error){ last_error = value; - error_code_text(value); + this->publish_state_(error_text_sensor_, error_code_text(value)); } - this->publish_state_(error_text_sensor_, buffer_error_code); return; } @@ -1483,12 +1477,10 @@ void VictronComponent::handle_value_() { static uint16_t last_charging_mode = 0; value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(charging_mode_id_sensor_, (float) value); - // Flash memory is slow, so only load the string if the value has changed. if( value != last_charging_mode ){ last_charging_mode = value; - charging_mode_text(value); + this->publish_state_(charging_mode_text_sensor_, charging_mode_text(value)); } - this->publish_state_(charging_mode_text_sensor_, buffer_charging_mode); return; } @@ -1524,12 +1516,10 @@ void VictronComponent::handle_value_() { if (label_ == "PID") { static uint32_t last_pid = UINT32_MAX; uint32_t value = strtol(value_.c_str(), nullptr, 0); - // Flash memory is slow, so only load the string if the value has changed. if (value != last_pid) { last_pid = value; - device_type_text(value); + this->publish_state_(device_type_text_sensor_, device_type_text(value)); } - this->publish_state_(device_type_text_sensor_, buffer_device_type); return; } From 4acf93a87086666125bee51a1ee3e08005cb5cc3 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 16:08:57 +0200 Subject: [PATCH 19/38] Show loop stats. --- components/victron/victron.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index e4afa40..3b9d2ff 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -323,9 +323,11 @@ static const char *prefix = " "; void VictronComponent::loop() { const uint32_t now = millis(); - if ((state_ > 0) && (now - last_transmission_ >= 200)) { + const uint32_t elapsed_time = now - last_transmission_; + bool available_data = false; + if ((state_ > 0) && (elapsed_time >= 200)) { // last transmission too long ago. Reset RX index. - ESP_LOGW(TAG, "Last transmission too long ago"); + ESP_LOGE(TAG, "Too old data: %ldms", elapsed_time); state_ = 0; } @@ -333,7 +335,9 @@ void VictronComponent::loop() { return; last_transmission_ = now; + while (available()) { + available_data = true; uint8_t c; read_byte(&c); if (state_ == 0) { @@ -385,6 +389,10 @@ void VictronComponent::loop() { } } } + uint32_t loop_time = millis() - now; + if (available_data && loop_time > 10){ + ESP_LOGD(TAG, "Loop: %ldms", loop_time); + } } static const char *charging_mode_text(int value) { From 8740247616e987e9187127bdbdad89f6c32b747b Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 16:34:08 +0200 Subject: [PATCH 20/38] Initially set to max value so the first time it will update the buffer. --- components/victron/victron.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 3b9d2ff..f207945 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1482,8 +1482,8 @@ void VictronComponent::handle_value_() { } if (label_ == "CS") { - static uint16_t last_charging_mode = 0; - value = atoi(value_.c_str()); // NOLINT(cert-err34-c) + static uint16_t last_charging_mode = UINT16_MAX; + value = static_cast(atoi(value_.c_str())); // NOLINT(cert-err34-c) this->publish_state_(charging_mode_id_sensor_, (float) value); if( value != last_charging_mode ){ last_charging_mode = value; From c2be69cec2c63e7b17205964796d38275f7e7456 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 17:50:29 +0200 Subject: [PATCH 21/38] Move to avoid missing updates when data is not available. --- components/victron/victron.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index f207945..1e4918a 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -330,12 +330,11 @@ void VictronComponent::loop() { ESP_LOGE(TAG, "Too old data: %ldms", elapsed_time); state_ = 0; } + last_transmission_ = now; if (!available()) return; - last_transmission_ = now; - while (available()) { available_data = true; uint8_t c; From 66ba07adb066bf1035d12095afc8b964b94eb439 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 18:03:24 +0200 Subject: [PATCH 22/38] Remove obsolete struct. --- components/victron/victron.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 1e4918a..31e995d 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -71,11 +71,6 @@ static const char ERROR_CODE_UNKNOWN[] PROGMEM = "Unknown"; static char buffer_error_code[53]; -struct ErrorCodeEntry { - int code; - const char *msg; -}; - static const char CHARGING_MODE_0[] PROGMEM = "Off"; static const char CHARGING_MODE_1[] PROGMEM = "Low power"; static const char CHARGING_MODE_2[] PROGMEM = "Fault"; From 5ad0c62f63824b3863a17eb106db8cb90d6d4d52 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 18:37:16 +0200 Subject: [PATCH 23/38] Add another buffer to store separate status strings. --- components/victron/victron.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 31e995d..fcad5b7 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -69,7 +69,8 @@ static const char ERROR_CODE_117[] PROGMEM = "Invalid/incompatible firmware"; static const char ERROR_CODE_119[] PROGMEM = "User settings invalid"; static const char ERROR_CODE_UNKNOWN[] PROGMEM = "Unknown"; -static char buffer_error_code[53]; +static char buffer_error_code_ERR[53]; +static char buffer_error_code_AR[53]; static const char CHARGING_MODE_0[] PROGMEM = "Off"; static const char CHARGING_MODE_1[] PROGMEM = "Low power"; @@ -445,7 +446,7 @@ static const char *charging_mode_text(int value) { return buffer_charging_mode; } -static const char *error_code_text(int value) { +static const char *error_code_text(char * const buffer, int value) { const char *result; switch (value) { case 0: @@ -512,8 +513,8 @@ static const char *error_code_text(int value) { result = ERROR_CODE_UNKNOWN; break; } - strcpy_P(buffer_error_code, result); - return buffer_error_code; + strcpy_P(buffer, result); + return buffer; } static const char *warning_code_text(int value) { @@ -1297,8 +1298,9 @@ void VictronComponent::handle_value_() { uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) if( value != last_error ) { last_error = value; - this->publish_state_(alarm_reason_text_sensor_, error_code_text(value)); // NOLINT(cert-err34-c) + error_code_text(buffer_error_code_AR, value); } + this->publish_state_(alarm_reason_text_sensor_, buffer_error_code_AR); // NOLINT(cert-err34-c) return; } @@ -1470,8 +1472,9 @@ void VictronComponent::handle_value_() { this->publish_state_(error_code_sensor_, value); if (value != last_error){ last_error = value; - this->publish_state_(error_text_sensor_, error_code_text(value)); + error_code_text(buffer_error_code_ERR, value); } + this->publish_state_(error_text_sensor_, buffer_error_code_ERR); return; } From 857134bc50540d091c221278eba78e533893c0b0 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Fri, 19 Sep 2025 19:00:07 +0200 Subject: [PATCH 24/38] Group all strings and buffers at the begining of file. --- components/victron/victron.cpp | 277 +++++++++++++++++++++++---------- 1 file changed, 196 insertions(+), 81 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index fcad5b7..5486d76 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -9,44 +9,7 @@ namespace victron { static const char *const TAG = "victron"; -static const uint8_t OFF_REASONS_SIZE = 16; -static const char OFF_REASONS_0[] PROGMEM = "No input power"; -static const char OFF_REASONS_1[] PROGMEM = "Switched off (power switch)"; -static const char OFF_REASONS_2[] PROGMEM = "Switched off (device mode register)"; -static const char OFF_REASONS_3[] PROGMEM = "Remote input"; -static const char OFF_REASONS_4[] PROGMEM = "Protection active"; -static const char OFF_REASONS_5[] PROGMEM = "Paygo"; -static const char OFF_REASONS_6[] PROGMEM = "BMS"; -static const char OFF_REASONS_7[] PROGMEM = "Engine shutdown detection"; -static const char OFF_REASONS_8[] PROGMEM = "Analysing input voltage"; -static const char OFF_REASONS_9[] PROGMEM = "Unknown: Bit 10"; -static const char OFF_REASONS_10[] PROGMEM = "Unknown: Bit 11"; -static const char OFF_REASONS_11[] PROGMEM = "Unknown: Bit 12"; -static const char OFF_REASONS_12[] PROGMEM = "Unknown: Bit 13"; -static const char OFF_REASONS_13[] PROGMEM = "Unknown: Bit 14"; -static const char OFF_REASONS_14[] PROGMEM = "Unknown: Bit 15"; -static const char OFF_REASONS_15[] PROGMEM = "Unknown: Bit 16"; -static const char *const OFF_REASONS[OFF_REASONS_SIZE] PROGMEM = { - OFF_REASONS_0, - OFF_REASONS_1, - OFF_REASONS_2, - OFF_REASONS_3, - OFF_REASONS_4, - OFF_REASONS_5, - OFF_REASONS_6, - OFF_REASONS_7, - OFF_REASONS_8, - OFF_REASONS_9, - OFF_REASONS_10, - OFF_REASONS_11, - OFF_REASONS_12, - OFF_REASONS_13, - OFF_REASONS_14, - OFF_REASONS_15 -}; - -static char buffer_off_reason[36]; - +// Error code strings in PROGMEM static const char ERROR_CODE_0[] PROGMEM = "No error"; static const char ERROR_CODE_2[] PROGMEM = "Battery voltage too high"; static const char ERROR_CODE_17[] PROGMEM = "Charger temperature too high"; @@ -72,6 +35,7 @@ static const char ERROR_CODE_UNKNOWN[] PROGMEM = "Unknown"; static char buffer_error_code_ERR[53]; static char buffer_error_code_AR[53]; +// Charging mode strings in PROGMEM static const char CHARGING_MODE_0[] PROGMEM = "Off"; static const char CHARGING_MODE_1[] PROGMEM = "Low power"; static const char CHARGING_MODE_2[] PROGMEM = "Fault"; @@ -91,6 +55,64 @@ static const char CHARGING_MODE_UNKNOWN[] PROGMEM = "Unknown"; static char buffer_charging_mode[30]; +// Warning code strings in PROGMEM +static const char WARNING_CODE_0[] PROGMEM = "No warning"; +static const char WARNING_CODE_1[] PROGMEM = "Low Voltage"; +static const char WARNING_CODE_2[] PROGMEM = "High Voltage"; +static const char WARNING_CODE_4[] PROGMEM = "Low SOC"; +static const char WARNING_CODE_8[] PROGMEM = "Low Starter Voltage"; +static const char WARNING_CODE_16[] PROGMEM = "High Starter Voltage"; +static const char WARNING_CODE_32[] PROGMEM = "Low Temperature"; +static const char WARNING_CODE_64[] PROGMEM = "High Temperature"; +static const char WARNING_CODE_128[] PROGMEM = "Mid Voltage"; +static const char WARNING_CODE_256[] PROGMEM = "Overload"; +static const char WARNING_CODE_512[] PROGMEM = "DC-ripple"; +static const char WARNING_CODE_1024[] PROGMEM = "Low V AC out"; +static const char WARNING_CODE_2048[] PROGMEM = "High V AC out"; +static const char WARNING_CODE_MULTIPLE[] PROGMEM = "Multiple warnings"; + +static char buffer_warning_code[22]; + +// Tracking mode strings in PROGMEM +static const char TRACKING_MODE_0[] PROGMEM = "Off"; +static const char TRACKING_MODE_1[] PROGMEM = "Limited"; +static const char TRACKING_MODE_2[] PROGMEM = "Active"; +static const char TRACKING_MODE_UNKNOWN[] PROGMEM = "Unknown"; + +static char buffer_tracking_mode[9]; + +// Device mode strings in PROGMEM +static const char DEVICE_MODE_0[] PROGMEM = "Off"; +static const char DEVICE_MODE_2[] PROGMEM = "On"; +static const char DEVICE_MODE_4[] PROGMEM = "Off"; +static const char DEVICE_MODE_5[] PROGMEM = "Eco"; +static const char DEVICE_MODE_UNKNOWN[] PROGMEM = "Unknown"; + +static char buffer_device_mode[9]; + +// DC monitor mode strings in PROGMEM +static const char DC_MONITOR_MODE_SOLAR_CHARGER[] PROGMEM = "Solar charger"; +static const char DC_MONITOR_MODE_WIND_TURBINE[] PROGMEM = "Wind turbine"; +static const char DC_MONITOR_MODE_SHAFT_GENERATOR[] PROGMEM = "Shaft generator"; +static const char DC_MONITOR_MODE_ALTERNATOR[] PROGMEM = "Alternator"; +static const char DC_MONITOR_MODE_FUEL_CELL[] PROGMEM = "Fuel cell"; +static const char DC_MONITOR_MODE_WATER_GENERATOR[] PROGMEM = "Water generator"; +static const char DC_MONITOR_MODE_DC_DC_CHARGER[] PROGMEM = "DC/DC charger"; +static const char DC_MONITOR_MODE_AC_CHARGER[] PROGMEM = "AC charger"; +static const char DC_MONITOR_MODE_GENERIC_SOURCE[] PROGMEM = "Generic source"; +static const char DC_MONITOR_MODE_BATTERY_MONITOR[] PROGMEM = "Battery monitor (BMV)"; +static const char DC_MONITOR_MODE_GENERIC_LOAD[] PROGMEM = "Generic load"; +static const char DC_MONITOR_MODE_ELECTRIC_DRIVE[] PROGMEM = "Electric drive"; +static const char DC_MONITOR_MODE_FRIDGE[] PROGMEM = "Fridge"; +static const char DC_MONITOR_MODE_WATER_PUMP[] PROGMEM = "Water pump"; +static const char DC_MONITOR_MODE_BILGE_PUMP[] PROGMEM = "Bilge pump"; +static const char DC_MONITOR_MODE_DC_SYSTEM[] PROGMEM = "DC system"; +static const char DC_MONITOR_MODE_INVERTER[] PROGMEM = "Inverter"; +static const char DC_MONITOR_MODE_WATER_HEATER[] PROGMEM = "Water heater"; +static const char DC_MONITOR_MODE_UNKNOWN[] PROGMEM = "Unknown"; + +static char buffer_dc_monitor_mode[22]; + // Device type strings in PROGMEM static const char DEVICE_TYPE_BMV_700[] PROGMEM = "BMV-700"; static const char DEVICE_TYPE_BMV_702[] PROGMEM = "BMV-702"; @@ -258,6 +280,45 @@ static const char DEVICE_TYPE_UNKNOWN[] PROGMEM = "Unknown"; static char buffer_device_type[48]; +// Off reason strings in PROGMEM +static const uint8_t OFF_REASONS_SIZE = 16; +static const char OFF_REASONS_0[] PROGMEM = "No input power"; +static const char OFF_REASONS_1[] PROGMEM = "Switched off (power switch)"; +static const char OFF_REASONS_2[] PROGMEM = "Switched off (device mode register)"; +static const char OFF_REASONS_3[] PROGMEM = "Remote input"; +static const char OFF_REASONS_4[] PROGMEM = "Protection active"; +static const char OFF_REASONS_5[] PROGMEM = "Paygo"; +static const char OFF_REASONS_6[] PROGMEM = "BMS"; +static const char OFF_REASONS_7[] PROGMEM = "Engine shutdown detection"; +static const char OFF_REASONS_8[] PROGMEM = "Analysing input voltage"; +static const char OFF_REASONS_9[] PROGMEM = "Unknown: Bit 10"; +static const char OFF_REASONS_10[] PROGMEM = "Unknown: Bit 11"; +static const char OFF_REASONS_11[] PROGMEM = "Unknown: Bit 12"; +static const char OFF_REASONS_12[] PROGMEM = "Unknown: Bit 13"; +static const char OFF_REASONS_13[] PROGMEM = "Unknown: Bit 14"; +static const char OFF_REASONS_14[] PROGMEM = "Unknown: Bit 15"; +static const char OFF_REASONS_15[] PROGMEM = "Unknown: Bit 16"; +static const char *const OFF_REASONS[OFF_REASONS_SIZE] PROGMEM = { + OFF_REASONS_0, + OFF_REASONS_1, + OFF_REASONS_2, + OFF_REASONS_3, + OFF_REASONS_4, + OFF_REASONS_5, + OFF_REASONS_6, + OFF_REASONS_7, + OFF_REASONS_8, + OFF_REASONS_9, + OFF_REASONS_10, + OFF_REASONS_11, + OFF_REASONS_12, + OFF_REASONS_13, + OFF_REASONS_14, + OFF_REASONS_15 +}; + +static char buffer_off_reason[36]; + void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) static const char *prefix = " "; ESP_LOGCONFIG(TAG, "Victron:"); @@ -518,107 +579,161 @@ static const char *error_code_text(char * const buffer, int value) { } static const char *warning_code_text(int value) { + const char *result; switch (value) { case 0: - return "No warning"; + result = WARNING_CODE_0; + break; case 1: - return "Low Voltage"; + result = WARNING_CODE_1; + break; case 2: - return "High Voltage"; + result = WARNING_CODE_2; + break; case 4: - return "Low SOC"; + result = WARNING_CODE_4; + break; case 8: - return "Low Starter Voltage"; + result = WARNING_CODE_8; + break; case 16: - return "High Starter Voltage"; + result = WARNING_CODE_16; + break; case 32: - return "Low Temperature"; + result = WARNING_CODE_32; + break; case 64: - return "High Temperature"; + result = WARNING_CODE_64; + break; case 128: - return "Mid Voltage"; + result = WARNING_CODE_128; + break; case 256: - return "Overload"; + result = WARNING_CODE_256; + break; case 512: - return "DC-ripple"; + result = WARNING_CODE_512; + break; case 1024: - return "Low V AC out"; + result = WARNING_CODE_1024; + break; case 2048: - return "High V AC out"; + result = WARNING_CODE_2048; + break; default: - return "Multiple warnings"; + result = WARNING_CODE_MULTIPLE; + break; } + strcpy_P(buffer_warning_code, result); + return buffer_warning_code; } static const char *tracking_mode_text(int value) { + const char *result; switch (value) { case 0: - return "Off"; + result = TRACKING_MODE_0; + break; case 1: - return "Limited"; + result = TRACKING_MODE_1; + break; case 2: - return "Active"; + result = TRACKING_MODE_2; + break; default: - return "Unknown"; + result = TRACKING_MODE_UNKNOWN; + break; } + strcpy_P(buffer_tracking_mode, result); + return buffer_tracking_mode; } static const char *device_mode_text(int value) { + const char *result; switch (value) { case 0: - return "Off"; + result = DEVICE_MODE_0; + break; case 2: - return "On"; + result = DEVICE_MODE_2; + break; case 4: - return "Off"; + result = DEVICE_MODE_4; + break; case 5: - return "Eco"; + result = DEVICE_MODE_5; + break; default: - return "Unknown"; + result = DEVICE_MODE_UNKNOWN; + break; } + strcpy_P(buffer_device_mode, result); + return buffer_device_mode; } -static std::string dc_monitor_mode_text(int value) { +static const char *dc_monitor_mode_text(int value) { + const char *result; switch (value) { case -9: - return "Solar charger"; + result = DC_MONITOR_MODE_SOLAR_CHARGER; + break; case -8: - return "Wind turbine"; + result = DC_MONITOR_MODE_WIND_TURBINE; + break; case -7: - return "Shaft generator"; + result = DC_MONITOR_MODE_SHAFT_GENERATOR; + break; case -6: - return "Alternator"; + result = DC_MONITOR_MODE_ALTERNATOR; + break; case -5: - return "Fuel cell"; + result = DC_MONITOR_MODE_FUEL_CELL; + break; case -4: - return "Water generator"; + result = DC_MONITOR_MODE_WATER_GENERATOR; + break; case -3: - return "DC/DC charger"; + result = DC_MONITOR_MODE_DC_DC_CHARGER; + break; case -2: - return "AC charger"; + result = DC_MONITOR_MODE_AC_CHARGER; + break; case -1: - return "Generic source"; + result = DC_MONITOR_MODE_GENERIC_SOURCE; + break; case 0: - return "Battery monitor (BMV)"; + result = DC_MONITOR_MODE_BATTERY_MONITOR; + break; case 1: - return "Generic load"; + result = DC_MONITOR_MODE_GENERIC_LOAD; + break; case 2: - return "Electric drive"; + result = DC_MONITOR_MODE_ELECTRIC_DRIVE; + break; case 3: - return "Fridge"; + result = DC_MONITOR_MODE_FRIDGE; + break; case 4: - return "Water pump"; + result = DC_MONITOR_MODE_WATER_PUMP; + break; case 5: - return "Bilge pump"; + result = DC_MONITOR_MODE_BILGE_PUMP; + break; case 6: - return "DC system"; + result = DC_MONITOR_MODE_DC_SYSTEM; + break; case 7: - return "Inverter"; + result = DC_MONITOR_MODE_INVERTER; + break; case 8: - return "Water heater"; + result = DC_MONITOR_MODE_WATER_HEATER; + break; default: - return "Unknown"; + result = DC_MONITOR_MODE_UNKNOWN; + break; } + strcpy_P(buffer_dc_monitor_mode, result); + return buffer_dc_monitor_mode; } static const char *device_type_text(int value) { From 25192c106a5e11a353020da514885a8acfda6776 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 16:13:23 +0200 Subject: [PATCH 25/38] Style for clang --- components/victron/victron.cpp | 94 +++++++++++++++++----------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 5486d76..62df40f 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -248,20 +248,34 @@ static const char DEVICE_TYPE_SMARTSHUNT_500A_50MV[] PROGMEM = "SmartShunt 500A/ static const char DEVICE_TYPE_SMARTSHUNT_1000A_50MV[] PROGMEM = "SmartShunt 1000A/50mV"; static const char DEVICE_TYPE_SMARTSHUNT_2000A_50MV[] PROGMEM = "SmartShunt 2000A/50mV"; static const char DEVICE_TYPE_MULTI_RS_SOLAR_48V_6000VA_230V[] PROGMEM = "Multi RS Solar 48V 6000VA 230V"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_12V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 12V 5000VA 230Vac 64k"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_24V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 24V 5000VA 230Vac 64k"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_48V_5000VA_230VAC_64K[] PROGMEM = "Phoenix Inverter Smart 48V 5000VA 230Vac 64k"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 800VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 800VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 800VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 800VA 120Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 800VA 120Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 800VA 120Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 12V 1200VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 1200VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 1200VA 230Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 24V 1200VA 120Vac 64k HS"; -static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120VAC_64K_HS[] PROGMEM = "Phoenix Inverter 48V 1200VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_12V_5000VA_230VAC_64K[] PROGMEM = + "Phoenix Inverter Smart 12V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_24V_5000VA_230VAC_64K[] PROGMEM = + "Phoenix Inverter Smart 24V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_SMART_48V_5000VA_230VAC_64K[] PROGMEM = + "Phoenix Inverter Smart 48V 5000VA 230Vac 64k"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_230VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 12V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_230VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 24V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_230VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 48V 800VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_800VA_120VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 12V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_800VA_120VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 24V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_800VA_120VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 48V 800VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_12V_1200VA_230VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 12V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_230VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 24V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_230VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 48V 1200VA 230Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_24V_1200VA_120VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 24V 1200VA 120Vac 64k HS"; +static const char DEVICE_TYPE_PHOENIX_INVERTER_48V_1200VA_120VAC_64K_HS[] PROGMEM = + "Phoenix Inverter 48V 1200VA 120Vac 64k HS"; static const char DEVICE_TYPE_ORION_XS_12V_12V_50A[] PROGMEM = "Orion XS 12V/12V-50A"; static const char DEVICE_TYPE_ORION_XS_1400[] PROGMEM = "Orion XS 1400"; static const char DEVICE_TYPE_BLUESOLAR_MPPT_75_50_REV2[] PROGMEM = "BlueSolar MPPT 75|50 rev2"; @@ -299,28 +313,14 @@ static const char OFF_REASONS_13[] PROGMEM = "Unknown: Bit 14"; static const char OFF_REASONS_14[] PROGMEM = "Unknown: Bit 15"; static const char OFF_REASONS_15[] PROGMEM = "Unknown: Bit 16"; static const char *const OFF_REASONS[OFF_REASONS_SIZE] PROGMEM = { - OFF_REASONS_0, - OFF_REASONS_1, - OFF_REASONS_2, - OFF_REASONS_3, - OFF_REASONS_4, - OFF_REASONS_5, - OFF_REASONS_6, - OFF_REASONS_7, - OFF_REASONS_8, - OFF_REASONS_9, - OFF_REASONS_10, - OFF_REASONS_11, - OFF_REASONS_12, - OFF_REASONS_13, - OFF_REASONS_14, - OFF_REASONS_15 -}; + OFF_REASONS_0, OFF_REASONS_1, OFF_REASONS_2, OFF_REASONS_3, OFF_REASONS_4, OFF_REASONS_5, + OFF_REASONS_6, OFF_REASONS_7, OFF_REASONS_8, OFF_REASONS_9, OFF_REASONS_10, OFF_REASONS_11, + OFF_REASONS_12, OFF_REASONS_13, OFF_REASONS_14, OFF_REASONS_15 }; static char buffer_off_reason[36]; void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) -static const char *prefix = " "; + static const char *prefix = " "; ESP_LOGCONFIG(TAG, "Victron:"); LOG_BINARY_SENSOR(prefix, "Load state", load_state_binary_sensor_); LOG_BINARY_SENSOR(prefix, "Relay state", relay_state_binary_sensor_); @@ -384,7 +384,7 @@ void VictronComponent::loop() { bool available_data = false; if ((state_ > 0) && (elapsed_time >= 200)) { // last transmission too long ago. Reset RX index. - ESP_LOGE(TAG, "Too old data: %ldms", elapsed_time); + ESP_LOGW(TAG, "Too old data: %ums", elapsed_time); state_ = 0; } last_transmission_ = now; @@ -445,10 +445,10 @@ void VictronComponent::loop() { } } } - uint32_t loop_time = millis() - now; - if (available_data && loop_time > 10){ - ESP_LOGD(TAG, "Loop: %ldms", loop_time); - } + uint32_t loop_time = millis() - now; + if (available_data && loop_time > 10){ + ESP_LOGD(TAG, "Loop: %ums", loop_time); + } } static const char *charging_mode_text(int value) { @@ -507,7 +507,7 @@ static const char *charging_mode_text(int value) { return buffer_charging_mode; } -static const char *error_code_text(char * const buffer, int value) { +static const char *error_code_text(char *const buffer, int value) { const char *result; switch (value) { case 0: @@ -1278,7 +1278,7 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - strcpy_P(buffer_off_reason, (PGM_P)pgm_read_ptr(&OFF_REASONS[i])); + strcpy_P(buffer_off_reason, (PGM_P) pgm_read_ptr(&OFF_REASONS[i])); value_list.append(buffer_off_reason); } } @@ -1411,7 +1411,7 @@ void VictronComponent::handle_value_() { if (label_ == "AR") { static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) - if( value != last_error ) { + if(value != last_error) { last_error = value; error_code_text(buffer_error_code_AR, value); } @@ -1422,10 +1422,10 @@ void VictronComponent::handle_value_() { if (label_ == "OR") { auto off_reason_bitmask = parse_hex(value_.substr(2, value_.size() - 2)); if (off_reason_bitmask) { - static uint32_t last_off_mask = UINT32_MAX; + static uint32_t last_off_mask = UINT32_MAX; this->publish_state_(off_reason_bitmask_sensor_, *off_reason_bitmask); // Load the string only if it has changed. - if (*off_reason_bitmask != last_off_mask){ + if (*off_reason_bitmask != last_off_mask) { last_off_mask = *off_reason_bitmask; this->publish_state_(off_reason_text_sensor_, off_reason_text(*off_reason_bitmask)); } @@ -1597,9 +1597,9 @@ void VictronComponent::handle_value_() { static uint16_t last_charging_mode = UINT16_MAX; value = static_cast(atoi(value_.c_str())); // NOLINT(cert-err34-c) this->publish_state_(charging_mode_id_sensor_, (float) value); - if( value != last_charging_mode ){ - last_charging_mode = value; - this->publish_state_(charging_mode_text_sensor_, charging_mode_text(value)); + if(value != last_charging_mode) { + last_charging_mode = value; + this->publish_state_(charging_mode_text_sensor_, charging_mode_text(value)); } return; } @@ -1719,11 +1719,11 @@ void VictronComponent::publish_state_(sensor::Sensor *sensor, float value) { } void VictronComponent::publish_state_(text_sensor::TextSensor *text_sensor, const std::string &state) { - publish_state_(text_sensor, state.c_str()); + publish_state_(text_sensor, state.c_str()); } void VictronComponent::publish_state_once_(text_sensor::TextSensor *text_sensor, const std::string &state) { - publish_state_once_(text_sensor, state.c_str()); + publish_state_once_(text_sensor, state.c_str()); } void VictronComponent::publish_state_(text_sensor::TextSensor *text_sensor, const char *state) { From d94835b507b50ac623a0b63c9bd5c120861538c2 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 16:16:19 +0200 Subject: [PATCH 26/38] Remove include. --- components/victron/victron.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 62df40f..ec6ec9d 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -2,7 +2,6 @@ #include "esphome/core/log.h" #include // std::min #include "esphome/core/helpers.h" -#include namespace esphome { namespace victron { From 938317f601df5594f4e4db1ad43753b06de68b6a Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 16:20:44 +0200 Subject: [PATCH 27/38] More clang styling. --- components/victron/victron.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index ec6ec9d..410f211 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -312,9 +312,9 @@ static const char OFF_REASONS_13[] PROGMEM = "Unknown: Bit 14"; static const char OFF_REASONS_14[] PROGMEM = "Unknown: Bit 15"; static const char OFF_REASONS_15[] PROGMEM = "Unknown: Bit 16"; static const char *const OFF_REASONS[OFF_REASONS_SIZE] PROGMEM = { - OFF_REASONS_0, OFF_REASONS_1, OFF_REASONS_2, OFF_REASONS_3, OFF_REASONS_4, OFF_REASONS_5, - OFF_REASONS_6, OFF_REASONS_7, OFF_REASONS_8, OFF_REASONS_9, OFF_REASONS_10, OFF_REASONS_11, - OFF_REASONS_12, OFF_REASONS_13, OFF_REASONS_14, OFF_REASONS_15 }; + OFF_REASONS_0, OFF_REASONS_1, OFF_REASONS_2, OFF_REASONS_3, OFF_REASONS_4, OFF_REASONS_5, + OFF_REASONS_6, OFF_REASONS_7, OFF_REASONS_8, OFF_REASONS_9, OFF_REASONS_10, OFF_REASONS_11, + OFF_REASONS_12, OFF_REASONS_13, OFF_REASONS_14, OFF_REASONS_15}; static char buffer_off_reason[36]; @@ -445,8 +445,8 @@ void VictronComponent::loop() { } } uint32_t loop_time = millis() - now; - if (available_data && loop_time > 10){ - ESP_LOGD(TAG, "Loop: %ums", loop_time); + if (available_data && loop_time > 20){ + ESP_LOGD(TAG, "Loop: %ums", loop_time); } } @@ -1410,7 +1410,7 @@ void VictronComponent::handle_value_() { if (label_ == "AR") { static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) - if(value != last_error) { + if (value != last_error) { last_error = value; error_code_text(buffer_error_code_AR, value); } @@ -1584,19 +1584,19 @@ void VictronComponent::handle_value_() { static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(error_code_sensor_, value); - if (value != last_error){ - last_error = value; - error_code_text(buffer_error_code_ERR, value); + if (value != last_error) { + last_error = value; + error_code_text(buffer_error_code_ERR, value); } this->publish_state_(error_text_sensor_, buffer_error_code_ERR); return; } if (label_ == "CS") { - static uint16_t last_charging_mode = UINT16_MAX; + static uint16_t last_charging_mode = UINT16_MAX; value = static_cast(atoi(value_.c_str())); // NOLINT(cert-err34-c) this->publish_state_(charging_mode_id_sensor_, (float) value); - if(value != last_charging_mode) { + if (value != last_charging_mode) { last_charging_mode = value; this->publish_state_(charging_mode_text_sensor_, charging_mode_text(value)); } From 246142eb7136a87162cf425fb6b4257aadf96371 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 16:28:18 +0200 Subject: [PATCH 28/38] Use pgminclude for flash memory. --- components/victron/victron.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 410f211..0f3cfe3 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1,6 +1,7 @@ #include "victron.h" #include "esphome/core/log.h" #include // std::min +#include #include "esphome/core/helpers.h" namespace esphome { From 34e0c1e3a975d2f3c58584208ca0a88646f72369 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 16:33:59 +0200 Subject: [PATCH 29/38] Add include to build examples. --- components/victron/victron.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 0f3cfe3..a6872da 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1,8 +1,8 @@ #include "victron.h" #include "esphome/core/log.h" #include // std::min -#include #include "esphome/core/helpers.h" +#include "esphome/core/log.h" namespace esphome { namespace victron { @@ -446,7 +446,7 @@ void VictronComponent::loop() { } } uint32_t loop_time = millis() - now; - if (available_data && loop_time > 20){ + if (available_data && loop_time > 20) { ESP_LOGD(TAG, "Loop: %ums", loop_time); } } From 93b60c49d0e23c8ebfcce6068b63ab103e9fc658 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 16:44:38 +0200 Subject: [PATCH 30/38] Use appropiate strcpy function for esp8266. --- components/victron/victron.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index a6872da..6d60ec3 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -2,7 +2,7 @@ #include "esphome/core/log.h" #include // std::min #include "esphome/core/helpers.h" -#include "esphome/core/log.h" + namespace esphome { namespace victron { @@ -503,7 +503,7 @@ static const char *charging_mode_text(int value) { result = CHARGING_MODE_UNKNOWN; break; } - strcpy_P(buffer_charging_mode, result); + strcpy(buffer_charging_mode, result); return buffer_charging_mode; } @@ -574,7 +574,7 @@ static const char *error_code_text(char *const buffer, int value) { result = ERROR_CODE_UNKNOWN; break; } - strcpy_P(buffer, result); + strcpy(buffer, result); return buffer; } @@ -624,7 +624,7 @@ static const char *warning_code_text(int value) { result = WARNING_CODE_MULTIPLE; break; } - strcpy_P(buffer_warning_code, result); + strcpy(buffer_warning_code, result); return buffer_warning_code; } @@ -644,7 +644,7 @@ static const char *tracking_mode_text(int value) { result = TRACKING_MODE_UNKNOWN; break; } - strcpy_P(buffer_tracking_mode, result); + strcpy(buffer_tracking_mode, result); return buffer_tracking_mode; } @@ -667,7 +667,7 @@ static const char *device_mode_text(int value) { result = DEVICE_MODE_UNKNOWN; break; } - strcpy_P(buffer_device_mode, result); + strcpy(buffer_device_mode, result); return buffer_device_mode; } @@ -732,7 +732,7 @@ static const char *dc_monitor_mode_text(int value) { result = DC_MONITOR_MODE_UNKNOWN; break; } - strcpy_P(buffer_dc_monitor_mode, result); + strcpy(buffer_dc_monitor_mode, result); return buffer_dc_monitor_mode; } @@ -1263,7 +1263,7 @@ static const char *device_type_text(int value) { result = DEVICE_TYPE_UNKNOWN; break; } - strcpy_P(buffer_device_type, result); + strcpy(buffer_device_type, result); return buffer_device_type; } @@ -1278,7 +1278,7 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - strcpy_P(buffer_off_reason, (PGM_P) pgm_read_ptr(&OFF_REASONS[i])); + strcpy(buffer_off_reason, (PGM_P) pgm_read_ptr(&OFF_REASONS[i])); value_list.append(buffer_off_reason); } } From cd0af560dcd6184d89e76ba979b838411836a3e6 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 16:51:19 +0200 Subject: [PATCH 31/38] Use explicit conversion without external types. --- components/victron/victron.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 6d60ec3..28d5609 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1278,7 +1278,7 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - strcpy(buffer_off_reason, (PGM_P) pgm_read_ptr(&OFF_REASONS[i])); + strcpy(buffer_off_reason, (const char *)pgm_read_ptr(&OFF_REASONS[i])); value_list.append(buffer_off_reason); } } From b73758e9c67261c01334bb3cb54e876d0365d082 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 16:52:09 +0200 Subject: [PATCH 32/38] Update clang style --- components/victron/victron.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 28d5609..3b0db43 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -3,7 +3,6 @@ #include // std::min #include "esphome/core/helpers.h" - namespace esphome { namespace victron { From c20568831e623fc505d5a31718967b75f88c16d4 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 17:14:15 +0200 Subject: [PATCH 33/38] Update clang style --- components/victron/victron.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 3b0db43..44a68bb 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1277,7 +1277,7 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - strcpy(buffer_off_reason, (const char *)pgm_read_ptr(&OFF_REASONS[i])); + strcpy(buffer_off_reason, (const char *) pgm_read_ptr(&OFF_REASONS[i])); value_list.append(buffer_off_reason); } } From bb30666f9f7624fd5867059cd43fa620ac5f1849 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 17:15:47 +0200 Subject: [PATCH 34/38] Reformat to avoid arduino modifiers. --- components/victron/victron.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 44a68bb..b90125d 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -1277,7 +1277,7 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - strcpy(buffer_off_reason, (const char *) pgm_read_ptr(&OFF_REASONS[i])); + strcpy(buffer_off_reason, OFF_REASONS[i]); value_list.append(buffer_off_reason); } } From 01131a5244677af34c6afe0110fe7ca55579b0b4 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 21:42:26 +0200 Subject: [PATCH 35/38] Refactor global static buffers to local. --- components/victron/victron.cpp | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index b90125d..27b28c1 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -31,9 +31,6 @@ static const char ERROR_CODE_117[] PROGMEM = "Invalid/incompatible firmware"; static const char ERROR_CODE_119[] PROGMEM = "User settings invalid"; static const char ERROR_CODE_UNKNOWN[] PROGMEM = "Unknown"; -static char buffer_error_code_ERR[53]; -static char buffer_error_code_AR[53]; - // Charging mode strings in PROGMEM static const char CHARGING_MODE_0[] PROGMEM = "Off"; static const char CHARGING_MODE_1[] PROGMEM = "Low power"; @@ -52,8 +49,6 @@ static const char CHARGING_MODE_248[] PROGMEM = "BatterySafe"; static const char CHARGING_MODE_252[] PROGMEM = "External control"; static const char CHARGING_MODE_UNKNOWN[] PROGMEM = "Unknown"; -static char buffer_charging_mode[30]; - // Warning code strings in PROGMEM static const char WARNING_CODE_0[] PROGMEM = "No warning"; static const char WARNING_CODE_1[] PROGMEM = "Low Voltage"; @@ -70,16 +65,12 @@ static const char WARNING_CODE_1024[] PROGMEM = "Low V AC out"; static const char WARNING_CODE_2048[] PROGMEM = "High V AC out"; static const char WARNING_CODE_MULTIPLE[] PROGMEM = "Multiple warnings"; -static char buffer_warning_code[22]; - // Tracking mode strings in PROGMEM static const char TRACKING_MODE_0[] PROGMEM = "Off"; static const char TRACKING_MODE_1[] PROGMEM = "Limited"; static const char TRACKING_MODE_2[] PROGMEM = "Active"; static const char TRACKING_MODE_UNKNOWN[] PROGMEM = "Unknown"; -static char buffer_tracking_mode[9]; - // Device mode strings in PROGMEM static const char DEVICE_MODE_0[] PROGMEM = "Off"; static const char DEVICE_MODE_2[] PROGMEM = "On"; @@ -87,8 +78,6 @@ static const char DEVICE_MODE_4[] PROGMEM = "Off"; static const char DEVICE_MODE_5[] PROGMEM = "Eco"; static const char DEVICE_MODE_UNKNOWN[] PROGMEM = "Unknown"; -static char buffer_device_mode[9]; - // DC monitor mode strings in PROGMEM static const char DC_MONITOR_MODE_SOLAR_CHARGER[] PROGMEM = "Solar charger"; static const char DC_MONITOR_MODE_WIND_TURBINE[] PROGMEM = "Wind turbine"; @@ -110,8 +99,6 @@ static const char DC_MONITOR_MODE_INVERTER[] PROGMEM = "Inverter"; static const char DC_MONITOR_MODE_WATER_HEATER[] PROGMEM = "Water heater"; static const char DC_MONITOR_MODE_UNKNOWN[] PROGMEM = "Unknown"; -static char buffer_dc_monitor_mode[22]; - // Device type strings in PROGMEM static const char DEVICE_TYPE_BMV_700[] PROGMEM = "BMV-700"; static const char DEVICE_TYPE_BMV_702[] PROGMEM = "BMV-702"; @@ -291,8 +278,6 @@ static const char DEVICE_TYPE_SMARTSOLAR_MPPT_RS_450_200[] PROGMEM = "SmartSolar static const char DEVICE_TYPE_UNKNOWN[] PROGMEM = "Unknown"; -static char buffer_device_type[48]; - // Off reason strings in PROGMEM static const uint8_t OFF_REASONS_SIZE = 16; static const char OFF_REASONS_0[] PROGMEM = "No input power"; @@ -316,8 +301,6 @@ static const char *const OFF_REASONS[OFF_REASONS_SIZE] PROGMEM = { OFF_REASONS_6, OFF_REASONS_7, OFF_REASONS_8, OFF_REASONS_9, OFF_REASONS_10, OFF_REASONS_11, OFF_REASONS_12, OFF_REASONS_13, OFF_REASONS_14, OFF_REASONS_15}; -static char buffer_off_reason[36]; - void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size) static const char *prefix = " "; ESP_LOGCONFIG(TAG, "Victron:"); @@ -451,6 +434,7 @@ void VictronComponent::loop() { } static const char *charging_mode_text(int value) { + static char buffer_charging_mode[30]; const char *result; switch (value) { case 0: @@ -578,6 +562,7 @@ static const char *error_code_text(char *const buffer, int value) { } static const char *warning_code_text(int value) { + static char buffer_warning_code[22]; const char *result; switch (value) { case 0: @@ -628,6 +613,7 @@ static const char *warning_code_text(int value) { } static const char *tracking_mode_text(int value) { + static char buffer_tracking_mode[9]; const char *result; switch (value) { case 0: @@ -648,6 +634,7 @@ static const char *tracking_mode_text(int value) { } static const char *device_mode_text(int value) { + static char buffer_device_mode[9]; const char *result; switch (value) { case 0: @@ -671,6 +658,7 @@ static const char *device_mode_text(int value) { } static const char *dc_monitor_mode_text(int value) { + static char buffer_dc_monitor_mode[22]; const char *result; switch (value) { case -9: @@ -736,6 +724,7 @@ static const char *dc_monitor_mode_text(int value) { } static const char *device_type_text(int value) { + static char buffer_device_type[48]; const char *result; switch (value) { case 0x203: @@ -1267,6 +1256,7 @@ static const char *device_type_text(int value) { } static std::string off_reason_text(uint32_t mask) { + static char buffer_off_reason[36]; bool first = true; std::string value_list = ""; if (mask) { @@ -1408,6 +1398,7 @@ void VictronComponent::handle_value_() { } if (label_ == "AR") { + static char buffer_error_code_AR[53]; static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) if (value != last_error) { @@ -1581,6 +1572,7 @@ void VictronComponent::handle_value_() { } if (label_ == "ERR") { + static char buffer_error_code_ERR[53]; static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(error_code_sensor_, value); From 31e14ea7fd1608979fee7fbc7fc8759882a84cf0 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 22:52:05 +0200 Subject: [PATCH 36/38] Prefer limit copy of data. --- components/victron/victron.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 27b28c1..26befc9 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -486,7 +486,8 @@ static const char *charging_mode_text(int value) { result = CHARGING_MODE_UNKNOWN; break; } - strcpy(buffer_charging_mode, result); + // Use strlcpy instead of strcpy + strlcpy(buffer_charging_mode, result, sizeof(buffer_charging_mode)); return buffer_charging_mode; } @@ -557,7 +558,8 @@ static const char *error_code_text(char *const buffer, int value) { result = ERROR_CODE_UNKNOWN; break; } - strcpy(buffer, result); + // Use strlcpy instead of strcpy + strlcpy(buffer, result, 53); return buffer; } @@ -608,7 +610,8 @@ static const char *warning_code_text(int value) { result = WARNING_CODE_MULTIPLE; break; } - strcpy(buffer_warning_code, result); + // Use strlcpy instead of strcpy + strlcpy(buffer_warning_code, result, sizeof(buffer_warning_code)); return buffer_warning_code; } @@ -629,7 +632,8 @@ static const char *tracking_mode_text(int value) { result = TRACKING_MODE_UNKNOWN; break; } - strcpy(buffer_tracking_mode, result); + // Use strlcpy instead of strcpy + strlcpy(buffer_tracking_mode, result, sizeof(buffer_tracking_mode)); return buffer_tracking_mode; } @@ -653,7 +657,8 @@ static const char *device_mode_text(int value) { result = DEVICE_MODE_UNKNOWN; break; } - strcpy(buffer_device_mode, result); + // Use strlcpy instead of strcpy + strlcpy(buffer_device_mode, result, sizeof(buffer_device_mode)); return buffer_device_mode; } @@ -719,7 +724,8 @@ static const char *dc_monitor_mode_text(int value) { result = DC_MONITOR_MODE_UNKNOWN; break; } - strcpy(buffer_dc_monitor_mode, result); + // Use strlcpy instead of strcpy + strlcpy(buffer_dc_monitor_mode, result, sizeof(buffer_dc_monitor_mode)); return buffer_dc_monitor_mode; } @@ -1251,7 +1257,8 @@ static const char *device_type_text(int value) { result = DEVICE_TYPE_UNKNOWN; break; } - strcpy(buffer_device_type, result); + // Use strlcpy instead of strcpy + strlcpy(buffer_device_type, result, sizeof(buffer_device_type)); return buffer_device_type; } @@ -1267,7 +1274,8 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - strcpy(buffer_off_reason, OFF_REASONS[i]); + // Use strlcpy instead of strcpy + strlcpy(buffer_off_reason, OFF_REASONS[i], sizeof(buffer_off_reason)); value_list.append(buffer_off_reason); } } From f7e92faf62d4ec5eaae18d450692699f66b1fa23 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Sun, 21 Sep 2025 22:55:30 +0200 Subject: [PATCH 37/38] Refactor to use a constant for buffer size. --- components/victron/victron.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 26befc9..25452ff 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -8,6 +8,9 @@ namespace victron { static const char *const TAG = "victron"; +// Use a constant for error buffer size +static const size_t MAX_ERROR_BUFFER = 53; + // Error code strings in PROGMEM static const char ERROR_CODE_0[] PROGMEM = "No error"; static const char ERROR_CODE_2[] PROGMEM = "Battery voltage too high"; @@ -559,7 +562,7 @@ static const char *error_code_text(char *const buffer, int value) { break; } // Use strlcpy instead of strcpy - strlcpy(buffer, result, 53); + strlcpy(buffer, result, MAX_ERROR_BUFFER); return buffer; } @@ -1406,14 +1409,14 @@ void VictronComponent::handle_value_() { } if (label_ == "AR") { - static char buffer_error_code_AR[53]; + static char buffer_error_code_ar[MAX_ERROR_BUFFER]; static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) if (value != last_error) { last_error = value; - error_code_text(buffer_error_code_AR, value); + error_code_text(buffer_error_code_ar, value); } - this->publish_state_(alarm_reason_text_sensor_, buffer_error_code_AR); // NOLINT(cert-err34-c) + this->publish_state_(alarm_reason_text_sensor_, buffer_error_code_ar); // NOLINT(cert-err34-c) return; } @@ -1580,15 +1583,15 @@ void VictronComponent::handle_value_() { } if (label_ == "ERR") { - static char buffer_error_code_ERR[53]; + static char buffer_error_code_err[MAX_ERROR_BUFFER]; static uint16_t last_error = UINT16_MAX; uint16_t value = atoi(value_.c_str()); // NOLINT(cert-err34-c) this->publish_state_(error_code_sensor_, value); if (value != last_error) { last_error = value; - error_code_text(buffer_error_code_ERR, value); + error_code_text(buffer_error_code_err, value); } - this->publish_state_(error_text_sensor_, buffer_error_code_ERR); + this->publish_state_(error_text_sensor_, buffer_error_code_err); return; } From d3eb2df0fa2b23f65e8fde22fd5df9cef2b20ad7 Mon Sep 17 00:00:00 2001 From: Orestes Sanchez Benavente Date: Mon, 22 Sep 2025 00:10:47 +0200 Subject: [PATCH 38/38] Use strncpy and memset to copy from flash to memory buffer. --- components/victron/victron.cpp | 40 ++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/components/victron/victron.cpp b/components/victron/victron.cpp index 25452ff..17e007d 100644 --- a/components/victron/victron.cpp +++ b/components/victron/victron.cpp @@ -489,8 +489,9 @@ static const char *charging_mode_text(int value) { result = CHARGING_MODE_UNKNOWN; break; } - // Use strlcpy instead of strcpy - strlcpy(buffer_charging_mode, result, sizeof(buffer_charging_mode)); + // Use strncpy instead of strcpy + memset(buffer_charging_mode, 0, sizeof(buffer_charging_mode)); + strncpy(buffer_charging_mode, result, sizeof(buffer_charging_mode)); return buffer_charging_mode; } @@ -561,8 +562,9 @@ static const char *error_code_text(char *const buffer, int value) { result = ERROR_CODE_UNKNOWN; break; } - // Use strlcpy instead of strcpy - strlcpy(buffer, result, MAX_ERROR_BUFFER); + // Use strncpy instead of strcpy + memset(buffer, 0, MAX_ERROR_BUFFER); + strncpy(buffer, result, MAX_ERROR_BUFFER); return buffer; } @@ -613,8 +615,9 @@ static const char *warning_code_text(int value) { result = WARNING_CODE_MULTIPLE; break; } - // Use strlcpy instead of strcpy - strlcpy(buffer_warning_code, result, sizeof(buffer_warning_code)); + // Use strncpy instead of strcpy + memset(buffer_warning_code, 0, sizeof(buffer_warning_code)); + strncpy(buffer_warning_code, result, sizeof(buffer_warning_code)); return buffer_warning_code; } @@ -635,8 +638,9 @@ static const char *tracking_mode_text(int value) { result = TRACKING_MODE_UNKNOWN; break; } - // Use strlcpy instead of strcpy - strlcpy(buffer_tracking_mode, result, sizeof(buffer_tracking_mode)); + // Use strncpy instead of strcpy + memset(buffer_tracking_mode, 0, sizeof(buffer_tracking_mode)); + strncpy(buffer_tracking_mode, result, sizeof(buffer_tracking_mode)); return buffer_tracking_mode; } @@ -660,8 +664,9 @@ static const char *device_mode_text(int value) { result = DEVICE_MODE_UNKNOWN; break; } - // Use strlcpy instead of strcpy - strlcpy(buffer_device_mode, result, sizeof(buffer_device_mode)); + // Use strncpy instead of strcpy + memset(buffer_device_mode, 0, sizeof(buffer_device_mode)); + strncpy(buffer_device_mode, result, sizeof(buffer_device_mode)); return buffer_device_mode; } @@ -727,8 +732,9 @@ static const char *dc_monitor_mode_text(int value) { result = DC_MONITOR_MODE_UNKNOWN; break; } - // Use strlcpy instead of strcpy - strlcpy(buffer_dc_monitor_mode, result, sizeof(buffer_dc_monitor_mode)); + // Use strncpy instead of strcpy + memset(buffer_dc_monitor_mode, 0, sizeof(buffer_dc_monitor_mode)); + strncpy(buffer_dc_monitor_mode, result, sizeof(buffer_dc_monitor_mode)); return buffer_dc_monitor_mode; } @@ -1260,8 +1266,9 @@ static const char *device_type_text(int value) { result = DEVICE_TYPE_UNKNOWN; break; } - // Use strlcpy instead of strcpy - strlcpy(buffer_device_type, result, sizeof(buffer_device_type)); + // Use strncpy instead of strcpy + memset(buffer_device_type, 0, sizeof(buffer_device_type)); + strncpy(buffer_device_type, result, sizeof(buffer_device_type)); return buffer_device_type; } @@ -1277,8 +1284,9 @@ static std::string off_reason_text(uint32_t mask) { } else { value_list.append(";"); } - // Use strlcpy instead of strcpy - strlcpy(buffer_off_reason, OFF_REASONS[i], sizeof(buffer_off_reason)); + // Use strncpy instead of strcpy + memset(buffer_off_reason, 0, sizeof(buffer_off_reason)); + strncpy(buffer_off_reason, OFF_REASONS[i], sizeof(buffer_off_reason)); value_list.append(buffer_off_reason); } }