mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Add support for Daly Smart BMS
This commit is contained in:
		
							
								
								
									
										30
									
								
								esphome/components/daly_bms/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								esphome/components/daly_bms/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import uart | ||||
| from esphome.const import CONF_ID | ||||
|  | ||||
| CODEOWNERS = ["@s1lvi0"] | ||||
| DEPENDENCIES = ["uart"] | ||||
| AUTO_LOAD = ["sensor", "text_sensor", "binary_sensor"] | ||||
|  | ||||
| CONF_BSM_DALY_ID = "bms_daly_id" | ||||
|  | ||||
| daly_bms = cg.esphome_ns.namespace("daly_bms") | ||||
| DalyBmsComponent = daly_bms.class_("DalyBmsComponent", uart.UARTDevice, cg.Component) | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     cv.Schema( | ||||
|         { | ||||
|             cv.GenerateID(): cv.declare_id(DalyBmsComponent), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
|     .extend(uart.UART_DEVICE_SCHEMA) | ||||
|     .extend(cv.polling_component_schema("30s")), | ||||
| ) | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     await cg.register_component(var, config) | ||||
|     await uart.register_uart_device(var, config) | ||||
							
								
								
									
										46
									
								
								esphome/components/daly_bms/binary_sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								esphome/components/daly_bms/binary_sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| 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 DalyBmsComponent, CONF_BSM_DALY_ID | ||||
|  | ||||
| CONF_CHARGING_MOS_ENABLED = "charging_mos_enabled" | ||||
| CONF_DISCHARGING_MOS_ENABLED = "discharging_mos_enabled" | ||||
|  | ||||
| TYPES = [ | ||||
|     CONF_CHARGING_MOS_ENABLED, | ||||
|     CONF_DISCHARGING_MOS_ENABLED, | ||||
| ] | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     cv.Schema( | ||||
|         { | ||||
|             cv.GenerateID(CONF_BSM_DALY_ID): cv.use_id(DalyBmsComponent), | ||||
|             cv.Optional(CONF_CHARGING_MOS_ENABLED): binary_sensor.BINARY_SENSOR_SCHEMA.extend( | ||||
|                 { | ||||
|                     cv.GenerateID(): cv.declare_id(binary_sensor.BinarySensor), | ||||
|                 } | ||||
|             ), | ||||
|             cv.Optional(CONF_DISCHARGING_MOS_ENABLED): binary_sensor.BINARY_SENSOR_SCHEMA.extend( | ||||
|                 { | ||||
|                     cv.GenerateID(): cv.declare_id(binary_sensor.BinarySensor), | ||||
|                 } | ||||
|             ), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
| ) | ||||
|  | ||||
|  | ||||
| async def setup_conf(config, key, hub): | ||||
|     if key in config: | ||||
|         conf = config[key] | ||||
|         sens = cg.new_Pvariable(conf[CONF_ID]) | ||||
|         await binary_sensor.register_binary_sensor(sens, conf) | ||||
|         cg.add(getattr(hub, f"set_{key}_binary_sensor")(sens)) | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     hub = await cg.get_variable(config[CONF_BSM_DALY_ID]) | ||||
|     for key in TYPES: | ||||
|         await setup_conf(config, key, hub) | ||||
							
								
								
									
										188
									
								
								esphome/components/daly_bms/daly_bms.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								esphome/components/daly_bms/daly_bms.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | ||||
| #include "daly_bms.h" | ||||
| #include "esphome/core/log.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace daly_bms { | ||||
|  | ||||
| static const char *const TAG = "daly_bms"; | ||||
|  | ||||
| static const unsigned char DALY_TEMPERATURE_OFFSET = 40; | ||||
|  | ||||
| static const unsigned char DALY_REQUEST_battery_level = 0x90; | ||||
| static const unsigned char DALY_REQUEST_MIN_MAX_VOLTAGE = 0x91; | ||||
| static const unsigned char DALY_REQUEST_MIN_MAX_TEMPERATURE = 0x92; | ||||
| static const unsigned char DALY_REQUEST_MOS = 0x93; | ||||
| static const unsigned char DALY_REQUEST_STATUS = 0x94; | ||||
| static const unsigned char DALY_REQUEST_TEMPERATURE = 0x96; | ||||
|  | ||||
| void DalyBmsComponent::setup() {} | ||||
|  | ||||
| void DalyBmsComponent::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "DALY_BMS:"); | ||||
|   this->check_uart_settings(9600); | ||||
| } | ||||
|  | ||||
| void DalyBmsComponent::update() { | ||||
|   this->request_data(DALY_REQUEST_battery_level); | ||||
|   this->request_data(DALY_REQUEST_MIN_MAX_VOLTAGE); | ||||
|   this->request_data(DALY_REQUEST_MIN_MAX_TEMPERATURE); | ||||
|   this->request_data(DALY_REQUEST_MOS); | ||||
|   this->request_data(DALY_REQUEST_STATUS); | ||||
|   this->request_data(DALY_REQUEST_TEMPERATURE); | ||||
|  | ||||
|   unsigned char *get_battery_level_data; | ||||
|   int available_data = this->available(); | ||||
|   if (available_data >= 13) { | ||||
|     get_battery_level_data = (unsigned char *) malloc(available_data); | ||||
|     this->read_array(get_battery_level_data, available_data); | ||||
|     this->decode_data(get_battery_level_data, available_data); | ||||
|   } | ||||
| } | ||||
|  | ||||
| float DalyBmsComponent::get_setup_priority() const { return setup_priority::DATA; } | ||||
|  | ||||
| void DalyBmsComponent::request_data(unsigned char data_id) { | ||||
|   unsigned char request_message[13]; | ||||
|  | ||||
|   request_message[0] = 0xA5;     // Start Flag | ||||
|   request_message[1] = 0x80;     // Communication Module Address | ||||
|   request_message[2] = data_id;  // Data ID | ||||
|   request_message[3] = 0x08;     // Data Length (Fixed) | ||||
|   request_message[4] = 0x00;     // Empty Data | ||||
|   request_message[5] = 0x00;     //     | | ||||
|   request_message[6] = 0x00;     //     | | ||||
|   request_message[7] = 0x00;     //     | | ||||
|   request_message[8] = 0x00;     //     | | ||||
|   request_message[9] = 0x00;     //     | | ||||
|   request_message[10] = 0x00;    //     | | ||||
|   request_message[11] = 0x00;    // Empty Data | ||||
|   request_message[12] = (unsigned char) (request_message[0] + request_message[1] + request_message[2] + | ||||
|                                          request_message[3]);  // Checksum (Lower byte of the other bytes sum) | ||||
|  | ||||
|   this->write_array(request_message, sizeof(request_message)); | ||||
|   this->flush(); | ||||
| } | ||||
|  | ||||
| void DalyBmsComponent::decode_data(unsigned char *data, int length) { | ||||
|   unsigned char *start_flag_position; | ||||
|  | ||||
|   while (data != NULL) { | ||||
|     start_flag_position = (unsigned char *) strchr((const char *) data, 0xA5); | ||||
|  | ||||
|     if (start_flag_position != NULL) { | ||||
|       length = length - (start_flag_position - data); | ||||
|       data = start_flag_position; | ||||
|  | ||||
|       if (length >= 13 && data[1] == 0x01) { | ||||
|  | ||||
|         unsigned char checksum; | ||||
|         int sum = 0; | ||||
|         for (int i = 0; i < 12; i++) { | ||||
|           sum += data[i]; | ||||
|         } | ||||
|         checksum = sum; | ||||
|  | ||||
|         if (checksum == data[12]) { | ||||
|           switch (data[2]) { | ||||
|             case DALY_REQUEST_battery_level: | ||||
|               if (this->voltage_sensor_) { | ||||
|                 this->voltage_sensor_->publish_state((float) (((data[4] << 8) | data[5]) / 10)); | ||||
|               } | ||||
|               if (this->current_sensor_) { | ||||
|                 this->current_sensor_->publish_state((float) ((((data[8] << 8) | data[9]) - 30000) / 10)); | ||||
|               } | ||||
|               if (this->battery_level_sensor_) { | ||||
|                 this->battery_level_sensor_->publish_state((float) (((data[10] << 8) | data[11]) / 10)); | ||||
|               } | ||||
|               break; | ||||
|  | ||||
|             case DALY_REQUEST_MIN_MAX_VOLTAGE: | ||||
|               if (this->max_cell_voltage_) { | ||||
|                 this->max_cell_voltage_->publish_state((float) ((data[4] << 8) | data[5]) / 1000); | ||||
|               } | ||||
|               if (this->max_cell_volatge_number_) { | ||||
|                 this->max_cell_volatge_number_->publish_state(data[6]); | ||||
|               } | ||||
|               if (this->min_cell_voltage_) { | ||||
|                 this->min_cell_voltage_->publish_state((float) ((data[7] << 8) | data[8]) / 1000); | ||||
|               } | ||||
|               if (this->min_cell_voltage_number_) { | ||||
|                 this->min_cell_voltage_number_->publish_state(data[9]); | ||||
|               } | ||||
|               break; | ||||
|  | ||||
|             case DALY_REQUEST_MIN_MAX_TEMPERATURE: | ||||
|               if (this->max_temperature_) { | ||||
|                 this->max_temperature_->publish_state(data[4] - DALY_TEMPERATURE_OFFSET); | ||||
|               } | ||||
|               if (this->max_temperature_probe_number_) { | ||||
|                 this->max_temperature_probe_number_->publish_state(data[5]); | ||||
|               } | ||||
|               if (this->min_temperature_) { | ||||
|                 this->min_temperature_->publish_state(data[6] - DALY_TEMPERATURE_OFFSET); | ||||
|               } | ||||
|               if (this->min_temperature_probe_number_) { | ||||
|                 this->min_temperature_probe_number_->publish_state(data[7]); | ||||
|               } | ||||
|               break; | ||||
|  | ||||
|             case DALY_REQUEST_MOS: | ||||
|               if (this->status_text_sensor_ != nullptr) { | ||||
|                 switch (data[4]) { | ||||
|                   case 0: | ||||
|                     this->status_text_sensor_->publish_state("Stationary"); | ||||
|                     break; | ||||
|                   case 1: | ||||
|                     this->status_text_sensor_->publish_state("Charging"); | ||||
|                     break; | ||||
|                   case 2: | ||||
|                     this->status_text_sensor_->publish_state("Discharging"); | ||||
|                     break; | ||||
|                   default: | ||||
|                     break; | ||||
|                 } | ||||
|               } | ||||
|               if (this->charging_mos_enabled_) { | ||||
|                 this->charging_mos_enabled_->publish_state(data[5]); | ||||
|               } | ||||
|               if (this->discharging_mos_enabled_) { | ||||
|                 this->discharging_mos_enabled_->publish_state(data[6]); | ||||
|               } | ||||
|               if (this->remaining_capacity_) { | ||||
|                 this->remaining_capacity_->publish_state( | ||||
|                     (float) ((data[8] << 24) | (data[9] << 16) | (data[10] << 8) | data[11]) / 1000); | ||||
|               } | ||||
|               break; | ||||
|  | ||||
|             case DALY_REQUEST_STATUS: | ||||
|               break; | ||||
|  | ||||
|             case DALY_REQUEST_TEMPERATURE: | ||||
|               if (data[4] == 1) { | ||||
|                 if (this->temperature_1_sensor_) { | ||||
|                   this->temperature_1_sensor_->publish_state(data[5] - DALY_TEMPERATURE_OFFSET); | ||||
|                 } | ||||
|                 if (this->temperature_2_sensor_) { | ||||
|                   this->temperature_2_sensor_->publish_state(data[6] - DALY_TEMPERATURE_OFFSET); | ||||
|                 } | ||||
|               } | ||||
|               break; | ||||
|  | ||||
|             default: | ||||
|               break; | ||||
|           } | ||||
|           data = &data[13]; | ||||
|         } | ||||
|       } else { | ||||
|         data = NULL; | ||||
|       } | ||||
|     } else { | ||||
|       data = NULL; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   free(data); | ||||
| } | ||||
|  | ||||
| }  // namespace daly_bms | ||||
| }  // namespace esphome | ||||
							
								
								
									
										81
									
								
								esphome/components/daly_bms/daly_bms.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								esphome/components/daly_bms/daly_bms.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/sensor/sensor.h" | ||||
