mirror of
https://github.com/esphome/esphome.git
synced 2024-11-23 23:48:11 +01:00
DALY Modbus BMS: use loops for cell voltage configs
This commit is contained in:
parent
2f6d552589
commit
b024e79687
3 changed files with 62 additions and 89 deletions
|
@ -14,7 +14,6 @@ static const uint8_t DALY_MODBUS_REQUEST_ADDRESS_OFFSET = 0x80;
|
||||||
static const uint8_t DALY_MODBUS_RESPONSE_ADDRESS_OFFSET = 0x50;
|
static const uint8_t DALY_MODBUS_RESPONSE_ADDRESS_OFFSET = 0x50;
|
||||||
|
|
||||||
static const uint8_t DALY_MODBUS_READ_CELL_VOLTAGES_ADDR = DALY_MODBUS_ADDR_CELL_VOLT_1;
|
static const uint8_t DALY_MODBUS_READ_CELL_VOLTAGES_ADDR = DALY_MODBUS_ADDR_CELL_VOLT_1;
|
||||||
static const uint8_t DALY_MODBUS_READ_CELL_VOLTAGES_LENGTH = 16; // 16 cell voltages
|
|
||||||
|
|
||||||
static const uint8_t DALY_MODBUS_READ_DATA_ADDR = DALY_MODBUS_ADDR_CELL_TEMP_1;
|
static const uint8_t DALY_MODBUS_READ_DATA_ADDR = DALY_MODBUS_ADDR_CELL_TEMP_1;
|
||||||
static const uint8_t DALY_MODBUS_READ_DATA_LENGTH = DALY_MODBUS_REGISTER_MAX - DALY_MODBUS_ADDR_CELL_TEMP_1 + 1;
|
static const uint8_t DALY_MODBUS_READ_DATA_LENGTH = DALY_MODBUS_REGISTER_MAX - DALY_MODBUS_ADDR_CELL_TEMP_1 + 1;
|
||||||
|
@ -52,7 +51,8 @@ void DalyHkmsBmsComponent::loop() {
|
||||||
{
|
{
|
||||||
case ReadState::READ_CELL_VOLTAGES:
|
case ReadState::READ_CELL_VOLTAGES:
|
||||||
start_address = DALY_MODBUS_READ_CELL_VOLTAGES_ADDR;
|
start_address = DALY_MODBUS_READ_CELL_VOLTAGES_ADDR;
|
||||||
register_count = DALY_MODBUS_READ_CELL_VOLTAGES_LENGTH;
|
// avoid reading all 48 cell voltages if we only want 16 or so
|
||||||
|
register_count = this->cell_voltage_sensors_max_;
|
||||||
break;
|
break;
|
||||||
case ReadState::READ_DATA:
|
case ReadState::READ_DATA:
|
||||||
start_address = DALY_MODBUS_READ_DATA_ADDR;
|
start_address = DALY_MODBUS_READ_DATA_ADDR;
|
||||||
|
@ -76,7 +76,7 @@ void DalyHkmsBmsComponent::loop() {
|
||||||
|
|
||||||
void DalyHkmsBmsComponent::update() {
|
void DalyHkmsBmsComponent::update() {
|
||||||
if(this->read_state_ == ReadState::IDLE){
|
if(this->read_state_ == ReadState::IDLE){
|
||||||
this->read_state_ = ReadState::READ_CELL_VOLTAGES;
|
this->advance_read_state();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void DalyHkmsBmsComponent::on_modbus_data(const std::vector<uint8_t> &data) {
|
||||||
{
|
{
|
||||||
case ReadState::READ_CELL_VOLTAGES:
|
case ReadState::READ_CELL_VOLTAGES:
|
||||||
register_offset = DALY_MODBUS_READ_CELL_VOLTAGES_ADDR;
|
register_offset = DALY_MODBUS_READ_CELL_VOLTAGES_ADDR;
|
||||||
register_count = DALY_MODBUS_READ_CELL_VOLTAGES_LENGTH;
|
register_count = this->cell_voltage_sensors_max_;
|
||||||
break;
|
break;
|
||||||
case ReadState::READ_DATA:
|
case ReadState::READ_DATA:
|
||||||
register_offset = DALY_MODBUS_READ_DATA_ADDR;
|
register_offset = DALY_MODBUS_READ_DATA_ADDR;
|
||||||
|
@ -129,25 +129,11 @@ void DalyHkmsBmsComponent::on_modbus_data(const std::vector<uint8_t> &data) {
|
||||||
|
|
||||||
if (this->read_state_ == ReadState::READ_CELL_VOLTAGES) {
|
if (this->read_state_ == ReadState::READ_CELL_VOLTAGES) {
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
publish_sensor_state(this->cell_1_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 , 0, 0.001);
|
for (size_t i = 0; i < this->cell_voltage_sensors_max_; i++)
|
||||||
publish_sensor_state(this->cell_2_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 1 , 0, 0.001);
|
{
|
||||||
publish_sensor_state(this->cell_3_voltage_sensor_ , DALY_MODBUS_ADDR_CELL_VOLT_1 + 2 , 0, 0.001);
|
publish_sensor_state(this->cell_voltage_sensors_[i], register_offset, DALY_MODBUS_ADDR_CELL_VOLT_1 + i, 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);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->read_state_ = ReadState::READ_DATA;
|
|
||||||
} else if (this->read_state_ == ReadState::READ_DATA) {
|
} else if (this->read_state_ == ReadState::READ_DATA) {
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
publish_sensor_state(this->temperature_1_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 , -40, 1, 255);
|
publish_sensor_state(this->temperature_1_sensor_, DALY_MODBUS_ADDR_CELL_TEMP_1 , -40, 1, 255);
|
||||||
|
@ -217,8 +203,27 @@ void DalyHkmsBmsComponent::on_modbus_data(const std::vector<uint8_t> &data) {
|
||||||
this->precharging_mos_enabled_binary_sensor_->publish_state(get_register(DALY_MODBUS_ADDR_PRECHG_MOS_ACTIVE) > 0);
|
this->precharging_mos_enabled_binary_sensor_->publish_state(get_register(DALY_MODBUS_ADDR_PRECHG_MOS_ACTIVE) > 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
this->advance_read_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DalyHkmsBmsComponent::advance_read_state() {
|
||||||
|
switch (this->read_state_)
|
||||||
|
{
|
||||||
|
case ReadState::IDLE:
|
||||||
|
// skip reading cell voltages if there are no cell voltage sensors
|
||||||
|
if (this->cell_voltage_sensors_max_ == 0) {
|
||||||
|
this->read_state_ = ReadState::READ_DATA;
|
||||||
|
} else {
|
||||||
|
this->read_state_ = ReadState::READ_CELL_VOLTAGES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ReadState::READ_CELL_VOLTAGES:
|
||||||
|
this->read_state_ = ReadState::READ_DATA;
|
||||||
|
break;
|
||||||
|
case ReadState::READ_DATA:
|
||||||
this->read_state_ = ReadState::IDLE;
|
this->read_state_ = ReadState::IDLE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace daly_hkms_bms {
|
namespace daly_hkms_bms {
|
||||||
|
|
||||||
|
static const uint8_t DALY_MODBUS_MAX_CELL_COUNT = 48;
|
||||||
|
|
||||||
class DalyHkmsBmsComponent : public PollingComponent, public modbus::ModbusDevice {
|
class DalyHkmsBmsComponent : public PollingComponent, public modbus::ModbusDevice {
|
||||||
public:
|
public:
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
@ -28,6 +30,12 @@ class DalyHkmsBmsComponent : public PollingComponent, public modbus::ModbusDevic
|
||||||
void set_daly_address(uint8_t address);
|
void set_daly_address(uint8_t address);
|
||||||
|
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
|
void set_cell_voltage_sensor(size_t cell, sensor::Sensor *sensor) {
|
||||||
|
if(cell > this->cell_voltage_sensors_max_)
|
||||||
|
this->cell_voltage_sensors_max_ = cell;
|
||||||
|
this->cell_voltage_sensors_[cell-1] = sensor;
|
||||||
|
};
|
||||||
|
|
||||||
SUB_SENSOR(voltage)
|
SUB_SENSOR(voltage)
|
||||||
SUB_SENSOR(current)
|
SUB_SENSOR(current)
|
||||||
SUB_SENSOR(battery_level)
|
SUB_SENSOR(battery_level)
|
||||||
|
@ -53,22 +61,6 @@ class DalyHkmsBmsComponent : public PollingComponent, public modbus::ModbusDevic
|
||||||
SUB_SENSOR(temperature_8)
|
SUB_SENSOR(temperature_8)
|
||||||
SUB_SENSOR(temperature_mos)
|
SUB_SENSOR(temperature_mos)
|
||||||
SUB_SENSOR(temperature_board)
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
@ -87,8 +79,12 @@ class DalyHkmsBmsComponent : public PollingComponent, public modbus::ModbusDevic
|
||||||
uint32_t last_send_;
|
uint32_t last_send_;
|
||||||
uint8_t daly_address_;
|
uint8_t daly_address_;
|
||||||
|
|
||||||
enum class ReadState{ READ_CELL_VOLTAGES, READ_DATA, IDLE } read_state_{ReadState::IDLE};
|
sensor::Sensor *cell_voltage_sensors_[DALY_MODBUS_MAX_CELL_COUNT]{};
|
||||||
|
size_t cell_voltage_sensors_max_{0};
|
||||||
|
|
||||||
|
void advance_read_state();
|
||||||
|
|
||||||
|
enum class ReadState{ READ_CELL_VOLTAGES, READ_DATA, IDLE } read_state_{ReadState::IDLE};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace daly_hkms_bms
|
} // namespace daly_hkms_bms
|
||||||
|
|
|
@ -48,23 +48,6 @@ CONF_TEMPERATURE_8 = "temperature_8"
|
||||||
CONF_TEMPERATURE_MOS = "temperature_mos"
|
CONF_TEMPERATURE_MOS = "temperature_mos"
|
||||||
CONF_TEMPERATURE_BOARD = "temperature_board"
|
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_BATTERY_OUTLINE = "mdi:battery-outline"
|
||||||
ICON_THERMOMETER_CHEVRON_UP = "mdi:thermometer-chevron-up"
|
ICON_THERMOMETER_CHEVRON_UP = "mdi:thermometer-chevron-up"
|
||||||
|
@ -73,6 +56,8 @@ ICON_CAR_BATTERY = "mdi:car-battery"
|
||||||
|
|
||||||
UNIT_AMPERE_HOUR = "Ah"
|
UNIT_AMPERE_HOUR = "Ah"
|
||||||
|
|
||||||
|
MAX_CELL_NUMBER = 48
|
||||||
|
|
||||||
TYPES = [
|
TYPES = [
|
||||||
CONF_VOLTAGE,
|
CONF_VOLTAGE,
|
||||||
CONF_CURRENT,
|
CONF_CURRENT,
|
||||||
|
@ -99,22 +84,7 @@ TYPES = [
|
||||||
CONF_TEMPERATURE_8,
|
CONF_TEMPERATURE_8,
|
||||||
CONF_TEMPERATURE_MOS,
|
CONF_TEMPERATURE_MOS,
|
||||||
CONF_TEMPERATURE_BOARD,
|
CONF_TEMPERATURE_BOARD,
|
||||||
CONF_CELL_1_VOLTAGE,
|
# Cell voltages are handled by loops below
|
||||||
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(
|
TEMPERATURE_SENSOR_SCHEMA = sensor.sensor_schema(
|
||||||
|
@ -133,6 +103,15 @@ CELL_VOLTAGE_SCHEMA = sensor.sensor_schema(
|
||||||
accuracy_decimals=3,
|
accuracy_decimals=3,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_cell_voltage_key(cell):
|
||||||
|
return f"cell_{cell}_voltage"
|
||||||
|
|
||||||
|
def get_cell_voltages_schema():
|
||||||
|
schema_obj = {}
|
||||||
|
for i in range(1, MAX_CELL_NUMBER+1):
|
||||||
|
schema_obj[cv.Optional(get_cell_voltage_key(i))] = CELL_VOLTAGE_SCHEMA
|
||||||
|
return cv.Schema(schema_obj)
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
|
@ -241,24 +220,9 @@ CONFIG_SCHEMA = (
|
||||||
cv.Optional(CONF_TEMPERATURE_8): TEMPERATURE_SENSOR_SCHEMA,
|
cv.Optional(CONF_TEMPERATURE_8): TEMPERATURE_SENSOR_SCHEMA,
|
||||||
cv.Optional(CONF_TEMPERATURE_MOS): TEMPERATURE_SENSOR_SCHEMA,
|
cv.Optional(CONF_TEMPERATURE_MOS): TEMPERATURE_SENSOR_SCHEMA,
|
||||||
cv.Optional(CONF_TEMPERATURE_BOARD): 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(get_cell_voltages_schema())
|
||||||
.extend(cv.COMPONENT_SCHEMA)
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -267,7 +231,15 @@ async def setup_conf(config, key, hub):
|
||||||
sens = await sensor.new_sensor(sensor_config)
|
sens = await sensor.new_sensor(sensor_config)
|
||||||
cg.add(getattr(hub, f"set_{key}_sensor")(sens))
|
cg.add(getattr(hub, f"set_{key}_sensor")(sens))
|
||||||
|
|
||||||
|
async def setup_cell_voltage_conf(config, cell, hub):
|
||||||
|
key = get_cell_voltage_key(cell)
|
||||||
|
if sensor_config := config.get(key):
|
||||||
|
sens = await sensor.new_sensor(sensor_config)
|
||||||
|
cg.add(hub.set_cell_voltage_sensor(cell, sens))
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
hub = await cg.get_variable(config[CONF_DALY_HKMS_BMS_ID])
|
hub = await cg.get_variable(config[CONF_DALY_HKMS_BMS_ID])
|
||||||
for key in TYPES:
|
for key in TYPES:
|
||||||
await setup_conf(config, key, hub)
|
await setup_conf(config, key, hub)
|
||||||
|
for i in range(1, MAX_CELL_NUMBER+1):
|
||||||
|
await setup_cell_voltage_conf(config, i, hub)
|
||||||
|
|
Loading…
Reference in a new issue