DALY Modbus BMS: add most registers

This commit is contained in:
patagona 2024-09-29 05:42:25 +02:00
parent 5d767d9f92
commit d76d623033
6 changed files with 509 additions and 26 deletions

View File

@ -0,0 +1,48 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import binary_sensor
from . import DalyHkmsBmsComponent, CONF_DALY_HKMS_BMS_ID
CONF_CHARGING_MOS_ENABLED = "charging_mos_enabled"
CONF_DISCHARGING_MOS_ENABLED = "discharging_mos_enabled"
CONF_PRECHARGING_MOS_ENABLED = "precharging_mos_enabled"
CONF_BALANCING_ACTIVE = "balancing_active"
TYPES = [
CONF_CHARGING_MOS_ENABLED,
CONF_DISCHARGING_MOS_ENABLED,
CONF_PRECHARGING_MOS_ENABLED,
CONF_BALANCING_ACTIVE,
]
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(CONF_DALY_HKMS_BMS_ID): cv.use_id(DalyHkmsBmsComponent),
cv.Optional(
CONF_CHARGING_MOS_ENABLED
): binary_sensor.binary_sensor_schema(),
cv.Optional(
CONF_DISCHARGING_MOS_ENABLED
): binary_sensor.binary_sensor_schema(),
cv.Optional(
CONF_PRECHARGING_MOS_ENABLED
): binary_sensor.binary_sensor_schema(),
cv.Optional(
CONF_BALANCING_ACTIVE
): binary_sensor.binary_sensor_schema(),
}
).extend(cv.COMPONENT_SCHEMA)
)
async def setup_conf(config, key, hub):
if sensor_config := config.get(key):
var = await binary_sensor.new_binary_sensor(sensor_config)
cg.add(getattr(hub, f"set_{key}_binary_sensor")(var))
async def to_code(config):
hub = await cg.get_variable(config[CONF_DALY_HKMS_BMS_ID])
for key in TYPES:
await setup_conf(config, key, hub)

View File