| #include "esphome/components/text_sensor/text_sensor.h" | ||||
| #include "esphome/components/binary_sensor/binary_sensor.h" | ||||
| #include "esphome/components/uart/uart.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace daly_bms { | ||||
|  | ||||
| class DalyBmsComponent : public PollingComponent, public uart::UARTDevice { | ||||
|  public: | ||||
|   DalyBmsComponent() = default; | ||||
|  | ||||
|   // SENSORS | ||||
|   void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; } | ||||
|   void set_current_sensor(sensor::Sensor *current_sensor) { current_sensor_ = current_sensor; } | ||||
|   void set_battery_level_sensor(sensor::Sensor *battery_level_sensor) { battery_level_sensor_ = battery_level_sensor; } | ||||
|   void set_max_cell_voltage_sensor(sensor::Sensor *max_cell_voltage) { max_cell_voltage_ = max_cell_voltage; } | ||||
|   void set_max_cell_voltage_number_sensor(sensor::Sensor *max_cell_volatge_number) { | ||||
|     max_cell_volatge_number_ = max_cell_volatge_number; | ||||
|   } | ||||
|   void set_min_cell_voltage_sensor(sensor::Sensor *min_cell_voltage) { min_cell_voltage_ = min_cell_voltage; } | ||||
|   void set_min_cell_voltage_number_sensor(sensor::Sensor *min_cell_voltage_number) { | ||||
|     min_cell_voltage_number_ = min_cell_voltage_number; | ||||
|   } | ||||
|   void set_max_temperature_sensor(sensor::Sensor *max_temperature) { max_temperature_ = max_temperature; } | ||||
|   void set_max_temperature_probe_number_sensor(sensor::Sensor *max_temperature_probe_number) { | ||||
|     max_temperature_probe_number_ = max_temperature_probe_number; | ||||
|   } | ||||
|   void set_min_temperature_sensor(sensor::Sensor *min_temperature) { min_temperature_ = min_temperature; } | ||||
|   void set_min_temperature_probe_number_sensor(sensor::Sensor *min_temperature_probe_number) { | ||||
|     min_temperature_probe_number_ = min_temperature_probe_number; | ||||
|   } | ||||
|   void set_remaining_capacity_sensor(sensor::Sensor *remaining_capacity) { remaining_capacity_ = remaining_capacity; } | ||||
|   void set_temperature_1_sensor(sensor::Sensor *temperature_1_sensor) { temperature_1_sensor_ = temperature_1_sensor; } | ||||
|   void set_temperature_2_sensor(sensor::Sensor *temperature_2_sensor) { temperature_2_sensor_ = temperature_2_sensor; } | ||||
|   // TEXT_SENSORS | ||||
|   void set_status_text_sensor(text_sensor::TextSensor *status_text_sensor) { status_text_sensor_ = status_text_sensor; } | ||||
|   // BINARY_SENSORS | ||||
|   void set_charging_mos_enabled_binary_sensor(binary_sensor::BinarySensor *charging_mos_enabled) { | ||||
|     charging_mos_enabled_ = charging_mos_enabled; | ||||
|   } | ||||
|   void set_discharging_mos_enabled_binary_sensor(binary_sensor::BinarySensor *discharging_mos_enabled) { | ||||
|     discharging_mos_enabled_ = discharging_mos_enabled; | ||||
|   } | ||||
|  | ||||
|   void setup() override; | ||||
|   void dump_config() override; | ||||
|   void update() override; | ||||
|  | ||||
|   float get_setup_priority() const override; | ||||
|  | ||||
|  protected: | ||||
|   void request_data(unsigned char data_id); | ||||
|   void decode_data(unsigned char *data, int length); | ||||
|  | ||||
|   sensor::Sensor *voltage_sensor_{nullptr}; | ||||
|   sensor::Sensor *current_sensor_{nullptr}; | ||||
|   sensor::Sensor *battery_level_sensor_{nullptr}; | ||||
|   sensor::Sensor *max_cell_voltage_{nullptr}; | ||||
|   sensor::Sensor *max_cell_volatge_number_{nullptr}; | ||||
|   sensor::Sensor *min_cell_voltage_{nullptr}; | ||||
|   sensor::Sensor *min_cell_voltage_number_{nullptr}; | ||||
|   sensor::Sensor *max_temperature_{nullptr}; | ||||
|   sensor::Sensor *max_temperature_probe_number_{nullptr}; | ||||
|   sensor::Sensor *min_temperature_{nullptr}; | ||||
|   sensor::Sensor *min_temperature_probe_number_{nullptr}; | ||||
|   sensor::Sensor *remaining_capacity_{nullptr}; | ||||
|   sensor::Sensor *temperature_1_sensor_{nullptr}; | ||||
|   sensor::Sensor *temperature_2_sensor_{nullptr}; | ||||
|  | ||||
|   text_sensor::TextSensor *status_text_sensor_{nullptr}; | ||||
|  | ||||
|   binary_sensor::BinarySensor *charging_mos_enabled_{nullptr}; | ||||
|   binary_sensor::BinarySensor *discharging_mos_enabled_{nullptr}; | ||||
| }; | ||||
|  | ||||
| }  // namespace daly_bms | ||||
| }  // namespace esphome | ||||
							
								
								
									
										203
									
								
								esphome/components/daly_bms/sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								esphome/components/daly_bms/sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import sensor | ||||
