mirror of
https://github.com/esphome/esphome.git
synced 2026-10-18 04:02:54 +00:00
[bq76972] Expose the sensors as a sensor platform (#21006)
This commit is contained in:
@@ -1,18 +1,10 @@
|
||||
from esphome import automation
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.components import i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ADDRESS,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_VOLT,
|
||||
)
|
||||
from esphome.const import CONF_ADDRESS
|
||||
from esphome.types import ConfigType
|
||||
|
||||
AUTO_LOAD = ["sensor"]
|
||||
CODEOWNERS = ["@limpkin"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
DOMAIN = "bq76972"
|
||||
@@ -25,37 +17,7 @@ BQ76972Component = bq76972_ns.class_(
|
||||
|
||||
CONF_REG_DISABLED = "reg_disabled"
|
||||
CONF_CRC_ENABLED = "crc_enabled"
|
||||
CONF_STACK_VOLTAGE = "stack_voltage"
|
||||
|
||||
# Ordered as the chip reports them, starting at command 0x68
|
||||
CONF_TEMPERATURES = [
|
||||
"internal_temperature",
|
||||
"cfetoff_temperature",
|
||||
"dfetoff_temperature",
|
||||
"alert_temperature",
|
||||
"ts1_temperature",
|
||||
"ts2_temperature",
|
||||
"ts3_temperature",
|
||||
"hdq_temperature",
|
||||
"dchg_temperature",
|
||||
"ddsg_temperature",
|
||||
]
|
||||
|
||||
CONF_CELL_VOLTAGES = [f"cell_{i}_voltage" for i in range(1, 17)]
|
||||
|
||||
voltage_sensor_schema = sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
accuracy_decimals=3,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
)
|
||||
|
||||
temp_sensor_schema = sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
)
|
||||
CONF_BQ76972_ID = "bq76972_id"
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
@@ -63,9 +25,6 @@ CONFIG_SCHEMA = (
|
||||
cv.GenerateID(): cv.declare_id(BQ76972Component),
|
||||
cv.Optional(CONF_CRC_ENABLED, default=False): cv.boolean,
|
||||
cv.Optional(CONF_REG_DISABLED, default=False): cv.boolean,
|
||||
cv.Optional(CONF_STACK_VOLTAGE): voltage_sensor_schema,
|
||||
**{cv.Optional(key): voltage_sensor_schema for key in CONF_CELL_VOLTAGES},
|
||||
**{cv.Optional(key): temp_sensor_schema for key in CONF_TEMPERATURES},
|
||||
}
|
||||
)
|
||||
.extend(i2c.i2c_device_schema(0x08))
|
||||
@@ -79,19 +38,6 @@ async def to_code(config: ConfigType) -> None:
|
||||
cg.add(var.set_crc_mode(config[CONF_CRC_ENABLED]))
|
||||
cg.add(var.set_reg_disable(config[CONF_REG_DISABLED]))
|
||||
|
||||
sensors = sensor.sub_sensors(config)
|
||||
await sensors(CONF_STACK_VOLTAGE, var.set_stack_voltage_sensor)
|
||||
|
||||
for idx, key in enumerate(CONF_TEMPERATURES):
|
||||
if (conf := config.get(key)) is not None:
|
||||
sens = await sensor.new_sensor(conf)
|
||||
cg.add(var.set_temperature_sensor(sens, idx))
|
||||
|
||||
for idx, key in enumerate(CONF_CELL_VOLTAGES):
|
||||
if (conf := config.get(key)) is not None:
|
||||
sens = await sensor.new_sensor(conf)
|
||||
cg.add(var.set_cell_sensor(sens, idx))
|
||||
|
||||
|
||||
BQ76972_PROGRAM_I2C_ADDRESS_SCHEMA = cv.maybe_simple_value(
|
||||
{
|
||||
|
||||
@@ -172,10 +172,12 @@ const LogString *BQ76972Component::configure_() {
|
||||
const bool write_regs = !regs_disabled;
|
||||
|
||||
bool write_thermistors = false;
|
||||
#ifdef USE_SENSOR
|
||||
for (size_t i = 1; i < BQ76972_NUM_TEMPERATURES; i++) {
|
||||
if (i != BQ76972_TS1_INDEX && this->temperature_sensors_[i] != nullptr)
|
||||
write_thermistors = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (write_regs || write_thermistors) {
|
||||
if (!this->enter_cfg_update_())
|
||||
@@ -201,12 +203,14 @@ const LogString *BQ76972Component::write_config_(bool write_regs) {
|
||||
!this->write_subcommand_(BQ76972_MEM_REG0_CONFIG, &zero, 1))
|
||||
return LOG_STR("Writing regulator config failed");
|
||||
}
|
||||
#ifdef USE_SENSOR
|
||||
for (size_t i = 1; i < BQ76972_NUM_TEMPERATURES; i++) {
|
||||
if (i == BQ76972_TS1_INDEX || this->temperature_sensors_[i] == nullptr)
|
||||
continue;
|
||||
if (!this->write_subcommand_(BQ76972_MEM_TEMP_PIN_CONFIG_BASE + i, &BQ76972_PIN_CONFIG_THERMISTOR, 1))
|
||||
return LOG_STR("Writing thermistor pin config failed");
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -248,6 +252,7 @@ void BQ76972Component::program_i2c_address(uint8_t address) {
|
||||
ESP_LOGI(TAG, "I2C address set to 0x%02X", address);
|
||||
}
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
template<size_t N> static bool any_set(const std::array<sensor::Sensor *, N> &sensors) {
|
||||
for (auto *sensor : sensors) {
|
||||
if (sensor != nullptr)
|
||||
@@ -294,5 +299,8 @@ void BQ76972Component::update() {
|
||||
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
|
||||
}
|
||||
}
|
||||
#else
|
||||
void BQ76972Component::update() {}
|
||||
#endif
|
||||
|
||||
} // namespace esphome::bq76972
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/defines.h"
|
||||
#ifdef USE_SENSOR
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -19,9 +22,11 @@ class BQ76972Component final : public PollingComponent, public i2c::I2CDevice {
|
||||
|
||||
void set_crc_mode(bool crc_mode) { this->crc_mode_ = crc_mode; }
|
||||
void set_reg_disable(bool reg_disable) { this->reg_disable_ = reg_disable; }
|
||||
#ifdef USE_SENSOR
|
||||
void set_stack_voltage_sensor(sensor::Sensor *s) { this->stack_voltage_sensor_ = s; }
|
||||
void set_cell_sensor(sensor::Sensor *s, size_t index) { this->cell_sensors_[index] = s; }
|
||||
void set_temperature_sensor(sensor::Sensor *s, size_t index) { this->temperature_sensors_[index] = s; }
|
||||
#endif
|
||||
|
||||
void program_i2c_address(uint8_t address);
|
||||
|
||||
@@ -43,9 +48,11 @@ class BQ76972Component final : public PollingComponent, public i2c::I2CDevice {
|
||||
bool reg_disable_{false};
|
||||
bool crc_mode_{false};
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
sensor::Sensor *stack_voltage_sensor_{nullptr};
|
||||
std::array<sensor::Sensor *, BQ76972_NUM_CELLS> cell_sensors_{};
|
||||
std::array<sensor::Sensor *, BQ76972_NUM_TEMPERATURES> temperature_sensors_{};
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace esphome::bq76972
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import sensor
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_VOLT,
|
||||
)
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from . import CONF_BQ76972_ID, BQ76972Component
|
||||
|
||||
DEPENDENCIES = ["bq76972"]
|
||||
|
||||
CONF_STACK_VOLTAGE = "stack_voltage"
|
||||
|
||||
# Ordered as the chip reports them, starting at command 0x68
|
||||
CONF_TEMPERATURES = [
|
||||
"internal_temperature",
|
||||
"cfetoff_temperature",
|
||||
"dfetoff_temperature",
|
||||
"alert_temperature",
|
||||
"ts1_temperature",
|
||||
"ts2_temperature",
|
||||
"ts3_temperature",
|
||||
"hdq_temperature",
|
||||
"dchg_temperature",
|
||||
"ddsg_temperature",
|
||||
]
|
||||
|
||||
CONF_CELL_VOLTAGES = [f"cell_{i}_voltage" for i in range(1, 17)]
|
||||
|
||||
voltage_sensor_schema = sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
accuracy_decimals=3,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
)
|
||||
|
||||
temp_sensor_schema = sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_BQ76972_ID): cv.use_id(BQ76972Component),
|
||||
cv.Optional(CONF_STACK_VOLTAGE): voltage_sensor_schema,
|
||||
**{cv.Optional(key): voltage_sensor_schema for key in CONF_CELL_VOLTAGES},
|
||||
**{cv.Optional(key): temp_sensor_schema for key in CONF_TEMPERATURES},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
hub = await cg.get_variable(config[CONF_BQ76972_ID])
|
||||
|
||||
sensors = sensor.sub_sensors(config)
|
||||
await sensors(CONF_STACK_VOLTAGE, hub.set_stack_voltage_sensor)
|
||||
|
||||
for idx, key in enumerate(CONF_TEMPERATURES):
|
||||
if (conf := config.get(key)) is not None:
|
||||
sens = await sensor.new_sensor(conf)
|
||||
cg.add(hub.set_temperature_sensor(sens, idx))
|
||||
|
||||
for idx, key in enumerate(CONF_CELL_VOLTAGES):
|
||||
if (conf := config.get(key)) is not None:
|
||||
sens = await sensor.new_sensor(conf)
|
||||
cg.add(hub.set_cell_sensor(sens, idx))
|
||||
@@ -1,60 +1,64 @@
|
||||
bq76972:
|
||||
id: bq76972_id
|
||||
id: bms
|
||||
i2c_id: i2c_bus
|
||||
address: 0x08
|
||||
crc_enabled: true
|
||||
reg_disabled: true
|
||||
update_interval: 10s
|
||||
stack_voltage:
|
||||
name: "Pack Total Voltage"
|
||||
internal_temperature:
|
||||
name: "Temperature - Internal"
|
||||
ts1_temperature:
|
||||
name: "Temperature - Pin TS1"
|
||||
ts2_temperature:
|
||||
name: "Temperature - Pin TS2"
|
||||
ts3_temperature:
|
||||
name: "Temperature - Pin TS3"
|
||||
hdq_temperature:
|
||||
name: "Temperature - Pin HDQ"
|
||||
cell_1_voltage:
|
||||
name: "Cell 1 Voltage"
|
||||
cell_2_voltage:
|
||||
name: "Cell 2 Voltage"
|
||||
cell_3_voltage:
|
||||
name: "Cell 3 Voltage"
|
||||
cell_4_voltage:
|
||||
name: "Cell 4 Voltage"
|
||||
cell_5_voltage:
|
||||
name: "Cell 5 Voltage"
|
||||
cell_6_voltage:
|
||||
name: "Cell 6 Voltage"
|
||||
cell_7_voltage:
|
||||
name: "Cell 7 Voltage"
|
||||
cell_8_voltage:
|
||||
name: "Cell 8 Voltage"
|
||||
cell_9_voltage:
|
||||
name: "Cell 9 Voltage"
|
||||
cell_10_voltage:
|
||||
name: "Cell 10 Voltage"
|
||||
cell_11_voltage:
|
||||
name: "Cell 11 Voltage"
|
||||
cell_12_voltage:
|
||||
name: "Cell 12 Voltage"
|
||||
cell_13_voltage:
|
||||
name: "Cell 13 Voltage"
|
||||
cell_14_voltage:
|
||||
name: "Cell 14 Voltage"
|
||||
cell_15_voltage:
|
||||
name: "Cell 15 Voltage"
|
||||
cell_16_voltage:
|
||||
name: "Cell 16 Voltage"
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: "Program BQ I2C Address"
|
||||
on_press:
|
||||
- bq76972.program_i2c_address:
|
||||
id: bq76972_id
|
||||
id: bms
|
||||
address: 0x09
|
||||
- bq76972.program_i2c_address: !lambda "return 0x08;"
|
||||
|
||||
sensor:
|
||||
- platform: bq76972
|
||||
bq76972_id: bms
|
||||
stack_voltage:
|
||||
name: "Pack Total Voltage"
|
||||
internal_temperature:
|
||||
name: "Temperature - Internal"
|
||||
ts1_temperature:
|
||||
name: "Temperature - Pin TS1"
|
||||
ts2_temperature:
|
||||
name: "Temperature - Pin TS2"
|
||||
ts3_temperature:
|
||||
name: "Temperature - Pin TS3"
|
||||
hdq_temperature:
|
||||
name: "Temperature - Pin HDQ"
|
||||
cell_1_voltage:
|
||||
name: "Cell 1 Voltage"
|
||||
cell_2_voltage:
|
||||
name: "Cell 2 Voltage"
|
||||
cell_3_voltage:
|
||||
name: "Cell 3 Voltage"
|
||||
cell_4_voltage:
|
||||
name: "Cell 4 Voltage"
|
||||
cell_5_voltage:
|
||||
name: "Cell 5 Voltage"
|
||||
cell_6_voltage:
|
||||
name: "Cell 6 Voltage"
|
||||
cell_7_voltage:
|
||||
name: "Cell 7 Voltage"
|
||||
cell_8_voltage:
|
||||
name: "Cell 8 Voltage"
|
||||
cell_9_voltage:
|
||||
name: "Cell 9 Voltage"
|
||||
cell_10_voltage:
|
||||
name: "Cell 10 Voltage"
|
||||
cell_11_voltage:
|
||||
name: "Cell 11 Voltage"
|
||||
cell_12_voltage:
|
||||
name: "Cell 12 Voltage"
|
||||
cell_13_voltage:
|
||||
name: "Cell 13 Voltage"
|
||||
cell_14_voltage:
|
||||
name: "Cell 14 Voltage"
|
||||
cell_15_voltage:
|
||||
name: "Cell 15 Voltage"
|
||||
cell_16_voltage:
|
||||
name: "Cell 16 Voltage"
|
||||
|
||||
Reference in New Issue
Block a user