From 84290bdf08cfec6614922844a75d015a98390858 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 12 Mar 2022 10:05:18 +0100 Subject: [PATCH 001/114] Add draft --- components/pipsolar/__init__.py | 32 + components/pipsolar/binary_sensor/__init__.py | 144 +++ components/pipsolar/output/__init__.py | 106 ++ .../pipsolar/output/pipsolar_output.cpp | 22 + components/pipsolar/output/pipsolar_output.h | 40 + components/pipsolar/pipsolar.cpp | 972 ++++++++++++++++++ components/pipsolar/pipsolar.h | 223 ++++ components/pipsolar/sensor/__init__.py | 220 ++++ components/pipsolar/switch/__init__.py | 60 ++ .../pipsolar/switch/pipsolar_switch.cpp | 24 + components/pipsolar/switch/pipsolar_switch.h | 25 + components/pipsolar/text_sensor/__init__.py | 52 + .../text_sensor/pipsolar_textsensor.cpp | 13 + .../text_sensor/pipsolar_textsensor.h | 20 + esp32-example.yaml | 4 + esp8266-example.yaml | 4 + 16 files changed, 1961 insertions(+) create mode 100644 components/pipsolar/__init__.py create mode 100644 components/pipsolar/binary_sensor/__init__.py create mode 100644 components/pipsolar/output/__init__.py create mode 100644 components/pipsolar/output/pipsolar_output.cpp create mode 100644 components/pipsolar/output/pipsolar_output.h create mode 100644 components/pipsolar/pipsolar.cpp create mode 100644 components/pipsolar/pipsolar.h create mode 100644 components/pipsolar/sensor/__init__.py create mode 100644 components/pipsolar/switch/__init__.py create mode 100644 components/pipsolar/switch/pipsolar_switch.cpp create mode 100644 components/pipsolar/switch/pipsolar_switch.h create mode 100644 components/pipsolar/text_sensor/__init__.py create mode 100644 components/pipsolar/text_sensor/pipsolar_textsensor.cpp create mode 100644 components/pipsolar/text_sensor/pipsolar_textsensor.h diff --git a/components/pipsolar/__init__.py b/components/pipsolar/__init__.py new file mode 100644 index 00000000..20e46721 --- /dev/null +++ b/components/pipsolar/__init__.py @@ -0,0 +1,32 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.const import CONF_ID +from esphome.components import uart + +DEPENDENCIES = ["uart"] +CODEOWNERS = ["@andreashergert1984"] +AUTO_LOAD = ["binary_sensor", "text_sensor", "sensor", "switch", "output"] +MULTI_CONF = True + +CONF_PIPSOLAR_ID = "pipsolar_id" + +pipsolar_ns = cg.esphome_ns.namespace("pipsolar") +PipsolarComponent = pipsolar_ns.class_("Pipsolar", cg.Component) + +PIPSOLAR_COMPONENT_SCHEMA = cv.COMPONENT_SCHEMA.extend( + { + cv.Required(CONF_PIPSOLAR_ID): cv.use_id(PipsolarComponent), + } +) + +CONFIG_SCHEMA = cv.All( + cv.Schema({cv.GenerateID(): cv.declare_id(PipsolarComponent)}) + .extend(cv.polling_component_schema("1s")) + .extend(uart.UART_DEVICE_SCHEMA) +) + + +def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + yield cg.register_component(var, config) + yield uart.register_uart_device(var, config) diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py new file mode 100644 index 00000000..5c6af3bf --- /dev/null +++ b/components/pipsolar/binary_sensor/__init__.py @@ -0,0 +1,144 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import binary_sensor +from esphome.const import ( + CONF_ID, +) +from .. import PIPSOLAR_COMPONENT_SCHEMA, CONF_PIPSOLAR_ID + +DEPENDENCIES = ["uart"] + +CONF_ADD_SBU_PRIORITY_VERSION = "add_sbu_priority_version" +CONF_CONFIGURATION_STATUS = "configuration_status" +CONF_SCC_FIRMWARE_VERSION = "scc_firmware_version" +CONF_LOAD_STATUS = "load_status" +CONF_BATTERY_VOLTAGE_TO_STEADY_WHILE_CHARGING = ( + "battery_voltage_to_steady_while_charging" +) +CONF_CHARGING_STATUS = "charging_status" +CONF_SCC_CHARGING_STATUS = "scc_charging_status" +CONF_AC_CHARGING_STATUS = "ac_charging_status" +CONF_CHARGING_TO_FLOATING_MODE = "charging_to_floating_mode" +CONF_SWITCH_ON = "switch_on" +CONF_DUSTPROOF_INSTALLED = "dustproof_installed" +CONF_SILENCE_BUZZER_OPEN_BUZZER = "silence_buzzer_open_buzzer" +CONF_OVERLOAD_BYPASS_FUNCTION = "overload_bypass_function" +CONF_LCD_ESCAPE_TO_DEFAULT = "lcd_escape_to_default" +CONF_OVERLOAD_RESTART_FUNCTION = "overload_restart_function" +CONF_OVER_TEMPERATURE_RESTART_FUNCTION = "over_temperature_restart_function" +CONF_BACKLIGHT_ON = "backlight_on" +CONF_ALARM_ON_WHEN_PRIMARY_SOURCE_INTERRUPT = "alarm_on_when_primary_source_interrupt" +CONF_FAULT_CODE_RECORD = "fault_code_record" +CONF_POWER_SAVING = "power_saving" + +CONF_WARNINGS_PRESENT = "warnings_present" +CONF_FAULTS_PRESENT = "faults_present" +CONF_WARNING_POWER_LOSS = "warning_power_loss" +CONF_FAULT_INVERTER_FAULT = "fault_inverter_fault" +CONF_FAULT_BUS_OVER = "fault_bus_over" +CONF_FAULT_BUS_UNDER = "fault_bus_under" +CONF_FAULT_BUS_SOFT_FAIL = "fault_bus_soft_fail" +CONF_WARNING_LINE_FAIL = "warning_line_fail" +CONF_FAULT_OPVSHORT = "fault_opvshort" +CONF_FAULT_INVERTER_VOLTAGE_TOO_LOW = "fault_inverter_voltage_too_low" +CONF_FAULT_INVERTER_VOLTAGE_TOO_HIGH = "fault_inverter_voltage_too_high" +CONF_WARNING_OVER_TEMPERATURE = "warning_over_temperature" +CONF_WARNING_FAN_LOCK = "warning_fan_lock" +CONF_WARNING_BATTERY_VOLTAGE_HIGH = "warning_battery_voltage_high" +CONF_WARNING_BATTERY_LOW_ALARM = "warning_battery_low_alarm" +CONF_WARNING_BATTERY_UNDER_SHUTDOWN = "warning_battery_under_shutdown" +CONF_WARNING_BATTERY_DERATING = "warning_battery_derating" +CONF_WARNING_OVER_LOAD = "warning_over_load" +CONF_WARNING_EEPROM_FAILED = "warning_eeprom_failed" +CONF_FAULT_INVERTER_OVER_CURRENT = "fault_inverter_over_current" +CONF_FAULT_INVERTER_SOFT_FAILED = "fault_inverter_soft_failed" +CONF_FAULT_SELF_TEST_FAILED = "fault_self_test_failed" +CONF_FAULT_OP_DC_VOLTAGE_OVER = "fault_op_dc_voltage_over" +CONF_FAULT_BATTERY_OPEN = "fault_battery_open" +CONF_FAULT_CURRENT_SENSOR_FAILED = "fault_current_sensor_failed" +CONF_FAULT_BATTERY_SHORT = "fault_battery_short" +CONF_WARNING_POWER_LIMIT = "warning_power_limit" +CONF_WARNING_PV_VOLTAGE_HIGH = "warning_pv_voltage_high" +CONF_FAULT_MPPT_OVERLOAD = "fault_mppt_overload" +CONF_WARNING_MPPT_OVERLOAD = "warning_mppt_overload" +CONF_WARNING_BATTERY_TOO_LOW_TO_CHARGE = "warning_battery_too_low_to_charge" +CONF_FAULT_DC_DC_OVER_CURRENT = "fault_dc_dc_over_current" +CONF_FAULT_CODE = "fault_code" +CONF_WARNUNG_LOW_PV_ENERGY = "warnung_low_pv_energy" +CONF_WARNING_HIGH_AC_INPUT_DURING_BUS_SOFT_START = ( + "warning_high_ac_input_during_bus_soft_start" +) +CONF_WARNING_BATTERY_EQUALIZATION = "warning_battery_equalization" + +TYPES = [ + CONF_ADD_SBU_PRIORITY_VERSION, + CONF_CONFIGURATION_STATUS, + CONF_SCC_FIRMWARE_VERSION, + CONF_LOAD_STATUS, + CONF_BATTERY_VOLTAGE_TO_STEADY_WHILE_CHARGING, + CONF_CHARGING_STATUS, + CONF_SCC_CHARGING_STATUS, + CONF_AC_CHARGING_STATUS, + CONF_CHARGING_TO_FLOATING_MODE, + CONF_SWITCH_ON, + CONF_DUSTPROOF_INSTALLED, + CONF_SILENCE_BUZZER_OPEN_BUZZER, + CONF_OVERLOAD_BYPASS_FUNCTION, + CONF_LCD_ESCAPE_TO_DEFAULT, + CONF_OVERLOAD_RESTART_FUNCTION, + CONF_OVER_TEMPERATURE_RESTART_FUNCTION, + CONF_BACKLIGHT_ON, + CONF_ALARM_ON_WHEN_PRIMARY_SOURCE_INTERRUPT, + CONF_FAULT_CODE_RECORD, + CONF_POWER_SAVING, + CONF_WARNINGS_PRESENT, + CONF_FAULTS_PRESENT, + CONF_WARNING_POWER_LOSS, + CONF_FAULT_INVERTER_FAULT, + CONF_FAULT_BUS_OVER, + CONF_FAULT_BUS_UNDER, + CONF_FAULT_BUS_SOFT_FAIL, + CONF_WARNING_LINE_FAIL, + CONF_FAULT_OPVSHORT, + CONF_FAULT_INVERTER_VOLTAGE_TOO_LOW, + CONF_FAULT_INVERTER_VOLTAGE_TOO_HIGH, + CONF_WARNING_OVER_TEMPERATURE, + CONF_WARNING_FAN_LOCK, + CONF_WARNING_BATTERY_VOLTAGE_HIGH, + CONF_WARNING_BATTERY_LOW_ALARM, + CONF_WARNING_BATTERY_UNDER_SHUTDOWN, + CONF_WARNING_BATTERY_DERATING, + CONF_WARNING_OVER_LOAD, + CONF_WARNING_EEPROM_FAILED, + CONF_FAULT_INVERTER_OVER_CURRENT, + CONF_FAULT_INVERTER_SOFT_FAILED, + CONF_FAULT_SELF_TEST_FAILED, + CONF_FAULT_OP_DC_VOLTAGE_OVER, + CONF_FAULT_BATTERY_OPEN, + CONF_FAULT_CURRENT_SENSOR_FAILED, + CONF_FAULT_BATTERY_SHORT, + CONF_WARNING_POWER_LIMIT, + CONF_WARNING_PV_VOLTAGE_HIGH, + CONF_FAULT_MPPT_OVERLOAD, + CONF_WARNING_MPPT_OVERLOAD, + CONF_WARNING_BATTERY_TOO_LOW_TO_CHARGE, + CONF_FAULT_DC_DC_OVER_CURRENT, + CONF_FAULT_CODE, + CONF_WARNUNG_LOW_PV_ENERGY, + CONF_WARNING_HIGH_AC_INPUT_DURING_BUS_SOFT_START, + CONF_WARNING_BATTERY_EQUALIZATION, +] + +CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( + {cv.Optional(type): binary_sensor.BINARY_SENSOR_SCHEMA for type in TYPES} +) + + +async def to_code(config): + paren = await cg.get_variable(config[CONF_PIPSOLAR_ID]) + for type in TYPES: + if type in config: + conf = config[type] + sens = cg.new_Pvariable(conf[CONF_ID]) + await binary_sensor.register_binary_sensor(sens, conf) + cg.add(getattr(paren, f"set_{type}")(sens)) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py new file mode 100644 index 00000000..b518d485 --- /dev/null +++ b/components/pipsolar/output/__init__.py @@ -0,0 +1,106 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome import automation +from esphome.components import output +from esphome.const import CONF_ID, CONF_VALUE +from .. import PIPSOLAR_COMPONENT_SCHEMA, CONF_PIPSOLAR_ID, pipsolar_ns + +DEPENDENCIES = ["pipsolar"] + +PipsolarOutput = pipsolar_ns.class_("PipsolarOutput", output.FloatOutput) +SetOutputAction = pipsolar_ns.class_("SetOutputAction", automation.Action) + +CONF_POSSIBLE_VALUES = "possible_values" + +# 3.11 PCVV: Setting battery C.V. (constant voltage) charging voltage 48.0V ~ 58.4V for 48V unit +# battery_bulk_voltage; +# battery_recharge_voltage; 12V unit: 11V/11.3V/11.5V/11.8V/12V/12.3V/12.5V/12.8V +# 24V unit: 22V/22.5V/23V/23.5V/24V/24.5V/25V/25.5V +# 48V unit: 44V/45V/46V/47V/48V/49V/50V/51V +# battery_under_voltage; 40.0V ~ 48.0V for 48V unit +# battery_float_voltage; 48.0V ~ 58.4V for 48V unit +# battery_type; 00 for AGM, 01 for Flooded battery +# current_max_ac_charging_current; +# output_source_priority; 00 / 01 / 02 +# charger_source_priority; For HS: 00 for utility first, 01 for solar first, 02 for solar and utility, 03 for only solar charging +# For MS/MSX: 00 for utility first, 01 for solar first, 03 for only solar charging +# battery_redischarge_voltage; 12V unit: 00.0V12V/12.3V/12.5V/12.8V/13V/13.3V/13.5V/13.8V/14V/14.3V/14.5 +# 24V unit: 00.0V/24V/24.5V/25V/25.5V/26V/26.5V/27V/27.5V/28V/28.5V/29V +# 48V unit: 00.0V48V/49V/50V/51V/52V/53V/54V/55V/56V/57V/58V + +CONF_BATTERY_RECHARGE_VOLTAGE = "battery_recharge_voltage" +CONF_BATTERY_UNDER_VOLTAGE = "battery_under_voltage" +CONF_BATTERY_FLOAT_VOLTAGE = "battery_float_voltage" +CONF_BATTERY_TYPE = "battery_type" +CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" +CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" +CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" +CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" +CONF_BATTERY_REDISCHARGE_VOLTAGE = "battery_redischarge_voltage" + +TYPES = { + CONF_BATTERY_RECHARGE_VOLTAGE: ( + [44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0], + "PBCV%02.1f", + ), + CONF_BATTERY_UNDER_VOLTAGE: ( + [40.0, 40.1, 42, 43, 44, 45, 46, 47, 48.0], + "PSDV%02.1f", + ), + CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), + CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20], "MUCHGC0%02.0f"), + CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), + CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), + CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), + CONF_BATTERY_REDISCHARGE_VOLTAGE: ( + [0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58], + "PBDV%02.1f", + ), +} + +CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( + { + cv.Optional(type): output.FLOAT_OUTPUT_SCHEMA.extend( + { + cv.Required(CONF_ID): cv.declare_id(PipsolarOutput), + cv.Optional(CONF_POSSIBLE_VALUES, default=values): cv.All( + cv.ensure_list(cv.positive_float), cv.Length(min=1) + ), + } + ) + for type, (values, _) in TYPES.items() + } +) + + +async def to_code(config): + paren = await cg.get_variable(config[CONF_PIPSOLAR_ID]) + + for type, (_, command) in TYPES.items(): + if type in config: + conf = config[type] + var = cg.new_Pvariable(conf[CONF_ID]) + await output.register_output(var, conf) + cg.add(var.set_parent(paren)) + cg.add(var.set_set_command(command)) + if (CONF_POSSIBLE_VALUES) in conf: + cg.add(var.set_possible_values(conf[CONF_POSSIBLE_VALUES])) + + +@automation.register_action( + "output.pipsolar.set_level", + SetOutputAction, + cv.Schema( + { + cv.Required(CONF_ID): cv.use_id(CONF_ID), + cv.Required(CONF_VALUE): cv.templatable(cv.positive_float), + } + ), +) +def output_pipsolar_set_level_to_code(config, action_id, template_arg, args): + paren = yield cg.get_variable(config[CONF_ID]) + var = cg.new_Pvariable(action_id, template_arg, paren) + template_ = yield cg.templatable(config[CONF_VALUE], args, float) + cg.add(var.set_level(template_)) + yield var diff --git a/components/pipsolar/output/pipsolar_output.cpp b/components/pipsolar/output/pipsolar_output.cpp new file mode 100644 index 00000000..b843f1f3 --- /dev/null +++ b/components/pipsolar/output/pipsolar_output.cpp @@ -0,0 +1,22 @@ +#include "pipsolar_output.h" +#include "esphome/core/log.h" +#include "esphome/core/helpers.h" + +namespace esphome { +namespace pipsolar { + +static const char *const TAG = "pipsolar.output"; + +void PipsolarOutput::write_state(float state) { + char tmp[10]; + sprintf(tmp, this->set_command_.c_str(), state); + + if (std::find(this->possible_values_.begin(), this->possible_values_.end(), state) != this->possible_values_.end()) { + ESP_LOGD(TAG, "Will write: %s out of value %f / %02.0f", tmp, state, state); + this->parent_->switch_command(std::string(tmp)); + } else { + ESP_LOGD(TAG, "Will not write: %s as it is not in list of allowed values", tmp); + } +} +} // namespace pipsolar +} // namespace esphome diff --git a/components/pipsolar/output/pipsolar_output.h b/components/pipsolar/output/pipsolar_output.h new file mode 100644 index 00000000..fe783cf0 --- /dev/null +++ b/components/pipsolar/output/pipsolar_output.h @@ -0,0 +1,40 @@ +#pragma once + +#include "../pipsolar.h" +#include "esphome/components/output/float_output.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace pipsolar { + +class Pipsolar; + +class PipsolarOutput : public output::FloatOutput { + public: + PipsolarOutput() {} + void set_parent(Pipsolar *parent) { this->parent_ = parent; } + void set_set_command(const std::string &command) { this->set_command_ = command; }; + void set_possible_values(std::vector possible_values) { this->possible_values_ = std::move(possible_values); } + void set_value(float value) { this->write_state(value); }; + + protected: + void write_state(float state) override; + std::string set_command_; + Pipsolar *parent_; + std::vector possible_values_; +}; + +template class SetOutputAction : public Action { + public: + SetOutputAction(PipsolarOutput *output) : output_(output) {} + + TEMPLATABLE_VALUE(float, level) + + void play(Ts... x) override { this->output_->set_value(this->level_.value(x...)); } + + protected: + PipsolarOutput *output_; +}; + +} // namespace pipsolar +} // namespace esphome diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp new file mode 100644 index 00000000..948c58ba --- /dev/null +++ b/components/pipsolar/pipsolar.cpp @@ -0,0 +1,972 @@ +#include "pipsolar.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace pipsolar { + +static const char *const TAG = "pipsolar"; + +void Pipsolar::setup() { + this->state_ = STATE_IDLE; + this->command_start_millis_ = 0; +} + +void Pipsolar::empty_uart_buffer_() { + uint8_t byte; + while (this->available()) { + this->read_byte(&byte); + } +} + +void Pipsolar::loop() { + // Read message + if (this->state_ == STATE_IDLE) { + this->empty_uart_buffer_(); + switch (this->send_next_command_()) { + case 0: + // no command send (empty queue) time to poll + if (millis() - this->last_poll_ > this->update_interval_) { + this->send_next_poll_(); + this->last_poll_ = millis(); + } + return; + break; + case 1: + // command send + return; + break; + } + } + if (this->state_ == STATE_COMMAND_COMPLETE) { + if (this->check_incoming_length_(4)) { + ESP_LOGD(TAG, "response length for command OK"); + if (this->check_incoming_crc_()) { + // crc ok + if (this->read_buffer_[1] == 'A' && this->read_buffer_[2] == 'C' && this->read_buffer_[3] == 'K') { + ESP_LOGD(TAG, "command successful"); + } else { + ESP_LOGD(TAG, "command not successful"); + } + this->command_queue_[this->command_queue_position_] = std::string(""); + this->command_queue_position_ = (command_queue_position_ + 1) % COMMAND_QUEUE_LENGTH; + this->state_ = STATE_IDLE; + + } else { + // crc failed + this->command_queue_[this->command_queue_position_] = std::string(""); + this->command_queue_position_ = (command_queue_position_ + 1) % COMMAND_QUEUE_LENGTH; + this->state_ = STATE_IDLE; + } + } else { + ESP_LOGD(TAG, "response length for command %s not OK: with length %zu", + this->command_queue_[this->command_queue_position_].c_str(), this->read_pos_); + this->command_queue_[this->command_queue_position_] = std::string(""); + this->command_queue_position_ = (command_queue_position_ + 1) % COMMAND_QUEUE_LENGTH; + this->state_ = STATE_IDLE; + } + } + + if (this->state_ == STATE_POLL_DECODED) { + std::string mode; + switch (this->used_polling_commands_[this->last_polling_command_].identifier) { + case POLLING_QPIRI: + if (this->grid_rating_voltage_) { + this->grid_rating_voltage_->publish_state(value_grid_rating_voltage_); + } + if (this->grid_rating_current_) { + this->grid_rating_current_->publish_state(value_grid_rating_current_); + } + if (this->ac_output_rating_voltage_) { + this->ac_output_rating_voltage_->publish_state(value_ac_output_rating_voltage_); + } + if (this->ac_output_rating_frequency_) { + this->ac_output_rating_frequency_->publish_state(value_ac_output_rating_frequency_); + } + if (this->ac_output_rating_current_) { + this->ac_output_rating_current_->publish_state(value_ac_output_rating_current_); + } + if (this->ac_output_rating_apparent_power_) { + this->ac_output_rating_apparent_power_->publish_state(value_ac_output_rating_apparent_power_); + } + if (this->ac_output_rating_active_power_) { + this->ac_output_rating_active_power_->publish_state(value_ac_output_rating_active_power_); + } + if (this->battery_rating_voltage_) { + this->battery_rating_voltage_->publish_state(value_battery_rating_voltage_); + } + if (this->battery_recharge_voltage_) { + this->battery_recharge_voltage_->publish_state(value_battery_recharge_voltage_); + } + if (this->battery_under_voltage_) { + this->battery_under_voltage_->publish_state(value_battery_under_voltage_); + } + if (this->battery_bulk_voltage_) { + this->battery_bulk_voltage_->publish_state(value_battery_bulk_voltage_); + } + if (this->battery_float_voltage_) { + this->battery_float_voltage_->publish_state(value_battery_float_voltage_); + } + if (this->battery_type_) { + this->battery_type_->publish_state(value_battery_type_); + } + if (this->current_max_ac_charging_current_) { + this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); + } + if (this->current_max_charging_current_) { + this->current_max_charging_current_->publish_state(value_current_max_charging_current_); + } + if (this->input_voltage_range_) { + this->input_voltage_range_->publish_state(value_input_voltage_range_); + } + // special for input voltage range switch + if (this->input_voltage_range_switch_) { + this->input_voltage_range_switch_->publish_state(value_input_voltage_range_ == 1); + } + if (this->output_source_priority_) { + this->output_source_priority_->publish_state(value_output_source_priority_); + } + // special for output source priority switches + if (this->output_source_priority_utility_switch_) { + this->output_source_priority_utility_switch_->publish_state(value_output_source_priority_ == 0); + } + if (this->output_source_priority_solar_switch_) { + this->output_source_priority_solar_switch_->publish_state(value_output_source_priority_ == 1); + } + if (this->output_source_priority_battery_switch_) { + this->output_source_priority_battery_switch_->publish_state(value_output_source_priority_ == 2); + } + if (this->charger_source_priority_) { + this->charger_source_priority_->publish_state(value_charger_source_priority_); + } + if (this->parallel_max_num_) { + this->parallel_max_num_->publish_state(value_parallel_max_num_); + } + if (this->machine_type_) { + this->machine_type_->publish_state(value_machine_type_); + } + if (this->topology_) { + this->topology_->publish_state(value_topology_); + } + if (this->output_mode_) { + this->output_mode_->publish_state(value_output_mode_); + } + if (this->battery_redischarge_voltage_) { + this->battery_redischarge_voltage_->publish_state(value_battery_redischarge_voltage_); + } + if (this->pv_ok_condition_for_parallel_) { + this->pv_ok_condition_for_parallel_->publish_state(value_pv_ok_condition_for_parallel_); + } + // special for pv ok condition switch + if (this->pv_ok_condition_for_parallel_switch_) { + this->pv_ok_condition_for_parallel_switch_->publish_state(value_pv_ok_condition_for_parallel_ == 1); + } + if (this->pv_power_balance_) { + this->pv_power_balance_->publish_state(value_pv_power_balance_ == 1); + } + // special for power balance switch + if (this->pv_power_balance_switch_) { + this->pv_power_balance_switch_->publish_state(value_pv_power_balance_ == 1); + } + this->state_ = STATE_IDLE; + break; + case POLLING_QPIGS: + if (this->grid_voltage_) { + this->grid_voltage_->publish_state(value_grid_voltage_); + } + if (this->grid_frequency_) { + this->grid_frequency_->publish_state(value_grid_frequency_); + } + if (this->ac_output_voltage_) { + this->ac_output_voltage_->publish_state(value_ac_output_voltage_); + } + if (this->ac_output_frequency_) { + this->ac_output_frequency_->publish_state(value_ac_output_frequency_); + } + if (this->ac_output_apparent_power_) { + this->ac_output_apparent_power_->publish_state(value_ac_output_apparent_power_); + } + if (this->ac_output_active_power_) { + this->ac_output_active_power_->publish_state(value_ac_output_active_power_); + } + if (this->output_load_percent_) { + this->output_load_percent_->publish_state(value_output_load_percent_); + } + if (this->bus_voltage_) { + this->bus_voltage_->publish_state(value_bus_voltage_); + } + if (this->battery_voltage_) { + this->battery_voltage_->publish_state(value_battery_voltage_); + } + if (this->battery_charging_current_) { + this->battery_charging_current_->publish_state(value_battery_charging_current_); + } + if (this->battery_capacity_percent_) { + this->battery_capacity_percent_->publish_state(value_battery_capacity_percent_); + } + if (this->inverter_heat_sink_temperature_) { + this->inverter_heat_sink_temperature_->publish_state(value_inverter_heat_sink_temperature_); + } + if (this->pv_input_current_for_battery_) { + this->pv_input_current_for_battery_->publish_state(value_pv_input_current_for_battery_); + } + if (this->pv_input_voltage_) { + this->pv_input_voltage_->publish_state(value_pv_input_voltage_); + } + if (this->battery_voltage_scc_) { + this->battery_voltage_scc_->publish_state(value_battery_voltage_scc_); + } + if (this->battery_discharge_current_) { + this->battery_discharge_current_->publish_state(value_battery_discharge_current_); + } + if (this->add_sbu_priority_version_) { + this->add_sbu_priority_version_->publish_state(value_add_sbu_priority_version_); + } + if (this->configuration_status_) { + this->configuration_status_->publish_state(value_configuration_status_); + } + if (this->scc_firmware_version_) { + this->scc_firmware_version_->publish_state(value_scc_firmware_version_); + } + if (this->load_status_) { + this->load_status_->publish_state(value_load_status_); + } + if (this->battery_voltage_to_steady_while_charging_) { + this->battery_voltage_to_steady_while_charging_->publish_state( + value_battery_voltage_to_steady_while_charging_); + } + if (this->charging_status_) { + this->charging_status_->publish_state(value_charging_status_); + } + if (this->scc_charging_status_) { + this->scc_charging_status_->publish_state(value_scc_charging_status_); + } + if (this->ac_charging_status_) { + this->ac_charging_status_->publish_state(value_ac_charging_status_); + } + if (this->battery_voltage_offset_for_fans_on_) { + this->battery_voltage_offset_for_fans_on_->publish_state(value_battery_voltage_offset_for_fans_on_ / 10.0f); + } //.1 scale + if (this->eeprom_version_) { + this->eeprom_version_->publish_state(value_eeprom_version_); + } + if (this->pv_charging_power_) { + this->pv_charging_power_->publish_state(value_pv_charging_power_); + } + if (this->charging_to_floating_mode_) { + this->charging_to_floating_mode_->publish_state(value_charging_to_floating_mode_); + } + if (this->switch_on_) { + this->switch_on_->publish_state(value_switch_on_); + } + if (this->dustproof_installed_) { + this->dustproof_installed_->publish_state(value_dustproof_installed_); + } + this->state_ = STATE_IDLE; + break; + case POLLING_QMOD: + if (this->device_mode_) { + mode = value_device_mode_; + this->device_mode_->publish_state(mode); + } + this->state_ = STATE_IDLE; + break; + case POLLING_QFLAG: + if (this->silence_buzzer_open_buzzer_) { + this->silence_buzzer_open_buzzer_->publish_state(value_silence_buzzer_open_buzzer_); + } + if (this->overload_bypass_function_) { + this->overload_bypass_function_->publish_state(value_overload_bypass_function_); + } + if (this->lcd_escape_to_default_) { + this->lcd_escape_to_default_->publish_state(value_lcd_escape_to_default_); + } + if (this->overload_restart_function_) { + this->overload_restart_function_->publish_state(value_overload_restart_function_); + } + if (this->over_temperature_restart_function_) { + this->over_temperature_restart_function_->publish_state(value_over_temperature_restart_function_); + } + if (this->backlight_on_) { + this->backlight_on_->publish_state(value_backlight_on_); + } + if (this->alarm_on_when_primary_source_interrupt_) { + this->alarm_on_when_primary_source_interrupt_->publish_state(value_alarm_on_when_primary_source_interrupt_); + } + if (this->fault_code_record_) { + this->fault_code_record_->publish_state(value_fault_code_record_); + } + if (this->power_saving_) { + this->power_saving_->publish_state(value_power_saving_); + } + this->state_ = STATE_IDLE; + break; + case POLLING_QPIWS: + if (this->warnings_present_) { + this->warnings_present_->publish_state(value_warnings_present_); + } + if (this->faults_present_) { + this->faults_present_->publish_state(value_faults_present_); + } + if (this->warning_power_loss_) { + this->warning_power_loss_->publish_state(value_warning_power_loss_); + } + if (this->fault_inverter_fault_) { + this->fault_inverter_fault_->publish_state(value_fault_inverter_fault_); + } + if (this->fault_bus_over_) { + this->fault_bus_over_->publish_state(value_fault_bus_over_); + } + if (this->fault_bus_under_) { + this->fault_bus_under_->publish_state(value_fault_bus_under_); + } + if (this->fault_bus_soft_fail_) { + this->fault_bus_soft_fail_->publish_state(value_fault_bus_soft_fail_); + } + if (this->warning_line_fail_) { + this->warning_line_fail_->publish_state(value_warning_line_fail_); + } + if (this->fault_opvshort_) { + this->fault_opvshort_->publish_state(value_fault_opvshort_); + } + if (this->fault_inverter_voltage_too_low_) { + this->fault_inverter_voltage_too_low_->publish_state(value_fault_inverter_voltage_too_low_); + } + if (this->fault_inverter_voltage_too_high_) { + this->fault_inverter_voltage_too_high_->publish_state(value_fault_inverter_voltage_too_high_); + } + if (this->warning_over_temperature_) { + this->warning_over_temperature_->publish_state(value_warning_over_temperature_); + } + if (this->warning_fan_lock_) { + this->warning_fan_lock_->publish_state(value_warning_fan_lock_); + } + if (this->warning_battery_voltage_high_) { + this->warning_battery_voltage_high_->publish_state(value_warning_battery_voltage_high_); + } + if (this->warning_battery_low_alarm_) { + this->warning_battery_low_alarm_->publish_state(value_warning_battery_low_alarm_); + } + if (this->warning_battery_under_shutdown_) { + this->warning_battery_under_shutdown_->publish_state(value_warning_battery_under_shutdown_); + } + if (this->warning_battery_derating_) { + this->warning_battery_derating_->publish_state(value_warning_battery_derating_); + } + if (this->warning_over_load_) { + this->warning_over_load_->publish_state(value_warning_over_load_); + } + if (this->warning_eeprom_failed_) { + this->warning_eeprom_failed_->publish_state(value_warning_eeprom_failed_); + } + if (this->fault_inverter_over_current_) { + this->fault_inverter_over_current_->publish_state(value_fault_inverter_over_current_); + } + if (this->fault_inverter_soft_failed_) { + this->fault_inverter_soft_failed_->publish_state(value_fault_inverter_soft_failed_); + } + if (this->fault_self_test_failed_) { + this->fault_self_test_failed_->publish_state(value_fault_self_test_failed_); + } + if (this->fault_op_dc_voltage_over_) { + this->fault_op_dc_voltage_over_->publish_state(value_fault_op_dc_voltage_over_); + } + if (this->fault_battery_open_) { + this->fault_battery_open_->publish_state(value_fault_battery_open_); + } + if (this->fault_current_sensor_failed_) { + this->fault_current_sensor_failed_->publish_state(value_fault_current_sensor_failed_); + } + if (this->fault_battery_short_) { + this->fault_battery_short_->publish_state(value_fault_battery_short_); + } + if (this->warning_power_limit_) { + this->warning_power_limit_->publish_state(value_warning_power_limit_); + } + if (this->warning_pv_voltage_high_) { + this->warning_pv_voltage_high_->publish_state(value_warning_pv_voltage_high_); + } + if (this->fault_mppt_overload_) { + this->fault_mppt_overload_->publish_state(value_fault_mppt_overload_); + } + if (this->warning_mppt_overload_) { + this->warning_mppt_overload_->publish_state(value_warning_mppt_overload_); + } + if (this->warning_battery_too_low_to_charge_) { + this->warning_battery_too_low_to_charge_->publish_state(value_warning_battery_too_low_to_charge_); + } + if (this->fault_dc_dc_over_current_) { + this->fault_dc_dc_over_current_->publish_state(value_fault_dc_dc_over_current_); + } + if (this->fault_code_) { + this->fault_code_->publish_state(value_fault_code_); + } + if (this->warnung_low_pv_energy_) { + this->warnung_low_pv_energy_->publish_state(value_warnung_low_pv_energy_); + } + if (this->warning_high_ac_input_during_bus_soft_start_) { + this->warning_high_ac_input_during_bus_soft_start_->publish_state( + value_warning_high_ac_input_during_bus_soft_start_); + } + if (this->warning_battery_equalization_) { + this->warning_battery_equalization_->publish_state(value_warning_battery_equalization_); + } + this->state_ = STATE_IDLE; + break; + case POLLING_QT: + case POLLING_QMN: + this->state_ = STATE_IDLE; + break; + } + } + + if (this->state_ == STATE_POLL_CHECKED) { + bool enabled = true; + std::string fc; + char tmp[PIPSOLAR_READ_BUFFER_LENGTH]; + sprintf(tmp, "%s", this->read_buffer_); + switch (this->used_polling_commands_[this->last_polling_command_].identifier) { + case POLLING_QPIRI: + ESP_LOGD(TAG, "Decode QPIRI"); + sscanf(tmp, "(%f %f %f %f %f %d %d %f %f %f %f %f %d %d %d %d %d %d %d %d %d %d %f %d %d", // NOLINT + &value_grid_rating_voltage_, &value_grid_rating_current_, &value_ac_output_rating_voltage_, // NOLINT + &value_ac_output_rating_frequency_, &value_ac_output_rating_current_, // NOLINT + &value_ac_output_rating_apparent_power_, &value_ac_output_rating_active_power_, // NOLINT + &value_battery_rating_voltage_, &value_battery_recharge_voltage_, // NOLINT + &value_battery_under_voltage_, &value_battery_bulk_voltage_, &value_battery_float_voltage_, // NOLINT + &value_battery_type_, &value_current_max_ac_charging_current_, // NOLINT + &value_current_max_charging_current_, &value_input_voltage_range_, // NOLINT + &value_output_source_priority_, &value_charger_source_priority_, &value_parallel_max_num_, // NOLINT + &value_machine_type_, &value_topology_, &value_output_mode_, // NOLINT + &value_battery_redischarge_voltage_, &value_pv_ok_condition_for_parallel_, // NOLINT + &value_pv_power_balance_); // NOLINT + if (this->last_qpiri_) { + this->last_qpiri_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + case POLLING_QPIGS: + ESP_LOGD(TAG, "Decode QPIGS"); + // Response examples of the PIP 2424MSE1 + // 226.7 49.9 226.7 49.9 0498 0479 016 427 27.00 005 100 0035 01.9 255.1 00.00 00000 10010110 00 00 00510 110 + // 225.8 49.9 225.8 49.9 0609 0565 020 427 27.00 005 100 0035 02.2 259.9 00.00 00000 10010110 00 00 00590 110 + sscanf( // NOLINT + tmp, // NOLINT + "(%f %f %f %f %d %d %d %d %f %d %d %d %f %f %f %d %1d%1d%1d%1d%1d%1d%1d%1d %d %d %d %1d%1d%1d", // NOLINT + // 225.8 | | | | | | 1 // NOLINT + // 49.9 | | | | | | 2 // NOLINT + // 225.8 | | | | | 3 // NOLINT + // 49.9 | | | | | 4 // NOLINT + // 0609 | | | | | 5 // NOLINT + // 0565 | | | | | 6 // NOLINT + // 020 | | | | | 7 // NOLINT + // 427| | | | | 8 // NOLINT + // 27.00 | | | | 9 // NOLINT + // 005 | | | | 10 // NOLINT + // 100 | | | | 11 // NOLINT + // 0035| | | | 12 // NOLINT + // 02.2 | | | 13 // NOLINT + // 259.9 | | | 14 // NOLINT + // 00.00 | | | 15 // NOLINT + // 00000 | | | 16 // NOLINT + // 1 | | | 17 // NOLINT + // 0 | | | 18 // NOLINT + // 0 | | 19 // NOLINT + // 1 | | 20 // NOLINT + // 0 | | 21 // NOLINT + // 1 | | 22 // NOLINT + // 1 | | 23 // NOLINT + // 0 | 24 // NOLINT + // 00 | 25 // NOLINT + // 00 | 26 // NOLINT + // 00590 | 27 // NOLINT + // 1 | 28 // NOLINT + // 1 29 // NOLINT + // 0 30 // NOLINT + // // NOLINT + &value_grid_voltage_, // 1 // NOLINT + &value_grid_frequency_, // 2 // NOLINT + &value_ac_output_voltage_, // 3 // NOLINT + &value_ac_output_frequency_, // 4 // NOLINT + &value_ac_output_apparent_power_, // 5 // NOLINT + &value_ac_output_active_power_, // 6 // NOLINT + &value_output_load_percent_, // 7 // NOLINT + &value_bus_voltage_, // 8 // NOLINT + &value_battery_voltage_, // 9 // NOLINT + &value_battery_charging_current_, // 10 // NOLINT + &value_battery_capacity_percent_, // 11 // NOLINT + &value_inverter_heat_sink_temperature_, // 12 // NOLINT + &value_pv_input_current_for_battery_, // 13 // NOLINT + &value_pv_input_voltage_, // 14 // NOLINT + &value_battery_voltage_scc_, // 15 // NOLINT + &value_battery_discharge_current_, // 16 // NOLINT + &value_add_sbu_priority_version_, // 17 // NOLINT + &value_configuration_status_, // 18 // NOLINT + &value_scc_firmware_version_, // 19 // NOLINT + &value_load_status_, // 20 // NOLINT + &value_battery_voltage_to_steady_while_charging_, // 21 // NOLINT + &value_charging_status_, // 22 // NOLINT + &value_scc_charging_status_, // 23 // NOLINT + &value_ac_charging_status_, // 24 // NOLINT + &value_battery_voltage_offset_for_fans_on_, // 25 // NOLINT + &value_eeprom_version_, // 26 // NOLINT + &value_pv_charging_power_, // 27 // NOLINT + &value_charging_to_floating_mode_, // 28 // NOLINT + &value_switch_on_, // 29 // NOLINT + &value_dustproof_installed_ // 30 // NOLINT + ); + if (this->last_qpigs_) { + this->last_qpigs_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + case POLLING_QMOD: + ESP_LOGD(TAG, "Decode QMOD"); + this->value_device_mode_ = char(this->read_buffer_[1]); + if (this->last_qmod_) { + this->last_qmod_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + case POLLING_QFLAG: + ESP_LOGD(TAG, "Decode QFLAG"); + // result like:"(EbkuvxzDajy" + // get through all char: ignore first "(" Enable flag on 'E', Disable on 'D') else set the corresponding value + for (size_t i = 1; i < strlen(tmp); i++) { + switch (tmp[i]) { + case 'E': + enabled = true; + break; + case 'D': + enabled = false; + break; + case 'a': + this->value_silence_buzzer_open_buzzer_ = enabled; + break; + case 'b': + this->value_overload_bypass_function_ = enabled; + break; + case 'k': + this->value_lcd_escape_to_default_ = enabled; + break; + case 'u': + this->value_overload_restart_function_ = enabled; + break; + case 'v': + this->value_over_temperature_restart_function_ = enabled; + break; + case 'x': + this->value_backlight_on_ = enabled; + break; + case 'y': + this->value_alarm_on_when_primary_source_interrupt_ = enabled; + break; + case 'z': + this->value_fault_code_record_ = enabled; + break; + case 'j': + this->value_power_saving_ = enabled; + break; + } + } + if (this->last_qflag_) { + this->last_qflag_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + case POLLING_QPIWS: + ESP_LOGD(TAG, "Decode QPIWS"); + // '(00000000000000000000000000000000' + // iterate over all available flag (as not all models have all flags, but at least in the same order) + this->value_warnings_present_ = false; + this->value_faults_present_ = true; + + for (size_t i = 1; i < strlen(tmp); i++) { + enabled = tmp[i] == '1'; + switch (i) { + case 1: + this->value_warning_power_loss_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 2: + this->value_fault_inverter_fault_ = enabled; + this->value_faults_present_ += enabled; + break; + case 3: + this->value_fault_bus_over_ = enabled; + this->value_faults_present_ += enabled; + break; + case 4: + this->value_fault_bus_under_ = enabled; + this->value_faults_present_ += enabled; + break; + case 5: + this->value_fault_bus_soft_fail_ = enabled; + this->value_faults_present_ += enabled; + break; + case 6: + this->value_warning_line_fail_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 7: + this->value_fault_opvshort_ = enabled; + this->value_faults_present_ += enabled; + break; + case 8: + this->value_fault_inverter_voltage_too_low_ = enabled; + this->value_faults_present_ += enabled; + break; + case 9: + this->value_fault_inverter_voltage_too_high_ = enabled; + this->value_faults_present_ += enabled; + break; + case 10: + this->value_warning_over_temperature_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 11: + this->value_warning_fan_lock_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 12: + this->value_warning_battery_voltage_high_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 13: + this->value_warning_battery_low_alarm_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 15: + this->value_warning_battery_under_shutdown_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 16: + this->value_warning_battery_derating_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 17: + this->value_warning_over_load_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 18: + this->value_warning_eeprom_failed_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 19: + this->value_fault_inverter_over_current_ = enabled; + this->value_faults_present_ += enabled; + break; + case 20: + this->value_fault_inverter_soft_failed_ = enabled; + this->value_faults_present_ += enabled; + break; + case 21: + this->value_fault_self_test_failed_ = enabled; + this->value_faults_present_ += enabled; + break; + case 22: + this->value_fault_op_dc_voltage_over_ = enabled; + this->value_faults_present_ += enabled; + break; + case 23: + this->value_fault_battery_open_ = enabled; + this->value_faults_present_ += enabled; + break; + case 24: + this->value_fault_current_sensor_failed_ = enabled; + this->value_faults_present_ += enabled; + break; + case 25: + this->value_fault_battery_short_ = enabled; + this->value_faults_present_ += enabled; + break; + case 26: + this->value_warning_power_limit_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 27: + this->value_warning_pv_voltage_high_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 28: + this->value_fault_mppt_overload_ = enabled; + this->value_faults_present_ += enabled; + break; + case 29: + this->value_warning_mppt_overload_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 30: + this->value_warning_battery_too_low_to_charge_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 31: + this->value_fault_dc_dc_over_current_ = enabled; + this->value_faults_present_ += enabled; + break; + case 32: + fc = tmp[i]; + fc += tmp[i + 1]; + this->value_fault_code_ = parse_number(fc).value_or(0); + break; + case 34: + this->value_warnung_low_pv_energy_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 35: + this->value_warning_high_ac_input_during_bus_soft_start_ = enabled; + this->value_warnings_present_ += enabled; + break; + case 36: + this->value_warning_battery_equalization_ = enabled; + this->value_warnings_present_ += enabled; + break; + } + } + if (this->last_qpiws_) { + this->last_qpiws_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + case POLLING_QT: + ESP_LOGD(TAG, "Decode QT"); + if (this->last_qt_) { + this->last_qt_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + case POLLING_QMN: + ESP_LOGD(TAG, "Decode QMN"); + if (this->last_qmn_) { + this->last_qmn_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + default: + this->state_ = STATE_IDLE; + break; + } + return; + } + + if (this->state_ == STATE_POLL_COMPLETE) { + if (this->check_incoming_crc_()) { + if (this->read_buffer_[0] == '(' && this->read_buffer_[1] == 'N' && this->read_buffer_[2] == 'A' && + this->read_buffer_[3] == 'K') { + this->state_ = STATE_IDLE; + return; + } + // crc ok + this->state_ = STATE_POLL_CHECKED; + return; + } else { + this->state_ = STATE_IDLE; + } + } + + if (this->state_ == STATE_COMMAND || this->state_ == STATE_POLL) { + while (this->available()) { + uint8_t byte; + this->read_byte(&byte); + + if (this->read_pos_ == PIPSOLAR_READ_BUFFER_LENGTH) { + this->read_pos_ = 0; + this->empty_uart_buffer_(); + } + this->read_buffer_[this->read_pos_] = byte; + this->read_pos_++; + + // end of answer + if (byte == 0x0D) { + this->read_buffer_[this->read_pos_] = 0; + this->empty_uart_buffer_(); + if (this->state_ == STATE_POLL) { + this->state_ = STATE_POLL_COMPLETE; + } + if (this->state_ == STATE_COMMAND) { + this->state_ = STATE_COMMAND_COMPLETE; + } + } + } // available + } + if (this->state_ == STATE_COMMAND) { + if (millis() - this->command_start_millis_ > esphome::pipsolar::Pipsolar::COMMAND_TIMEOUT) { + // command timeout + const char *command = this->command_queue_[this->command_queue_position_].c_str(); + this->command_start_millis_ = millis(); + ESP_LOGD(TAG, "timeout command from queue: %s", command); + this->command_queue_[this->command_queue_position_] = std::string(""); + this->command_queue_position_ = (command_queue_position_ + 1) % COMMAND_QUEUE_LENGTH; + this->state_ = STATE_IDLE; + return; + } else { + } + } + if (this->state_ == STATE_POLL) { + if (millis() - this->command_start_millis_ > esphome::pipsolar::Pipsolar::COMMAND_TIMEOUT) { + // command timeout + ESP_LOGD(TAG, "timeout command to poll: %s", this->used_polling_commands_[this->last_polling_command_].command); + this->state_ = STATE_IDLE; + } else { + } + } +} + +uint8_t Pipsolar::check_incoming_length_(uint8_t length) { + if (this->read_pos_ - 3 == length) { + return 1; + } + return 0; +} + +uint8_t Pipsolar::check_incoming_crc_() { + uint16_t crc16; + crc16 = calc_crc_(read_buffer_, read_pos_ - 3); + ESP_LOGD(TAG, "checking crc on incoming message"); + if (((uint8_t)((crc16) >> 8)) == read_buffer_[read_pos_ - 3] && + ((uint8_t)((crc16) &0xff)) == read_buffer_[read_pos_ - 2]) { + ESP_LOGD(TAG, "CRC OK"); + read_buffer_[read_pos_ - 1] = 0; + read_buffer_[read_pos_ - 2] = 0; + read_buffer_[read_pos_ - 3] = 0; + return 1; + } + ESP_LOGD(TAG, "CRC NOK expected: %X %X but got: %X %X", ((uint8_t)((crc16) >> 8)), ((uint8_t)((crc16) &0xff)), + read_buffer_[read_pos_ - 3], read_buffer_[read_pos_ - 2]); + return 0; +} + +// send next command used +uint8_t Pipsolar::send_next_command_() { + uint16_t crc16; + if (this->command_queue_[this->command_queue_position_].length() != 0) { + const char *command = this->command_queue_[this->command_queue_position_].c_str(); + uint8_t byte_command[16]; + uint8_t length = this->command_queue_[this->command_queue_position_].length(); + for (uint8_t i = 0; i < length; i++) { + byte_command[i] = (uint8_t) this->command_queue_[this->command_queue_position_].at(i); + } + this->state_ = STATE_COMMAND; + this->command_start_millis_ = millis(); + this->empty_uart_buffer_(); + this->read_pos_ = 0; + crc16 = calc_crc_(byte_command, length); + this->write_str(command); + // checksum + this->write(((uint8_t)((crc16) >> 8))); // highbyte + this->write(((uint8_t)((crc16) &0xff))); // lowbyte + // end Byte + this->write(0x0D); + ESP_LOGD(TAG, "Sending command from queue: %s with length %d", command, length); + return 1; + } + return 0; +} + +void Pipsolar::send_next_poll_() { + uint16_t crc16; + this->last_polling_command_ = (this->last_polling_command_ + 1) % 15; + if (this->used_polling_commands_[this->last_polling_command_].length == 0) { + this->last_polling_command_ = 0; + } + if (this->used_polling_commands_[this->last_polling_command_].length == 0) { + // no command specified + return; + } + this->state_ = STATE_POLL; + this->command_start_millis_ = millis(); + this->empty_uart_buffer_(); + this->read_pos_ = 0; + crc16 = calc_crc_(this->used_polling_commands_[this->last_polling_command_].command, + this->used_polling_commands_[this->last_polling_command_].length); + this->write_array(this->used_polling_commands_[this->last_polling_command_].command, + this->used_polling_commands_[this->last_polling_command_].length); + // checksum + this->write(((uint8_t)((crc16) >> 8))); // highbyte + this->write(((uint8_t)((crc16) &0xff))); // lowbyte + // end Byte + this->write(0x0D); + ESP_LOGD(TAG, "Sending polling command : %s with length %d", + this->used_polling_commands_[this->last_polling_command_].command, + this->used_polling_commands_[this->last_polling_command_].length); +} + +void Pipsolar::queue_command_(const char *command, uint8_t length) { + uint8_t next_position = command_queue_position_; + for (uint8_t i = 0; i < COMMAND_QUEUE_LENGTH; i++) { + uint8_t testposition = (next_position + i) % COMMAND_QUEUE_LENGTH; + if (command_queue_[testposition].length() == 0) { + command_queue_[testposition] = command; + ESP_LOGD(TAG, "Command queued successfully: %s with length %u at position %d", command, + command_queue_[testposition].length(), testposition); + return; + } + } + ESP_LOGD(TAG, "Command queue full dropping command: %s", command); +} + +void Pipsolar::switch_command(const std::string &command) { + ESP_LOGD(TAG, "got command: %s", command.c_str()); + queue_command_(command.c_str(), command.length()); +} +void Pipsolar::dump_config() { + ESP_LOGCONFIG(TAG, "Pipsolar:"); + ESP_LOGCONFIG(TAG, "used commands:"); + for (auto &used_polling_command : this->used_polling_commands_) { + if (used_polling_command.length != 0) { + ESP_LOGCONFIG(TAG, "%s", used_polling_command.command); + } + } +} +void Pipsolar::update() {} + +void Pipsolar::add_polling_command_(const char *command, ENUMPollingCommand polling_command) { + for (auto &used_polling_command : this->used_polling_commands_) { + if (used_polling_command.length == strlen(command)) { + uint8_t len = strlen(command); + if (memcmp(used_polling_command.command, command, len) == 0) { + return; + } + } + if (used_polling_command.length == 0) { + size_t length = strlen(command) + 1; + const char *beg = command; + const char *end = command + length; + used_polling_command.command = new uint8_t[length]; // NOLINT(cppcoreguidelines-owning-memory) + size_t i = 0; + for (; beg != end; ++beg, ++i) { + used_polling_command.command[i] = (uint8_t)(*beg); + } + used_polling_command.errors = 0; + used_polling_command.identifier = polling_command; + used_polling_command.length = length - 1; + return; + } + } +} + +uint16_t Pipsolar::calc_crc_(uint8_t *msg, int n) { + // Initial value. xmodem uses 0xFFFF but this example + // requires an initial value of zero. + uint16_t x = 0; + while (n--) { + x = crc_xmodem_update_(x, (uint16_t) *msg++); + } + return (x); +} + +// See bottom of this page: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html +// Polynomial: x^16 + x^12 + x^5 + 1 (0x1021) +uint16_t Pipsolar::crc_xmodem_update_(uint16_t crc, uint8_t data) { + int i; + crc = crc ^ ((uint16_t) data << 8); + for (i = 0; i < 8; i++) { + if (crc & 0x8000) + crc = (crc << 1) ^ 0x1021; //(polynomial = 0x1021) + else + crc <<= 1; + } + return crc; +} + +} // namespace pipsolar +} // namespace esphome diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h new file mode 100644 index 00000000..d335d727 --- /dev/null +++ b/components/pipsolar/pipsolar.h @@ -0,0 +1,223 @@ +#pragma once + +#include "esphome/components/binary_sensor/binary_sensor.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/switch/switch.h" +#include "esphome/components/text_sensor/text_sensor.h" +#include "esphome/components/uart/uart.h" +#include "esphome/core/automation.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace pipsolar { + +enum ENUMPollingCommand { + POLLING_QPIRI = 0, + POLLING_QPIGS = 1, + POLLING_QMOD = 2, + POLLING_QFLAG = 3, + POLLING_QPIWS = 4, + POLLING_QT = 5, + POLLING_QMN = 6, +}; +struct PollingCommand { + uint8_t *command; + uint8_t length = 0; + uint8_t errors; + ENUMPollingCommand identifier; +}; + +#define PIPSOLAR_VALUED_ENTITY_(type, name, polling_command, value_type) \ + protected: \ + value_type value_##name##_; \ + PIPSOLAR_ENTITY_(type, name, polling_command) + +#define PIPSOLAR_ENTITY_(type, name, polling_command) \ + protected: \ + type *name##_{}; /* NOLINT */ \ +\ + public: \ + void set_##name(type *name) { /* NOLINT */ \ + this->name##_ = name; \ + this->add_polling_command_(#polling_command, POLLING_##polling_command); \ + } + +#define PIPSOLAR_SENSOR(name, polling_command, value_type) \ + PIPSOLAR_VALUED_ENTITY_(sensor::Sensor, name, polling_command, value_type) +#define PIPSOLAR_SWITCH(name, polling_command) PIPSOLAR_ENTITY_(switch_::Switch, name, polling_command) +#define PIPSOLAR_BINARY_SENSOR(name, polling_command, value_type) \ + PIPSOLAR_VALUED_ENTITY_(binary_sensor::BinarySensor, name, polling_command, value_type) +#define PIPSOLAR_VALUED_TEXT_SENSOR(name, polling_command, value_type) \ + PIPSOLAR_VALUED_ENTITY_(text_sensor::TextSensor, name, polling_command, value_type) +#define PIPSOLAR_TEXT_SENSOR(name, polling_command) PIPSOLAR_ENTITY_(text_sensor::TextSensor, name, polling_command) + +class Pipsolar : public uart::UARTDevice, public PollingComponent { + // QPIGS values + PIPSOLAR_SENSOR(grid_voltage, QPIGS, float) + PIPSOLAR_SENSOR(grid_frequency, QPIGS, float) + PIPSOLAR_SENSOR(ac_output_voltage, QPIGS, float) + PIPSOLAR_SENSOR(ac_output_frequency, QPIGS, float) + PIPSOLAR_SENSOR(ac_output_apparent_power, QPIGS, int) + PIPSOLAR_SENSOR(ac_output_active_power, QPIGS, int) + PIPSOLAR_SENSOR(output_load_percent, QPIGS, int) + PIPSOLAR_SENSOR(bus_voltage, QPIGS, int) + PIPSOLAR_SENSOR(battery_voltage, QPIGS, float) + PIPSOLAR_SENSOR(battery_charging_current, QPIGS, int) + PIPSOLAR_SENSOR(battery_capacity_percent, QPIGS, int) + PIPSOLAR_SENSOR(inverter_heat_sink_temperature, QPIGS, int) + PIPSOLAR_SENSOR(pv_input_current_for_battery, QPIGS, float) + PIPSOLAR_SENSOR(pv_input_voltage, QPIGS, float) + PIPSOLAR_SENSOR(battery_voltage_scc, QPIGS, float) + PIPSOLAR_SENSOR(battery_discharge_current, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(add_sbu_priority_version, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(configuration_status, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(scc_firmware_version, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(load_status, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(battery_voltage_to_steady_while_charging, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(charging_status, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(scc_charging_status, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(ac_charging_status, QPIGS, int) + PIPSOLAR_SENSOR(battery_voltage_offset_for_fans_on, QPIGS, int) //.1 scale + PIPSOLAR_SENSOR(eeprom_version, QPIGS, int) + PIPSOLAR_SENSOR(pv_charging_power, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(charging_to_floating_mode, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(switch_on, QPIGS, int) + PIPSOLAR_BINARY_SENSOR(dustproof_installed, QPIGS, int) + + // QPIRI values + PIPSOLAR_SENSOR(grid_rating_voltage, QPIRI, float) + PIPSOLAR_SENSOR(grid_rating_current, QPIRI, float) + PIPSOLAR_SENSOR(ac_output_rating_voltage, QPIRI, float) + PIPSOLAR_SENSOR(ac_output_rating_frequency, QPIRI, float) + PIPSOLAR_SENSOR(ac_output_rating_current, QPIRI, float) + PIPSOLAR_SENSOR(ac_output_rating_apparent_power, QPIRI, int) + PIPSOLAR_SENSOR(ac_output_rating_active_power, QPIRI, int) + PIPSOLAR_SENSOR(battery_rating_voltage, QPIRI, float) + PIPSOLAR_SENSOR(battery_recharge_voltage, QPIRI, float) + PIPSOLAR_SENSOR(battery_under_voltage, QPIRI, float) + PIPSOLAR_SENSOR(battery_bulk_voltage, QPIRI, float) + PIPSOLAR_SENSOR(battery_float_voltage, QPIRI, float) + PIPSOLAR_SENSOR(battery_type, QPIRI, int) + PIPSOLAR_SENSOR(current_max_ac_charging_current, QPIRI, int) + PIPSOLAR_SENSOR(current_max_charging_current, QPIRI, int) + PIPSOLAR_SENSOR(input_voltage_range, QPIRI, int) + PIPSOLAR_SENSOR(output_source_priority, QPIRI, int) + PIPSOLAR_SENSOR(charger_source_priority, QPIRI, int) + PIPSOLAR_SENSOR(parallel_max_num, QPIRI, int) + PIPSOLAR_SENSOR(machine_type, QPIRI, int) + PIPSOLAR_SENSOR(topology, QPIRI, int) + PIPSOLAR_SENSOR(output_mode, QPIRI, int) + PIPSOLAR_SENSOR(battery_redischarge_voltage, QPIRI, float) + PIPSOLAR_SENSOR(pv_ok_condition_for_parallel, QPIRI, int) + PIPSOLAR_SENSOR(pv_power_balance, QPIRI, int) + + // QMOD values + PIPSOLAR_VALUED_TEXT_SENSOR(device_mode, QMOD, char) + + // QFLAG values + PIPSOLAR_BINARY_SENSOR(silence_buzzer_open_buzzer, QFLAG, int) + PIPSOLAR_BINARY_SENSOR(overload_bypass_function, QFLAG, int) + PIPSOLAR_BINARY_SENSOR(lcd_escape_to_default, QFLAG, int) + PIPSOLAR_BINARY_SENSOR(overload_restart_function, QFLAG, int) + PIPSOLAR_BINARY_SENSOR(over_temperature_restart_function, QFLAG, int) + PIPSOLAR_BINARY_SENSOR(backlight_on, QFLAG, int) + PIPSOLAR_BINARY_SENSOR(alarm_on_when_primary_source_interrupt, QFLAG, int) + PIPSOLAR_BINARY_SENSOR(fault_code_record, QFLAG, int) + PIPSOLAR_BINARY_SENSOR(power_saving, QFLAG, int) + + // QPIWS values + PIPSOLAR_BINARY_SENSOR(warnings_present, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(faults_present, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_power_loss, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_inverter_fault, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_bus_over, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_bus_under, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_bus_soft_fail, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_line_fail, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_opvshort, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_inverter_voltage_too_low, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_inverter_voltage_too_high, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_over_temperature, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_fan_lock, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_battery_voltage_high, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_battery_low_alarm, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_battery_under_shutdown, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_battery_derating, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_over_load, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_eeprom_failed, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_inverter_over_current, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_inverter_soft_failed, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_self_test_failed, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_op_dc_voltage_over, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_battery_open, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_current_sensor_failed, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_battery_short, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_power_limit, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_pv_voltage_high, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_mppt_overload, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_mppt_overload, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_battery_too_low_to_charge, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_dc_dc_over_current, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(fault_code, QPIWS, int) + PIPSOLAR_BINARY_SENSOR(warnung_low_pv_energy, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_high_ac_input_during_bus_soft_start, QPIWS, bool) + PIPSOLAR_BINARY_SENSOR(warning_battery_equalization, QPIWS, bool) + + PIPSOLAR_TEXT_SENSOR(last_qpigs, QPIGS) + PIPSOLAR_TEXT_SENSOR(last_qpiri, QPIRI) + PIPSOLAR_TEXT_SENSOR(last_qmod, QMOD) + PIPSOLAR_TEXT_SENSOR(last_qflag, QFLAG) + PIPSOLAR_TEXT_SENSOR(last_qpiws, QPIWS) + PIPSOLAR_TEXT_SENSOR(last_qt, QT) + PIPSOLAR_TEXT_SENSOR(last_qmn, QMN) + + PIPSOLAR_SWITCH(output_source_priority_utility_switch, QPIRI) + PIPSOLAR_SWITCH(output_source_priority_solar_switch, QPIRI) + PIPSOLAR_SWITCH(output_source_priority_battery_switch, QPIRI) + PIPSOLAR_SWITCH(input_voltage_range_switch, QPIRI) + PIPSOLAR_SWITCH(pv_ok_condition_for_parallel_switch, QPIRI) + PIPSOLAR_SWITCH(pv_power_balance_switch, QPIRI) + + void switch_command(const std::string &command); + void setup() override; + void loop() override; + void dump_config() override; + void update() override; + + protected: + static const size_t PIPSOLAR_READ_BUFFER_LENGTH = 110; // maximum supported answer length + static const size_t COMMAND_QUEUE_LENGTH = 10; + static const size_t COMMAND_TIMEOUT = 5000; + uint32_t last_poll_ = 0; + void add_polling_command_(const char *command, ENUMPollingCommand polling_command); + void empty_uart_buffer_(); + uint8_t check_incoming_crc_(); + uint8_t check_incoming_length_(uint8_t length); + uint16_t calc_crc_(uint8_t *msg, int n); + uint16_t crc_xmodem_update_(uint16_t crc, uint8_t data); + uint8_t send_next_command_(); + void send_next_poll_(); + void queue_command_(const char *command, uint8_t length); + std::string command_queue_[COMMAND_QUEUE_LENGTH]; + uint8_t command_queue_position_ = 0; + uint8_t read_buffer_[PIPSOLAR_READ_BUFFER_LENGTH]; + size_t read_pos_{0}; + + uint32_t command_start_millis_ = 0; + uint8_t state_; + enum State { + STATE_IDLE = 0, + STATE_POLL = 1, + STATE_COMMAND = 2, + STATE_POLL_COMPLETE = 3, + STATE_COMMAND_COMPLETE = 4, + STATE_POLL_CHECKED = 5, + STATE_POLL_DECODED = 6, + }; + + uint8_t last_polling_command_ = 0; + PollingCommand used_polling_commands_[15]; +}; + +} // namespace pipsolar +} // namespace esphome diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py new file mode 100644 index 00000000..a206e419 --- /dev/null +++ b/components/pipsolar/sensor/__init__.py @@ -0,0 +1,220 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor +from esphome.const import ( + DEVICE_CLASS_CURRENT, + DEVICE_CLASS_EMPTY, + DEVICE_CLASS_POWER, + DEVICE_CLASS_TEMPERATURE, + DEVICE_CLASS_VOLTAGE, + ICON_CURRENT_AC, + ICON_EMPTY, + UNIT_AMPERE, + UNIT_CELSIUS, + UNIT_HERTZ, + UNIT_PERCENT, + UNIT_VOLT, + UNIT_EMPTY, + UNIT_VOLT_AMPS, + UNIT_WATT, + CONF_BUS_VOLTAGE, + CONF_BATTERY_VOLTAGE, +) +from .. import PIPSOLAR_COMPONENT_SCHEMA, CONF_PIPSOLAR_ID + +DEPENDENCIES = ["uart"] + +# QPIRI sensors +CONF_GRID_RATING_VOLTAGE = "grid_rating_voltage" +CONF_GRID_RATING_CURRENT = "grid_rating_current" +CONF_AC_OUTPUT_RATING_VOLTAGE = "ac_output_rating_voltage" +CONF_AC_OUTPUT_RATING_FREQUENCY = "ac_output_rating_frequency" +CONF_AC_OUTPUT_RATING_CURRENT = "ac_output_rating_current" +CONF_AC_OUTPUT_RATING_APPARENT_POWER = "ac_output_rating_apparent_power" +CONF_AC_OUTPUT_RATING_ACTIVE_POWER = "ac_output_rating_active_power" +CONF_BATTERY_RATING_VOLTAGE = "battery_rating_voltage" +CONF_BATTERY_RECHARGE_VOLTAGE = "battery_recharge_voltage" +CONF_BATTERY_UNDER_VOLTAGE = "battery_under_voltage" +CONF_BATTERY_BULK_VOLTAGE = "battery_bulk_voltage" +CONF_BATTERY_FLOAT_VOLTAGE = "battery_float_voltage" +CONF_BATTERY_TYPE = "battery_type" +CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" +CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" +CONF_INPUT_VOLTAGE_RANGE = "input_voltage_range" +CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" +CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" +CONF_PARALLEL_MAX_NUM = "parallel_max_num" +CONF_MACHINE_TYPE = "machine_type" +CONF_TOPOLOGY = "topology" +CONF_OUTPUT_MODE = "output_mode" +CONF_BATTERY_REDISCHARGE_VOLTAGE = "battery_redischarge_voltage" +CONF_PV_OK_CONDITION_FOR_PARALLEL = "pv_ok_condition_for_parallel" +CONF_PV_POWER_BALANCE = "pv_power_balance" + +CONF_GRID_VOLTAGE = "grid_voltage" +CONF_GRID_FREQUENCY = "grid_frequency" +CONF_AC_OUTPUT_VOLTAGE = "ac_output_voltage" +CONF_AC_OUTPUT_FREQUENCY = "ac_output_frequency" +CONF_AC_OUTPUT_APPARENT_POWER = "ac_output_apparent_power" +CONF_AC_OUTPUT_ACTIVE_POWER = "ac_output_active_power" +CONF_OUTPUT_LOAD_PERCENT = "output_load_percent" +CONF_BATTERY_CHARGING_CURRENT = "battery_charging_current" +CONF_BATTERY_CAPACITY_PERCENT = "battery_capacity_percent" +CONF_INVERTER_HEAT_SINK_TEMPERATURE = "inverter_heat_sink_temperature" +CONF_PV_INPUT_CURRENT_FOR_BATTERY = "pv_input_current_for_battery" +CONF_PV_INPUT_VOLTAGE = "pv_input_voltage" +CONF_BATTERY_VOLTAGE_SCC = "battery_voltage_scc" +CONF_BATTERY_DISCHARGE_CURRENT = "battery_discharge_current" +CONF_ADD_SBU_PRIORITY_VERSION = "add_sbu_priority_version" +CONF_CONFIGURATION_STATUS = "configuration_status" +CONF_SCC_FIRMWARE_VERSION = "scc_firmware_version" +CONF_BATTERY_VOLTAGE_OFFSET_FOR_FANS_ON = "battery_voltage_offset_for_fans_on" +CONF_EEPROM_VERSION = "eeprom_version" +CONF_PV_CHARGING_POWER = "pv_charging_power" + +TYPES = { + CONF_GRID_RATING_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_GRID_RATING_CURRENT: sensor.sensor_schema( + UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + ), + CONF_AC_OUTPUT_RATING_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_AC_OUTPUT_RATING_FREQUENCY: sensor.sensor_schema( + UNIT_HERTZ, ICON_CURRENT_AC, 1, DEVICE_CLASS_EMPTY + ), + CONF_AC_OUTPUT_RATING_CURRENT: sensor.sensor_schema( + UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + ), + CONF_AC_OUTPUT_RATING_APPARENT_POWER: sensor.sensor_schema( + UNIT_VOLT_AMPS, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_AC_OUTPUT_RATING_ACTIVE_POWER: sensor.sensor_schema( + UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER + ), + CONF_BATTERY_RATING_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_RECHARGE_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_UNDER_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_BULK_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_FLOAT_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_TYPE: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: sensor.sensor_schema( + UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + ), + CONF_CURRENT_MAX_CHARGING_CURRENT: sensor.sensor_schema( + UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + ), + CONF_INPUT_VOLTAGE_RANGE: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_OUTPUT_SOURCE_PRIORITY: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_CHARGER_SOURCE_PRIORITY: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_PARALLEL_MAX_NUM: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_MACHINE_TYPE: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_TOPOLOGY: sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY), + CONF_OUTPUT_MODE: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_BATTERY_REDISCHARGE_VOLTAGE: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_PV_OK_CONDITION_FOR_PARALLEL: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_PV_POWER_BALANCE: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_GRID_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_GRID_FREQUENCY: sensor.sensor_schema( + UNIT_HERTZ, ICON_CURRENT_AC, 1, DEVICE_CLASS_EMPTY + ), + CONF_AC_OUTPUT_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_AC_OUTPUT_FREQUENCY: sensor.sensor_schema( + UNIT_HERTZ, ICON_CURRENT_AC, 1, DEVICE_CLASS_EMPTY + ), + CONF_AC_OUTPUT_APPARENT_POWER: sensor.sensor_schema( + UNIT_VOLT_AMPS, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_AC_OUTPUT_ACTIVE_POWER: sensor.sensor_schema( + UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER + ), + CONF_OUTPUT_LOAD_PERCENT: sensor.sensor_schema( + UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_BUS_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_CHARGING_CURRENT: sensor.sensor_schema( + UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + ), + CONF_BATTERY_CAPACITY_PERCENT: sensor.sensor_schema( + UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_INVERTER_HEAT_SINK_TEMPERATURE: sensor.sensor_schema( + UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE + ), + CONF_PV_INPUT_CURRENT_FOR_BATTERY: sensor.sensor_schema( + UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + ), + CONF_PV_INPUT_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_VOLTAGE_SCC: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_BATTERY_DISCHARGE_CURRENT: sensor.sensor_schema( + UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + ), + CONF_BATTERY_VOLTAGE_OFFSET_FOR_FANS_ON: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_EEPROM_VERSION: sensor.sensor_schema( + UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + ), + CONF_PV_CHARGING_POWER: sensor.sensor_schema( + UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER + ), +} + +CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( + {cv.Optional(type): schema for type, schema in TYPES.items()} +) + + +async def to_code(config): + paren = await cg.get_variable(config[CONF_PIPSOLAR_ID]) + + for type, _ in TYPES.items(): + if type in config: + conf = config[type] + sens = await sensor.new_sensor(conf) + cg.add(getattr(paren, f"set_{type}")(sens)) diff --git a/components/pipsolar/switch/__init__.py b/components/pipsolar/switch/__init__.py new file mode 100644 index 00000000..5ff33b10 --- /dev/null +++ b/components/pipsolar/switch/__init__.py @@ -0,0 +1,60 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import switch +from esphome.const import ( + CONF_ID, + CONF_INVERTED, + CONF_ICON, + ICON_POWER, +) +from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA, pipsolar_ns + +DEPENDENCIES = ["uart"] + +CONF_OUTPUT_SOURCE_PRIORITY_UTILITY = "output_source_priority_utility" +CONF_OUTPUT_SOURCE_PRIORITY_SOLAR = "output_source_priority_solar" +CONF_OUTPUT_SOURCE_PRIORITY_BATTERY = "output_source_priority_battery" +CONF_INPUT_VOLTAGE_RANGE = "input_voltage_range" +CONF_PV_OK_CONDITION_FOR_PARALLEL = "pv_ok_condition_for_parallel" +CONF_PV_POWER_BALANCE = "pv_power_balance" + +TYPES = { + CONF_OUTPUT_SOURCE_PRIORITY_UTILITY: ("POP00", None), + CONF_OUTPUT_SOURCE_PRIORITY_SOLAR: ("POP01", None), + CONF_OUTPUT_SOURCE_PRIORITY_BATTERY: ("POP02", None), + CONF_INPUT_VOLTAGE_RANGE: ("PGR01", "PGR00"), + CONF_PV_OK_CONDITION_FOR_PARALLEL: ("PPVOKC1", "PPVOKC0"), + CONF_PV_POWER_BALANCE: ("PSPB1", "PSPB0"), +} + +PipsolarSwitch = pipsolar_ns.class_("PipsolarSwitch", switch.Switch, cg.Component) + +PIPSWITCH_SCHEMA = switch.SWITCH_SCHEMA.extend( + { + cv.GenerateID(): cv.declare_id(PipsolarSwitch), + cv.Optional(CONF_INVERTED): cv.invalid( + "Pipsolar switches do not support inverted mode!" + ), + cv.Optional(CONF_ICON, default=ICON_POWER): switch.icon, + } +).extend(cv.COMPONENT_SCHEMA) + +CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( + {cv.Optional(type): PIPSWITCH_SCHEMA for type in TYPES} +) + + +async def to_code(config): + paren = await cg.get_variable(config[CONF_PIPSOLAR_ID]) + + for type, (on, off) in TYPES.items(): + if type in config: + conf = config[type] + var = cg.new_Pvariable(conf[CONF_ID]) + await cg.register_component(var, conf) + await switch.register_switch(var, conf) + cg.add(getattr(paren, f"set_{type}_switch")(var)) + cg.add(var.set_parent(paren)) + cg.add(var.set_on_command(on)) + if off is not None: + cg.add(var.set_off_command(off)) diff --git a/components/pipsolar/switch/pipsolar_switch.cpp b/components/pipsolar/switch/pipsolar_switch.cpp new file mode 100644 index 00000000..7eaeac1c --- /dev/null +++ b/components/pipsolar/switch/pipsolar_switch.cpp @@ -0,0 +1,24 @@ +#include "pipsolar_switch.h" +#include "esphome/core/log.h" +#include "esphome/core/application.h" + +namespace esphome { +namespace pipsolar { + +static const char *const TAG = "pipsolar.switch"; + +void PipsolarSwitch::dump_config() { LOG_SWITCH("", "Pipsolar Switch", this); } +void PipsolarSwitch::write_state(bool state) { + if (state) { + if (this->on_command_.length() > 0) { + this->parent_->switch_command(this->on_command_); + } + } else { + if (this->off_command_.length() > 0) { + this->parent_->switch_command(this->off_command_); + } + } +} + +} // namespace pipsolar +} // namespace esphome diff --git a/components/pipsolar/switch/pipsolar_switch.h b/components/pipsolar/switch/pipsolar_switch.h new file mode 100644 index 00000000..11ff6c85 --- /dev/null +++ b/components/pipsolar/switch/pipsolar_switch.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../pipsolar.h" +#include "esphome/components/switch/switch.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace pipsolar { +class Pipsolar; +class PipsolarSwitch : public switch_::Switch, public Component { + public: + void set_parent(Pipsolar *parent) { this->parent_ = parent; }; + void set_on_command(const std::string &command) { this->on_command_ = command; }; + void set_off_command(const std::string &command) { this->off_command_ = command; }; + void dump_config() override; + + protected: + void write_state(bool state) override; + std::string on_command_; + std::string off_command_; + Pipsolar *parent_; +}; + +} // namespace pipsolar +} // namespace esphome diff --git a/components/pipsolar/text_sensor/__init__.py b/components/pipsolar/text_sensor/__init__.py new file mode 100644 index 00000000..fe6c4979 --- /dev/null +++ b/components/pipsolar/text_sensor/__init__.py @@ -0,0 +1,52 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import text_sensor +from esphome.const import CONF_ID +from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA, pipsolar_ns + +DEPENDENCIES = ["uart"] + +CONF_DEVICE_MODE = "device_mode" +CONF_LAST_QPIGS = "last_qpigs" +CONF_LAST_QPIRI = "last_qpiri" +CONF_LAST_QMOD = "last_qmod" +CONF_LAST_QFLAG = "last_qflag" +CONF_LAST_QPIWS = "last_qpiws" +CONF_LAST_QT = "last_qt" +CONF_LAST_QMN = "last_qmn" + +PipsolarTextSensor = pipsolar_ns.class_( + "PipsolarTextSensor", text_sensor.TextSensor, cg.Component +) + +TYPES = [ + CONF_DEVICE_MODE, + CONF_LAST_QPIGS, + CONF_LAST_QPIRI, + CONF_LAST_QMOD, + CONF_LAST_QFLAG, + CONF_LAST_QPIWS, + CONF_LAST_QT, + CONF_LAST_QMN, +] + +CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( + { + cv.Optional(type): text_sensor.TEXT_SENSOR_SCHEMA.extend( + {cv.GenerateID(): cv.declare_id(PipsolarTextSensor)} + ) + for type in TYPES + } +) + + +async def to_code(config): + paren = await cg.get_variable(config[CONF_PIPSOLAR_ID]) + + for type in TYPES: + if type in config: + conf = config[type] + var = cg.new_Pvariable(conf[CONF_ID]) + await text_sensor.register_text_sensor(var, conf) + await cg.register_component(var, conf) + cg.add(getattr(paren, f"set_{type}")(var)) diff --git a/components/pipsolar/text_sensor/pipsolar_textsensor.cpp b/components/pipsolar/text_sensor/pipsolar_textsensor.cpp new file mode 100644 index 00000000..ee1fe2d1 --- /dev/null +++ b/components/pipsolar/text_sensor/pipsolar_textsensor.cpp @@ -0,0 +1,13 @@ +#include "pipsolar_textsensor.h" +#include "esphome/core/log.h" +#include "esphome/core/application.h" + +namespace esphome { +namespace pipsolar { + +static const char *const TAG = "pipsolar.text_sensor"; + +void PipsolarTextSensor::dump_config() { LOG_TEXT_SENSOR("", "Pipsolar TextSensor", this); } + +} // namespace pipsolar +} // namespace esphome diff --git a/components/pipsolar/text_sensor/pipsolar_textsensor.h b/components/pipsolar/text_sensor/pipsolar_textsensor.h new file mode 100644 index 00000000..871f6d8d --- /dev/null +++ b/components/pipsolar/text_sensor/pipsolar_textsensor.h @@ -0,0 +1,20 @@ +#pragma once + +#include "../pipsolar.h" +#include "esphome/components/text_sensor/text_sensor.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace pipsolar { +class Pipsolar; +class PipsolarTextSensor : public Component, public text_sensor::TextSensor { + public: + void set_parent(Pipsolar *parent) { this->parent_ = parent; }; + void dump_config() override; + + protected: + Pipsolar *parent_; +}; + +} // namespace pipsolar +} // namespace esphome diff --git a/esp32-example.yaml b/esp32-example.yaml index 6b7d5a78..d068987a 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -14,6 +14,10 @@ esphome: platform: ESP32 board: esp-wrover-kit +external_components: + - source: github://syssi/esphome-pipsolar@pip8084 + refresh: 0s + wifi: ssid: !secret wifi_ssid password: !secret wifi_password diff --git a/esp8266-example.yaml b/esp8266-example.yaml index ee6134aa..3915ab4e 100644 --- a/esp8266-example.yaml +++ b/esp8266-example.yaml @@ -14,6 +14,10 @@ esphome: platform: ESP8266 board: d1_mini +external_components: + - source: github://syssi/esphome-pipsolar@pip8048 + refresh: 0s + wifi: ssid: !secret wifi_ssid password: !secret wifi_password From a09387671bfd0d425d14d3228e1f9919006a9d5a Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 12 Mar 2022 10:09:46 +0100 Subject: [PATCH 002/114] Apply @SeByDocKy PIP8048 improvements --- components/pipsolar/__init__.py | 2 +- components/pipsolar/output/__init__.py | 8 +- components/pipsolar/pipsolar.cpp | 119 ++++++++------------ components/pipsolar/pipsolar.h | 24 ++-- components/pipsolar/sensor/__init__.py | 39 +++++-- components/pipsolar/text_sensor/__init__.py | 3 + 6 files changed, 101 insertions(+), 94 deletions(-) diff --git a/components/pipsolar/__init__.py b/components/pipsolar/__init__.py index 20e46721..2d0cd9ea 100644 --- a/components/pipsolar/__init__.py +++ b/components/pipsolar/__init__.py @@ -1,7 +1,7 @@ import esphome.codegen as cg import esphome.config_validation as cv -from esphome.const import CONF_ID from esphome.components import uart +from esphome.const import CONF_ID DEPENDENCIES = ["uart"] CODEOWNERS = ["@andreashergert1984"] diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index b518d485..85141fa1 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -3,7 +3,8 @@ from esphome import automation from esphome.components import output from esphome.const import CONF_ID, CONF_VALUE -from .. import PIPSOLAR_COMPONENT_SCHEMA, CONF_PIPSOLAR_ID, pipsolar_ns + +from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA, pipsolar_ns DEPENDENCIES = ["pipsolar"] @@ -28,6 +29,7 @@ # 24V unit: 00.0V/24V/24.5V/25V/25.5V/26V/26.5V/27V/27.5V/28V/28.5V/29V # 48V unit: 00.0V48V/49V/50V/51V/52V/53V/54V/55V/56V/57V/58V +CONF_BATTERY_BULK_VOLTAGE = "battery_bulk_voltage" CONF_BATTERY_RECHARGE_VOLTAGE = "battery_recharge_voltage" CONF_BATTERY_UNDER_VOLTAGE = "battery_under_voltage" CONF_BATTERY_FLOAT_VOLTAGE = "battery_float_voltage" @@ -39,6 +41,10 @@ CONF_BATTERY_REDISCHARGE_VOLTAGE = "battery_redischarge_voltage" TYPES = { + CONF_BATTERY_BULK_VOLTAGE: ( + [44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0], + "PCVV%02.1f", + ), CONF_BATTERY_RECHARGE_VOLTAGE: ( [44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0], "PBCV%02.1f", diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 948c58ba..97c4fc4f 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -206,11 +206,11 @@ void Pipsolar::loop() { if (this->inverter_heat_sink_temperature_) { this->inverter_heat_sink_temperature_->publish_state(value_inverter_heat_sink_temperature_); } - if (this->pv_input_current_for_battery_) { - this->pv_input_current_for_battery_->publish_state(value_pv_input_current_for_battery_); + if (this->pv1_input_current_) { + this->pv1_input_current_->publish_state(value_pv1_input_current_); } - if (this->pv_input_voltage_) { - this->pv_input_voltage_->publish_state(value_pv_input_voltage_); + if (this->pv1_input_voltage_) { + this->pv1_input_voltage_->publish_state(value_pv1_input_voltage_); } if (this->battery_voltage_scc_) { this->battery_voltage_scc_->publish_state(value_battery_voltage_scc_); @@ -249,8 +249,8 @@ void Pipsolar::loop() { if (this->eeprom_version_) { this->eeprom_version_->publish_state(value_eeprom_version_); } - if (this->pv_charging_power_) { - this->pv_charging_power_->publish_state(value_pv_charging_power_); + if (this->pv1_charging_power_) { + this->pv1_charging_power_->publish_state(value_pv1_charging_power_); } if (this->charging_to_floating_mode_) { this->charging_to_floating_mode_->publish_state(value_charging_to_floating_mode_); @@ -263,6 +263,18 @@ void Pipsolar::loop() { } this->state_ = STATE_IDLE; break; + case POLLING_QPIGS2: + if (this->pv2_input_current_) { + this->pv2_input_current_->publish_state(value_pv2_input_current_); + } + if (this->pv2_input_voltage_) { + this->pv2_input_voltage_->publish_state(value_pv2_input_voltage_); + } + if (this->pv2_charging_power_) { + this->pv2_charging_power_->publish_state(value_pv2_charging_power_); + } + this->state_ = STATE_IDLE; + break; case POLLING_QMOD: if (this->device_mode_) { mode = value_device_mode_; @@ -446,79 +458,38 @@ void Pipsolar::loop() { break; case POLLING_QPIGS: ESP_LOGD(TAG, "Decode QPIGS"); - // Response examples of the PIP 2424MSE1 - // 226.7 49.9 226.7 49.9 0498 0479 016 427 27.00 005 100 0035 01.9 255.1 00.00 00000 10010110 00 00 00510 110 - // 225.8 49.9 225.8 49.9 0609 0565 020 427 27.00 005 100 0035 02.2 259.9 00.00 00000 10010110 00 00 00590 110 - sscanf( // NOLINT - tmp, // NOLINT - "(%f %f %f %f %d %d %d %d %f %d %d %d %f %f %f %d %1d%1d%1d%1d%1d%1d%1d%1d %d %d %d %1d%1d%1d", // NOLINT - // 225.8 | | | | | | 1 // NOLINT - // 49.9 | | | | | | 2 // NOLINT - // 225.8 | | | | | 3 // NOLINT - // 49.9 | | | | | 4 // NOLINT - // 0609 | | | | | 5 // NOLINT - // 0565 | | | | | 6 // NOLINT - // 020 | | | | | 7 // NOLINT - // 427| | | | | 8 // NOLINT - // 27.00 | | | | 9 // NOLINT - // 005 | | | | 10 // NOLINT - // 100 | | | | 11 // NOLINT - // 0035| | | | 12 // NOLINT - // 02.2 | | | 13 // NOLINT - // 259.9 | | | 14 // NOLINT - // 00.00 | | | 15 // NOLINT - // 00000 | | | 16 // NOLINT - // 1 | | | 17 // NOLINT - // 0 | | | 18 // NOLINT - // 0 | | 19 // NOLINT - // 1 | | 20 // NOLINT - // 0 | | 21 // NOLINT - // 1 | | 22 // NOLINT - // 1 | | 23 // NOLINT - // 0 | 24 // NOLINT - // 00 | 25 // NOLINT - // 00 | 26 // NOLINT - // 00590 | 27 // NOLINT - // 1 | 28 // NOLINT - // 1 29 // NOLINT - // 0 30 // NOLINT - // // NOLINT - &value_grid_voltage_, // 1 // NOLINT - &value_grid_frequency_, // 2 // NOLINT - &value_ac_output_voltage_, // 3 // NOLINT - &value_ac_output_frequency_, // 4 // NOLINT - &value_ac_output_apparent_power_, // 5 // NOLINT - &value_ac_output_active_power_, // 6 // NOLINT - &value_output_load_percent_, // 7 // NOLINT - &value_bus_voltage_, // 8 // NOLINT - &value_battery_voltage_, // 9 // NOLINT - &value_battery_charging_current_, // 10 // NOLINT - &value_battery_capacity_percent_, // 11 // NOLINT - &value_inverter_heat_sink_temperature_, // 12 // NOLINT - &value_pv_input_current_for_battery_, // 13 // NOLINT - &value_pv_input_voltage_, // 14 // NOLINT - &value_battery_voltage_scc_, // 15 // NOLINT - &value_battery_discharge_current_, // 16 // NOLINT - &value_add_sbu_priority_version_, // 17 // NOLINT - &value_configuration_status_, // 18 // NOLINT - &value_scc_firmware_version_, // 19 // NOLINT - &value_load_status_, // 20 // NOLINT - &value_battery_voltage_to_steady_while_charging_, // 21 // NOLINT - &value_charging_status_, // 22 // NOLINT - &value_scc_charging_status_, // 23 // NOLINT - &value_ac_charging_status_, // 24 // NOLINT - &value_battery_voltage_offset_for_fans_on_, // 25 // NOLINT - &value_eeprom_version_, // 26 // NOLINT - &value_pv_charging_power_, // 27 // NOLINT - &value_charging_to_floating_mode_, // 28 // NOLINT - &value_switch_on_, // 29 // NOLINT - &value_dustproof_installed_ // 30 // NOLINT - ); + sscanf( // NOLINT + tmp, // NOLINT + "(%f %f %f %f %d %d %d %d %f %d %d %d %f %f %f %d %1d%1d%1d%1d%1d%1d%1d%1d %d %d %d %1d%1d%1d", // NOLINT + &value_grid_voltage_, &value_grid_frequency_, &value_ac_output_voltage_, // NOLINT + &value_ac_output_frequency_, // NOLINT + &value_ac_output_apparent_power_, &value_ac_output_active_power_, &value_output_load_percent_, // NOLINT + &value_bus_voltage_, &value_battery_voltage_, &value_battery_charging_current_, // NOLINT + &value_battery_capacity_percent_, &value_inverter_heat_sink_temperature_, // NOLINT + &value_pv1_input_current_, &value_pv1_input_voltage_, &value_battery_voltage_scc_, // NOLINT + &value_battery_discharge_current_, &value_add_sbu_priority_version_, // NOLINT + &value_configuration_status_, &value_scc_firmware_version_, &value_load_status_, // NOLINT + &value_battery_voltage_to_steady_while_charging_, &value_charging_status_, // NOLINT + &value_scc_charging_status_, &value_ac_charging_status_, // NOLINT + &value_battery_voltage_offset_for_fans_on_, &value_eeprom_version_, &value_pv1_charging_power_, // NOLINT + &value_charging_to_floating_mode_, &value_switch_on_, // NOLINT + &value_dustproof_installed_); // NOLINT if (this->last_qpigs_) { this->last_qpigs_->publish_state(tmp); } this->state_ = STATE_POLL_DECODED; break; + case POLLING_QPIGS2: + ESP_LOGD(TAG, "Decode QPIGS2"); + sscanf( // NOLINT + tmp, // NOLINT + "(%f %f %d", // NOLINT + &value_pv2_input_current_, &value_pv2_input_voltage_, &value_pv2_charging_power_); // NOLINT + if (this->last_qpigs2_) { + this->last_qpigs2_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; case POLLING_QMOD: ESP_LOGD(TAG, "Decode QMOD"); this->value_device_mode_ = char(this->read_buffer_[1]); diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index d335d727..81343150 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -14,11 +14,12 @@ namespace pipsolar { enum ENUMPollingCommand { POLLING_QPIRI = 0, POLLING_QPIGS = 1, - POLLING_QMOD = 2, - POLLING_QFLAG = 3, - POLLING_QPIWS = 4, - POLLING_QT = 5, - POLLING_QMN = 6, + POLLING_QPIGS2 = 2, + POLLING_QMOD = 3, + POLLING_QFLAG = 4, + POLLING_QPIWS = 5, + POLLING_QT = 6, + POLLING_QMN = 7, }; struct PollingCommand { uint8_t *command; @@ -65,8 +66,8 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SENSOR(battery_charging_current, QPIGS, int) PIPSOLAR_SENSOR(battery_capacity_percent, QPIGS, int) PIPSOLAR_SENSOR(inverter_heat_sink_temperature, QPIGS, int) - PIPSOLAR_SENSOR(pv_input_current_for_battery, QPIGS, float) - PIPSOLAR_SENSOR(pv_input_voltage, QPIGS, float) + PIPSOLAR_SENSOR(pv1_input_current, QPIGS, float) + PIPSOLAR_SENSOR(pv1_input_voltage, QPIGS, float) PIPSOLAR_SENSOR(battery_voltage_scc, QPIGS, float) PIPSOLAR_SENSOR(battery_discharge_current, QPIGS, int) PIPSOLAR_BINARY_SENSOR(add_sbu_priority_version, QPIGS, int) @@ -79,11 +80,17 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_BINARY_SENSOR(ac_charging_status, QPIGS, int) PIPSOLAR_SENSOR(battery_voltage_offset_for_fans_on, QPIGS, int) //.1 scale PIPSOLAR_SENSOR(eeprom_version, QPIGS, int) - PIPSOLAR_SENSOR(pv_charging_power, QPIGS, int) + PIPSOLAR_SENSOR(pv1_charging_power, QPIGS, int) PIPSOLAR_BINARY_SENSOR(charging_to_floating_mode, QPIGS, int) PIPSOLAR_BINARY_SENSOR(switch_on, QPIGS, int) PIPSOLAR_BINARY_SENSOR(dustproof_installed, QPIGS, int) + // QPIGS2 values + + PIPSOLAR_SENSOR(pv2_input_current, QPIGS2, float) + PIPSOLAR_SENSOR(pv2_input_voltage, QPIGS2, float) + PIPSOLAR_SENSOR(pv2_charging_power, QPIGS2, int) + // QPIRI values PIPSOLAR_SENSOR(grid_rating_voltage, QPIRI, float) PIPSOLAR_SENSOR(grid_rating_current, QPIRI, float) @@ -164,6 +171,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_BINARY_SENSOR(warning_battery_equalization, QPIWS, bool) PIPSOLAR_TEXT_SENSOR(last_qpigs, QPIGS) + PIPSOLAR_TEXT_SENSOR(last_qpigs2, QPIGS2) PIPSOLAR_TEXT_SENSOR(last_qpiri, QPIRI) PIPSOLAR_TEXT_SENSOR(last_qmod, QMOD) PIPSOLAR_TEXT_SENSOR(last_qflag, QFLAG) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index a206e419..dc0ef939 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -2,6 +2,8 @@ import esphome.config_validation as cv from esphome.components import sensor from esphome.const import ( + CONF_BATTERY_VOLTAGE, + CONF_BUS_VOLTAGE, DEVICE_CLASS_CURRENT, DEVICE_CLASS_EMPTY, DEVICE_CLASS_POWER, @@ -11,16 +13,15 @@ ICON_EMPTY, UNIT_AMPERE, UNIT_CELSIUS, + UNIT_EMPTY, UNIT_HERTZ, UNIT_PERCENT, UNIT_VOLT, - UNIT_EMPTY, UNIT_VOLT_AMPS, UNIT_WATT, - CONF_BUS_VOLTAGE, - CONF_BATTERY_VOLTAGE, ) -from .. import PIPSOLAR_COMPONENT_SCHEMA, CONF_PIPSOLAR_ID + +from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA DEPENDENCIES = ["uart"] @@ -51,6 +52,8 @@ CONF_PV_OK_CONDITION_FOR_PARALLEL = "pv_ok_condition_for_parallel" CONF_PV_POWER_BALANCE = "pv_power_balance" +# QPIGS sensors + CONF_GRID_VOLTAGE = "grid_voltage" CONF_GRID_FREQUENCY = "grid_frequency" CONF_AC_OUTPUT_VOLTAGE = "ac_output_voltage" @@ -61,8 +64,8 @@ CONF_BATTERY_CHARGING_CURRENT = "battery_charging_current" CONF_BATTERY_CAPACITY_PERCENT = "battery_capacity_percent" CONF_INVERTER_HEAT_SINK_TEMPERATURE = "inverter_heat_sink_temperature" -CONF_PV_INPUT_CURRENT_FOR_BATTERY = "pv_input_current_for_battery" -CONF_PV_INPUT_VOLTAGE = "pv_input_voltage" +CONF_PV1_INPUT_CURRENT = "pv1_input_current" +CONF_PV1_INPUT_VOLTAGE = "pv1_input_voltage" CONF_BATTERY_VOLTAGE_SCC = "battery_voltage_scc" CONF_BATTERY_DISCHARGE_CURRENT = "battery_discharge_current" CONF_ADD_SBU_PRIORITY_VERSION = "add_sbu_priority_version" @@ -70,7 +73,14 @@ CONF_SCC_FIRMWARE_VERSION = "scc_firmware_version" CONF_BATTERY_VOLTAGE_OFFSET_FOR_FANS_ON = "battery_voltage_offset_for_fans_on" CONF_EEPROM_VERSION = "eeprom_version" -CONF_PV_CHARGING_POWER = "pv_charging_power" +CONF_PV1_CHARGING_POWER = "pv1_charging_power" + +# QPIGS2 sensors + +CONF_PV2_INPUT_CURRENT = "pv2_input_current" +CONF_PV2_INPUT_VOLTAGE = "pv2_input_voltage" +CONF_PV2_CHARGING_POWER = "pv2_charging_power" + TYPES = { CONF_GRID_RATING_VOLTAGE: sensor.sensor_schema( @@ -182,10 +192,10 @@ CONF_INVERTER_HEAT_SINK_TEMPERATURE: sensor.sensor_schema( UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE ), - CONF_PV_INPUT_CURRENT_FOR_BATTERY: sensor.sensor_schema( + CONF_PV1_INPUT_CURRENT: sensor.sensor_schema( UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT ), - CONF_PV_INPUT_VOLTAGE: sensor.sensor_schema( + CONF_PV1_INPUT_VOLTAGE: sensor.sensor_schema( UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE ), CONF_BATTERY_VOLTAGE_SCC: sensor.sensor_schema( @@ -200,7 +210,16 @@ CONF_EEPROM_VERSION: sensor.sensor_schema( UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY ), - CONF_PV_CHARGING_POWER: sensor.sensor_schema( + CONF_PV1_CHARGING_POWER: sensor.sensor_schema( + UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER + ), + CONF_PV2_INPUT_CURRENT: sensor.sensor_schema( + UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + ), + CONF_PV2_INPUT_VOLTAGE: sensor.sensor_schema( + UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + ), + CONF_PV2_CHARGING_POWER: sensor.sensor_schema( UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER ), } diff --git a/components/pipsolar/text_sensor/__init__.py b/components/pipsolar/text_sensor/__init__.py index fe6c4979..9ded1cb2 100644 --- a/components/pipsolar/text_sensor/__init__.py +++ b/components/pipsolar/text_sensor/__init__.py @@ -2,12 +2,14 @@ import esphome.config_validation as cv from esphome.components import text_sensor from esphome.const import CONF_ID + from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA, pipsolar_ns DEPENDENCIES = ["uart"] CONF_DEVICE_MODE = "device_mode" CONF_LAST_QPIGS = "last_qpigs" +CONF_LAST_QPIGS2 = "last_qpigs2" CONF_LAST_QPIRI = "last_qpiri" CONF_LAST_QMOD = "last_qmod" CONF_LAST_QFLAG = "last_qflag" @@ -22,6 +24,7 @@ TYPES = [ CONF_DEVICE_MODE, CONF_LAST_QPIGS, + CONF_LAST_QPIGS2, CONF_LAST_QPIRI, CONF_LAST_QMOD, CONF_LAST_QFLAG, From 52d7c8c9e13ccb8614d79df1b4a2f0cfdd15c0bd Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 12 Mar 2022 10:11:21 +0100 Subject: [PATCH 003/114] Add esphome-2022.3.0b1 compatibility --- components/pipsolar/sensor/__init__.py | 237 ++++++++++++++++++++----- 1 file changed, 190 insertions(+), 47 deletions(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index dc0ef939..dd3790a4 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -84,143 +84,286 @@ TYPES = { CONF_GRID_RATING_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_GRID_RATING_CURRENT: sensor.sensor_schema( - UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + unit_of_measurement=UNIT_AMPERE, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_CURRENT, ), CONF_AC_OUTPUT_RATING_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_AC_OUTPUT_RATING_FREQUENCY: sensor.sensor_schema( - UNIT_HERTZ, ICON_CURRENT_AC, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_HERTZ, + icon=ICON_CURRENT_AC, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_RATING_CURRENT: sensor.sensor_schema( - UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + unit_of_measurement=UNIT_AMPERE, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_CURRENT, ), CONF_AC_OUTPUT_RATING_APPARENT_POWER: sensor.sensor_schema( - UNIT_VOLT_AMPS, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_VOLT_AMPS, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_RATING_ACTIVE_POWER: sensor.sensor_schema( - UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER + unit_of_measurement=UNIT_WATT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, ), CONF_BATTERY_RATING_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_RECHARGE_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_UNDER_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_BULK_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_FLOAT_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_TYPE: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_CURRENT_MAX_AC_CHARGING_CURRENT: sensor.sensor_schema( - UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + unit_of_measurement=UNIT_AMPERE, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_CURRENT, ), CONF_CURRENT_MAX_CHARGING_CURRENT: sensor.sensor_schema( - UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + unit_of_measurement=UNIT_AMPERE, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_CURRENT, ), CONF_INPUT_VOLTAGE_RANGE: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_OUTPUT_SOURCE_PRIORITY: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_CHARGER_SOURCE_PRIORITY: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_PARALLEL_MAX_NUM: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_MACHINE_TYPE: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, + ), + CONF_TOPOLOGY: sensor.sensor_schema( + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), - CONF_TOPOLOGY: sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY), CONF_OUTPUT_MODE: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_BATTERY_REDISCHARGE_VOLTAGE: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_PV_OK_CONDITION_FOR_PARALLEL: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_PV_POWER_BALANCE: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_GRID_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_GRID_FREQUENCY: sensor.sensor_schema( - UNIT_HERTZ, ICON_CURRENT_AC, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_HERTZ, + icon=ICON_CURRENT_AC, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_AC_OUTPUT_FREQUENCY: sensor.sensor_schema( - UNIT_HERTZ, ICON_CURRENT_AC, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_HERTZ, + icon=ICON_CURRENT_AC, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_APPARENT_POWER: sensor.sensor_schema( - UNIT_VOLT_AMPS, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_VOLT_AMPS, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_ACTIVE_POWER: sensor.sensor_schema( - UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER + unit_of_measurement=UNIT_WATT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, ), CONF_OUTPUT_LOAD_PERCENT: sensor.sensor_schema( - UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_PERCENT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_BUS_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_CHARGING_CURRENT: sensor.sensor_schema( - UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + unit_of_measurement=UNIT_AMPERE, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_CURRENT, ), CONF_BATTERY_CAPACITY_PERCENT: sensor.sensor_schema( - UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_PERCENT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_INVERTER_HEAT_SINK_TEMPERATURE: sensor.sensor_schema( - UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE + unit_of_measurement=UNIT_CELSIUS, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, ), CONF_PV1_INPUT_CURRENT: sensor.sensor_schema( - UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + unit_of_measurement=UNIT_AMPERE, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_CURRENT, ), CONF_PV1_INPUT_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_VOLTAGE_SCC: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_DISCHARGE_CURRENT: sensor.sensor_schema( - UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + unit_of_measurement=UNIT_AMPERE, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_CURRENT, ), CONF_BATTERY_VOLTAGE_OFFSET_FOR_FANS_ON: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_EEPROM_VERSION: sensor.sensor_schema( - UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY + unit_of_measurement=UNIT_EMPTY, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, ), CONF_PV1_CHARGING_POWER: sensor.sensor_schema( - UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER + unit_of_measurement=UNIT_WATT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, ), CONF_PV2_INPUT_CURRENT: sensor.sensor_schema( - UNIT_AMPERE, ICON_EMPTY, 1, DEVICE_CLASS_CURRENT + unit_of_measurement=UNIT_AMPERE, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_CURRENT, ), CONF_PV2_INPUT_VOLTAGE: sensor.sensor_schema( - UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE + unit_of_measurement=UNIT_VOLT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_PV2_CHARGING_POWER: sensor.sensor_schema( - UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER + unit_of_measurement=UNIT_WATT, + icon=ICON_EMPTY, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, ), } From d2c1422003875bffc4624c5338d44639e9bd3a07 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 12 Mar 2022 10:24:55 +0100 Subject: [PATCH 004/114] Enable the CI --- .github/workflows/ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d5c7f799..549a26ce 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,6 +4,7 @@ on: # yamllint disable-line rule:truthy push: branches: - main + - pip8048 pull_request: schedule: - cron: 0 12 * * * From 79d4488310ae996f30b13c34df009a0d286336cf Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 12 Mar 2022 10:37:12 +0100 Subject: [PATCH 005/114] Fix typo --- esp32-example.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp32-example.yaml b/esp32-example.yaml index d068987a..8cfe2aac 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -15,7 +15,7 @@ esphome: board: esp-wrover-kit external_components: - - source: github://syssi/esphome-pipsolar@pip8084 + - source: github://syssi/esphome-pipsolar@pip8048 refresh: 0s wifi: From dd1746f4da81bbf408c54005ae7249f1e7b40b80 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 12 Mar 2022 10:41:05 +0100 Subject: [PATCH 006/114] Add new sensors to the config examples --- esp32-example.yaml | 23 +++++++++++++++++------ esp8266-example.yaml | 23 +++++++++++++++++------ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/esp32-example.yaml b/esp32-example.yaml index 8cfe2aac..b249810f 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -123,10 +123,14 @@ sensor: name: "${name} battery_capacity_percent" inverter_heat_sink_temperature: name: "${name} inverter_heat_sink_temperature" - pv_input_current_for_battery: - name: "${name} pv_input_current_for_battery" - pv_input_voltage: - name: "${name} pv_input_voltage" + pv1_input_current_for_battery: + name: "${name} pv1_input_current_for_battery" + pv1_input_voltage: + name: "${name} pv1_input_voltage" + pv2_input_current_for_battery: + name: "${name} pv2_input_current_for_battery" + pv2_input_voltage: + name: "${name} pv2_input_voltage" battery_voltage_scc: name: "${name} battery_voltage_scc" battery_discharge_current: @@ -135,8 +139,10 @@ sensor: name: "${name} battery_voltage_offset_for_fans_on" # eeprom_version: # name: "${name} eeprom_version" - pv_charging_power: - name: "${name} pv_charging_power" + pv1_charging_power: + name: "${name} pv1_charging_power" + pv2_charging_power: + name: "${name} pv2_charging_power" text_sensor: - platform: pipsolar @@ -211,3 +217,8 @@ output: pipsolar_id: inverter0 battery_recharge_voltage: id: inverter0_battery_recharge_voltage_out + + - platform: pipsolar + pipsolar_id: inverter0 + battery_bulk_voltage: + id: inverter0_battery_bulk_voltage_out diff --git a/esp8266-example.yaml b/esp8266-example.yaml index 3915ab4e..f1cb3786 100644 --- a/esp8266-example.yaml +++ b/esp8266-example.yaml @@ -123,10 +123,14 @@ sensor: name: "${name} battery_capacity_percent" inverter_heat_sink_temperature: name: "${name} inverter_heat_sink_temperature" - pv_input_current_for_battery: - name: "${name} pv_input_current_for_battery" - pv_input_voltage: - name: "${name} pv_input_voltage" + pv1_input_current_for_battery: + name: "${name} pv1_input_current_for_battery" + pv1_input_voltage: + name: "${name} pv1_input_voltage" + pv2_input_current_for_battery: + name: "${name} pv2_input_current_for_battery" + pv2_input_voltage: + name: "${name} pv2_input_voltage" battery_voltage_scc: name: "${name} battery_voltage_scc" battery_discharge_current: @@ -135,8 +139,10 @@ sensor: name: "${name} battery_voltage_offset_for_fans_on" # eeprom_version: # name: "${name} eeprom_version" - pv_charging_power: - name: "${name} pv_charging_power" + pv1_charging_power: + name: "${name} pv1_charging_power" + pv2_charging_power: + name: "${name} pv2_charging_power" text_sensor: - platform: pipsolar @@ -211,3 +217,8 @@ output: pipsolar_id: inverter0 battery_recharge_voltage: id: inverter0_battery_recharge_voltage_out + + - platform: pipsolar + pipsolar_id: inverter0 + battery_bulk_voltage: + id: inverter0_battery_bulk_voltage_out From 5e1dcb6106cf7150f43397bb2093a0faa1cf850d Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 12 Mar 2022 10:45:34 +0100 Subject: [PATCH 007/114] Rename sensors --- esp32-example.yaml | 8 ++++---- esp8266-example.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/esp32-example.yaml b/esp32-example.yaml index b249810f..189cee96 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -123,12 +123,12 @@ sensor: name: "${name} battery_capacity_percent" inverter_heat_sink_temperature: name: "${name} inverter_heat_sink_temperature" - pv1_input_current_for_battery: - name: "${name} pv1_input_current_for_battery" + pv1_input_current: + name: "${name} pv1_input_current" pv1_input_voltage: name: "${name} pv1_input_voltage" - pv2_input_current_for_battery: - name: "${name} pv2_input_current_for_battery" + pv2_input_current: + name: "${name} pv2_input_current" pv2_input_voltage: name: "${name} pv2_input_voltage" battery_voltage_scc: diff --git a/esp8266-example.yaml b/esp8266-example.yaml index f1cb3786..c0556709 100644 --- a/esp8266-example.yaml +++ b/esp8266-example.yaml @@ -123,12 +123,12 @@ sensor: name: "${name} battery_capacity_percent" inverter_heat_sink_temperature: name: "${name} inverter_heat_sink_temperature" - pv1_input_current_for_battery: - name: "${name} pv1_input_current_for_battery" + pv1_input_current: + name: "${name} pv1_input_current" pv1_input_voltage: name: "${name} pv1_input_voltage" - pv2_input_current_for_battery: - name: "${name} pv2_input_current_for_battery" + pv2_input_current: + name: "${name} pv2_input_current" pv2_input_voltage: name: "${name} pv2_input_voltage" battery_voltage_scc: From bc02ee8c09e48f924009bc0256912c1185540ec3 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 19 Mar 2022 19:33:50 +0100 Subject: [PATCH 008/114] Change CRC method --- components/pipsolar/pipsolar.cpp | 53 ++++++++++++++++++++------------ components/pipsolar/pipsolar.h | 3 +- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 97c4fc4f..67bbfde6 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -915,28 +915,41 @@ void Pipsolar::add_polling_command_(const char *command, ENUMPollingCommand poll } } -uint16_t Pipsolar::calc_crc_(uint8_t *msg, int n) { - // Initial value. xmodem uses 0xFFFF but this example - // requires an initial value of zero. - uint16_t x = 0; - while (n--) { - x = crc_xmodem_update_(x, (uint16_t) *msg++); - } - return (x); -} +uint16_t Pipsolar::calc_crc_(uint8_t *msg, uint8_t len) { + uint16_t crc; + + uint8_t da; + uint8_t *ptr; + uint8_t bCRCHign; + uint8_t bCRCLow; + + uint16_t crc_ta[16] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef}; -// See bottom of this page: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html -// Polynomial: x^16 + x^12 + x^5 + 1 (0x1021) -uint16_t Pipsolar::crc_xmodem_update_(uint16_t crc, uint8_t data) { - int i; - crc = crc ^ ((uint16_t) data << 8); - for (i = 0; i < 8; i++) { - if (crc & 0x8000) - crc = (crc << 1) ^ 0x1021; //(polynomial = 0x1021) - else - crc <<= 1; + ptr = msg; + crc = 0; + + while (len-- != 0) { + da = ((uint8_t)(crc >> 8)) >> 4; + crc <<= 4; + crc ^= crc_ta[da ^ (*ptr >> 4)]; + da = ((uint8_t)(crc >> 8)) >> 4; + crc <<= 4; + crc ^= crc_ta[da ^ (*ptr & 0x0f)]; + ptr++; } - return crc; + + bCRCLow = crc; + bCRCHign = (uint8_t)(crc >> 8); + + if (bCRCLow == 0x28 || bCRCLow == 0x0d || bCRCLow == 0x0a) + bCRCLow++; + if (bCRCHign == 0x28 || bCRCHign == 0x0d || bCRCHign == 0x0a) + bCRCHign++; + + crc = ((uint16_t) bCRCHign) << 8; + crc += bCRCLow; + return (crc); } } // namespace pipsolar diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 81343150..d05cf011 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -201,8 +201,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { void empty_uart_buffer_(); uint8_t check_incoming_crc_(); uint8_t check_incoming_length_(uint8_t length); - uint16_t calc_crc_(uint8_t *msg, int n); - uint16_t crc_xmodem_update_(uint16_t crc, uint8_t data); + uint16_t calc_crc_(uint8_t *msg, uint8_t len); uint8_t send_next_command_(); void send_next_poll_(); void queue_command_(const char *command, uint8_t length); From f5b1cb93421c671114bd102f4da4f0cc5f803152 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Mon, 21 Mar 2022 19:49:02 +0100 Subject: [PATCH 009/114] Merge improved pipsolar crc (#3316) --- components/pipsolar/pipsolar.cpp | 30 +++++++++++++++--------------- components/pipsolar/pipsolar.h | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 67bbfde6..ba2c8890 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -791,7 +791,7 @@ uint8_t Pipsolar::check_incoming_length_(uint8_t length) { uint8_t Pipsolar::check_incoming_crc_() { uint16_t crc16; - crc16 = calc_crc_(read_buffer_, read_pos_ - 3); + crc16 = cal_crc_half_(read_buffer_, read_pos_ - 3); ESP_LOGD(TAG, "checking crc on incoming message"); if (((uint8_t)((crc16) >> 8)) == read_buffer_[read_pos_ - 3] && ((uint8_t)((crc16) &0xff)) == read_buffer_[read_pos_ - 2]) { @@ -820,7 +820,7 @@ uint8_t Pipsolar::send_next_command_() { this->command_start_millis_ = millis(); this->empty_uart_buffer_(); this->read_pos_ = 0; - crc16 = calc_crc_(byte_command, length); + crc16 = cal_crc_half_(byte_command, length); this->write_str(command); // checksum this->write(((uint8_t)((crc16) >> 8))); // highbyte @@ -847,8 +847,8 @@ void Pipsolar::send_next_poll_() { this->command_start_millis_ = millis(); this->empty_uart_buffer_(); this->read_pos_ = 0; - crc16 = calc_crc_(this->used_polling_commands_[this->last_polling_command_].command, - this->used_polling_commands_[this->last_polling_command_].length); + crc16 = cal_crc_half_(this->used_polling_commands_[this->last_polling_command_].command, + this->used_polling_commands_[this->last_polling_command_].length); this->write_array(this->used_polling_commands_[this->last_polling_command_].command, this->used_polling_commands_[this->last_polling_command_].length); // checksum @@ -915,13 +915,13 @@ void Pipsolar::add_polling_command_(const char *command, ENUMPollingCommand poll } } -uint16_t Pipsolar::calc_crc_(uint8_t *msg, uint8_t len) { +uint16_t Pipsolar::cal_crc_half_(uint8_t *msg, uint8_t len) { uint16_t crc; uint8_t da; uint8_t *ptr; - uint8_t bCRCHign; - uint8_t bCRCLow; + uint8_t b_crc_hign; + uint8_t b_crc_low; uint16_t crc_ta[16] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef}; @@ -939,16 +939,16 @@ uint16_t Pipsolar::calc_crc_(uint8_t *msg, uint8_t len) { ptr++; } - bCRCLow = crc; - bCRCHign = (uint8_t)(crc >> 8); + b_crc_low = crc; + b_crc_hign = (uint8_t)(crc >> 8); - if (bCRCLow == 0x28 || bCRCLow == 0x0d || bCRCLow == 0x0a) - bCRCLow++; - if (bCRCHign == 0x28 || bCRCHign == 0x0d || bCRCHign == 0x0a) - bCRCHign++; + if (b_crc_low == 0x28 || b_crc_low == 0x0d || b_crc_low == 0x0a) + b_crc_low++; + if (b_crc_hign == 0x28 || b_crc_hign == 0x0d || b_crc_hign == 0x0a) + b_crc_hign++; - crc = ((uint16_t) bCRCHign) << 8; - crc += bCRCLow; + crc = ((uint16_t) b_crc_hign) << 8; + crc += b_crc_low; return (crc); } diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index d05cf011..9b188335 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -201,7 +201,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { void empty_uart_buffer_(); uint8_t check_incoming_crc_(); uint8_t check_incoming_length_(uint8_t length); - uint16_t calc_crc_(uint8_t *msg, uint8_t len); + uint16_t cal_crc_half_(uint8_t *msg, uint8_t len); uint8_t send_next_command_(); void send_next_poll_(); void queue_command_(const char *command, uint8_t length); From b73aad2efc4273d8b2908f14c077e29956886cf3 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Mon, 21 Mar 2022 19:52:00 +0100 Subject: [PATCH 010/114] Merge andreashergert1984/esphome/tree/enhance_pipsolar_select --- components/pipsolar/__init__.py | 2 +- components/pipsolar/pipsolar.cpp | 5 + components/pipsolar/pipsolar.h | 7 + components/pipsolar/select/__init__.py | 169 ++++++++++++++++++ .../pipsolar/select/pipsolar_select.cpp | 42 +++++ components/pipsolar/select/pipsolar_select.h | 41 +++++ 6 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 components/pipsolar/select/__init__.py create mode 100644 components/pipsolar/select/pipsolar_select.cpp create mode 100644 components/pipsolar/select/pipsolar_select.h diff --git a/components/pipsolar/__init__.py b/components/pipsolar/__init__.py index 2d0cd9ea..2a7284cd 100644 --- a/components/pipsolar/__init__.py +++ b/components/pipsolar/__init__.py @@ -5,7 +5,7 @@ DEPENDENCIES = ["uart"] CODEOWNERS = ["@andreashergert1984"] -AUTO_LOAD = ["binary_sensor", "text_sensor", "sensor", "switch", "output"] +AUTO_LOAD = ["binary_sensor", "text_sensor", "sensor", "switch", "output", "select"] MULTI_CONF = True CONF_PIPSOLAR_ID = "pipsolar_id" diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index ba2c8890..c391509c 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -125,6 +125,11 @@ void Pipsolar::loop() { if (this->output_source_priority_) { this->output_source_priority_->publish_state(value_output_source_priority_); } + // special for output source priority select + if (this->output_source_priority_select_) { + std::string value = std::to_string(value_output_source_priority_); + this->output_source_priority_select_->map_and_publish(value); + } // special for output source priority switches if (this->output_source_priority_utility_switch_) { this->output_source_priority_utility_switch_->publish_state(value_output_source_priority_ == 0); diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 9b188335..4d3202b2 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -3,6 +3,8 @@ #include "esphome/components/binary_sensor/binary_sensor.h" #include "esphome/components/sensor/sensor.h" #include "esphome/components/switch/switch.h" +#include "esphome/components/select/select.h" +#include "esphome/components/pipsolar/select/pipsolar_select.h" #include "esphome/components/text_sensor/text_sensor.h" #include "esphome/components/uart/uart.h" #include "esphome/core/automation.h" @@ -10,6 +12,7 @@ namespace esphome { namespace pipsolar { +class PipsolarSelect; enum ENUMPollingCommand { POLLING_QPIRI = 0, @@ -46,6 +49,7 @@ struct PollingCommand { #define PIPSOLAR_SENSOR(name, polling_command, value_type) \ PIPSOLAR_VALUED_ENTITY_(sensor::Sensor, name, polling_command, value_type) #define PIPSOLAR_SWITCH(name, polling_command) PIPSOLAR_ENTITY_(switch_::Switch, name, polling_command) +#define PIPSOLAR_SELECT(name, polling_command) PIPSOLAR_ENTITY_(pipsolar::PipsolarSelect, name, polling_command) #define PIPSOLAR_BINARY_SENSOR(name, polling_command, value_type) \ PIPSOLAR_VALUED_ENTITY_(binary_sensor::BinarySensor, name, polling_command, value_type) #define PIPSOLAR_VALUED_TEXT_SENSOR(name, polling_command, value_type) \ @@ -186,6 +190,8 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SWITCH(pv_ok_condition_for_parallel_switch, QPIRI) PIPSOLAR_SWITCH(pv_power_balance_switch, QPIRI) + PIPSOLAR_SELECT(output_source_priority_select, QPIRI) + void switch_command(const std::string &command); void setup() override; void loop() override; @@ -193,6 +199,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { void update() override; protected: + friend class PipsolarSelect; static const size_t PIPSOLAR_READ_BUFFER_LENGTH = 110; // maximum supported answer length static const size_t COMMAND_QUEUE_LENGTH = 10; static const size_t COMMAND_TIMEOUT = 5000; diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py new file mode 100644 index 00000000..c6f180e4 --- /dev/null +++ b/components/pipsolar/select/__init__.py @@ -0,0 +1,169 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import select +from esphome.const import CONF_ID, CONF_OPTIMISTIC +from esphome.jsonschema import jschema_composite + +from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA, pipsolar_ns + +DEPENDENCIES = ["uart"] + +CODEOWNERS = ["@andreashergert1984"] +CONF_OPTIONSMAP = "optionsmap" +CONF_STATUSMAP = "statusmap" + +CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" + +PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) + + +@jschema_composite +def ensure_option_map(): + def validator(value): + cv.check_not_templatable(value) + option = cv.All(cv.string_strict) + mapping = cv.All(cv.string_strict) + options_map_schema = cv.Schema({option: mapping}) + value = options_map_schema(value) + + all_values = list(value.values()) + unique_values = set(value.values()) + if len(all_values) != len(unique_values): + raise cv.Invalid("Mapping values must be unique.") + + return value + + return validator + + +# def register_count_value_type_min(value): +# reg_count = value.get(CONF_REGISTER_COUNT) +# if reg_count is not None: +# value_type = value[CONF_VALUE_TYPE] +# min_register_count = TYPE_REGISTER_MAP[value_type] +# if min_register_count > reg_count: +# raise cv.Invalid( +# f"Value type {value_type} needs at least {min_register_count} registers" +# ) +# return value + +# INTEGER_SENSOR_VALUE_TYPE = { +# key: value for key, value in SENSOR_VALUE_TYPE.items() if not key.startswith("FP") +# } + +# CONFIG_SCHEMA = cv.All( +# select.SELECT_SCHEMA.extend(cv.COMPONENT_SCHEMA).extend( +# { +# cv.GenerateID(): cv.declare_id(PipSolarSelect), +# cv.GenerateID(CONF_MODBUS_CONTROLLER_ID): cv.use_id(ModbusController), +# cv.Required(CONF_ADDRESS): cv.positive_int, +# cv.Optional(CONF_VALUE_TYPE, default="U_WORD"): cv.enum( +# INTEGER_SENSOR_VALUE_TYPE +# ), +# cv.Optional(CONF_REGISTER_COUNT): cv.positive_int, +# cv.Optional(CONF_SKIP_UPDATES, default=0): cv.positive_int, +# cv.Optional(CONF_FORCE_NEW_RANGE, default=False): cv.boolean, +# cv.Required(CONF_OPTIONSMAP): ensure_option_map(), +# cv.Optional(CONF_USE_WRITE_MULTIPLE, default=False): cv.boolean, +# cv.Optional(CONF_OPTIMISTIC, default=False): cv.boolean, +# cv.Optional(CONF_LAMBDA): cv.returning_lambda, +# cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda, +# }, +# ), +# register_count_value_type_min, +# ) + +TYPES = { + CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), +} + + +PIPSELECT_SCHEMA = select.SELECT_SCHEMA.extend( + { + cv.GenerateID(): cv.declare_id(PipsolarSelect), + cv.Optional(CONF_OPTIONSMAP): ensure_option_map(), + cv.Optional(CONF_STATUSMAP): ensure_option_map(), + } +).extend(cv.COMPONENT_SCHEMA) + + +CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( + {cv.Optional(type): PIPSELECT_SCHEMA for type in TYPES} +) + + +async def to_code(config): + paren = await cg.get_variable(config[CONF_PIPSOLAR_ID]) + + for type, (on, off) in TYPES.items(): + if type in config: + conf = config[type] + options_map = conf[CONF_OPTIONSMAP] + var = cg.new_Pvariable(conf[CONF_ID]) + await cg.register_component(var, conf) + await select.register_select(var, conf, options=list(options_map.keys())) + cg.add(getattr(paren, f"set_{type}_select")(var)) + cg.add(var.set_parent(paren)) + for mappingkey in options_map.keys(): + cg.add(var.add_mapping(mappingkey, options_map[mappingkey])) + if CONF_STATUSMAP in conf: + status_map = conf[CONF_STATUSMAP] + for mappingkey in status_map.keys(): + cg.add(var.add_status_mapping(mappingkey, status_map[mappingkey])) + # cg.add(var.set_optimistic(conf[CONF_OPTIMISTIC])) + + +# async def to_code(config): +# value_type = config[CONF_VALUE_TYPE] +# reg_count = config.get(CONF_REGISTER_COUNT) +# if reg_count is None: +# reg_count = TYPE_REGISTER_MAP[value_type] + +# options_map = config[CONF_OPTIONSMAP] + +# var = cg.new_Pvariable( +# config[CONF_ID], +# value_type, +# config[CONF_ADDRESS], +# reg_count, +# config[CONF_SKIP_UPDATES], +# config[CONF_FORCE_NEW_RANGE], +# list(options_map.values()), +# ) + +# await cg.register_component(var, config) +# await select.register_select(var, config, options=list(options_map.keys())) + +# parent = await cg.get_variable(config[CONF_MODBUS_CONTROLLER_ID]) +# cg.add(parent.add_sensor_item(var)) +# cg.add(var.set_parent(parent)) +# cg.add(var.set_use_write_mutiple(config[CONF_USE_WRITE_MULTIPLE])) +# cg.add(var.set_optimistic(config[CONF_OPTIMISTIC])) + +# if CONF_LAMBDA in config: +# template_ = await cg.process_lambda( +# config[CONF_LAMBDA], +# [ +# (ModbusSelect.operator("const_ptr"), "item"), +# (cg.int64, "x"), +# ( +# cg.std_vector.template(cg.uint8).operator("const").operator("ref"), +# "data", +# ), +# ], +# return_type=cg.optional.template(cg.std_string), +# ) +# cg.add(var.set_template(template_)) + +# if CONF_WRITE_LAMBDA in config: +# template_ = await cg.process_lambda( +# config[CONF_WRITE_LAMBDA], +# [ +# (ModbusSelect.operator("const_ptr"), "item"), +# (cg.std_string.operator("const").operator("ref"), "x"), +# (cg.int64, "value"), +# (cg.std_vector.template(cg.uint16).operator("ref"), "payload"), +# ], +# return_type=cg.optional.template(cg.int64), +# ) +# cg.add(var.set_write_template(template_)) diff --git a/components/pipsolar/select/pipsolar_select.cpp b/components/pipsolar/select/pipsolar_select.cpp new file mode 100644 index 00000000..75e2ff45 --- /dev/null +++ b/components/pipsolar/select/pipsolar_select.cpp @@ -0,0 +1,42 @@ +#include "pipsolar_select.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace pipsolar { + +static const char *const TAG = "pipsolar.select"; + +void PipsolarSelect::dump_config() { LOG_SELECT(TAG, "Pipsolar Controller Select", this); } + +void PipsolarSelect::control(const std::string &value) { + ESP_LOGD(TAG, "got option: %s", value.c_str()); + if (this->mapping_.find(value) != this->mapping_.end()) { + ESP_LOGD(TAG, "found mapped option %s for option %s", this->mapping_[value].c_str(), value.c_str()); + this->parent_->switch_command(this->mapping_[value]); + } else { + ESP_LOGD(TAG, "could not find option %s in mapping", value.c_str()); + return; + } + // auto options = this->traits.get_options(); + // auto opt_it = std::find(options.cbegin(), options.cend(), value); + // size_t idx = std::distance(options.cbegin(), opt_it); + // std::string mapval = this->mapping_[idx]; + // ESP_LOGD(TAG, "Found value %s for option '%s'", *mapval.c_str(), value.c_str()); + + if (this->optimistic_) + this->publish_state(value); +} + +void PipsolarSelect::map_and_publish(std::string &value) { + ESP_LOGD(TAG, "got value: %s", value.c_str()); + if (this->status_mapping_.find(value) != this->status_mapping_.end()) { + ESP_LOGD(TAG, "found mapped option %s for option %s", this->status_mapping_[value].c_str(), value.c_str()); + this->publish_state(this->status_mapping_[value]); + } else { + ESP_LOGD(TAG, "could not find option %s in mapping", value.c_str()); + return; + } +} + +} // namespace pipsolar +} // namespace esphome diff --git a/components/pipsolar/select/pipsolar_select.h b/components/pipsolar/select/pipsolar_select.h new file mode 100644 index 00000000..06050579 --- /dev/null +++ b/components/pipsolar/select/pipsolar_select.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +#include "esphome/components/pipsolar/pipsolar.h" +#include "esphome/components/select/select.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace pipsolar { +class Pipsolar; + +class PipsolarSelect : public Component, public select::Select { + public: + PipsolarSelect( + // uint16_t start_address, uint8_t register_count, uint8_t skip_updates, + // bool force_new_range, std::vector mapping + ) { + // this->mapping_ = std::move(mapping); + } + + void set_parent(Pipsolar *const parent) { this->parent_ = parent; } + void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; } + void add_mapping(std::string key, std::string value) { this->mapping_[key] = value; } + void add_status_mapping(std::string key, std::string value) { this->status_mapping_[key] = value; } + void dump_config() override; + // void parse_and_publish(const std::vector &data) override; + void control(const std::string &value) override; + void map_and_publish(std::string &value); + + protected: + std::map mapping_; + std::map status_mapping_; + + Pipsolar *parent_; + bool optimistic_{false}; +}; + +} // namespace pipsolar +} // namespace esphome From 0fcd60150e67bb7626f5fbe6477bcba2256889f8 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Mon, 21 Mar 2022 19:58:38 +0100 Subject: [PATCH 011/114] Add select example --- esp32-example.yaml | 15 +++++++++++++++ esp8266-example.yaml | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/esp32-example.yaml b/esp32-example.yaml index 189cee96..e3eabf33 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -222,3 +222,18 @@ output: pipsolar_id: inverter0 battery_bulk_voltage: id: inverter0_battery_bulk_voltage_out + +select: + - platform: pipsolar + pipsolar_id: inverter0 + output_source_priority: + id: inverter0_output_source_priority_select + name: inverter0_output_source_priority_select + optionsmap: + "Utility first": "POP00" + "Solar only": "POP01" + "Solar Battery Utility": "POP02" + statusmap: + "0": "Utility first" + "1": "Solar only" + "2": "Solar Battery Utility" diff --git a/esp8266-example.yaml b/esp8266-example.yaml index c0556709..084aa2d1 100644 --- a/esp8266-example.yaml +++ b/esp8266-example.yaml @@ -222,3 +222,18 @@ output: pipsolar_id: inverter0 battery_bulk_voltage: id: inverter0_battery_bulk_voltage_out + +select: + - platform: pipsolar + pipsolar_id: inverter0 + output_source_priority: + id: inverter0_output_source_priority_select + name: inverter0_output_source_priority_select + optionsmap: + "Utility first": "POP00" + "Solar only": "POP01" + "Solar Battery Utility": "POP02" + statusmap: + "0": "Utility first" + "1": "Solar only" + "2": "Solar Battery Utility" From 9ad69999aa98e7b5448eeefb1d027d6595e7ba4b Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Mon, 21 Mar 2022 20:06:14 +0100 Subject: [PATCH 012/114] Use esphome::to_string --- components/pipsolar/pipsolar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index c391509c..47ae3ec7 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -127,7 +127,7 @@ void Pipsolar::loop() { } // special for output source priority select if (this->output_source_priority_select_) { - std::string value = std::to_string(value_output_source_priority_); + std::string value = esphome::to_string(value_output_source_priority_); this->output_source_priority_select_->map_and_publish(value); } // special for output source priority switches From 5f40093ab8aa16c213aa34ff25f7f0c2acb963e8 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 30 Apr 2022 17:46:14 +0200 Subject: [PATCH 013/114] Drop jschema_composite --- components/pipsolar/select/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index c6f180e4..31bb3f0f 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -2,7 +2,6 @@ import esphome.config_validation as cv from esphome.components import select from esphome.const import CONF_ID, CONF_OPTIMISTIC -from esphome.jsonschema import jschema_composite from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA, pipsolar_ns @@ -17,7 +16,6 @@ PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) -@jschema_composite def ensure_option_map(): def validator(value): cv.check_not_templatable(value) From a6fce4e3fb2be93a08066a70f4574f7596a16bc0 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 24 Sep 2022 08:49:11 +0200 Subject: [PATCH 014/114] Merge some esphome 2022.9.0 tidys ups --- components/pipsolar/binary_sensor/__init__.py | 10 +-- components/pipsolar/sensor/__init__.py | 80 ------------------- components/pipsolar/switch/__init__.py | 20 +---- components/pipsolar/text_sensor/__init__.py | 14 +--- 4 files changed, 9 insertions(+), 115 deletions(-) diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py index 5c6af3bf..2019f329 100644 --- a/components/pipsolar/binary_sensor/__init__.py +++ b/components/pipsolar/binary_sensor/__init__.py @@ -1,9 +1,6 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import binary_sensor -from esphome.const import ( - CONF_ID, -) from .. import PIPSOLAR_COMPONENT_SCHEMA, CONF_PIPSOLAR_ID DEPENDENCIES = ["uart"] @@ -130,7 +127,7 @@ ] CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( - {cv.Optional(type): binary_sensor.BINARY_SENSOR_SCHEMA for type in TYPES} + {cv.Optional(type): binary_sensor.binary_sensor_schema() for type in TYPES} ) @@ -139,6 +136,5 @@ async def to_code(config): for type in TYPES: if type in config: conf = config[type] - sens = cg.new_Pvariable(conf[CONF_ID]) - await binary_sensor.register_binary_sensor(sens, conf) - cg.add(getattr(paren, f"set_{type}")(sens)) + var = await binary_sensor.new_binary_sensor(conf) + cg.add(getattr(paren, f"set_{type}")(var)) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index dd3790a4..1290e6ba 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -5,15 +5,12 @@ CONF_BATTERY_VOLTAGE, CONF_BUS_VOLTAGE, DEVICE_CLASS_CURRENT, - DEVICE_CLASS_EMPTY, DEVICE_CLASS_POWER, DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_VOLTAGE, ICON_CURRENT_AC, - ICON_EMPTY, UNIT_AMPERE, UNIT_CELSIUS, - UNIT_EMPTY, UNIT_HERTZ, UNIT_PERCENT, UNIT_VOLT, @@ -85,19 +82,16 @@ TYPES = { CONF_GRID_RATING_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_GRID_RATING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_CURRENT, ), CONF_AC_OUTPUT_RATING_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), @@ -105,137 +99,89 @@ unit_of_measurement=UNIT_HERTZ, icon=ICON_CURRENT_AC, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_RATING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_CURRENT, ), CONF_AC_OUTPUT_RATING_APPARENT_POWER: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT_AMPS, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_RATING_ACTIVE_POWER: sensor.sensor_schema( unit_of_measurement=UNIT_WATT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_POWER, ), CONF_BATTERY_RATING_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_RECHARGE_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_UNDER_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_BULK_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_FLOAT_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_TYPE: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_CURRENT_MAX_AC_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_CURRENT, ), CONF_CURRENT_MAX_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_CURRENT, ), CONF_INPUT_VOLTAGE_RANGE: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_OUTPUT_SOURCE_PRIORITY: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_CHARGER_SOURCE_PRIORITY: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_PARALLEL_MAX_NUM: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_MACHINE_TYPE: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_TOPOLOGY: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_OUTPUT_MODE: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_BATTERY_REDISCHARGE_VOLTAGE: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_PV_OK_CONDITION_FOR_PARALLEL: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_PV_POWER_BALANCE: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_GRID_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), @@ -243,11 +189,9 @@ unit_of_measurement=UNIT_HERTZ, icon=ICON_CURRENT_AC, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), @@ -255,113 +199,89 @@ unit_of_measurement=UNIT_HERTZ, icon=ICON_CURRENT_AC, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_APPARENT_POWER: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT_AMPS, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_AC_OUTPUT_ACTIVE_POWER: sensor.sensor_schema( unit_of_measurement=UNIT_WATT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_POWER, ), CONF_OUTPUT_LOAD_PERCENT: sensor.sensor_schema( unit_of_measurement=UNIT_PERCENT, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_BUS_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_CURRENT, ), CONF_BATTERY_CAPACITY_PERCENT: sensor.sensor_schema( unit_of_measurement=UNIT_PERCENT, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_INVERTER_HEAT_SINK_TEMPERATURE: sensor.sensor_schema( unit_of_measurement=UNIT_CELSIUS, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_TEMPERATURE, ), CONF_PV1_INPUT_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_CURRENT, ), CONF_PV1_INPUT_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_VOLTAGE_SCC: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_DISCHARGE_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_CURRENT, ), CONF_BATTERY_VOLTAGE_OFFSET_FOR_FANS_ON: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_EEPROM_VERSION: sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - icon=ICON_EMPTY, accuracy_decimals=1, - device_class=DEVICE_CLASS_EMPTY, ), CONF_PV1_CHARGING_POWER: sensor.sensor_schema( unit_of_measurement=UNIT_WATT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_POWER, ), CONF_PV2_INPUT_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_CURRENT, ), CONF_PV2_INPUT_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_VOLTAGE, ), CONF_PV2_CHARGING_POWER: sensor.sensor_schema( unit_of_measurement=UNIT_WATT, - icon=ICON_EMPTY, accuracy_decimals=1, device_class=DEVICE_CLASS_POWER, ), diff --git a/components/pipsolar/switch/__init__.py b/components/pipsolar/switch/__init__.py index 5ff33b10..7658c7d4 100644 --- a/components/pipsolar/switch/__init__.py +++ b/components/pipsolar/switch/__init__.py @@ -1,12 +1,7 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import switch -from esphome.const import ( - CONF_ID, - CONF_INVERTED, - CONF_ICON, - ICON_POWER, -) +from esphome.const import ICON_POWER from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA, pipsolar_ns DEPENDENCIES = ["uart"] @@ -29,14 +24,8 @@ PipsolarSwitch = pipsolar_ns.class_("PipsolarSwitch", switch.Switch, cg.Component) -PIPSWITCH_SCHEMA = switch.SWITCH_SCHEMA.extend( - { - cv.GenerateID(): cv.declare_id(PipsolarSwitch), - cv.Optional(CONF_INVERTED): cv.invalid( - "Pipsolar switches do not support inverted mode!" - ), - cv.Optional(CONF_ICON, default=ICON_POWER): switch.icon, - } +PIPSWITCH_SCHEMA = switch.switch_schema( + PipsolarSwitch, icon=ICON_POWER, block_inverted=True ).extend(cv.COMPONENT_SCHEMA) CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( @@ -50,9 +39,8 @@ async def to_code(config): for type, (on, off) in TYPES.items(): if type in config: conf = config[type] - var = cg.new_Pvariable(conf[CONF_ID]) + var = await switch.new_switch(conf) await cg.register_component(var, conf) - await switch.register_switch(var, conf) cg.add(getattr(paren, f"set_{type}_switch")(var)) cg.add(var.set_parent(paren)) cg.add(var.set_on_command(on)) diff --git a/components/pipsolar/text_sensor/__init__.py b/components/pipsolar/text_sensor/__init__.py index 9ded1cb2..6be3f208 100644 --- a/components/pipsolar/text_sensor/__init__.py +++ b/components/pipsolar/text_sensor/__init__.py @@ -1,9 +1,8 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import text_sensor -from esphome.const import CONF_ID -from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA, pipsolar_ns +from .. import CONF_PIPSOLAR_ID, PIPSOLAR_COMPONENT_SCHEMA DEPENDENCIES = ["uart"] @@ -17,10 +16,6 @@ CONF_LAST_QT = "last_qt" CONF_LAST_QMN = "last_qmn" -PipsolarTextSensor = pipsolar_ns.class_( - "PipsolarTextSensor", text_sensor.TextSensor, cg.Component -) - TYPES = [ CONF_DEVICE_MODE, CONF_LAST_QPIGS, @@ -34,12 +29,7 @@ ] CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( - { - cv.Optional(type): text_sensor.TEXT_SENSOR_SCHEMA.extend( - {cv.GenerateID(): cv.declare_id(PipsolarTextSensor)} - ) - for type in TYPES - } + {cv.Optional(type): text_sensor.text_sensor_schema() for type in TYPES} ) From 7e823fdb6c4fb93fed1328c62824d445a5ee5231 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 24 Sep 2022 08:55:04 +0200 Subject: [PATCH 015/114] Migrate some minor changes from the official pipsolar component --- components/pipsolar/__init__.py | 2 +- components/pipsolar/binary_sensor/__init__.py | 1 + components/pipsolar/sensor/__init__.py | 2 ++ components/pipsolar/text_sensor/__init__.py | 4 +--- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/__init__.py b/components/pipsolar/__init__.py index 2a7284cd..9da6af19 100644 --- a/components/pipsolar/__init__.py +++ b/components/pipsolar/__init__.py @@ -13,7 +13,7 @@ pipsolar_ns = cg.esphome_ns.namespace("pipsolar") PipsolarComponent = pipsolar_ns.class_("Pipsolar", cg.Component) -PIPSOLAR_COMPONENT_SCHEMA = cv.COMPONENT_SCHEMA.extend( +PIPSOLAR_COMPONENT_SCHEMA = cv.Schema( { cv.Required(CONF_PIPSOLAR_ID): cv.use_id(PipsolarComponent), } diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py index 2019f329..f4b34fd5 100644 --- a/components/pipsolar/binary_sensor/__init__.py +++ b/components/pipsolar/binary_sensor/__init__.py @@ -1,6 +1,7 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import binary_sensor + from .. import PIPSOLAR_COMPONENT_SCHEMA, CONF_PIPSOLAR_ID DEPENDENCIES = ["uart"] diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 1290e6ba..fa46426d 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -117,10 +117,12 @@ CONF_BATTERY_RATING_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_RECHARGE_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_UNDER_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, diff --git a/components/pipsolar/text_sensor/__init__.py b/components/pipsolar/text_sensor/__init__.py index 6be3f208..1977d7b5 100644 --- a/components/pipsolar/text_sensor/__init__.py +++ b/components/pipsolar/text_sensor/__init__.py @@ -39,7 +39,5 @@ async def to_code(config): for type in TYPES: if type in config: conf = config[type] - var = cg.new_Pvariable(conf[CONF_ID]) - await text_sensor.register_text_sensor(var, conf) - await cg.register_component(var, conf) + var = await text_sensor.new_text_sensor(conf) cg.add(getattr(paren, f"set_{type}")(var)) From 5bf8a53f76d57156f783a25cb369305d8f59a9bf Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 16 Nov 2022 20:29:56 +0100 Subject: [PATCH 016/114] Update __init__.py - Add unit of measurement and device class = volt for CONF_BATTERY_REDISCHARGE_VOLTAGE --- components/pipsolar/sensor/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index fa46426d..1b05dc06 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -174,7 +174,9 @@ accuracy_decimals=1, ), CONF_BATTERY_REDISCHARGE_VOLTAGE: sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, ), CONF_PV_OK_CONDITION_FOR_PARALLEL: sensor.sensor_schema( accuracy_decimals=1, From 0aabac373ae32fc37cc3ee005874b6b29a981b06 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Thu, 17 Nov 2022 21:58:03 +0100 Subject: [PATCH 017/114] Update __init__.py set CONF_CURRENT_MAX_CHARGING_CURRENT accuracy_decimals = 0 --- components/pipsolar/sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 1b05dc06..1c5c120e 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -149,7 +149,7 @@ ), CONF_CURRENT_MAX_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - accuracy_decimals=1, + accuracy_decimals=0, device_class=DEVICE_CLASS_CURRENT, ), CONF_INPUT_VOLTAGE_RANGE: sensor.sensor_schema( From 6fccdf264421d4b9d3f53910ed84a8c5b4690c6b Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 23 Nov 2022 21:27:38 +0100 Subject: [PATCH 018/114] Update __init__.py - Add charging_discharging_controls option for the PBATCD command (need to be tested) --- components/pipsolar/select/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 31bb3f0f..7b43645e 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -12,6 +12,7 @@ CONF_STATUSMAP = "statusmap" CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" +CONF_CHARGING_DISCHARGING_CONTROLS = "charging_discharging_controls" PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) @@ -73,6 +74,7 @@ def validator(value): TYPES = { CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), + CONF_CHARGING_DISCHARGING_CONTROLS: ("PBATCD111", None) } From c167c39d28728472243f92b77b9b298ecf220520 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 17:54:34 +0100 Subject: [PATCH 019/114] Update __init__.py --- components/pipsolar/select/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 7b43645e..1be09bbb 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -74,7 +74,7 @@ def validator(value): TYPES = { CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), - CONF_CHARGING_DISCHARGING_CONTROLS: ("PBATCD111", None) + CONF_CHARGING_DISCHARGING_CONTROLS: ("PBATCD111", None), } From 1df593ad919bcfdb705d096bfdef7e7f78922066 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 19:15:38 +0100 Subject: [PATCH 020/114] Update pipsolar.h -add charging_discharging_controls_select --- components/pipsolar/pipsolar.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 4d3202b2..8dba6099 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -191,6 +191,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SWITCH(pv_power_balance_switch, QPIRI) PIPSOLAR_SELECT(output_source_priority_select, QPIRI) + PIPSOLAR_SELECT(charging_discharging_controls_select, QPIRI) void switch_command(const std::string &command); void setup() override; From 2b410645a1290d8048f8c65c80f369e5118e7432 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 19:18:06 +0100 Subject: [PATCH 021/114] Update pipsolar.cpp - Add charging_discharging_controls select --- components/pipsolar/pipsolar.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 47ae3ec7..5ebfa995 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -129,6 +129,11 @@ void Pipsolar::loop() { if (this->output_source_priority_select_) { std::string value = esphome::to_string(value_output_source_priority_); this->output_source_priority_select_->map_and_publish(value); + } + // special for output source priority select + if (this->charging_discharging_controls_select_) { + std::string value = esphome::to_string(value_charging_discharging_controls_); + this->charging_discharging_controls_select_->map_and_publish(value); } // special for output source priority switches if (this->output_source_priority_utility_switch_) { From d7433323a658f2046cc31de2e6d5053c33f50fe0 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:02:43 +0100 Subject: [PATCH 022/114] Update __init__.py - Add QBATCD --- components/pipsolar/sensor/__init__.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 1c5c120e..eac53bde 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -78,6 +78,12 @@ CONF_PV2_INPUT_VOLTAGE = "pv2_input_voltage" CONF_PV2_CHARGING_POWER = "pv2_charging_power" +# QBATCD sensors + +CONF_DISCHARGE_ONOFF = "discharge_onoff" +CONF_DISCHARGE_WITH_STANDBY_ONOFF = "discharge_with_standby_onoff +COND_CHARGE_ONOFF = "charge_onoff" + TYPES = { CONF_GRID_RATING_VOLTAGE: sensor.sensor_schema( @@ -289,6 +295,15 @@ accuracy_decimals=1, device_class=DEVICE_CLASS_POWER, ), + CONF_DISCHARGE_ONOFF: sensor.sensor_schema( + accuracy_decimals=1, + ), + CONF_DISCHARGE_WITH_STANDBY_ONOFF: sensor.sensor_schema( + accuracy_decimals=1, + ), + CONF_CHARGE_ONOFF: sensor.sensor_schema( + accuracy_decimals=1, + ), } CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( From 8fe00077eee4c7245134b8fd65ecb26f436d2f7f Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:14:55 +0100 Subject: [PATCH 023/114] Update __init__.py --- components/pipsolar/sensor/__init__.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index eac53bde..0227b8b3 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -78,11 +78,6 @@ CONF_PV2_INPUT_VOLTAGE = "pv2_input_voltage" CONF_PV2_CHARGING_POWER = "pv2_charging_power" -# QBATCD sensors - -CONF_DISCHARGE_ONOFF = "discharge_onoff" -CONF_DISCHARGE_WITH_STANDBY_ONOFF = "discharge_with_standby_onoff -COND_CHARGE_ONOFF = "charge_onoff" TYPES = { From 68027646cf1fdad587d4379412ecbfe46734b18f Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:16:01 +0100 Subject: [PATCH 024/114] Update __init__.py --- components/pipsolar/binary_sensor/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py index f4b34fd5..96dbd3f3 100644 --- a/components/pipsolar/binary_sensor/__init__.py +++ b/components/pipsolar/binary_sensor/__init__.py @@ -68,6 +68,15 @@ ) CONF_WARNING_BATTERY_EQUALIZATION = "warning_battery_equalization" +# QBATCD sensors + +CONF_DISCHARGE_ONOFF = "discharge_onoff" +CONF_DISCHARGE_WITH_STANDBY_ONOFF = "discharge_with_standby_onoff +COND_CHARGE_ONOFF = "charge_onoff" + + + + TYPES = [ CONF_ADD_SBU_PRIORITY_VERSION, CONF_CONFIGURATION_STATUS, From 54d10057a8c2261f83cb3d05376af4941fcb5112 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:16:47 +0100 Subject: [PATCH 025/114] Update __init__.py --- components/pipsolar/sensor/__init__.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 0227b8b3..c7482dc4 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -290,15 +290,6 @@ accuracy_decimals=1, device_class=DEVICE_CLASS_POWER, ), - CONF_DISCHARGE_ONOFF: sensor.sensor_schema( - accuracy_decimals=1, - ), - CONF_DISCHARGE_WITH_STANDBY_ONOFF: sensor.sensor_schema( - accuracy_decimals=1, - ), - CONF_CHARGE_ONOFF: sensor.sensor_schema( - accuracy_decimals=1, - ), } CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( From 427634a7687d3f1b0d2358c999e1d925dbb8b6ce Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:18:52 +0100 Subject: [PATCH 026/114] Update __init__.py --- components/pipsolar/binary_sensor/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py index 96dbd3f3..1aa6631b 100644 --- a/components/pipsolar/binary_sensor/__init__.py +++ b/components/pipsolar/binary_sensor/__init__.py @@ -72,10 +72,7 @@ CONF_DISCHARGE_ONOFF = "discharge_onoff" CONF_DISCHARGE_WITH_STANDBY_ONOFF = "discharge_with_standby_onoff -COND_CHARGE_ONOFF = "charge_onoff" - - - +CONF_CHARGE_ONOFF = "charge_onoff" TYPES = [ CONF_ADD_SBU_PRIORITY_VERSION, @@ -134,6 +131,9 @@ CONF_WARNUNG_LOW_PV_ENERGY, CONF_WARNING_HIGH_AC_INPUT_DURING_BUS_SOFT_START, CONF_WARNING_BATTERY_EQUALIZATION, + CONF_DISCHARGE_ONOFF, + CONF_DISCHARGE_WITH_STANDBY_ONOFF, + COND_CHARGE_ONOFF, ] CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( From 4fc60468709068332d6764faeb0594e93c31be02 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:19:27 +0100 Subject: [PATCH 027/114] Update __init__.py --- components/pipsolar/binary_sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py index 1aa6631b..4bc60d08 100644 --- a/components/pipsolar/binary_sensor/__init__.py +++ b/components/pipsolar/binary_sensor/__init__.py @@ -68,7 +68,7 @@ ) CONF_WARNING_BATTERY_EQUALIZATION = "warning_battery_equalization" -# QBATCD sensors +# QBATCD binary sensors CONF_DISCHARGE_ONOFF = "discharge_onoff" CONF_DISCHARGE_WITH_STANDBY_ONOFF = "discharge_with_standby_onoff From cf88adc8ff6be49af97e73f5d11b4b3d38013031 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:21:47 +0100 Subject: [PATCH 028/114] Update pipsolar.h --- components/pipsolar/pipsolar.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 8dba6099..92b1fe4d 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -23,6 +23,7 @@ enum ENUMPollingCommand { POLLING_QPIWS = 5, POLLING_QT = 6, POLLING_QMN = 7, + POLLING_QBATCD = 8; }; struct PollingCommand { uint8_t *command; @@ -173,6 +174,12 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_BINARY_SENSOR(warnung_low_pv_energy, QPIWS, bool) PIPSOLAR_BINARY_SENSOR(warning_high_ac_input_during_bus_soft_start, QPIWS, bool) PIPSOLAR_BINARY_SENSOR(warning_battery_equalization, QPIWS, bool) + + // QBATCD values + PIPSOLAR_BINARY_SENSOR(warnings_present, QBATCD, bool) + PIPSOLAR_BINARY_SENSOR(faults_present, QBATCD, bool) + PIPSOLAR_BINARY_SENSOR(warning_power_loss, QBATCD, bool) + PIPSOLAR_TEXT_SENSOR(last_qpigs, QPIGS) PIPSOLAR_TEXT_SENSOR(last_qpigs2, QPIGS2) @@ -191,7 +198,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SWITCH(pv_power_balance_switch, QPIRI) PIPSOLAR_SELECT(output_source_priority_select, QPIRI) - PIPSOLAR_SELECT(charging_discharging_controls_select, QPIRI) + PIPSOLAR_SELECT(charging_discharging_controls_select, QBATCD) void switch_command(const std::string &command); void setup() override; From ded2d4c627540c04474e274ba1508c6e91d8a2ca Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:49:54 +0100 Subject: [PATCH 029/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 47 ++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 5ebfa995..e477e330 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -129,11 +129,6 @@ void Pipsolar::loop() { if (this->output_source_priority_select_) { std::string value = esphome::to_string(value_output_source_priority_); this->output_source_priority_select_->map_and_publish(value); - } - // special for output source priority select - if (this->charging_discharging_controls_select_) { - std::string value = esphome::to_string(value_charging_discharging_controls_); - this->charging_discharging_controls_select_->map_and_publish(value); } // special for output source priority switches if (this->output_source_priority_utility_switch_) { @@ -432,6 +427,24 @@ void Pipsolar::loop() { if (this->warning_battery_equalization_) { this->warning_battery_equalization_->publish_state(value_warning_battery_equalization_); } + this->state_ = STATE_IDLE; + break; + case POLLING_QBATCD: + if (this->discharge_onoff_) { + this->discharge_onoff_->publish_state(value_discharge_onoff_); + } + if (this->discharge_with_standby_onoff_) { + this->discharge_with_standby_onoff_->publish_state(value_discharge_with_standby_onoff_); + } + if (this-charge_onoff_) { + this->charge_onoff_->publish_state(value_charge_onoff_); + } + // special for output source priority select + if (this->charging_discharging_controls_select_) { + std::string value = esphome::to_string(value_charging_discharging_controls_); + this->charging_discharging_controls_select_->map_and_publish(value); + } + this->state_ = STATE_IDLE; break; case POLLING_QT: @@ -722,6 +735,30 @@ void Pipsolar::loop() { } this->state_ = STATE_POLL_DECODED; break; + case POLLING_QBATCD: + ESP_LOGD(TAG, "Decode QBACD"); + // '(000' + // iterate over all available flag (as not all models have all flags, but at least in the same order) + + for (size_t i = 1; i < strlen(tmp); i++) { + enabled = tmp[i] == '1'; + switch (i) { + case 1: + this->value_discharge_onoff_ = enabled; + break; + case 2: + this->value_discharge_with_standby_onoff_ = enabled; + break; + case 3: + this->value_charge_onoff_ = enabled + break; + } + } + if (this->last_qbatcd_) { + this->last_qbatcd_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; default: this->state_ = STATE_IDLE; break; From 8fe486c2ca968fd2543e1b8d3e920888fec82e02 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:52:07 +0100 Subject: [PATCH 030/114] Update __init__.py --- components/pipsolar/binary_sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py index 4bc60d08..05985503 100644 --- a/components/pipsolar/binary_sensor/__init__.py +++ b/components/pipsolar/binary_sensor/__init__.py @@ -71,7 +71,7 @@ # QBATCD binary sensors CONF_DISCHARGE_ONOFF = "discharge_onoff" -CONF_DISCHARGE_WITH_STANDBY_ONOFF = "discharge_with_standby_onoff +CONF_DISCHARGE_WITH_STANDBY_ONOFF = "discharge_with_standby_onoff" CONF_CHARGE_ONOFF = "charge_onoff" TYPES = [ From 9ac29f5f171bce8a93ed34233e0d1358b33ffe7e Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:53:00 +0100 Subject: [PATCH 031/114] Update __init__.py --- components/pipsolar/binary_sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py index 05985503..91e1a82b 100644 --- a/components/pipsolar/binary_sensor/__init__.py +++ b/components/pipsolar/binary_sensor/__init__.py @@ -133,7 +133,7 @@ CONF_WARNING_BATTERY_EQUALIZATION, CONF_DISCHARGE_ONOFF, CONF_DISCHARGE_WITH_STANDBY_ONOFF, - COND_CHARGE_ONOFF, + CONF_CHARGE_ONOFF, ] CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( From 2d0d0f5582c47a41e23fe76f56fe39afed36a87b Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 20:55:54 +0100 Subject: [PATCH 032/114] Update pipsolar.h --- components/pipsolar/pipsolar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 92b1fe4d..6346bdc1 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -23,7 +23,7 @@ enum ENUMPollingCommand { POLLING_QPIWS = 5, POLLING_QT = 6, POLLING_QMN = 7, - POLLING_QBATCD = 8; + POLLING_QBATCD = 8, }; struct PollingCommand { uint8_t *command; From 7d8a0f2b304a7e9ebf794d4226c6e591457f1feb Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 21:00:20 +0100 Subject: [PATCH 033/114] Update pipsolar.h --- components/pipsolar/pipsolar.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 6346bdc1..7fc93336 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -176,9 +176,9 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_BINARY_SENSOR(warning_battery_equalization, QPIWS, bool) // QBATCD values - PIPSOLAR_BINARY_SENSOR(warnings_present, QBATCD, bool) - PIPSOLAR_BINARY_SENSOR(faults_present, QBATCD, bool) - PIPSOLAR_BINARY_SENSOR(warning_power_loss, QBATCD, bool) + PIPSOLAR_BINARY_SENSOR(discharge_onoff, QBATCD, bool) + PIPSOLAR_BINARY_SENSOR(discharge_with_standby_onoff, QBATCD, bool) + PIPSOLAR_BINARY_SENSOR(charge_onoff, QBATCD, bool) PIPSOLAR_TEXT_SENSOR(last_qpigs, QPIGS) From c04fe4aa22008657b43a66835ebfd1034911b221 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 21:02:45 +0100 Subject: [PATCH 034/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index e477e330..966aa1a5 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -436,7 +436,7 @@ void Pipsolar::loop() { if (this->discharge_with_standby_onoff_) { this->discharge_with_standby_onoff_->publish_state(value_discharge_with_standby_onoff_); } - if (this-charge_onoff_) { + if (this->charge_onoff_) { this->charge_onoff_->publish_state(value_charge_onoff_); } // special for output source priority select From 7748ef91455f46fb79d9a130fd3ba54f8cbc1566 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 21:05:54 +0100 Subject: [PATCH 035/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 966aa1a5..2818443f 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -750,7 +750,7 @@ void Pipsolar::loop() { this->value_discharge_with_standby_onoff_ = enabled; break; case 3: - this->value_charge_onoff_ = enabled + this->value_charge_onoff_ = enabled; break; } } From 2aca0b5e41a580c10979b8f58535f1d4b24d2c8a Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 21:08:53 +0100 Subject: [PATCH 036/114] Update __init__.py --- components/pipsolar/text_sensor/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/pipsolar/text_sensor/__init__.py b/components/pipsolar/text_sensor/__init__.py index 1977d7b5..c4a7e024 100644 --- a/components/pipsolar/text_sensor/__init__.py +++ b/components/pipsolar/text_sensor/__init__.py @@ -15,6 +15,7 @@ CONF_LAST_QPIWS = "last_qpiws" CONF_LAST_QT = "last_qt" CONF_LAST_QMN = "last_qmn" +CONF_LAST_QBATCD = "last_qbatcd" TYPES = [ CONF_DEVICE_MODE, @@ -26,6 +27,7 @@ CONF_LAST_QPIWS, CONF_LAST_QT, CONF_LAST_QMN, + CONF_LAST_QBATCD, ] CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( From 7f6a2d1ed1be021a7311d8096ecd2bbffd4a56e1 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 21:29:32 +0100 Subject: [PATCH 037/114] Update pipsolar.h --- components/pipsolar/pipsolar.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 7fc93336..3f0f7220 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -189,6 +189,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_TEXT_SENSOR(last_qpiws, QPIWS) PIPSOLAR_TEXT_SENSOR(last_qt, QT) PIPSOLAR_TEXT_SENSOR(last_qmn, QMN) + PIPSOLAR_TEXT_SENSOR(last_qbatcd, QBATCD) PIPSOLAR_SWITCH(output_source_priority_utility_switch, QPIRI) PIPSOLAR_SWITCH(output_source_priority_solar_switch, QPIRI) From 9a6657f0715b1a8b6c8fc2ffb5f7ff1faa2729d5 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sat, 26 Nov 2022 21:41:56 +0100 Subject: [PATCH 038/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 2818443f..94c390e3 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -440,10 +440,12 @@ void Pipsolar::loop() { this->charge_onoff_->publish_state(value_charge_onoff_); } // special for output source priority select + /* if (this->charging_discharging_controls_select_) { std::string value = esphome::to_string(value_charging_discharging_controls_); this->charging_discharging_controls_select_->map_and_publish(value); } + */ this->state_ = STATE_IDLE; break; From b12c3aa5fba1bb36358c973d61f5259764590211 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sun, 27 Nov 2022 13:23:37 +0100 Subject: [PATCH 039/114] Introduce PIPSOLAR_VALUED_SELECT --- .gitignore | 2 +- components/pipsolar/pipsolar.cpp | 18 ++++++++---------- components/pipsolar/pipsolar.h | 7 ++++--- components/pipsolar/select/__init__.py | 4 ++-- components/pipsolar/sensor/__init__.py | 1 - esp8266-example.yaml | 24 ++++++++++++++++++++++++ 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index dd71e158..862848c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .idea/ -secret.yaml +secrets.yaml .esphome/ **/.pioenvs/ **/.piolibdeps/ diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 94c390e3..305207b6 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -439,14 +439,10 @@ void Pipsolar::loop() { if (this->charge_onoff_) { this->charge_onoff_->publish_state(value_charge_onoff_); } - // special for output source priority select - /* - if (this->charging_discharging_controls_select_) { - std::string value = esphome::to_string(value_charging_discharging_controls_); - this->charging_discharging_controls_select_->map_and_publish(value); + if (this->charging_discharging_control_select_) { + this->charging_discharging_control_select_->map_and_publish(value_charging_discharging_control_select_); } - */ - + this->state_ = STATE_IDLE; break; case POLLING_QT: @@ -738,10 +734,10 @@ void Pipsolar::loop() { this->state_ = STATE_POLL_DECODED; break; case POLLING_QBATCD: - ESP_LOGD(TAG, "Decode QBACD"); + ESP_LOGD(TAG, "Decode QBATCD"); // '(000' // iterate over all available flag (as not all models have all flags, but at least in the same order) - + for (size_t i = 1; i < strlen(tmp); i++) { enabled = tmp[i] == '1'; switch (i) { @@ -753,9 +749,11 @@ void Pipsolar::loop() { break; case 3: this->value_charge_onoff_ = enabled; - break; + break; } } + this->value_charging_discharging_control_select_ = tmp; + if (this->last_qbatcd_) { this->last_qbatcd_->publish_state(tmp); } diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 3f0f7220..56a95363 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -51,6 +51,8 @@ struct PollingCommand { PIPSOLAR_VALUED_ENTITY_(sensor::Sensor, name, polling_command, value_type) #define PIPSOLAR_SWITCH(name, polling_command) PIPSOLAR_ENTITY_(switch_::Switch, name, polling_command) #define PIPSOLAR_SELECT(name, polling_command) PIPSOLAR_ENTITY_(pipsolar::PipsolarSelect, name, polling_command) +#define PIPSOLAR_VALUED_SELECT(name, polling_command, value_type) \ + PIPSOLAR_VALUED_ENTITY_(pipsolar::PipsolarSelect, name, polling_command, value_type) #define PIPSOLAR_BINARY_SENSOR(name, polling_command, value_type) \ PIPSOLAR_VALUED_ENTITY_(binary_sensor::BinarySensor, name, polling_command, value_type) #define PIPSOLAR_VALUED_TEXT_SENSOR(name, polling_command, value_type) \ @@ -174,13 +176,12 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_BINARY_SENSOR(warnung_low_pv_energy, QPIWS, bool) PIPSOLAR_BINARY_SENSOR(warning_high_ac_input_during_bus_soft_start, QPIWS, bool) PIPSOLAR_BINARY_SENSOR(warning_battery_equalization, QPIWS, bool) - + // QBATCD values PIPSOLAR_BINARY_SENSOR(discharge_onoff, QBATCD, bool) PIPSOLAR_BINARY_SENSOR(discharge_with_standby_onoff, QBATCD, bool) PIPSOLAR_BINARY_SENSOR(charge_onoff, QBATCD, bool) - PIPSOLAR_TEXT_SENSOR(last_qpigs, QPIGS) PIPSOLAR_TEXT_SENSOR(last_qpigs2, QPIGS2) PIPSOLAR_TEXT_SENSOR(last_qpiri, QPIRI) @@ -199,7 +200,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SWITCH(pv_power_balance_switch, QPIRI) PIPSOLAR_SELECT(output_source_priority_select, QPIRI) - PIPSOLAR_SELECT(charging_discharging_controls_select, QBATCD) + PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); void setup() override; diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 1be09bbb..14bb8659 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -12,7 +12,7 @@ CONF_STATUSMAP = "statusmap" CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" -CONF_CHARGING_DISCHARGING_CONTROLS = "charging_discharging_controls" +CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) @@ -74,7 +74,7 @@ def validator(value): TYPES = { CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), - CONF_CHARGING_DISCHARGING_CONTROLS: ("PBATCD111", None), + CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), } diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index c7482dc4..1c5c120e 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -79,7 +79,6 @@ CONF_PV2_CHARGING_POWER = "pv2_charging_power" - TYPES = { CONF_GRID_RATING_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, diff --git a/esp8266-example.yaml b/esp8266-example.yaml index 084aa2d1..e9b559a8 100644 --- a/esp8266-example.yaml +++ b/esp8266-example.yaml @@ -237,3 +237,27 @@ select: "0": "Utility first" "1": "Solar only" "2": "Solar Battery Utility" + + - platform: pipsolar + pipsolar_id: inverter0 + charging_discharging_control: + # See MAX_Communication_Protocol_20200526.pdf page 18 + name: "${name} charging discharging control" + optionsmap: + "111": "PBATCD111" + "011": "PBATCD011" + "101": "PBATCD101" + "110": "PBATCD110" + "010": "PBATCD010" + "100": "PBATCD100" + "001": "PBATCD001" + "000": "PBATCD000" + statusmap: + "111": "111" + "011": "011" + "101": "101" + "110": "110" + "010": "010" + "100": "100" + "001": "001" + "000": "000" From 6fd253aed18c6ca80e3dc7f3eb9830ee15736293 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sun, 27 Nov 2022 13:26:44 +0100 Subject: [PATCH 040/114] Clean-up --- components/pipsolar/pipsolar.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 305207b6..9dd3395f 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -442,7 +442,6 @@ void Pipsolar::loop() { if (this->charging_discharging_control_select_) { this->charging_discharging_control_select_->map_and_publish(value_charging_discharging_control_select_); } - this->state_ = STATE_IDLE; break; case POLLING_QT: @@ -736,8 +735,6 @@ void Pipsolar::loop() { case POLLING_QBATCD: ESP_LOGD(TAG, "Decode QBATCD"); // '(000' - // iterate over all available flag (as not all models have all flags, but at least in the same order) - for (size_t i = 1; i < strlen(tmp); i++) { enabled = tmp[i] == '1'; switch (i) { From 6ce382db0a49bb296ce4bccc9048d6c15a846058 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sun, 27 Nov 2022 13:49:46 +0100 Subject: [PATCH 041/114] Add new select entity --- esp32-example.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/esp32-example.yaml b/esp32-example.yaml index e3eabf33..d723c5e4 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -237,3 +237,27 @@ select: "0": "Utility first" "1": "Solar only" "2": "Solar Battery Utility" + + - platform: pipsolar + pipsolar_id: inverter0 + charging_discharging_control: + # See MAX_Communication_Protocol_20200526.pdf page 18 + name: "${name} charging discharging control" + optionsmap: + "111": "PBATCD111" + "011": "PBATCD011" + "101": "PBATCD101" + "110": "PBATCD110" + "010": "PBATCD010" + "100": "PBATCD100" + "001": "PBATCD001" + "000": "PBATCD000" + statusmap: + "111": "111" + "011": "011" + "101": "101" + "110": "110" + "010": "010" + "100": "100" + "001": "001" + "000": "000" From 1ebc89f5a3e956b3fc1489b141a11e60ae35d2da Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 10:31:24 +0100 Subject: [PATCH 042/114] Update __init__.py - Change CONF_CURRENT_MAX_AC_CHARGING_CURRENT accuracy_decimal to 0 according to manual [2,10,20,30,40,50,60,70,80,90,100,110,120] --- components/pipsolar/sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 1c5c120e..60d65e28 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -144,7 +144,7 @@ ), CONF_CURRENT_MAX_AC_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - accuracy_decimals=1, + accuracy_decimals=0, device_class=DEVICE_CLASS_CURRENT, ), CONF_CURRENT_MAX_CHARGING_CURRENT: sensor.sensor_schema( From 24874ec645dcb1544c56d6555b73618861363454 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 11:52:12 +0100 Subject: [PATCH 043/114] Update __init__.py - Change CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC0%03.0f"), --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index 85141fa1..2994e3a3 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -55,7 +55,7 @@ ), CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20], "MUCHGC0%02.0f"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC0%03.0f"), CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), From 784c83d9f8c25bb2a5e8bc190852f3bb9c7aa311 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 11:59:20 +0100 Subject: [PATCH 044/114] Update __init__.py --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index 2994e3a3..9a5cd75c 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -55,7 +55,7 @@ ), CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC0%03.0f"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0f"), CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), From 38d09226437a7da5417ed08b7bc0fa3565c0cad0 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 12:14:22 +0100 Subject: [PATCH 045/114] Update __init__.py - Change to MCHGC%03.0f as proposed in https://github.com/syssi/esphome-pipsolar/issues/41 --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index 9a5cd75c..088c41a1 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -55,7 +55,7 @@ ), CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0f"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MCHGC%03.0f"), CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), From 1f33fcf002c2d24556d15784835e9d181d34a831 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 12:20:54 +0100 Subject: [PATCH 046/114] Update __init__.py - revert to "MUCHGC" --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index 088c41a1..ee09788b 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -55,7 +55,7 @@ ), CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MCHGC%03.0f"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0"), CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), From 642a1cdea6c190ac4cb1dbb2f24194f720463e0a Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 12:25:36 +0100 Subject: [PATCH 047/114] Update __init__.py --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index ee09788b..9a5cd75c 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -55,7 +55,7 @@ ), CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0f"), CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), From 35c48d532cab21cec3666000d3d9da53474259f9 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 12:51:52 +0100 Subject: [PATCH 048/114] Update __init__.py --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index 9a5cd75c..bda8fe13 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -55,7 +55,7 @@ ), CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0f"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90], "MUCHGC0%02.0f"), CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), From aec1edb089e9a6143df7dfa3032e3ab445015cfb Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 12:56:16 +0100 Subject: [PATCH 049/114] Update __init__.py --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index bda8fe13..9a5cd75c 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -55,7 +55,7 @@ ), CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90], "MUCHGC0%02.0f"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0f"), CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), From 1946c88e5d7fecb5f29d0ef9093fb0486dc2caa6 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 13:06:14 +0100 Subject: [PATCH 050/114] Update pipsolar_output.cpp - Increase buffer and precision display in debug --- components/pipsolar/output/pipsolar_output.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/output/pipsolar_output.cpp b/components/pipsolar/output/pipsolar_output.cpp index b843f1f3..b06abe20 100644 --- a/components/pipsolar/output/pipsolar_output.cpp +++ b/components/pipsolar/output/pipsolar_output.cpp @@ -8,11 +8,11 @@ namespace pipsolar { static const char *const TAG = "pipsolar.output"; void PipsolarOutput::write_state(float state) { - char tmp[10]; + char tmp[11]; sprintf(tmp, this->set_command_.c_str(), state); if (std::find(this->possible_values_.begin(), this->possible_values_.end(), state) != this->possible_values_.end()) { - ESP_LOGD(TAG, "Will write: %s out of value %f / %02.0f", tmp, state, state); + ESP_LOGD(TAG, "Will write: %s out of value %f / %03.0f", tmp, state, state); this->parent_->switch_command(std::string(tmp)); } else { ESP_LOGD(TAG, "Will not write: %s as it is not in list of allowed values", tmp); From 73cc84492f28f1be7be29c6cfe1d3554ee1d5c78 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 13:10:41 +0100 Subject: [PATCH 051/114] Update pipsolar_output.cpp - Increase tmp buffer size --- components/pipsolar/output/pipsolar_output.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/pipsolar_output.cpp b/components/pipsolar/output/pipsolar_output.cpp index b06abe20..adec2096 100644 --- a/components/pipsolar/output/pipsolar_output.cpp +++ b/components/pipsolar/output/pipsolar_output.cpp @@ -8,7 +8,7 @@ namespace pipsolar { static const char *const TAG = "pipsolar.output"; void PipsolarOutput::write_state(float state) { - char tmp[11]; + char tmp[12]; sprintf(tmp, this->set_command_.c_str(), state); if (std::find(this->possible_values_.begin(), this->possible_values_.end(), state) != this->possible_values_.end()) { From 155e4e193ee5b60defd721752f2a881893b32a06 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 18:23:50 +0100 Subject: [PATCH 052/114] Update __init__.py - Add PCPnn select option --- components/pipsolar/select/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 14bb8659..f31ed651 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -12,6 +12,7 @@ CONF_STATUSMAP = "statusmap" CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" +CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) @@ -74,6 +75,7 @@ def validator(value): TYPES = { CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), + CONF_CHARGER_SOURCE_PRIORITY: ("PCP00", None), CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), } From 212c97e4b51b1a0effcf004b80c8130c5802dcdf Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 18:29:36 +0100 Subject: [PATCH 053/114] Update pipsolar.h - Add PIPSOLAR_SELECT(output_charger_priority_select, QPIRI) --- components/pipsolar/pipsolar.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 56a95363..53748dc9 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -200,6 +200,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SWITCH(pv_power_balance_switch, QPIRI) PIPSOLAR_SELECT(output_source_priority_select, QPIRI) + PIPSOLAR_SELECT(output_charger_priority_select, QPIRI) PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); From df29f92ff98eecf19650eb436ac70c777c26077e Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 18:55:06 +0100 Subject: [PATCH 054/114] Update __init__.py - PCP02 by default --- components/pipsolar/select/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index f31ed651..8b76e75b 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -75,7 +75,7 @@ def validator(value): TYPES = { CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), - CONF_CHARGER_SOURCE_PRIORITY: ("PCP00", None), + CONF_CHARGER_SOURCE_PRIORITY: ("PCP02", None), CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), } From 76f46b030239b799dd79471d7c3be3b4819194c7 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:05:47 +0100 Subject: [PATCH 055/114] Update pipsolar.cpp - Add select map_and_publish for charger_source_priority --- components/pipsolar/pipsolar.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 9dd3395f..29ed9f92 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -143,6 +143,11 @@ void Pipsolar::loop() { if (this->charger_source_priority_) { this->charger_source_priority_->publish_state(value_charger_source_priority_); } + // special for output source priority select + if (this->charger_source_priority_select_) { + std::string value = esphome::to_string(value_charger_source_priority_); + this->output_charger_priority_select_->map_and_publish(value); + } if (this->parallel_max_num_) { this->parallel_max_num_->publish_state(value_parallel_max_num_); } From 02ecaeb60fc433ea6b0d3d078c0626b65f6b4f84 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:07:22 +0100 Subject: [PATCH 056/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 29ed9f92..ef83d551 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -146,7 +146,7 @@ void Pipsolar::loop() { // special for output source priority select if (this->charger_source_priority_select_) { std::string value = esphome::to_string(value_charger_source_priority_); - this->output_charger_priority_select_->map_and_publish(value); + this->charger_priority_select_->map_and_publish(value); } if (this->parallel_max_num_) { this->parallel_max_num_->publish_state(value_parallel_max_num_); From 3f6d96d169ebafac1dfe7c03687dfd2cd51a06a5 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:11:52 +0100 Subject: [PATCH 057/114] Update pipsolar.cpp typo --- components/pipsolar/pipsolar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index ef83d551..d89ae21c 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -143,11 +143,13 @@ void Pipsolar::loop() { if (this->charger_source_priority_) { this->charger_source_priority_->publish_state(value_charger_source_priority_); } - // special for output source priority select + // special for charger source priority select if (this->charger_source_priority_select_) { std::string value = esphome::to_string(value_charger_source_priority_); this->charger_priority_select_->map_and_publish(value); } + + if (this->parallel_max_num_) { this->parallel_max_num_->publish_state(value_parallel_max_num_); } From beef4956e76bdcc449be068cb255f941ddefaaa1 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:12:59 +0100 Subject: [PATCH 058/114] Update pipsolar.h - Fix select for charger_source_priority --- components/pipsolar/pipsolar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 53748dc9..4dd4ba99 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -200,7 +200,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SWITCH(pv_power_balance_switch, QPIRI) PIPSOLAR_SELECT(output_source_priority_select, QPIRI) - PIPSOLAR_SELECT(output_charger_priority_select, QPIRI) + PIPSOLAR_SELECT(charger_priority_select, QPIRI) PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); From 9497bfdba8d906ae28216059f44bb9ad3bc7ed89 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:14:24 +0100 Subject: [PATCH 059/114] Update pipsolar.h --- components/pipsolar/pipsolar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 4dd4ba99..f7ee7d2d 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -200,7 +200,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SWITCH(pv_power_balance_switch, QPIRI) PIPSOLAR_SELECT(output_source_priority_select, QPIRI) - PIPSOLAR_SELECT(charger_priority_select, QPIRI) + PIPSOLAR_SELECT(charger_source_priority_select, QPIRI) PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); From a845e7cabc1cd983b81016b02f0daa8a07a263c5 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:18:45 +0100 Subject: [PATCH 060/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index d89ae21c..22c8fcce 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -146,7 +146,7 @@ void Pipsolar::loop() { // special for charger source priority select if (this->charger_source_priority_select_) { std::string value = esphome::to_string(value_charger_source_priority_); - this->charger_priority_select_->map_and_publish(value); + this->charger_source_priority_select_->map_and_publish(value); } From 5e822d0ae34500cd35acc6b20c14f6f90fe0ce86 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:31:05 +0100 Subject: [PATCH 061/114] Update __init__.py - Change CONF_CHARGER_SOURCE_PRIORITY accuracy_decimal to 0 --- components/pipsolar/sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 60d65e28..23d4502e 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -159,7 +159,7 @@ accuracy_decimals=1, ), CONF_CHARGER_SOURCE_PRIORITY: sensor.sensor_schema( - accuracy_decimals=1, + accuracy_decimals=0, ), CONF_PARALLEL_MAX_NUM: sensor.sensor_schema( accuracy_decimals=1, From 87071f6e31e1eb9fd7794ed0f6e6e782a5d8cb53 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:33:45 +0100 Subject: [PATCH 062/114] Update __init__.py - Change charger_source_priority to PCP03 by default --- components/pipsolar/select/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 8b76e75b..9df003bd 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -75,7 +75,7 @@ def validator(value): TYPES = { CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), - CONF_CHARGER_SOURCE_PRIORITY: ("PCP02", None), + CONF_CHARGER_SOURCE_PRIORITY: ("PCP03", None), CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), } From e89d229159fa255e80b77f0d9af7055d4f0f3823 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 19:37:40 +0100 Subject: [PATCH 063/114] Update __init__.py - Change CONF_BATTERY_TYPE accuracy_decimal = 0 --- components/pipsolar/sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 23d4502e..2015b90d 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -140,7 +140,7 @@ device_class=DEVICE_CLASS_VOLTAGE, ), CONF_BATTERY_TYPE: sensor.sensor_schema( - accuracy_decimals=1, + accuracy_decimals=0, ), CONF_CURRENT_MAX_AC_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, From 76a590ec4dd5a362f1d602002b3c1072b85cfd3d Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 20:17:39 +0100 Subject: [PATCH 064/114] Update __init__.py - Mofify CONF_CURRENT_MAX_CHARGING_CURRENT to outup up to 120A (3 digits) --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index 9a5cd75c..3a3eee7d 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -56,7 +56,7 @@ CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0f"), - CONF_CURRENT_MAX_CHARGING_CURRENT: ([10, 20, 30, 40], "MCHGC0%02.0f"), + CONF_CURRENT_MAX_CHARGING_CURRENT: ([ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 ], "MCHGC%03.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), CONF_BATTERY_REDISCHARGE_VOLTAGE: ( From e308e108a668a5c870e863ca66ff9a7c33f63fb2 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 20:29:49 +0100 Subject: [PATCH 065/114] Update __init__.py - Upgrade CONF_CURRENT_MAX_CHARGING_CURRENT to accept up to 120A charging value --- components/pipsolar/output/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index 3a3eee7d..aa354f6a 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -79,7 +79,6 @@ } ) - async def to_code(config): paren = await cg.get_variable(config[CONF_PIPSOLAR_ID]) From dd8dfcada2012d25ef21202e0852ac0886c05558 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 20:36:01 +0100 Subject: [PATCH 066/114] Update __init__.py - CONF_OUTPUT_SOURCE_PRIORITY accuracy_decimals to 0 --- components/pipsolar/sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 2015b90d..e3f0e72d 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -156,7 +156,7 @@ accuracy_decimals=1, ), CONF_OUTPUT_SOURCE_PRIORITY: sensor.sensor_schema( - accuracy_decimals=1, + accuracy_decimals=0, ), CONF_CHARGER_SOURCE_PRIORITY: sensor.sensor_schema( accuracy_decimals=0, From a4d9578ac73bd34da2ae75663433a2acfaefd56e Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 20:44:39 +0100 Subject: [PATCH 067/114] Update __init__.py - Change ICON_CURRENT_DC for max_charging and max_ac_charging --- components/pipsolar/sensor/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index e3f0e72d..f5ced573 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -144,11 +144,13 @@ ), CONF_CURRENT_MAX_AC_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, + icon=ICON_CURRENT_DC, accuracy_decimals=0, device_class=DEVICE_CLASS_CURRENT, ), CONF_CURRENT_MAX_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, + icon=ICON_CURRENT_DC, accuracy_decimals=0, device_class=DEVICE_CLASS_CURRENT, ), From 78c07cce10d14d5ff491821ff171a787c55f7855 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 20:45:19 +0100 Subject: [PATCH 068/114] Update __init__.py --- components/pipsolar/sensor/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index f5ced573..1232e9dc 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -9,6 +9,7 @@ DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_VOLTAGE, ICON_CURRENT_AC, + ICON_CURRENT_DC, UNIT_AMPERE, UNIT_CELSIUS, UNIT_HERTZ, From 5065958b79eb7cbb5aa6e95f3f0e4c92b0ca49f8 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 20:48:29 +0100 Subject: [PATCH 069/114] Update __init__.py - Revert back ICON_CURRENT_AC --- components/pipsolar/sensor/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index 1232e9dc..e3f0e72d 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -9,7 +9,6 @@ DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_VOLTAGE, ICON_CURRENT_AC, - ICON_CURRENT_DC, UNIT_AMPERE, UNIT_CELSIUS, UNIT_HERTZ, @@ -145,13 +144,11 @@ ), CONF_CURRENT_MAX_AC_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_CURRENT_DC, accuracy_decimals=0, device_class=DEVICE_CLASS_CURRENT, ), CONF_CURRENT_MAX_CHARGING_CURRENT: sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - icon=ICON_CURRENT_DC, accuracy_decimals=0, device_class=DEVICE_CLASS_CURRENT, ), From 12620a0a716d21bcac23970dbd7c1c5fe7a843c1 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Sun, 8 Jan 2023 21:20:46 +0100 Subject: [PATCH 070/114] Update __init__.py - Change some accuracy_decimals to 0 --- components/pipsolar/sensor/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/sensor/__init__.py b/components/pipsolar/sensor/__init__.py index e3f0e72d..9cd4ade6 100644 --- a/components/pipsolar/sensor/__init__.py +++ b/components/pipsolar/sensor/__init__.py @@ -162,16 +162,16 @@ accuracy_decimals=0, ), CONF_PARALLEL_MAX_NUM: sensor.sensor_schema( - accuracy_decimals=1, + accuracy_decimals=0, ), CONF_MACHINE_TYPE: sensor.sensor_schema( - accuracy_decimals=1, + accuracy_decimals=0, ), CONF_TOPOLOGY: sensor.sensor_schema( - accuracy_decimals=1, + accuracy_decimals=0, ), CONF_OUTPUT_MODE: sensor.sensor_schema( - accuracy_decimals=1, + accuracy_decimals=0, ), CONF_BATTERY_REDISCHARGE_VOLTAGE: sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, From 043138db78bc5921ef72bce3c20f7ca4ea1b32c3 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 13:48:25 +0100 Subject: [PATCH 071/114] Update __init__.py --- components/pipsolar/output/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/__init__.py b/components/pipsolar/output/__init__.py index aa354f6a..161a7f09 100644 --- a/components/pipsolar/output/__init__.py +++ b/components/pipsolar/output/__init__.py @@ -55,7 +55,7 @@ ), CONF_BATTERY_FLOAT_VOLTAGE: ([48.0, 49.0, 50.0, 51.0], "PBFT%02.1f"), CONF_BATTERY_TYPE: ([0, 1, 2], "PBT%02.0f"), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%03.0f"), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ([2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120], "MUCHGC%04.0f"), CONF_CURRENT_MAX_CHARGING_CURRENT: ([ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 ], "MCHGC%03.0f"), CONF_OUTPUT_SOURCE_PRIORITY: ([0, 1, 2], "POP%02.0f"), CONF_CHARGER_SOURCE_PRIORITY: ([0, 1, 2, 3], "PCP%02.0f"), From 0029290755d737588b07eaaaaa8091d9bf66c185 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 13:48:49 +0100 Subject: [PATCH 072/114] Update pipsolar_output.cpp --- components/pipsolar/output/pipsolar_output.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/pipsolar_output.cpp b/components/pipsolar/output/pipsolar_output.cpp index adec2096..f5bab644 100644 --- a/components/pipsolar/output/pipsolar_output.cpp +++ b/components/pipsolar/output/pipsolar_output.cpp @@ -8,7 +8,7 @@ namespace pipsolar { static const char *const TAG = "pipsolar.output"; void PipsolarOutput::write_state(float state) { - char tmp[12]; + char tmp[10]; sprintf(tmp, this->set_command_.c_str(), state); if (std::find(this->possible_values_.begin(), this->possible_values_.end(), state) != this->possible_values_.end()) { From f9d9ad747a9ae610a29e6895ff938e14a200f74e Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 13:52:56 +0100 Subject: [PATCH 073/114] Update pipsolar_output.cpp --- components/pipsolar/output/pipsolar_output.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/output/pipsolar_output.cpp b/components/pipsolar/output/pipsolar_output.cpp index f5bab644..adec2096 100644 --- a/components/pipsolar/output/pipsolar_output.cpp +++ b/components/pipsolar/output/pipsolar_output.cpp @@ -8,7 +8,7 @@ namespace pipsolar { static const char *const TAG = "pipsolar.output"; void PipsolarOutput::write_state(float state) { - char tmp[10]; + char tmp[12]; sprintf(tmp, this->set_command_.c_str(), state); if (std::find(this->possible_values_.begin(), this->possible_values_.end(), state) != this->possible_values_.end()) { From 22f89e03eb14b92caf7c10a9201ba86d6051e5bd Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 16:18:29 +0100 Subject: [PATCH 074/114] Update __init__.py - Add new current_max_ac_charging_current and current_max_charging_current select options --- components/pipsolar/select/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 9df003bd..763a1348 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -14,6 +14,9 @@ CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" +CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" +CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" + PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) @@ -77,6 +80,8 @@ def validator(value): CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), CONF_CHARGER_SOURCE_PRIORITY: ("PCP03", None), CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), + CONF_CURRENT_MAX_CHARGING_CURRENT: ("MCHGC010", None), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ("MUCHGC0002", None), } From 18867d2bbb22c2002be46e117e9273b75253261f Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 16:25:26 +0100 Subject: [PATCH 075/114] Update pipsolar.cpp - Add current_max_ac_charging_current and current_max_charging_current parts --- components/pipsolar/pipsolar.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 22c8fcce..0e5bc67e 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -112,9 +112,19 @@ void Pipsolar::loop() { if (this->current_max_ac_charging_current_) { this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); } + // select for current_max_ac_charging_current + if (this-value_current_max_ac_charging_current_) { + std::string value = esphome::to_string(value_current_max_ac_charging_current_); + this->value_current_max_ac_charging_current_->map_and_publish(value); + } if (this->current_max_charging_current_) { this->current_max_charging_current_->publish_state(value_current_max_charging_current_); } + // select for current_max_charging_current + if (this-value_current_max_charging_current_) { + std::string value = esphome::to_string(value_current_max_charging_current_); + this->value_current_max_charging_current_->map_and_publish(value); + } if (this->input_voltage_range_) { this->input_voltage_range_->publish_state(value_input_voltage_range_); } From 5d1f502ca7d17ab1933a497b0d71c239432c5038 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 16:27:20 +0100 Subject: [PATCH 076/114] Update pipsolar.h - Add current_max_ac_charging_current and current_max_charging_current parts --- components/pipsolar/pipsolar.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index f7ee7d2d..8fe762ad 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -201,6 +201,8 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SELECT(output_source_priority_select, QPIRI) PIPSOLAR_SELECT(charger_source_priority_select, QPIRI) + PIPSOLAR_SELECT(current_max_ac_charging_current, QPIRI) + PIPSOLAR_SELECT(current_max_charging_current, QPIRI) PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); From a3fb3210a42e02df20f885f8ed0d0d318dcfd4c6 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:12:10 +0100 Subject: [PATCH 077/114] Update __init__.py - Change CONF names --- components/pipsolar/select/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 763a1348..6ae2f910 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -14,8 +14,8 @@ CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" -CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" -CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" +CONF_CURRENT_MAX_CHARGING_CURRENT_SELECT = "current_max_charging_current" +CONF_CURRENT_MAX_AC_CHARGING_CURRENT_SELECT = "current_max_ac_charging_current" PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) @@ -80,8 +80,8 @@ def validator(value): CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), CONF_CHARGER_SOURCE_PRIORITY: ("PCP03", None), CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), - CONF_CURRENT_MAX_CHARGING_CURRENT: ("MCHGC010", None), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ("MUCHGC0002", None), + CONF_CURRENT_MAX_CHARGING_CURRENT_SELECT: ("MCHGC010", None), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT_SELECT: ("MUCHGC0002", None), } From f34d371896b7c1afcf66910e7dd3b07109158bde Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:13:47 +0100 Subject: [PATCH 078/114] Update __init__.py --- components/pipsolar/select/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 6ae2f910..97ddff2b 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -14,8 +14,8 @@ CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" -CONF_CURRENT_MAX_CHARGING_CURRENT_SELECT = "current_max_charging_current" -CONF_CURRENT_MAX_AC_CHARGING_CURRENT_SELECT = "current_max_ac_charging_current" +CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current_select" +CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) @@ -80,8 +80,8 @@ def validator(value): CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), CONF_CHARGER_SOURCE_PRIORITY: ("PCP03", None), CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), - CONF_CURRENT_MAX_CHARGING_CURRENT_SELECT: ("MCHGC010", None), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT_SELECT: ("MUCHGC0002", None), + CONF_CURRENT_MAX_CHARGING_CURRENT: ("MCHGC010", None), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ("MUCHGC0002", None), } From 00ca45d4b5ba950bd435d03cef7e9b942f71d956 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:15:38 +0100 Subject: [PATCH 079/114] Update pipsolar.h --- components/pipsolar/pipsolar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 8fe762ad..f46a7ff1 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -201,8 +201,8 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SELECT(output_source_priority_select, QPIRI) PIPSOLAR_SELECT(charger_source_priority_select, QPIRI) - PIPSOLAR_SELECT(current_max_ac_charging_current, QPIRI) - PIPSOLAR_SELECT(current_max_charging_current, QPIRI) + PIPSOLAR_SELECT(current_max_ac_charging_current_select, QPIRI) + PIPSOLAR_SELECT(current_max_charging_current_select, QPIRI) PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); From 9e3f26e189902b1ac631154f4928f38d847cfa75 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:17:30 +0100 Subject: [PATCH 080/114] Update pipsolar.cpp -forger _select_ suffix --- components/pipsolar/pipsolar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 0e5bc67e..547be551 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -113,17 +113,17 @@ void Pipsolar::loop() { this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); } // select for current_max_ac_charging_current - if (this-value_current_max_ac_charging_current_) { + if (this-value_current_max_ac_charging_current_select_) { std::string value = esphome::to_string(value_current_max_ac_charging_current_); - this->value_current_max_ac_charging_current_->map_and_publish(value); + this->value_current_max_ac_charging_current_select_->map_and_publish(value); } if (this->current_max_charging_current_) { this->current_max_charging_current_->publish_state(value_current_max_charging_current_); } // select for current_max_charging_current - if (this-value_current_max_charging_current_) { + if (this-value_current_max_charging_current_select_) { std::string value = esphome::to_string(value_current_max_charging_current_); - this->value_current_max_charging_current_->map_and_publish(value); + this->value_current_max_charging_current_select_->map_and_publish(value); } if (this->input_voltage_range_) { this->input_voltage_range_->publish_state(value_input_voltage_range_); From 23470118db723edcbe6133274cfdf7699aec54f6 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:19:16 +0100 Subject: [PATCH 081/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 547be551..7563c699 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -113,17 +113,17 @@ void Pipsolar::loop() { this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); } // select for current_max_ac_charging_current - if (this-value_current_max_ac_charging_current_select_) { + if (this-current_max_ac_charging_current_select_) { std::string value = esphome::to_string(value_current_max_ac_charging_current_); - this->value_current_max_ac_charging_current_select_->map_and_publish(value); + this->current_max_ac_charging_current_select_->map_and_publish(value); } if (this->current_max_charging_current_) { this->current_max_charging_current_->publish_state(value_current_max_charging_current_); } // select for current_max_charging_current - if (this-value_current_max_charging_current_select_) { + if (this-current_max_charging_current_select_) { std::string value = esphome::to_string(value_current_max_charging_current_); - this->value_current_max_charging_current_select_->map_and_publish(value); + this->current_max_charging_current_select_->map_and_publish(value); } if (this->input_voltage_range_) { this->input_voltage_range_->publish_state(value_input_voltage_range_); From a9e343d6293c759a07a7aaad2a046dc8a9681e38 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:27:35 +0100 Subject: [PATCH 082/114] Update __init__.py --- components/pipsolar/select/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 97ddff2b..763a1348 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -14,7 +14,7 @@ CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" -CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current_select" +CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" From 333efac36323f962456e5499c4914968d50c817e Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:43:26 +0100 Subject: [PATCH 083/114] Update pipsolar.h Use PIPSOLAR_VALUED_SELECT instead of PIPSOLAR_SELECT --- components/pipsolar/pipsolar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index f46a7ff1..df84fe86 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -201,8 +201,8 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SELECT(output_source_priority_select, QPIRI) PIPSOLAR_SELECT(charger_source_priority_select, QPIRI) - PIPSOLAR_SELECT(current_max_ac_charging_current_select, QPIRI) - PIPSOLAR_SELECT(current_max_charging_current_select, QPIRI) + PIPSOLAR_VALUED_SELECT(current_max_ac_charging_current_select, MUCHGC, std::string) + PIPSOLAR_VALUED_SELECT(current_max_charging_current_select, MCHGC, std::string) PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); From 8b0d08208742a6e7c0cfc672f56d3c28bbdd2484 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:54:23 +0100 Subject: [PATCH 084/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 7563c699..8a6e0179 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -491,6 +491,8 @@ void Pipsolar::loop() { if (this->last_qpiri_) { this->last_qpiri_->publish_state(tmp); } + this-current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; + this-current_max_charging_current_select_ = value_current_max_charging_current_; this->state_ = STATE_POLL_DECODED; break; case POLLING_QPIGS: From 113c49237d41664359cdf518d3f4383104899b5d Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 17:59:22 +0100 Subject: [PATCH 085/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 8a6e0179..99a0664b 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -491,8 +491,8 @@ void Pipsolar::loop() { if (this->last_qpiri_) { this->last_qpiri_->publish_state(tmp); } - this-current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; - this-current_max_charging_current_select_ = value_current_max_charging_current_; + this-value_current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; + this-value_current_max_charging_current_select_ = value_current_max_charging_current_; this->state_ = STATE_POLL_DECODED; break; case POLLING_QPIGS: From d8b94f3d4dc137d583fdbabc625c79fce2b75c9f Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:07:09 +0100 Subject: [PATCH 086/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 99a0664b..e38f0d28 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -112,19 +112,29 @@ void Pipsolar::loop() { if (this->current_max_ac_charging_current_) { this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); } - // select for current_max_ac_charging_current + /* select for current_max_ac_charging_current if (this-current_max_ac_charging_current_select_) { std::string value = esphome::to_string(value_current_max_ac_charging_current_); this->current_max_ac_charging_current_select_->map_and_publish(value); } + */ + if (this->>current_max_ac_charging_current_select_) { + this->>current_max_ac_charging_current_select_->map_and_publish(value_>current_max_ac_charging_current_select_); + } + + if (this->current_max_charging_current_) { this->current_max_charging_current_->publish_state(value_current_max_charging_current_); } - // select for current_max_charging_current + /* select for current_max_charging_current if (this-current_max_charging_current_select_) { std::string value = esphome::to_string(value_current_max_charging_current_); this->current_max_charging_current_select_->map_and_publish(value); } + */ + if (this->>current_max_charging_current_select_) { + this->>current_max_charging_current_select_->map_and_publish(value_>current_max_charging_current_select_); + } if (this->input_voltage_range_) { this->input_voltage_range_->publish_state(value_input_voltage_range_); } From 8df95b17df7a8ba749f92ab3307d06792894df38 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:43:40 +0100 Subject: [PATCH 087/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 48 +++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index e38f0d28..6bd387e6 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -471,6 +471,24 @@ void Pipsolar::loop() { } this->state_ = STATE_IDLE; break; + case POLLING_MUCHGC: + if (this->current_max_ac_charging_current_) { + this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); + } + if (this->current_max_ac_charging_current_select_) { + this->current_max_ac_charging_current_select_->map_and_publish(value_current_max_ac_charging_current_select_); + } + this->state_ = STATE_IDLE; + break; + case POLLING_MCHGC: + if (this->current_max_charging_current_) { + this->current_max_charging_current_->publish_state(value_current_max_charging_current_); + } + if (this->current_max_charging_current_select_) { + this->current_max_charging_current_select_->map_and_publish(value_current_max_charging_current_select_); + } + this->state_ = STATE_IDLE; + break; case POLLING_QT: case POLLING_QMN: this->state_ = STATE_IDLE; @@ -501,8 +519,10 @@ void Pipsolar::loop() { if (this->last_qpiri_) { this->last_qpiri_->publish_state(tmp); } + /* this-value_current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; this-value_current_max_charging_current_select_ = value_current_max_charging_current_; + */ this->state_ = STATE_POLL_DECODED; break; case POLLING_QPIGS: @@ -779,12 +799,38 @@ void Pipsolar::loop() { } } this->value_charging_discharging_control_select_ = tmp; - if (this->last_qbatcd_) { this->last_qbatcd_->publish_state(tmp); } this->state_ = STATE_POLL_DECODED; break; + + case POLLING_MUCHGC: + ESP_LOGD(TAG, "Decode MUCHGC"); + sscanf( // NOLINT + tmp, // NOLINT + "(%d", // NOLINT + &value_current_max_ac_charging_current_); // NOLINT + this->value_current_max_ac_charging_current_select = value_current_max_ac_charging_current_; + if (this->last_muchgc_) { + this->last_muchgc_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + + case POLLING_MCHGC: + ESP_LOGD(TAG, "Decode MCHGC"); + sscanf( // NOLINT + tmp, // NOLINT + "(%d", // NOLINT + &value_current_max_charging_current_); // NOLINT + this->value_current_max_charging_current_select = value_current_max_charging_current_; + if (this->last_mchgc_) { + this->last_mchgc_->publish_state(tmp); + } + this->state_ = STATE_POLL_DECODED; + break; + default: this->state_ = STATE_IDLE; break; From 91b920ce7e9318a878e6b85571199d353557ccd2 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:45:29 +0100 Subject: [PATCH 088/114] Update __init__.py --- components/pipsolar/text_sensor/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/pipsolar/text_sensor/__init__.py b/components/pipsolar/text_sensor/__init__.py index c4a7e024..ddfdfd88 100644 --- a/components/pipsolar/text_sensor/__init__.py +++ b/components/pipsolar/text_sensor/__init__.py @@ -16,6 +16,8 @@ CONF_LAST_QT = "last_qt" CONF_LAST_QMN = "last_qmn" CONF_LAST_QBATCD = "last_qbatcd" +CONF_LAST_MUCHGC = "last_muchgc" +CONF_LAST_MCHGC = "last_mchgc" TYPES = [ CONF_DEVICE_MODE, @@ -28,6 +30,8 @@ CONF_LAST_QT, CONF_LAST_QMN, CONF_LAST_QBATCD, + CONF_LAST_MUCHGC, + CONF_LAST_MCHGC, ] CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( From ca740f1bb4c8c35865ac1b3c066ee7a5a04c201d Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:49:09 +0100 Subject: [PATCH 089/114] Update pipsolar.cpp - Comment --- components/pipsolar/pipsolar.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 6bd387e6..2cd37241 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -471,6 +471,7 @@ void Pipsolar::loop() { } this->state_ = STATE_IDLE; break; +/* case POLLING_MUCHGC: if (this->current_max_ac_charging_current_) { this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); @@ -488,7 +489,8 @@ void Pipsolar::loop() { this->current_max_charging_current_select_->map_and_publish(value_current_max_charging_current_select_); } this->state_ = STATE_IDLE; - break; + break; +*/ case POLLING_QT: case POLLING_QMN: this->state_ = STATE_IDLE; @@ -804,7 +806,7 @@ void Pipsolar::loop() { } this->state_ = STATE_POLL_DECODED; break; - +/* case POLLING_MUCHGC: ESP_LOGD(TAG, "Decode MUCHGC"); sscanf( // NOLINT @@ -830,7 +832,7 @@ void Pipsolar::loop() { } this->state_ = STATE_POLL_DECODED; break; - + */ default: this->state_ = STATE_IDLE; break; From 4da2a8b1567da54d75c40b225dc45ec78be0a53e Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:51:16 +0100 Subject: [PATCH 090/114] Update pipsolar.h -Revert --- components/pipsolar/pipsolar.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index df84fe86..afb9494d 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -201,8 +201,12 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SELECT(output_source_priority_select, QPIRI) PIPSOLAR_SELECT(charger_source_priority_select, QPIRI) + /* + PIPSOLAR_SELECT(current_max_ac_charging_current_select, QPIRI) + PIPSOLAR_SELECT(current_max_charging_current_select, QPIRI) PIPSOLAR_VALUED_SELECT(current_max_ac_charging_current_select, MUCHGC, std::string) PIPSOLAR_VALUED_SELECT(current_max_charging_current_select, MCHGC, std::string) + */ PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); From ad7625bcddcc42232071bb2e8c2e96949eb02a75 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:52:26 +0100 Subject: [PATCH 091/114] Update pipsolar.h --- components/pipsolar/pipsolar.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index afb9494d..96adf18c 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -24,6 +24,10 @@ enum ENUMPollingCommand { POLLING_QT = 6, POLLING_QMN = 7, POLLING_QBATCD = 8, +/* + POLLING_MUCHGC = 9; + POLLING_MCHGC = 10; +*/ }; struct PollingCommand { uint8_t *command; From d8053eaa914de1e54b14501d0888cbea4c40a700 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:53:25 +0100 Subject: [PATCH 092/114] Update __init__.py --- components/pipsolar/text_sensor/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/text_sensor/__init__.py b/components/pipsolar/text_sensor/__init__.py index ddfdfd88..23a6c926 100644 --- a/components/pipsolar/text_sensor/__init__.py +++ b/components/pipsolar/text_sensor/__init__.py @@ -16,8 +16,8 @@ CONF_LAST_QT = "last_qt" CONF_LAST_QMN = "last_qmn" CONF_LAST_QBATCD = "last_qbatcd" -CONF_LAST_MUCHGC = "last_muchgc" -CONF_LAST_MCHGC = "last_mchgc" +#CONF_LAST_MUCHGC = "last_muchgc" +#CONF_LAST_MCHGC = "last_mchgc" TYPES = [ CONF_DEVICE_MODE, @@ -30,8 +30,8 @@ CONF_LAST_QT, CONF_LAST_QMN, CONF_LAST_QBATCD, - CONF_LAST_MUCHGC, - CONF_LAST_MCHGC, +# CONF_LAST_MUCHGC, +# CONF_LAST_MCHGC, ] CONFIG_SCHEMA = PIPSOLAR_COMPONENT_SCHEMA.extend( From 1869cc4f5a2f6200b272fb16db7211cb3aa7ba55 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:54:17 +0100 Subject: [PATCH 093/114] Update __init__.py --- components/pipsolar/select/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 763a1348..f61a09f0 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -14,8 +14,9 @@ CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" -CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" -CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" + +#CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" +#CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) @@ -80,8 +81,8 @@ def validator(value): CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), CONF_CHARGER_SOURCE_PRIORITY: ("PCP03", None), CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), - CONF_CURRENT_MAX_CHARGING_CURRENT: ("MCHGC010", None), - CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ("MUCHGC0002", None), +# CONF_CURRENT_MAX_CHARGING_CURRENT: ("MCHGC010", None), +# CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ("MUCHGC0002", None), } From 9490dea9e50189deacf7c6c9ba0c912e5a184a23 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 18:57:05 +0100 Subject: [PATCH 094/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 2cd37241..1592f31c 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -118,10 +118,11 @@ void Pipsolar::loop() { this->current_max_ac_charging_current_select_->map_and_publish(value); } */ + /* if (this->>current_max_ac_charging_current_select_) { this->>current_max_ac_charging_current_select_->map_and_publish(value_>current_max_ac_charging_current_select_); } - + */ if (this->current_max_charging_current_) { this->current_max_charging_current_->publish_state(value_current_max_charging_current_); @@ -132,9 +133,11 @@ void Pipsolar::loop() { this->current_max_charging_current_select_->map_and_publish(value); } */ + /* if (this->>current_max_charging_current_select_) { this->>current_max_charging_current_select_->map_and_publish(value_>current_max_charging_current_select_); } + */ if (this->input_voltage_range_) { this->input_voltage_range_->publish_state(value_input_voltage_range_); } From 3a0e13a44fbe9b2dd72211b2d60997e0fab6bd6a Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:18:24 +0100 Subject: [PATCH 095/114] Update pipsolar.h --- components/pipsolar/pipsolar.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index 96adf18c..c7eef4d9 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -205,9 +205,10 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SELECT(output_source_priority_select, QPIRI) PIPSOLAR_SELECT(charger_source_priority_select, QPIRI) - /* + PIPSOLAR_SELECT(current_max_ac_charging_current_select, QPIRI) PIPSOLAR_SELECT(current_max_charging_current_select, QPIRI) + /* PIPSOLAR_VALUED_SELECT(current_max_ac_charging_current_select, MUCHGC, std::string) PIPSOLAR_VALUED_SELECT(current_max_charging_current_select, MCHGC, std::string) */ From 859100df0ebf35c99554b92e167f45131ef51a61 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:19:01 +0100 Subject: [PATCH 096/114] Update __init__.py --- components/pipsolar/select/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index f61a09f0..8f28c640 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -15,8 +15,8 @@ CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" -#CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" -#CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" +CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" +CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" PipsolarSelect = pipsolar_ns.class_("PipsolarSelect", cg.Component, select.Select) @@ -81,8 +81,8 @@ def validator(value): CONF_OUTPUT_SOURCE_PRIORITY: ("POP00", None), CONF_CHARGER_SOURCE_PRIORITY: ("PCP03", None), CONF_CHARGING_DISCHARGING_CONTROL: ("PBATCD111", None), -# CONF_CURRENT_MAX_CHARGING_CURRENT: ("MCHGC010", None), -# CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ("MUCHGC0002", None), + CONF_CURRENT_MAX_CHARGING_CURRENT: ("MCHGC010", None), + CONF_CURRENT_MAX_AC_CHARGING_CURRENT: ("MUCHGC0002", None), } From 5bf037293b3ce43765cc3b20eb50b7177ee51b44 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:21:38 +0100 Subject: [PATCH 097/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index 1592f31c..ff05d2ab 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -112,12 +112,12 @@ void Pipsolar::loop() { if (this->current_max_ac_charging_current_) { this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); } - /* select for current_max_ac_charging_current + // select for current_max_ac_charging_current if (this-current_max_ac_charging_current_select_) { std::string value = esphome::to_string(value_current_max_ac_charging_current_); this->current_max_ac_charging_current_select_->map_and_publish(value); } - */ + /* if (this->>current_max_ac_charging_current_select_) { this->>current_max_ac_charging_current_select_->map_and_publish(value_>current_max_ac_charging_current_select_); @@ -127,12 +127,12 @@ void Pipsolar::loop() { if (this->current_max_charging_current_) { this->current_max_charging_current_->publish_state(value_current_max_charging_current_); } - /* select for current_max_charging_current + //select for current_max_charging_current if (this-current_max_charging_current_select_) { std::string value = esphome::to_string(value_current_max_charging_current_); this->current_max_charging_current_select_->map_and_publish(value); } - */ + /* if (this->>current_max_charging_current_select_) { this->>current_max_charging_current_select_->map_and_publish(value_>current_max_charging_current_select_); @@ -524,10 +524,10 @@ void Pipsolar::loop() { if (this->last_qpiri_) { this->last_qpiri_->publish_state(tmp); } - /* + this-value_current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; this-value_current_max_charging_current_select_ = value_current_max_charging_current_; - */ + this->state_ = STATE_POLL_DECODED; break; case POLLING_QPIGS: From 2fca5ae4eccb25b6bf6de414269c7597c85d2b07 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:34:45 +0100 Subject: [PATCH 098/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index ff05d2ab..fabc10ed 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -113,7 +113,7 @@ void Pipsolar::loop() { this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); } // select for current_max_ac_charging_current - if (this-current_max_ac_charging_current_select_) { + if (this->current_max_ac_charging_current_select_) { std::string value = esphome::to_string(value_current_max_ac_charging_current_); this->current_max_ac_charging_current_select_->map_and_publish(value); } @@ -128,7 +128,7 @@ void Pipsolar::loop() { this->current_max_charging_current_->publish_state(value_current_max_charging_current_); } //select for current_max_charging_current - if (this-current_max_charging_current_select_) { + if (this->current_max_charging_current_select_) { std::string value = esphome::to_string(value_current_max_charging_current_); this->current_max_charging_current_select_->map_and_publish(value); } From 0151c141e439640bbeaefcbf7f149beee198000a Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:36:48 +0100 Subject: [PATCH 099/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index fabc10ed..b997b588 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -525,8 +525,8 @@ void Pipsolar::loop() { this->last_qpiri_->publish_state(tmp); } - this-value_current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; - this-value_current_max_charging_current_select_ = value_current_max_charging_current_; + this->value_current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; + this->value_current_max_charging_current_select_ = value_current_max_charging_current_; this->state_ = STATE_POLL_DECODED; break; From fb1a6a958b2277a4da16004f11e3bac1e5b36489 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:39:16 +0100 Subject: [PATCH 100/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index b997b588..f1f36217 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -525,8 +525,8 @@ void Pipsolar::loop() { this->last_qpiri_->publish_state(tmp); } - this->value_current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; - this->value_current_max_charging_current_select_ = value_current_max_charging_current_; + this->current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; + this->current_max_charging_current_select_ = value_current_max_charging_current_; this->state_ = STATE_POLL_DECODED; break; From c50ff7e640bb6b50d08ef5692199ae16ddedeab1 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:40:59 +0100 Subject: [PATCH 101/114] Update pipsolar.cpp --- components/pipsolar/pipsolar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index f1f36217..c4cc3103 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -524,10 +524,10 @@ void Pipsolar::loop() { if (this->last_qpiri_) { this->last_qpiri_->publish_state(tmp); } - + /* this->current_max_ac_charging_current_select_ = value_current_max_ac_charging_current_; this->current_max_charging_current_select_ = value_current_max_charging_current_; - + */ this->state_ = STATE_POLL_DECODED; break; case POLLING_QPIGS: From 33ddbc8dc6c6413a5be93ecf2818ddcd4f61c9c9 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:49:40 +0100 Subject: [PATCH 102/114] Update __init__.py - Add CURRENT_MAX_AC_CHARGING_CURRENT & CURRENT_MAX_CHARGING_CURRENT --- components/pipsolar/select/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/components/pipsolar/select/__init__.py b/components/pipsolar/select/__init__.py index 8f28c640..763a1348 100644 --- a/components/pipsolar/select/__init__.py +++ b/components/pipsolar/select/__init__.py @@ -14,7 +14,6 @@ CONF_OUTPUT_SOURCE_PRIORITY = "output_source_priority" CONF_CHARGER_SOURCE_PRIORITY = "charger_source_priority" CONF_CHARGING_DISCHARGING_CONTROL = "charging_discharging_control" - CONF_CURRENT_MAX_CHARGING_CURRENT = "current_max_charging_current" CONF_CURRENT_MAX_AC_CHARGING_CURRENT = "current_max_ac_charging_current" From 9c39018f3660220a69218ebf2c70b4c4707b7b93 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:50:45 +0100 Subject: [PATCH 103/114] Update __init__.py - Clean up different attempts --- components/pipsolar/text_sensor/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/pipsolar/text_sensor/__init__.py b/components/pipsolar/text_sensor/__init__.py index 23a6c926..afcae4b2 100644 --- a/components/pipsolar/text_sensor/__init__.py +++ b/components/pipsolar/text_sensor/__init__.py @@ -16,8 +16,6 @@ CONF_LAST_QT = "last_qt" CONF_LAST_QMN = "last_qmn" CONF_LAST_QBATCD = "last_qbatcd" -#CONF_LAST_MUCHGC = "last_muchgc" -#CONF_LAST_MCHGC = "last_mchgc" TYPES = [ CONF_DEVICE_MODE, From 6e0ecf8ae8269155098d7523f3ea45eb00b290a6 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:52:44 +0100 Subject: [PATCH 104/114] Update pipsolar.cpp - Clearn up --- components/pipsolar/pipsolar.cpp | 63 +------------------------------- 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/components/pipsolar/pipsolar.cpp b/components/pipsolar/pipsolar.cpp index c4cc3103..a69cb2f3 100644 --- a/components/pipsolar/pipsolar.cpp +++ b/components/pipsolar/pipsolar.cpp @@ -118,12 +118,6 @@ void Pipsolar::loop() { this->current_max_ac_charging_current_select_->map_and_publish(value); } - /* - if (this->>current_max_ac_charging_current_select_) { - this->>current_max_ac_charging_current_select_->map_and_publish(value_>current_max_ac_charging_current_select_); - } - */ - if (this->current_max_charging_current_) { this->current_max_charging_current_->publish_state(value_current_max_charging_current_); } @@ -132,12 +126,7 @@ void Pipsolar::loop() { std::string value = esphome::to_string(value_current_max_charging_current_); this->current_max_charging_current_select_->map_and_publish(value); } - - /* - if (this->>current_max_charging_current_select_) { - this->>current_max_charging_current_select_->map_and_publish(value_>current_max_charging_current_select_); - } - */ + if (this->input_voltage_range_) { this->input_voltage_range_->publish_state(value_input_voltage_range_); } @@ -172,7 +161,6 @@ void Pipsolar::loop() { this->charger_source_priority_select_->map_and_publish(value); } - if (this->parallel_max_num_) { this->parallel_max_num_->publish_state(value_parallel_max_num_); } @@ -473,27 +461,7 @@ void Pipsolar::loop() { this->charging_discharging_control_select_->map_and_publish(value_charging_discharging_control_select_); } this->state_ = STATE_IDLE; - break; -/* - case POLLING_MUCHGC: - if (this->current_max_ac_charging_current_) { - this->current_max_ac_charging_current_->publish_state(value_current_max_ac_charging_current_); - } - if (this->current_max_ac_charging_current_select_) { - this->current_max_ac_charging_current_select_->map_and_publish(value_current_max_ac_charging_current_select_); - } - this->state_ = STATE_IDLE; - break; - case POLLING_MCHGC: - if (this->current_max_charging_current_) { - this->current_max_charging_current_->publish_state(value_current_max_charging_current_); - } - if (this->current_max_charging_current_select_) { - this->current_max_charging_current_select_->map_and_publish(value_current_max_charging_current_select_); - } - this->state_ = STATE_IDLE; - break; -*/ + break; case POLLING_QT: case POLLING_QMN: this->state_ = STATE_IDLE; @@ -809,33 +777,6 @@ void Pipsolar::loop() { } this->state_ = STATE_POLL_DECODED; break; -/* - case POLLING_MUCHGC: - ESP_LOGD(TAG, "Decode MUCHGC"); - sscanf( // NOLINT - tmp, // NOLINT - "(%d", // NOLINT - &value_current_max_ac_charging_current_); // NOLINT - this->value_current_max_ac_charging_current_select = value_current_max_ac_charging_current_; - if (this->last_muchgc_) { - this->last_muchgc_->publish_state(tmp); - } - this->state_ = STATE_POLL_DECODED; - break; - - case POLLING_MCHGC: - ESP_LOGD(TAG, "Decode MCHGC"); - sscanf( // NOLINT - tmp, // NOLINT - "(%d", // NOLINT - &value_current_max_charging_current_); // NOLINT - this->value_current_max_charging_current_select = value_current_max_charging_current_; - if (this->last_mchgc_) { - this->last_mchgc_->publish_state(tmp); - } - this->state_ = STATE_POLL_DECODED; - break; - */ default: this->state_ = STATE_IDLE; break; From b559657eb31df657553154b2902f62bec4cb40d7 Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 19:53:59 +0100 Subject: [PATCH 105/114] Update pipsolar.h - Clean up --- components/pipsolar/pipsolar.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index c7eef4d9..ef8d83de 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -24,10 +24,6 @@ enum ENUMPollingCommand { POLLING_QT = 6, POLLING_QMN = 7, POLLING_QBATCD = 8, -/* - POLLING_MUCHGC = 9; - POLLING_MCHGC = 10; -*/ }; struct PollingCommand { uint8_t *command; @@ -208,10 +204,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { PIPSOLAR_SELECT(current_max_ac_charging_current_select, QPIRI) PIPSOLAR_SELECT(current_max_charging_current_select, QPIRI) - /* - PIPSOLAR_VALUED_SELECT(current_max_ac_charging_current_select, MUCHGC, std::string) - PIPSOLAR_VALUED_SELECT(current_max_charging_current_select, MCHGC, std::string) - */ + PIPSOLAR_VALUED_SELECT(charging_discharging_control_select, QBATCD, std::string) void switch_command(const std::string &command); From 8249f59e0829bc18e367a74a1fa6ce1bda159cfa Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 20:55:26 +0100 Subject: [PATCH 106/114] Update esp32-example.yaml - Add new selects --- esp32-example.yaml | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/esp32-example.yaml b/esp32-example.yaml index d723c5e4..ce4b84d2 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -261,3 +261,82 @@ select: "100": "100" "001": "001" "000": "000" + + - platform: pipsolar + pipsolar_id: inverter0 + charger_source_priority: + name: ${name} charger_source_priority_select + optionsmap: +# "Utility first": "PCP00" + "Solar first": "PCP01" + "Solar and utility": "PCP02" + "Solar charging only": "PCP03" + statusmap: + # "0": "Utility first" + "1": "Solar first" + "2": "Solar and utility" + "3": "Solar charging only" + + - platform: pipsolar + pipsolar_id: inverter0 + current_max_ac_charging_current: + name: ${name} current_max_ac_charging_current_select + optionsmap: + "2A": "MUCHGC0002" + "10A": "MUCHGC0010" + "20A": "MUCHGC0020" + "30A": "MUCHGC0030" + "40A": "MUCHGC0040" + "50A": "MUCHGC0050" + "60A": "MUCHGC0060" + "70A": "MUCHGC0070" + "80A": "MUCHGC0080" + "90A": "MUCHGC0090" + "100A": "MUCHGC0100" + "110A": "MUCHGC0110" + "120A": "MUCHGC0120" + statusmap: + "2": "2A" + "10": "10A" + "20": "20A" + "30": "30A" + "40": "40A" + "50": "50A" + "60": "60A" + "70": "70A" + "80": "80A" + "90": "90A" + "100": "100A" + "110": "110A" + "120": "120A" + + - platform: pipsolar + pipsolar_id: inverter0 + current_max_charging_current: + name: ${name} current_max_charging_current_select + optionsmap: + "10A": "MCHGC010" + "20A": "MCHGC020" + "30A": "MCHGC030" + "40A": "MCHGC040" + "50A": "MCHGC050" + "60A": "MCHGC060" + "70A": "MCHGC070" + "80A": "MCHGC080" + "90A": "MCHGC090" + "100A": "MCHGC100" + "110A": "MCHGC110" + "120A": "MCHGC120" + statusmap: + "10": "10A" + "20": "20A" + "30": "30A" + "40": "40A" + "50": "50A" + "60": "60A" + "70": "70A" + "80": "80A" + "90": "90A" + "100": "100A" + "110": "110A" + "120": "120A" From 4fe65b803698b531d972fd083081435a7a0bdd1c Mon Sep 17 00:00:00 2001 From: SeByDocKy Date: Wed, 11 Jan 2023 20:57:03 +0100 Subject: [PATCH 107/114] Update esp8266-example.yaml - Add new selects --- esp8266-example.yaml | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/esp8266-example.yaml b/esp8266-example.yaml index e9b559a8..0b3c1a30 100644 --- a/esp8266-example.yaml +++ b/esp8266-example.yaml @@ -261,3 +261,82 @@ select: "100": "100" "001": "001" "000": "000" + + - platform: pipsolar + pipsolar_id: inverter0 + charger_source_priority: + name: ${name} charger_source_priority_select + optionsmap: +# "Utility first": "PCP00" + "Solar first": "PCP01" + "Solar and utility": "PCP02" + "Solar charging only": "PCP03" + statusmap: + # "0": "Utility first" + "1": "Solar first" + "2": "Solar and utility" + "3": "Solar charging only" + + - platform: pipsolar + pipsolar_id: inverter0 + current_max_ac_charging_current: + name: ${name} current_max_ac_charging_current_select + optionsmap: + "2A": "MUCHGC0002" + "10A": "MUCHGC0010" + "20A": "MUCHGC0020" + "30A": "MUCHGC0030" + "40A": "MUCHGC0040" + "50A": "MUCHGC0050" + "60A": "MUCHGC0060" + "70A": "MUCHGC0070" + "80A": "MUCHGC0080" + "90A": "MUCHGC0090" + "100A": "MUCHGC0100" + "110A": "MUCHGC0110" + "120A": "MUCHGC0120" + statusmap: + "2": "2A" + "10": "10A" + "20": "20A" + "30": "30A" + "40": "40A" + "50": "50A" + "60": "60A" + "70": "70A" + "80": "80A" + "90": "90A" + "100": "100A" + "110": "110A" + "120": "120A" + + - platform: pipsolar + pipsolar_id: inverter0 + current_max_charging_current: + name: ${name} current_max_charging_current_select + optionsmap: + "10A": "MCHGC010" + "20A": "MCHGC020" + "30A": "MCHGC030" + "40A": "MCHGC040" + "50A": "MCHGC050" + "60A": "MCHGC060" + "70A": "MCHGC070" + "80A": "MCHGC080" + "90A": "MCHGC090" + "100A": "MCHGC100" + "110A": "MCHGC110" + "120A": "MCHGC120" + statusmap: + "10": "10A" + "20": "20A" + "30": "30A" + "40": "40A" + "50": "50A" + "60": "60A" + "70": "70A" + "80": "80A" + "90": "90A" + "100": "100A" + "110": "110A" + "120": "120A" From c8ef854d7b914d4d0131c32154870751efb3953f Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Thu, 2 Feb 2023 08:33:52 +0100 Subject: [PATCH 108/114] Fix yamllint issues --- esp32-example.yaml | 8 ++++---- esp8266-example.yaml | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/esp32-example.yaml b/esp32-example.yaml index ce4b84d2..f9da8e71 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -299,7 +299,7 @@ select: "2": "2A" "10": "10A" "20": "20A" - "30": "30A" + "30": "30A" "40": "40A" "50": "50A" "60": "60A" @@ -312,7 +312,7 @@ select: - platform: pipsolar pipsolar_id: inverter0 - current_max_charging_current: + current_max_charging_current: name: ${name} current_max_charging_current_select optionsmap: "10A": "MCHGC010" @@ -330,7 +330,7 @@ select: statusmap: "10": "10A" "20": "20A" - "30": "30A" + "30": "30A" "40": "40A" "50": "50A" "60": "60A" @@ -339,4 +339,4 @@ select: "90": "90A" "100": "100A" "110": "110A" - "120": "120A" + "120": "120A" diff --git a/esp8266-example.yaml b/esp8266-example.yaml index 0b3c1a30..0d11df47 100644 --- a/esp8266-example.yaml +++ b/esp8266-example.yaml @@ -261,7 +261,7 @@ select: "100": "100" "001": "001" "000": "000" - + - platform: pipsolar pipsolar_id: inverter0 charger_source_priority: @@ -299,7 +299,7 @@ select: "2": "2A" "10": "10A" "20": "20A" - "30": "30A" + "30": "30A" "40": "40A" "50": "50A" "60": "60A" @@ -312,7 +312,7 @@ select: - platform: pipsolar pipsolar_id: inverter0 - current_max_charging_current: + current_max_charging_current: name: ${name} current_max_charging_current_select optionsmap: "10A": "MCHGC010" @@ -330,7 +330,7 @@ select: statusmap: "10": "10A" "20": "20A" - "30": "30A" + "30": "30A" "40": "40A" "50": "50A" "60": "60A" @@ -339,4 +339,4 @@ select: "90": "90A" "100": "100A" "110": "110A" - "120": "120A" + "120": "120A" From 02d293c889e96d10a28516f1d726ad14fc58ba65 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sun, 26 Feb 2023 10:31:22 +0100 Subject: [PATCH 109/114] Support long QPIGS responses --- components/pipsolar/pipsolar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/pipsolar/pipsolar.h b/components/pipsolar/pipsolar.h index ef8d83de..36e198a4 100644 --- a/components/pipsolar/pipsolar.h +++ b/components/pipsolar/pipsolar.h @@ -215,7 +215,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent { protected: friend class PipsolarSelect; - static const size_t PIPSOLAR_READ_BUFFER_LENGTH = 110; // maximum supported answer length + static const size_t PIPSOLAR_READ_BUFFER_LENGTH = 130; // maximum supported answer length static const size_t COMMAND_QUEUE_LENGTH = 10; static const size_t COMMAND_TIMEOUT = 5000; uint32_t last_poll_ = 0; From e1146449ad581724518fcb929e6932cb2aecdfbe Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 30 Mar 2024 11:54:53 +0100 Subject: [PATCH 110/114] Prefer ESP-IDF framework over arduino --- esp32-example.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/esp32-example.yaml b/esp32-example.yaml index f9da8e71..cd750705 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -11,8 +11,11 @@ substitutions: esphome: name: ${name} - platform: ESP32 - board: esp-wrover-kit + +esp32: + board: wemos_d1_mini32 + framework: + type: esp-idf external_components: - source: github://syssi/esphome-pipsolar@pip8048 From 1348d7740cdef91bb8cfaaf0635dba24dbeffaea Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 30 Mar 2024 13:34:10 +0100 Subject: [PATCH 111/114] Rename uart0 to uart_0 This change is required by ESPHome 2023.4.0 See https://github.com/esphome/esphome/pull/4446 --- esp32-example.yaml | 4 ++-- esp8266-example.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/esp32-example.yaml b/esp32-example.yaml index cd750705..f8b32477 100644 --- a/esp32-example.yaml +++ b/esp32-example.yaml @@ -37,13 +37,13 @@ mqtt: id: mqtt_client uart: - - id: uart0 + - id: uart_0 baud_rate: 2400 tx_pin: GPIO1 rx_pin: GPIO3 pipsolar: - uart_id: uart0 + uart_id: uart_0 id: inverter0 sensor: diff --git a/esp8266-example.yaml b/esp8266-example.yaml index 0d11df47..a5b7317c 100644 --- a/esp8266-example.yaml +++ b/esp8266-example.yaml @@ -34,13 +34,13 @@ mqtt: id: mqtt_client uart: - id: uart0 + id: uart_0 baud_rate: 2400 tx_pin: GPIO1 rx_pin: GPIO3 pipsolar: - uart_id: uart0 + uart_id: uart_0 id: inverter0 sensor: From f8f925b8c3977a999424fc00de28356b9e6c8857 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 30 Mar 2024 13:40:44 +0100 Subject: [PATCH 112/114] Fix CI --- .github/workflows/ci.yaml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 549a26ce..8443d814 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,10 +24,10 @@ jobs: steps: - name: ⤵️ Check out configuration from GitHub uses: actions/checkout@v2 - - name: Setup Python 3.8 + - name: Setup Python 3.9 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.9 - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel @@ -37,10 +37,16 @@ jobs: - name: Write secrets.yaml shell: bash run: 'echo -e "wifi_ssid: ssid\nwifi_password: password\nmqtt_host: host\nmqtt_username: username\nmqtt_password: password" > secrets.yaml' + - name: Write tests/secrets.yaml + shell: bash + run: 'echo -e "wifi_ssid: ssid\nwifi_password: password\nmqtt_host: host\nmqtt_username: username\nmqtt_password: password" > tests/secrets.yaml' - run: | esphome config esp32-example.yaml - run: | esphome config esp8266-example.yaml + esphome config tests/esp8266-test-ping.yaml + esphome config tests/esp8266-test-pong.yaml + esphome config tests/esp8266-test-protocols.yaml esphome-compile: runs-on: ubuntu-latest @@ -60,10 +66,10 @@ jobs: path: .pioenvs key: esphome-compile-pioenvs-${{ hashFiles('*.yaml') }} restore-keys: esphome-compile-pioenvs- - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.9 - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel From 16853dddf6103411be44d77fabca4f844da6005d Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 30 Mar 2024 13:45:45 +0100 Subject: [PATCH 113/114] Add tests --- tests/esp8266-test-ping.yaml | 40 ++++++++++ tests/esp8266-test-pong.yaml | 40 ++++++++++ tests/esp8266-test-protocols.yaml | 122 ++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 tests/esp8266-test-ping.yaml create mode 100644 tests/esp8266-test-pong.yaml create mode 100644 tests/esp8266-test-protocols.yaml diff --git a/tests/esp8266-test-ping.yaml b/tests/esp8266-test-ping.yaml new file mode 100644 index 00000000..4afd07a2 --- /dev/null +++ b/tests/esp8266-test-ping.yaml @@ -0,0 +1,40 @@ +substitutions: + name: pipsolar + tx_pin: GPIO4 + rx_pin: GPIO5 + +esphome: + name: ${name} + +esp8266: + board: d1_mini + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + +ota: + +logger: + level: DEBUG + +api: + reboot_timeout: 0s + +uart: + id: uart_0 + baud_rate: 2400 + tx_pin: ${tx_pin} + rx_pin: ${rx_pin} + debug: + direction: BOTH + dummy_receiver: true + after: + delimiter: "\r" + sequence: + - lambda: UARTDebug::log_string(direction, bytes); + +interval: + - interval: 2s + then: + - uart.write: "ping\r" diff --git a/tests/esp8266-test-pong.yaml b/tests/esp8266-test-pong.yaml new file mode 100644 index 00000000..52dab94d --- /dev/null +++ b/tests/esp8266-test-pong.yaml @@ -0,0 +1,40 @@ +substitutions: + name: pipsolar + tx_pin: GPIO4 + rx_pin: GPIO5 + +esphome: + name: ${name} + +esp8266: + board: d1_mini + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + +ota: + +logger: + level: DEBUG + +api: + reboot_timeout: 0s + +uart: + id: uart_0 + baud_rate: 2400 + tx_pin: ${tx_pin} + rx_pin: ${rx_pin} + debug: + direction: BOTH + dummy_receiver: true + after: + delimiter: "\r" + sequence: + - lambda: UARTDebug::log_string(direction, bytes); + +interval: + - interval: 2s + then: + - uart.write: "pong\r" diff --git a/tests/esp8266-test-protocols.yaml b/tests/esp8266-test-protocols.yaml new file mode 100644 index 00000000..506ed189 --- /dev/null +++ b/tests/esp8266-test-protocols.yaml @@ -0,0 +1,122 @@ +substitutions: + name: pipsolar + tx_pin: GPIO4 + rx_pin: GPIO5 + +esphome: + name: ${name} + +esp8266: + board: d1_mini + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + +ota: + +logger: + level: DEBUG + +api: + reboot_timeout: 0s + +uart: + id: uart_0 + baud_rate: 2400 + tx_pin: ${tx_pin} + rx_pin: ${rx_pin} + debug: + direction: BOTH + dummy_receiver: true + after: + delimiter: "\r" + sequence: + - lambda: UARTDebug::log_string(direction, bytes); + +interval: + - interval: 80s + then: + # PI30/PI30MAX/PI30REVO/PI41 + - logger.log: + level: INFO + format: "Testing PI30/PI30MAX/PI30REVO/PI41 commands..." + - logger.log: + level: INFO + format: "This is the set of commands supported by the pipsolar component!" + - uart.write: [0x51, 0x50, 0x49, 0xBE, 0xAC, 0x0D] # QPI\xbe\xac\r + - delay: 1s + - uart.write: [0x51, 0x44, 0x49, 0x71, 0x1B, 0x0D] # QDIq\x1b\r + - delay: 1s + - uart.write: [0x51, 0x46, 0x4C, 0x41, 0x47, 0x98, 0x74, 0x0D] # QFLAG\x98t\r + - delay: 1s + - uart.write: [0x51, 0x4D, 0x4E, 0xBB, 0x64, 0x0D] # QMN\xbbd\r + - delay: 1s + - uart.write: [0x51, 0x4D, 0x4F, 0x44, 0x49, 0xC1, 0x0D] # QMODI\xc1\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x49, 0x47, 0x53, 0xB7, 0xA9, 0x0D] # QPIGS\xB7\xA9\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x49, 0x52, 0x49, 0xF8, 0x54, 0x0D] # QPIRI\xF8T\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x49, 0x57, 0x53, 0xB4, 0xDA, 0x0D] # QPIWS\xb4\xda\r + - delay: 1s + - uart.write: [0x51, 0x54, 0x27, 0xFF, 0x0D] # QT'\xff\r + - delay: 1s + # Test some PI30 commands from Phocos Any-Grid PSW-H inverters + - uart.write: [0x51, 0x50, 0x47, 0x53, 0x30, 0x3F, 0xDA, 0x0D] # QPGS0\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x47, 0x53, 0x31, 0x2F, 0xFB, 0x0D] # QPGS1\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x47, 0x53, 0x32, 0x1F, 0x98, 0x0D] # QPGS2\r + - delay: 1s + + # PI41 split phase + - logger.log: + level: INFO + format: "Testing PI41 split phase / multiple strings commands..." + - uart.write: [0x51, 0x50, 0x49, 0x47, 0x53, 0x32, 0x68, 0x2D, 0x0D] # QPIGS2h-\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x32, 0x47, 0x53, 0x30, 0x14, 0x05, 0x0D] # QP2GS0\x14\x05\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x32, 0x47, 0x53, 0x31, 0x04, 0x24, 0x0D] # QP2GS1\x04$\r + - delay: 1s + + # PI18 + - logger.log: + level: INFO + format: "Testing unsupported PI18 commands..." + - uart.write: [0x5E, 0x50, 0x30, 0x30, 0x35, 0x50, 0x49, 0x71, 0x8B, 0x0D] # ^P005PIq\x8b\r + - delay: 1s + - uart.write: [0x5E, 0x50, 0x30, 0x30, 0x35, 0x47, 0x53, 0x58, 0x14, 0x0D] # ^P005GSX\x14\r + - delay: 1s + - uart.write: [0x5E, 0x50, 0x30, 0x30, 0x36, 0x4D, 0x4F, 0x44, 0xDD, 0xBE, 0x0D] # ^P006MOD\xdd\xbe\r + - delay: 1s + + # PI17 + - logger.log: + level: INFO + format: "Testing unsupported PI17 commands..." + - uart.write: [0x5E, 0x50, 0x30, 0x30, 0x33, 0x50, 0x49, 0x0D] # ^P003PI\r + - delay: 1s + - uart.write: [0x5E, 0x50, 0x30, 0x30, 0x34, 0x4D, 0x4F, 0x44, 0x0D] # ^P004MOD\r + - delay: 1s + - uart.write: [0x5E, 0x50, 0x30, 0x30, 0x35, 0x46, 0x4C, 0x41, 0x47, 0x0D] # ^P005FLAG\r + - delay: 1s + + # PI16 + - logger.log: + level: INFO + format: "Testing unsupported PI16 commands..." + - uart.write: [0x51, 0x50, 0x49, 0x0D] # QPI\r + - delay: 1s + - uart.write: [0x51, 0x4D, 0x4F, 0x44, 0x0D] # QMOD\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x49, 0x47, 0x53, 0x0D] # QPIGS\r + - delay: 1s + - uart.write: [0x51, 0x50, 0x49, 0x52, 0x49, 0x0D] # QPIRI\r + - delay: 1s + - uart.write: [0x51, 0x4D, 0x4F, 0x44, 0x0D] # QMOD\r + + - logger.log: + level: INFO + format: "Done. Repeating..." From ee994d8270567cea5025101725b3a71467990ea5 Mon Sep 17 00:00:00 2001 From: Sergiy Andrusenko Date: Fri, 14 Jun 2024 12:58:06 +0300 Subject: [PATCH 114/114] ename `binary_sensor.warnung_low_pv_energy` to `binary_sensor.warning_low_pv_energy` --- components/pipsolar/binary_sensor/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/pipsolar/binary_sensor/__init__.py b/components/pipsolar/binary_sensor/__init__.py index 91e1a82b..0cd98a0e 100644 --- a/components/pipsolar/binary_sensor/__init__.py +++ b/components/pipsolar/binary_sensor/__init__.py @@ -62,7 +62,7 @@ CONF_WARNING_BATTERY_TOO_LOW_TO_CHARGE = "warning_battery_too_low_to_charge" CONF_FAULT_DC_DC_OVER_CURRENT = "fault_dc_dc_over_current" CONF_FAULT_CODE = "fault_code" -CONF_WARNUNG_LOW_PV_ENERGY = "warnung_low_pv_energy" +CONF_WARNING_LOW_PV_ENERGY = "warning_low_pv_energy" CONF_WARNING_HIGH_AC_INPUT_DURING_BUS_SOFT_START = ( "warning_high_ac_input_during_bus_soft_start" ) @@ -128,7 +128,7 @@ CONF_WARNING_BATTERY_TOO_LOW_TO_CHARGE, CONF_FAULT_DC_DC_OVER_CURRENT, CONF_FAULT_CODE, - CONF_WARNUNG_LOW_PV_ENERGY, + CONF_WARNING_LOW_PV_ENERGY, CONF_WARNING_HIGH_AC_INPUT_DURING_BUS_SOFT_START, CONF_WARNING_BATTERY_EQUALIZATION, CONF_DISCHARGE_ONOFF,