| from esphome.const import ( | ||||
|     CONF_VOLTAGE, | ||||
|     CONF_CURRENT, | ||||
|     CONF_BATTERY_LEVEL, | ||||
|     DEVICE_CLASS_VOLTAGE, | ||||
|     DEVICE_CLASS_CURRENT, | ||||
|     DEVICE_CLASS_BATTERY, | ||||
|     DEVICE_CLASS_TEMPERATURE, | ||||
|     DEVICE_CLASS_EMPTY, | ||||
|     STATE_CLASS_MEASUREMENT, | ||||
|     STATE_CLASS_NONE, | ||||
|     UNIT_VOLT, | ||||
|     UNIT_AMPERE, | ||||
|     UNIT_PERCENT, | ||||
|     UNIT_CELSIUS, | ||||
|     UNIT_EMPTY, | ||||
|     ICON_FLASH, | ||||
|     ICON_PERCENT, | ||||
|     ICON_COUNTER, | ||||
|     ICON_THERMOMETER, | ||||
|     ICON_GAUGE, | ||||
| ) | ||||
| from . import DalyBmsComponent, CONF_BSM_DALY_ID | ||||
|  | ||||
| CONF_MAX_CELL_VOLTAGE = "max_cell_voltage" | ||||
| CONF_MAX_CELL_VOLTAGE_NUMBER = "max_cell_voltage_number" | ||||
| CONF_MIN_CELL_VOLTAGE = "min_cell_voltage" | ||||
| CONF_MIN_CELL_VOLTAGE_NUMBER = "min_cell_voltage_number" | ||||
| CONF_MAX_TEMPERATURE = "max_temperature" | ||||
| CONF_MAX_TEMPERATURE_PROBE_NUMBER = "max_temperature_probe_number" | ||||
| CONF_MIN_TEMPERATURE = "min_temperature" | ||||
| CONF_MIN_TEMPERATURE_PROBE_NUMBER = "min_temperature_probe_number" | ||||
| CONF_STATUS = "status" | ||||
| CONF_CELLS_NUMBER = "cells_number" | ||||
| CONF_TEMPERATURE_PROBES_NUMBER = "temperature_probe_number" | ||||
|  | ||||
| CONF_REMAINING_CAPACITY = "remaining_capacity" | ||||
| CONF_TEMPERATURE_1 = "temperature_1" | ||||
| CONF_TEMPERATURE_2 = "temperature_2" | ||||
|  | ||||
| ICON_CURRENT_DC = "mdi:current-dc" | ||||
| ICON_BATTERY_OUTLINE = "mdi:battery-outline" | ||||
| ICON_THERMOMETER_CHEVRON_UP = "mdi:thermometer-chevron-up" | ||||
| ICON_THERMOMETER_CHEVRON_DOWN = "mdi:thermometer-chevron-down" | ||||
| ICON_CAR_BATTERY = "mdi:car-battery" | ||||
|  | ||||
| UNIT_AMPERE_HOUR = "Ah" | ||||
|  | ||||
| TYPES = [ | ||||
|     CONF_VOLTAGE, | ||||
|     CONF_CURRENT, | ||||
|     CONF_BATTERY_LEVEL, | ||||
|     CONF_MAX_CELL_VOLTAGE, | ||||
|     CONF_MAX_CELL_VOLTAGE_NUMBER, | ||||
|     CONF_MIN_CELL_VOLTAGE, | ||||
|     CONF_MIN_CELL_VOLTAGE_NUMBER, | ||||
|     CONF_MAX_TEMPERATURE, | ||||
|     CONF_MAX_TEMPERATURE_PROBE_NUMBER, | ||||
|     CONF_MIN_TEMPERATURE, | ||||
|     CONF_MIN_TEMPERATURE_PROBE_NUMBER, | ||||
|     CONF_CELLS_NUMBER, | ||||
|     CONF_TEMPERATURE_PROBES_NUMBER, | ||||
|     CONF_REMAINING_CAPACITY, | ||||
|     CONF_TEMPERATURE_1, | ||||
|     CONF_TEMPERATURE_2, | ||||
| ] | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     cv.Schema( | ||||
|         { | ||||
|             cv.GenerateID(CONF_BSM_DALY_ID): cv.use_id(DalyBmsComponent), | ||||
|             cv.Optional(CONF_VOLTAGE): sensor.sensor_schema( | ||||
|                 UNIT_VOLT, | ||||
|                 ICON_FLASH, | ||||
|                 1, | ||||
|                 DEVICE_CLASS_VOLTAGE, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_CURRENT): sensor.sensor_schema( | ||||
|                 UNIT_AMPERE, | ||||
|                 ICON_CURRENT_DC, | ||||
|                 1, | ||||
|                 DEVICE_CLASS_CURRENT, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema( | ||||
|                 UNIT_PERCENT, | ||||
|                 ICON_PERCENT, | ||||
|                 1, | ||||
|                 DEVICE_CLASS_BATTERY, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_MAX_CELL_VOLTAGE): sensor.sensor_schema( | ||||
|                 UNIT_VOLT, | ||||
|                 ICON_FLASH, | ||||
|                 2, | ||||
|                 DEVICE_CLASS_VOLTAGE, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_MAX_CELL_VOLTAGE_NUMBER): sensor.sensor_schema( | ||||
|                 UNIT_EMPTY, | ||||
|                 ICON_COUNTER, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_EMPTY, | ||||
|                 STATE_CLASS_NONE, | ||||
|             ), | ||||
|             cv.Optional(CONF_MIN_CELL_VOLTAGE): sensor.sensor_schema( | ||||
|                 UNIT_VOLT, | ||||
|                 ICON_FLASH, | ||||
|                 2, | ||||
|                 DEVICE_CLASS_VOLTAGE, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_MIN_CELL_VOLTAGE_NUMBER): sensor.sensor_schema( | ||||
|                 UNIT_EMPTY, | ||||
|                 ICON_COUNTER, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_EMPTY, | ||||
|                 STATE_CLASS_NONE, | ||||
|             ), | ||||
|             cv.Optional(CONF_MAX_TEMPERATURE): sensor.sensor_schema( | ||||
|                 UNIT_CELSIUS, | ||||
|                 ICON_THERMOMETER_CHEVRON_UP, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_TEMPERATURE, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_MAX_TEMPERATURE_PROBE_NUMBER): sensor.sensor_schema( | ||||
|                 UNIT_EMPTY, | ||||
|                 ICON_COUNTER, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_EMPTY, | ||||
|                 STATE_CLASS_NONE, | ||||
|             ), | ||||
|             cv.Optional(CONF_MIN_TEMPERATURE): sensor.sensor_schema( | ||||
|                 UNIT_CELSIUS, | ||||
|                 ICON_THERMOMETER_CHEVRON_DOWN, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_TEMPERATURE, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_MIN_TEMPERATURE_PROBE_NUMBER): sensor.sensor_schema( | ||||
|                 UNIT_EMPTY, | ||||
|                 ICON_COUNTER, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_EMPTY, | ||||
|                 STATE_CLASS_NONE, | ||||
|             ), | ||||
|             cv.Optional(CONF_REMAINING_CAPACITY): sensor.sensor_schema( | ||||
|                 UNIT_AMPERE_HOUR, | ||||
|                 ICON_GAUGE, | ||||
|                 2, | ||||
|                 DEVICE_CLASS_VOLTAGE, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_CELLS_NUMBER): sensor.sensor_schema( | ||||
|                 UNIT_EMPTY, | ||||
|                 ICON_COUNTER, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_EMPTY, | ||||
|                 STATE_CLASS_NONE, | ||||
|             ), | ||||
|             cv.Optional(CONF_TEMPERATURE_PROBES_NUMBER): sensor.sensor_schema( | ||||
|                 UNIT_EMPTY, | ||||
|                 ICON_COUNTER, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_EMPTY, | ||||
|                 STATE_CLASS_NONE, | ||||
|             ), | ||||
|             cv.Optional(CONF_TEMPERATURE_1): sensor.sensor_schema( | ||||
|                 UNIT_CELSIUS, | ||||
|                 ICON_THERMOMETER, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_TEMPERATURE, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_TEMPERATURE_2): sensor.sensor_schema( | ||||
|                 UNIT_CELSIUS, | ||||
|                 ICON_THERMOMETER, | ||||
|                 0, | ||||
|                 DEVICE_CLASS_TEMPERATURE, | ||||
|                 STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
| ) | ||||
|  | ||||
|  | ||||
| async def setup_conf(config, key, hub): | ||||
|     if key in config: | ||||
|         conf = config[key] | ||||
|         sens = await sensor.new_sensor(conf) | ||||
|         cg.add(getattr(hub, f"set_{key}_sensor")(sens)) | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     hub = await cg.get_variable(config[CONF_BSM_DALY_ID]) | ||||
|     for key in TYPES: | ||||
|         await setup_conf(config, key, hub) | ||||
							
								
								
									
										42
									
								
								esphome/components/daly_bms/text_sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								esphome/components/daly_bms/text_sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import text_sensor | ||||
| from esphome.const import CONF_ICON, CONF_ID | ||||
| from . import DalyBmsComponent, CONF_BSM_DALY_ID | ||||
|  | ||||
| CONF_STATUS = "status" | ||||
|  | ||||
| ICON_CAR_BATTERY = "mdi:car-battery" | ||||
|  | ||||
| TYPES = [ | ||||
|     CONF_STATUS, | ||||
| ] | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     cv.Schema( | ||||
|         { | ||||
|             cv.GenerateID(CONF_BSM_DALY_ID): cv.use_id(DalyBmsComponent), | ||||
|             cv.Optional(CONF_STATUS): text_sensor.TEXT_SENSOR_SCHEMA.extend( | ||||
|                 { | ||||
|                     cv.GenerateID(): cv.declare_id(text_sensor.TextSensor), | ||||
|                     cv.Optional(CONF_ICON, default=ICON_CAR_BATTERY): cv.icon, | ||||
|                 } | ||||
|             ), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
| ) | ||||
|  | ||||
|  | ||||
| async def setup_conf(config, key, hub): | ||||
|     if key in config: | ||||
|         conf = config[key] | ||||
|         sens = cg.new_Pvariable(conf[CONF_ID]) | ||||
|         await text_sensor.register_text_sensor(sens, conf) | ||||
|         cg.add(getattr(hub, f"set_{key}_text_sensor")(sens)) | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     hub = await cg.get_variable(config[CONF_BSM_DALY_ID]) | ||||
|     for key in TYPES: | ||||
|         await setup_conf(config, key, hub) | ||||
		Reference in New Issue
	
	Block a user