diff --git a/esphome/components/bthome/__init__.py b/esphome/components/bthome/__init__.py index 5d4df43c00..fcba825f9b 100644 --- a/esphome/components/bthome/__init__.py +++ b/esphome/components/bthome/__init__.py @@ -4,13 +4,38 @@ from esphome.components.esp32 import add_idf_sdkconfig_option from esphome.components.esp32_ble import CONF_BLE_ID import esphome.config_validation as cv from esphome.const import ( + CONF_BINARY_SENSOR, CONF_ID, - CONF_BATTERY_LEVEL, - CONF_HUMIDITY, - CONF_ILLUMINANCE, - CONF_PRESSURE, - CONF_TEMPERATURE, CONF_TX_POWER, + DEVICE_CLASS_BATTERY, + DEVICE_CLASS_BATTERY_CHARGING, + DEVICE_CLASS_CARBON_DIOXIDE, + DEVICE_CLASS_CARBON_MONOXIDE, + DEVICE_CLASS_COLD, + DEVICE_CLASS_CURRENT, + DEVICE_CLASS_DOOR, + DEVICE_CLASS_EMPTY, + DEVICE_CLASS_ENERGY, + DEVICE_CLASS_GARAGE_DOOR, + DEVICE_CLASS_HUMIDITY, + DEVICE_CLASS_ILLUMINANCE, + DEVICE_CLASS_LIGHT, + DEVICE_CLASS_LOCK, + DEVICE_CLASS_MOISTURE, + DEVICE_CLASS_MOTION, + DEVICE_CLASS_OCCUPANCY, + DEVICE_CLASS_PM10, + DEVICE_CLASS_PM25, + DEVICE_CLASS_POWER, + DEVICE_CLASS_PRESSURE, + DEVICE_CLASS_SMOKE, + DEVICE_CLASS_SPEED, + DEVICE_CLASS_TEMPERATURE, + DEVICE_CLASS_TIMESTAMP, + DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS, + DEVICE_CLASS_VOLTAGE, + DEVICE_CLASS_WEIGHT, + DEVICE_CLASS_WINDOW, ) from esphome.core import TimePeriod @@ -33,96 +58,44 @@ CONF_MIN_INTERVAL = "min_interval" CONF_MAX_INTERVAL = "max_interval" CONF_SENSOR_TYPE = "type" -# Sensor type constants -CONF_BATTERY = "battery" -CONF_CO2 = "co2" -CONF_COUNT = "count" -CONF_CURRENT = "current" -CONF_DEWPOINT = "dewpoint" -CONF_DISTANCE = "distance" -CONF_ENERGY = "energy" -CONF_GAS = "gas" -CONF_MASS = "mass" -CONF_MOISTURE = "moisture" -CONF_PM25 = "pm2_5" -CONF_PM10 = "pm10" -CONF_POWER = "power" -CONF_ROTATION = "rotation" -CONF_SPEED = "speed" -CONF_TIMESTAMP = "timestamp" -CONF_TVOC = "tvoc" -CONF_VOLTAGE = "voltage" -CONF_VOLUME = "volume" - -# Binary sensor types -CONF_BINARY_SENSOR = "binary_sensor" -CONF_BATTERY_LOW = "battery_low" -CONF_BATTERY_CHARGING = "battery_charging" -CONF_CO = "carbon_monoxide" -CONF_COLD = "cold" -CONF_CONNECTIVITY = "connectivity" -CONF_DOOR = "door" -CONF_GARAGE_DOOR = "garage_door" -CONF_GAS_DETECTED = "gas" -CONF_GENERIC_BOOLEAN = "generic_boolean" -CONF_HEAT = "heat" -CONF_LIGHT = "light" -CONF_LOCK = "lock" -CONF_MOISTURE_DETECTED = "moisture" -CONF_MOTION = "motion" -CONF_MOVING = "moving" -CONF_OCCUPANCY = "occupancy" -CONF_OPENING = "opening" -CONF_PLUG = "plug" -CONF_POWER_ON = "power" -CONF_PRESENCE = "presence" -CONF_PROBLEM = "problem" -CONF_RUNNING = "running" -CONF_SAFETY = "safety" -CONF_SMOKE = "smoke" -CONF_SOUND = "sound" -CONF_TAMPER = "tamper" -CONF_VIBRATION = "vibration" -CONF_WINDOW = "window" - -# BTHome object IDs for sensors -SENSOR_OBJECT_IDS = { - CONF_BATTERY: 0x01, - CONF_TEMPERATURE: 0x02, # 0.01°C - CONF_HUMIDITY: 0x03, - CONF_PRESSURE: 0x04, - CONF_ILLUMINANCE: 0x05, - CONF_MASS: 0x06, - CONF_DEWPOINT: 0x08, - CONF_ENERGY: 0x0A, - CONF_POWER: 0x0B, - CONF_VOLTAGE: 0x0C, - CONF_PM25: 0x0D, - CONF_PM10: 0x0E, - CONF_CO2: 0x12, - CONF_TVOC: 0x13, - CONF_MOISTURE: 0x14, - CONF_CURRENT: 0x43, - CONF_SPEED: 0x44, - CONF_TIMESTAMP: 0x50, +# BTHome object IDs for sensors (mapping from device class to BTHome object ID) +SENSOR_DEVICE_CLASS_TO_OBJECT_ID = { + DEVICE_CLASS_BATTERY: 0x01, + DEVICE_CLASS_TEMPERATURE: 0x02, # 0.01°C + DEVICE_CLASS_HUMIDITY: 0x03, + DEVICE_CLASS_PRESSURE: 0x04, + DEVICE_CLASS_ILLUMINANCE: 0x05, + DEVICE_CLASS_WEIGHT: 0x06, # mass in kg + "dewpoint": 0x08, # Not a standard device class + DEVICE_CLASS_ENERGY: 0x0A, + DEVICE_CLASS_POWER: 0x0B, + DEVICE_CLASS_VOLTAGE: 0x0C, + DEVICE_CLASS_PM25: 0x0D, + DEVICE_CLASS_PM10: 0x0E, + DEVICE_CLASS_CARBON_DIOXIDE: 0x12, + DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS: 0x13, # TVOC + DEVICE_CLASS_MOISTURE: 0x14, + DEVICE_CLASS_CURRENT: 0x43, + DEVICE_CLASS_SPEED: 0x44, + DEVICE_CLASS_TIMESTAMP: 0x50, } -# BTHome object IDs for binary sensors -BINARY_SENSOR_OBJECT_IDS = { - CONF_GENERIC_BOOLEAN: 0x0F, - CONF_POWER_ON: 0x10, - CONF_BATTERY_LOW: 0x15, - CONF_BATTERY_CHARGING: 0x16, - CONF_CO: 0x17, - CONF_COLD: 0x18, - CONF_DOOR: 0x1A, - CONF_GARAGE_DOOR: 0x1B, - CONF_LIGHT: 0x1E, - CONF_LOCK: 0x1F, - CONF_MOTION: 0x21, - CONF_OCCUPANCY: 0x23, - CONF_SMOKE: 0x29, - CONF_WINDOW: 0x2D, +# BTHome object IDs for binary sensors (mapping from device class to BTHome object ID) +BINARY_SENSOR_DEVICE_CLASS_TO_OBJECT_ID = { + DEVICE_CLASS_EMPTY: 0x0F, # generic boolean + "power": 0x10, # power state (not DEVICE_CLASS_POWER which is for sensors) + "battery_low": 0x15, # Not a standard device class + DEVICE_CLASS_BATTERY_CHARGING: 0x16, + DEVICE_CLASS_CARBON_MONOXIDE: 0x17, + DEVICE_CLASS_COLD: 0x18, + DEVICE_CLASS_DOOR: 0x1A, + DEVICE_CLASS_GARAGE_DOOR: 0x1B, + DEVICE_CLASS_LIGHT: 0x1E, + DEVICE_CLASS_LOCK: 0x1F, + DEVICE_CLASS_MOTION: 0x21, + DEVICE_CLASS_OCCUPANCY: 0x23, + DEVICE_CLASS_SMOKE: 0x29, + DEVICE_CLASS_WINDOW: 0x2D, } @@ -171,7 +144,7 @@ CONFIG_SCHEMA = cv.All( cv.Schema( { cv.Required(CONF_SENSOR_TYPE): cv.one_of( - *SENSOR_OBJECT_IDS.keys(), lower=True + *SENSOR_DEVICE_CLASS_TO_OBJECT_ID.keys(), lower=True ), cv.Required(CONF_ID): cv.use_id(sensor.Sensor), } @@ -181,7 +154,7 @@ CONFIG_SCHEMA = cv.All( cv.Schema( { cv.Required(CONF_SENSOR_TYPE): cv.one_of( - *BINARY_SENSOR_OBJECT_IDS.keys(), lower=True + *BINARY_SENSOR_DEVICE_CLASS_TO_OBJECT_ID.keys(), lower=True ), cv.Required(CONF_ID): cv.use_id(binary_sensor.BinarySensor), } @@ -215,7 +188,7 @@ async def to_code(config): if CONF_MEASUREMENT in config: for measurement in config[CONF_MEASUREMENT]: sensor_type = measurement[CONF_SENSOR_TYPE] - object_id = SENSOR_OBJECT_IDS[sensor_type] + object_id = SENSOR_DEVICE_CLASS_TO_OBJECT_ID[sensor_type] sens = await cg.get_variable(measurement[CONF_ID]) cg.add(var.add_measurement(sens, object_id)) @@ -223,7 +196,7 @@ async def to_code(config): if CONF_BINARY_SENSOR in config: for measurement in config[CONF_BINARY_SENSOR]: sensor_type = measurement[CONF_SENSOR_TYPE] - object_id = BINARY_SENSOR_OBJECT_IDS[sensor_type] + object_id = BINARY_SENSOR_DEVICE_CLASS_TO_OBJECT_ID[sensor_type] sens = await cg.get_variable(measurement[CONF_ID]) cg.add(var.add_binary_measurement(sens, object_id))