@ -1,4 +1,5 @@
#include "daly_hkms_bms.h" #include "daly_hkms_bms.h"
#include "daly_hkms_bms_registers.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
namespace esphome { namespace esphome {
@ -14,9 +15,6 @@ static const uint8_t DALY_MODBUS_RESPONSE_ADDRESS_OFFSET = 0x50;
static const uint8_t MODBUS_CMD_READ_HOLDING_REGISTERS = 0x03; static const uint8_t MODBUS_CMD_READ_HOLDING_REGISTERS = 0x03;
static const uint16_t MODBUS_ADDR_SUM_VOLT = 56;
static const uint16_t MODBUS_REGISTER_COUNT = 3;
void DalyHkmsBmsComponent::set_daly_address(uint8_t daly_address) { void DalyHkmsBmsComponent::set_daly_address(uint8_t daly_address) {
this->daly_address_ = daly_address; this->daly_address_ = daly_address;
@ -49,7 +47,14 @@ void DalyHkmsBmsComponent::update() {
this->waiting_to_update_ = false; this->waiting_to_update_ = false;
// send the request using Modbus directly instead of ModbusDevice so we can send the data with the request address // send the request using Modbus directly instead of ModbusDevice so we can send the data with the request address
this->parent_->send(this->daly_address_ + DALY_MODBUS_REQUEST_ADDRESS_OFFSET, MODBUS_CMD_READ_HOLDING_REGISTERS, MODBUS_ADDR_SUM_VOLT, MODBUS_REGISTER_COUNT, 0, nullptr); uint8_t modbus_request_address = this->daly_address_ + DALY_MODBUS_REQUEST_ADDRESS_OFFSET;
this->parent_->send(
modbus_request_address,
MODBUS_CMD_READ_HOLDING_REGISTERS,
0x00,
DALY_MODBUS_REGISTER_COUNT,
0,
nullptr);
this->last_send_ = millis(); this->last_send_ = millis();
} }
@ -62,23 +67,105 @@ void DalyHkmsBmsComponent::on_modbus_data(const std::vector<uint8_t> &data) {
this->last_send_ = 0; this->last_send_ = 0;
// Also ignore the data if the message is too short. Otherwise we will publish invalid values. // Also ignore the data if the message is too short. Otherwise we will publish invalid values.
if (data.size() < MODBUS_REGISTER_COUNT * 2) if (data.size() < DALY_MODBUS_REGISTER_COUNT * 2)
return; return;
auto get_register = [&](size_t i) -> uint16_t {
return encode_uint16(data[i * 2], data[i * 2 + 1]);
};
auto publish_sensor_state = [&](sensor::Sensor *sensor, size_t i, int16_t offset, float factor,
int32_t unavailable_value = -1) -> void {
if (sensor == nullptr)
return;
uint16_t register_value = get_register(i);
float value = register_value == unavailable_value ? NAN : (register_value + offset) * factor;
sensor->publish_state(value);
};
#ifdef USE_SENSOR #ifdef USE_SENSOR
if (this->voltage_sensor_) { publish_sensor_state(this->cell_1_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 , 0, 0.001);
float voltage = encode_uint16(data[0], data[1]) / 10.0; publish_sensor_state(this->cell_2_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 1 , 0, 0.001);
this->voltage_sensor_->publish_state(voltage); publish_sensor_state(this->cell_3_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 2 , 0, 0.001);
} publish_sensor_state(this->cell_4_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 3 , 0, 0.001);
publish_sensor_state(this->cell_5_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 4 , 0, 0.001);
publish_sensor_state(this->cell_6_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 5 , 0, 0.001);
publish_sensor_state(this->cell_7_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 6 , 0, 0.001);
publish_sensor_state(this->cell_8_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 7 , 0, 0.001);
publish_sensor_state(this->cell_9_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 8 , 0, 0.001);
publish_sensor_state(this->cell_10_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_1 + 9 , 0, 0.001);
publish_sensor_state(this->cell_11_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_1 + 10, 0, 0.001);
publish_sensor_state(this->cell_12_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_1 + 11, 0, 0.001);
publish_sensor_state(this->cell_13_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_1 + 12, 0, 0.001);
publish_sensor_state(this->cell_14_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_1 + 13, 0, 0.001);
publish_sensor_state(this->cell_15_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_1 + 14, 0, 0.001);
publish_sensor_state(this->cell_16_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_1 + 15, 0, 0.001);
if (this->current_sensor_) { publish_sensor_state(this->temperature_1_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 , -40, 1, 255);
float current = (encode_uint16(data[2], data[3]) - 30000) / 10.0; publish_sensor_state(this->temperature_2_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 + 1, -40, 1, 255);
this->current_sensor_->publish_state(current); publish_sensor_state(this->temperature_3_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 + 2, -40, 1, 255);
} publish_sensor_state(this->temperature_4_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 + 3, -40, 1, 255);
publish_sensor_state(this->temperature_5_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 + 4, -40, 1, 255);
publish_sensor_state(this->temperature_6_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 + 5, -40, 1, 255);
publish_sensor_state(this->temperature_7_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 + 6, -40, 1, 255);
publish_sensor_state(this->temperature_8_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 + 7, -40, 1, 255);
if (this->battery_level_sensor_) { publish_sensor_state(this->voltage_sensor_, DALY_MODBUS_ADDR_VOLT, 0, 0.1);
float current = encode_uint16(data[4], data[5]) / 10.0; publish_sensor_state(this->current_sensor_, DALY_MODBUS_ADDR_CURR, -30000, 0.1);
this->battery_level_sensor_->publish_state(current); publish_sensor_state(this->battery_level_sensor_, DALY_MODBUS_ADDR_SOC, 0, 0.1);
publish_sensor_state(this->cells_number_sensor_, DALY_MODBUS_ADDR_CELL_COUNT, 0, 1);
publish_sensor_state(this->temps_number_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_COUNT, 0, 1);
publish_sensor_state(this->max_cell_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_MAX, 0, 0.001);
publish_sensor_state(this->max_cell_voltage_number_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_MAX_NUM, 0, 1);
publish_sensor_state(this->min_cell_voltage_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_MIN, 0, 0.001);
publish_sensor_state(this->min_cell_voltage_number_sensor_, DALY_MODBUS_ADDR_CELL_VOLT_MIN_NUM, 0, 1);
publish_sensor_state(this->max_temperature_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_MAX, -40, 1, 255);
publish_sensor_state(this->max_temperature_probe_number_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_MAX_NUM, 0, 1);
publish_sensor_state(this->min_temperature_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_MIN, -40, 1, 255);
publish_sensor_state(this->min_temperature_probe_number_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_MIN_NUM, 0, 1);
publish_sensor_state(this->remaining_capacity_sensor_, DALY_MODBUS_ADDR_REMAINING_CAPACITY, 0, 0.1);
publish_sensor_state(this->cycles_sensor_, DALY_MODBUS_ADDR_CYCLES, 0, 1);
publish_sensor_state(this->temperature_mos_sensor_, DALY_MODBUS_ADDR_MOS_TEMP, -40, 1, 255);
publish_sensor_state(this->temperature_board_sensor_, DALY_MODBUS_ADDR_BOARD_TEMP, -40, 1, 255);
#endif
#ifdef USE_TEXT_SENSOR
if (this->status_text_sensor_ != nullptr) {
switch (get_register(DALY_MODBUS_ADDR_CHG_DSCHG_STATUS)) {
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;
}
}
#endif
#ifdef USE_BINARY_SENSOR
if (this->balancing_active_binary_sensor_) {
this->balancing_active_binary_sensor_->publish_state(get_register(DALY_MODBUS_ADDR_BALANCE_STATUS) > 0);
}
if (this->charging_mos_enabled_binary_sensor_) {
this->charging_mos_enabled_binary_sensor_->publish_state(get_register(DALY_MODBUS_ADDR_CHG_MOS_ACTIVE) > 0);
}
if (this->discharging_mos_enabled_binary_sensor_) {
this->discharging_mos_enabled_binary_sensor_->publish_state(get_register(DALY_MODBUS_ADDR_DSCHG_MOS_ACTIVE) > 0);
}
if (this->precharging_mos_enabled_binary_sensor_) {
this->precharging_mos_enabled_binary_sensor_->publish_state(get_register(DALY_MODBUS_ADDR_PRECHG_MOS_ACTIVE) > 0);
} }
#endif #endif
} }

View File

@ -1,7 +1,16 @@
#pragma once #pragma once
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/core/defines.h"
#ifdef USE_SENSOR
#include "esphome/components/sensor/sensor.h" #include "esphome/components/sensor/sensor.h"
#endif
#ifdef USE_TEXT_SENSOR
#include "esphome/components/text_sensor/text_sensor.h"
#endif
#ifdef USE_BINARY_SENSOR
#include "esphome/components/binary_sensor/binary_sensor.h"
#endif
#include "esphome/components/modbus/modbus.h" #include "esphome/components/modbus/modbus.h"
#include <vector> #include <vector>
@ -22,6 +31,55 @@ class DalyHkmsBmsComponent : public PollingComponent, public modbus::ModbusDevic
SUB_SENSOR(voltage) SUB_SENSOR(voltage)
SUB_SENSOR(current) SUB_SENSOR(current)
SUB_SENSOR(battery_level) SUB_SENSOR(battery_level)
SUB_SENSOR(max_cell_voltage)
SUB_SENSOR(max_cell_voltage_number)
SUB_SENSOR(min_cell_voltage)
SUB_SENSOR(min_cell_voltage_number)
SUB_SENSOR(max_temperature)
SUB_SENSOR(max_temperature_probe_number)
SUB_SENSOR(min_temperature)
SUB_SENSOR(min_temperature_probe_number)
SUB_SENSOR(remaining_capacity)
SUB_SENSOR(cycles)
SUB_SENSOR(cells_number)
SUB_SENSOR(temps_number)
SUB_SENSOR(temperature_1)
SUB_SENSOR(temperature_2)
SUB_SENSOR(temperature_3)
SUB_SENSOR(temperature_4)
SUB_SENSOR(temperature_5)
SUB_SENSOR(temperature_6)
SUB_SENSOR(temperature_7)
SUB_SENSOR(temperature_8)
SUB_SENSOR(temperature_mos)
SUB_SENSOR(temperature_board)
SUB_SENSOR(cell_1_voltage)
SUB_SENSOR(cell_2_voltage)
SUB_SENSOR(cell_3_voltage)
SUB_SENSOR(cell_4_voltage)
SUB_SENSOR(cell_5_voltage)
SUB_SENSOR(cell_6_voltage)
SUB_SENSOR(cell_7_voltage)
SUB_SENSOR(cell_8_voltage)
SUB_SENSOR(cell_9_voltage)
SUB_SENSOR(cell_10_voltage)
SUB_SENSOR(cell_11_voltage)
SUB_SENSOR(cell_12_voltage)
SUB_SENSOR(cell_13_voltage)
SUB_SENSOR(cell_14_voltage)
SUB_SENSOR(cell_15_voltage)
SUB_SENSOR(cell_16_voltage)
#endif
#ifdef USE_TEXT_SENSOR
SUB_TEXT_SENSOR(status)
#endif
#ifdef USE_BINARY_SENSOR
SUB_BINARY_SENSOR(charging_mos_enabled)
SUB_BINARY_SENSOR(discharging_mos_enabled)
SUB_BINARY_SENSOR(precharging_mos_enabled)
SUB_BINARY_SENSOR(balancing_active)
#endif #endif
protected: protected:

View File

@ -0,0 +1,53 @@
#pragma once
namespace esphome {
namespace daly_hkms_bms {
// 0x00 - 0x2F
static const uint16_t DALY_MODBUS_ADDR_CELL_VOLT_1 = 0x00;
// 0x30 - 0x37
static const uint16_t DALY_MODBUS_ADDR_CELL_TEMP_1 = 0x30;
static const uint16_t DALY_MODBUS_ADDR_VOLT = 0x38;
static const uint16_t DALY_MODBUS_ADDR_CURR = 0x39;
static const uint16_t DALY_MODBUS_ADDR_SOC = 0x3A;
static const uint16_t DALY_MODBUS_ADDR_SOH = 0x3B;
static const uint16_t DALY_MODBUS_ADDR_CELL_COUNT = 0x3C;
static const uint16_t DALY_MODBUS_ADDR_CELL_TEMP_COUNT = 0x3D;
static const uint16_t DALY_MODBUS_ADDR_CELL_VOLT_MAX = 0x3E;
static const uint16_t DALY_MODBUS_ADDR_CELL_VOLT_MAX_NUM = 0x3F;
static const uint16_t DALY_MODBUS_ADDR_CELL_VOLT_MIN = 0x40;
static const uint16_t DALY_MODBUS_ADDR_CELL_VOLT_MIN_NUM = 0x41;
static const uint16_t DALY_MODBUS_ADDR_CELL_VOLT_DIFF = 0x42;
static const uint16_t DALY_MODBUS_ADDR_CELL_TEMP_MAX = 0x43;
static const uint16_t DALY_MODBUS_ADDR_CELL_TEMP_MAX_NUM = 0x44;
static const uint16_t DALY_MODBUS_ADDR_CELL_TEMP_MIN = 0x45;
static const uint16_t DALY_MODBUS_ADDR_CELL_TEMP_MIN_NUM = 0x46;
static const uint16_t DALY_MODBUS_ADDR_CELL_TEMP_DIFF = 0x47;
static const uint16_t DALY_MODBUS_ADDR_CHG_DSCHG_STATUS = 0x48;
static const uint16_t DALY_MODBUS_ADDR_REMAINING_CAPACITY = 0x4B;
static const uint16_t DALY_MODBUS_ADDR_CYCLES = 0x4C;
static const uint16_t DALY_MODBUS_ADDR_BALANCE_STATUS = 0x4D;
static const uint16_t DALY_MODBUS_ADDR_BALANCE_STATUS_PER_CELL_1_TO_16 = 0x4F;
static const uint16_t DALY_MODBUS_ADDR_BALANCE_STATUS_PER_CELL_17_TO_32 = 0x50;
static const uint16_t DALY_MODBUS_ADDR_BALANCE_STATUS_PER_CELL_33_TO_48 = 0x51;
static const uint16_t DALY_MODBUS_ADDR_CHG_MOS_ACTIVE = 0x52;
static const uint16_t DALY_MODBUS_ADDR_DSCHG_MOS_ACTIVE = 0x53;
static const uint16_t DALY_MODBUS_ADDR_PRECHG_MOS_ACTIVE = 0x54;
static const uint16_t DALY_MODBUS_ADDR_HEATING_MOS_ACTIVE = 0x55;
static const uint16_t DALY_MODBUS_ADDR_FAN_MOS_ACTIVE = 0x56;
static const uint16_t DALY_MODBUS_ADDR_POWER = 0x58;
static const uint16_t DALY_MODBUS_ADDR_ENERGY = 0x59;
static const uint16_t DALY_MODBUS_ADDR_MOS_TEMP = 0x5A;
static const uint16_t DALY_MODBUS_ADDR_BOARD_TEMP = 0x5B;
static const uint16_t DALY_MODBUS_ADDR_HEATING_TEMP = 0x5C;
static const uint16_t DALY_MODBUS_REGISTER_COUNT = 0x5D;
} // namespace daly_hkms_bms
} // namespace esphome

View File

@ -2,33 +2,137 @@ import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import sensor from esphome.components import sensor
from esphome.const import ( from esphome.const import (
CONF_CURRENT,
CONF_ID,
CONF_VOLTAGE, CONF_VOLTAGE,
CONF_CURRENT,
CONF_BATTERY_LEVEL, CONF_BATTERY_LEVEL,
DEVICE_CLASS_CURRENT, CONF_MAX_TEMPERATURE,
DEVICE_CLASS_POWER, CONF_MIN_TEMPERATURE,
DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_VOLTAGE,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_BATTERY, DEVICE_CLASS_BATTERY,
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT, STATE_CLASS_MEASUREMENT,
STATE_CLASS_TOTAL_INCREASING, UNIT_EMPTY,
UNIT_AMPERE,
UNIT_CELSIUS,
UNIT_VOLT, UNIT_VOLT,
UNIT_WATT, UNIT_AMPERE,
UNIT_PERCENT, UNIT_PERCENT,
UNIT_CELSIUS,
ICON_FLASH,
ICON_PERCENT, ICON_PERCENT,
ICON_COUNTER,
ICON_THERMOMETER,
ICON_GAUGE,
) )
from . import DalyHkmsBmsComponent, CONF_DALY_HKMS_BMS_ID from . import DalyHkmsBmsComponent, CONF_DALY_HKMS_BMS_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_PROBE_NUMBER = "max_temperature_probe_number"
CONF_MIN_TEMPERATURE_PROBE_NUMBER = "min_temperature_probe_number"
CONF_CELLS_NUMBER = "cells_number"
CONF_TEMPS_NUMBER = "temps_number"
CONF_REMAINING_CAPACITY = "remaining_capacity"
CONF_CYCLES = "cycles"
CONF_TEMPERATURE_1 = "temperature_1"
CONF_TEMPERATURE_2 = "temperature_2"
CONF_TEMPERATURE_3 = "temperature_3"
CONF_TEMPERATURE_4 = "temperature_4"
CONF_TEMPERATURE_5 = "temperature_5"
CONF_TEMPERATURE_6 = "temperature_6"
CONF_TEMPERATURE_7 = "temperature_7"
CONF_TEMPERATURE_8 = "temperature_8"
CONF_TEMPERATURE_MOS = "temperature_mos"
CONF_TEMPERATURE_BOARD = "temperature_board"
CONF_CELL_1_VOLTAGE = "cell_1_voltage"
CONF_CELL_2_VOLTAGE = "cell_2_voltage"
CONF_CELL_3_VOLTAGE = "cell_3_voltage"
CONF_CELL_4_VOLTAGE = "cell_4_voltage"
CONF_CELL_5_VOLTAGE = "cell_5_voltage"
CONF_CELL_6_VOLTAGE = "cell_6_voltage"
CONF_CELL_7_VOLTAGE = "cell_7_voltage"
CONF_CELL_8_VOLTAGE = "cell_8_voltage"
CONF_CELL_9_VOLTAGE = "cell_9_voltage"
CONF_CELL_10_VOLTAGE = "cell_10_voltage"
CONF_CELL_11_VOLTAGE = "cell_11_voltage"
CONF_CELL_12_VOLTAGE = "cell_12_voltage"
CONF_CELL_13_VOLTAGE = "cell_13_voltage"
CONF_CELL_14_VOLTAGE = "cell_14_voltage"
CONF_CELL_15_VOLTAGE = "cell_15_voltage"
CONF_CELL_16_VOLTAGE = "cell_16_voltage"
ICON_CURRENT_DC = "mdi:current-dc" 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 = [ TYPES = [
CONF_VOLTAGE, CONF_VOLTAGE,
CONF_CURRENT, CONF_CURRENT,
CONF_BATTERY_LEVEL, 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_TEMPS_NUMBER,
CONF_REMAINING_CAPACITY,
CONF_CYCLES,
CONF_TEMPERATURE_1,
CONF_TEMPERATURE_2,
CONF_TEMPERATURE_3,
CONF_TEMPERATURE_4,
CONF_TEMPERATURE_5,
CONF_TEMPERATURE_6,
CONF_TEMPERATURE_7,
CONF_TEMPERATURE_8,
CONF_TEMPERATURE_MOS,
CONF_TEMPERATURE_BOARD,
CONF_CELL_1_VOLTAGE,
CONF_CELL_2_VOLTAGE,
CONF_CELL_3_VOLTAGE,
CONF_CELL_4_VOLTAGE,
CONF_CELL_5_VOLTAGE,
CONF_CELL_6_VOLTAGE,
CONF_CELL_7_VOLTAGE,
CONF_CELL_8_VOLTAGE,
CONF_CELL_9_VOLTAGE,
CONF_CELL_10_VOLTAGE,
CONF_CELL_11_VOLTAGE,
CONF_CELL_12_VOLTAGE,
CONF_CELL_13_VOLTAGE,
CONF_CELL_14_VOLTAGE,
CONF_CELL_15_VOLTAGE,
CONF_CELL_16_VOLTAGE,
] ]
TEMPERATURE_SENSOR_SCHEMA = sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
icon=ICON_THERMOMETER,
accuracy_decimals=0,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
)
CELL_VOLTAGE_SCHEMA = sensor.sensor_schema(
unit_of_measurement=UNIT_VOLT,
device_class=DEVICE_CLASS_VOLTAGE,
state_class=STATE_CLASS_MEASUREMENT,
icon=ICON_FLASH,
accuracy_decimals=3,
)
CONFIG_SCHEMA = ( CONFIG_SCHEMA = (
cv.Schema( cv.Schema(
{ {
@ -54,6 +158,105 @@ CONFIG_SCHEMA = (
device_class=DEVICE_CLASS_BATTERY, device_class=DEVICE_CLASS_BATTERY,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ),
cv.Optional(CONF_MAX_CELL_VOLTAGE): sensor.sensor_schema(
unit_of_measurement=UNIT_VOLT,
icon=ICON_FLASH,
accuracy_decimals=3,
device_class=DEVICE_CLASS_VOLTAGE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_MAX_CELL_VOLTAGE_NUMBER): sensor.sensor_schema(
unit_of_measurement=UNIT_EMPTY,
icon=ICON_COUNTER,
accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_MIN_CELL_VOLTAGE): sensor.sensor_schema(
unit_of_measurement=UNIT_VOLT,
icon=ICON_FLASH,
accuracy_decimals=3,
device_class=DEVICE_CLASS_VOLTAGE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_MIN_CELL_VOLTAGE_NUMBER): sensor.sensor_schema(
unit_of_measurement=UNIT_EMPTY,
icon=ICON_COUNTER,
accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_MAX_TEMPERATURE): sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
icon=ICON_THERMOMETER_CHEVRON_UP,
accuracy_decimals=0,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_MAX_TEMPERATURE_PROBE_NUMBER): sensor.sensor_schema(
unit_of_measurement=UNIT_EMPTY,
icon=ICON_COUNTER,
accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_MIN_TEMPERATURE): sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
icon=ICON_THERMOMETER_CHEVRON_DOWN,
accuracy_decimals=0,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_MIN_TEMPERATURE_PROBE_NUMBER): sensor.sensor_schema(
unit_of_measurement=UNIT_EMPTY,
icon=ICON_COUNTER,
accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_REMAINING_CAPACITY): sensor.sensor_schema(
unit_of_measurement=UNIT_AMPERE_HOUR,
icon=ICON_GAUGE,
accuracy_decimals=1,
device_class=DEVICE_CLASS_VOLTAGE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_CYCLES): sensor.sensor_schema(
unit_of_measurement=UNIT_EMPTY,
icon=ICON_COUNTER,
accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_CELLS_NUMBER): sensor.sensor_schema(
icon=ICON_COUNTER,
accuracy_decimals=0,
),
cv.Optional(CONF_TEMPS_NUMBER): sensor.sensor_schema(
icon=ICON_COUNTER,
accuracy_decimals=0,
),
cv.Optional(CONF_TEMPERATURE_1): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_2): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_3): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_4): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_5): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_6): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_7): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_8): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_MOS): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_TEMPERATURE_BOARD): TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_CELL_1_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_2_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_3_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_4_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_5_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_6_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_7_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_8_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_9_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_10_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_11_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_12_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_13_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_14_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_15_VOLTAGE): CELL_VOLTAGE_SCHEMA,
cv.Optional(CONF_CELL_16_VOLTAGE): CELL_VOLTAGE_SCHEMA
} }
) )
.extend(cv.COMPONENT_SCHEMA) .extend(cv.COMPONENT_SCHEMA)

View File

@ -0,0 +1,34 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import text_sensor
from esphome.const import CONF_STATUS
from . import DalyHkmsBmsComponent, CONF_DALY_HKMS_BMS_ID
ICON_CAR_BATTERY = "mdi:car-battery"
TYPES = [
CONF_STATUS,
]
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(CONF_DALY_HKMS_BMS_ID): cv.use_id(DalyHkmsBmsComponent),
cv.Optional(CONF_STATUS): text_sensor.text_sensor_schema(
icon=ICON_CAR_BATTERY
),
}
).extend(cv.COMPONENT_SCHEMA)
)
async def setup_conf(config, key, hub):
if sensor_config := config.get(key):
sens = await text_sensor.new_text_sensor(sensor_config)
cg.add(getattr(hub, f"set_{key}_text_sensor")(sens))
async def to_code(config):
hub = await cg.get_variable(config[CONF_DALY_HKMS_BMS_ID])
for key in TYPES:
await setup_conf(config, key, hub)