Automate syncing device classes with HA (#4438)

* Sync device classes with HA

* Rename blacklist
This commit is contained in:
Oxan van Leeuwen 2023-02-16 01:28:12 +01:00 committed by GitHub
parent dbe5587806
commit 9aed758d1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 169 additions and 62 deletions

View file

@ -27,13 +27,13 @@ from esphome.const import (
CONF_TIMING,
CONF_TRIGGER_ID,
CONF_MQTT_ID,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_BATTERY_CHARGING,
DEVICE_CLASS_CARBON_MONOXIDE,
DEVICE_CLASS_COLD,
DEVICE_CLASS_CONNECTIVITY,
DEVICE_CLASS_DOOR,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_GARAGE_DOOR,
DEVICE_CLASS_GAS,
DEVICE_CLASS_HEAT,
@ -62,13 +62,13 @@ from esphome.util import Registry
CODEOWNERS = ["@esphome/core"]
DEVICE_CLASSES = [
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_BATTERY_CHARGING,
DEVICE_CLASS_CARBON_MONOXIDE,
DEVICE_CLASS_COLD,
DEVICE_CLASS_CONNECTIVITY,
DEVICE_CLASS_DOOR,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_GARAGE_DOOR,
DEVICE_CLASS_GAS,
DEVICE_CLASS_HEAT,

View file

@ -11,6 +11,7 @@ from esphome.const import (
CONF_ON_PRESS,
CONF_TRIGGER_ID,
CONF_MQTT_ID,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_RESTART,
DEVICE_CLASS_UPDATE,
)
@ -21,6 +22,7 @@ CODEOWNERS = ["@esphome/core"]
IS_PLATFORM_COMPONENT = True
DEVICE_CLASSES = [
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_RESTART,
DEVICE_CLASS_UPDATE,
]

View file

@ -17,6 +17,17 @@ from esphome.const import (
CONF_STOP,
CONF_MQTT_ID,
CONF_TRIGGER_ID,
DEVICE_CLASS_AWNING,
DEVICE_CLASS_BLIND,
DEVICE_CLASS_CURTAIN,
DEVICE_CLASS_DAMPER,
DEVICE_CLASS_DOOR,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_GARAGE,
DEVICE_CLASS_GATE,
DEVICE_CLASS_SHADE,
DEVICE_CLASS_SHUTTER,
DEVICE_CLASS_WINDOW,
)
from esphome.core import CORE, coroutine_with_priority
from esphome.cpp_helpers import setup_entity
@ -25,17 +36,17 @@ IS_PLATFORM_COMPONENT = True
CODEOWNERS = ["@esphome/core"]
DEVICE_CLASSES = [
"",
"awning",
"blind",
"curtain",
"damper",
"door",
"garage",
"gate",
"shade",
"shutter",
"window",
DEVICE_CLASS_AWNING,
DEVICE_CLASS_BLIND,
DEVICE_CLASS_CURTAIN,
DEVICE_CLASS_DAMPER,
DEVICE_CLASS_DOOR,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_GARAGE,
DEVICE_CLASS_GATE,
DEVICE_CLASS_SHADE,
DEVICE_CLASS_SHUTTER,
DEVICE_CLASS_WINDOW,
]
cover_ns = cg.esphome_ns.namespace("cover")

View file

@ -17,19 +17,23 @@ from esphome.const import (
CONF_VALUE,
CONF_OPERATION,
CONF_CYCLE,
DEVICE_CLASS_DISTANCE,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_APPARENT_POWER,
DEVICE_CLASS_AQI,
DEVICE_CLASS_ATMOSPHERIC_PRESSURE,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_CARBON_DIOXIDE,
DEVICE_CLASS_CARBON_MONOXIDE,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_DATA_RATE,
DEVICE_CLASS_DATA_SIZE,
DEVICE_CLASS_DISTANCE,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_ENERGY,
DEVICE_CLASS_FREQUENCY,
DEVICE_CLASS_GAS,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_IRRADIANCE,
DEVICE_CLASS_MOISTURE,
DEVICE_CLASS_MONETARY,
DEVICE_CLASS_NITROGEN_DIOXIDE,
@ -46,6 +50,7 @@ from esphome.const import (
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_REACTIVE_POWER,
DEVICE_CLASS_SIGNAL_STRENGTH,
DEVICE_CLASS_SOUND_PRESSURE,
DEVICE_CLASS_SPEED,
DEVICE_CLASS_SULPHUR_DIOXIDE,
DEVICE_CLASS_TEMPERATURE,
@ -53,8 +58,8 @@ from esphome.const import (
DEVICE_CLASS_VOLTAGE,
DEVICE_CLASS_VOLUME,
DEVICE_CLASS_WATER,
DEVICE_CLASS_WIND_SPEED,
DEVICE_CLASS_WEIGHT,
DEVICE_CLASS_WIND_SPEED,
)
from esphome.core import CORE, coroutine_with_priority
from esphome.cpp_helpers import setup_entity
@ -63,10 +68,13 @@ CODEOWNERS = ["@esphome/core"]
DEVICE_CLASSES = [
DEVICE_CLASS_APPARENT_POWER,
DEVICE_CLASS_AQI,
DEVICE_CLASS_ATMOSPHERIC_PRESSURE,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_CARBON_DIOXIDE,
DEVICE_CLASS_CARBON_MONOXIDE,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_DATA_RATE,
DEVICE_CLASS_DATA_SIZE,
DEVICE_CLASS_DISTANCE,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_ENERGY,
@ -74,6 +82,7 @@ DEVICE_CLASSES = [
DEVICE_CLASS_GAS,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_IRRADIANCE,
DEVICE_CLASS_MOISTURE,
DEVICE_CLASS_MONETARY,
DEVICE_CLASS_NITROGEN_DIOXIDE,
@ -83,13 +92,14 @@ DEVICE_CLASSES = [
DEVICE_CLASS_PM1,
DEVICE_CLASS_PM10,
DEVICE_CLASS_PM25,
DEVICE_CLASS_POWER_FACTOR,
DEVICE_CLASS_POWER,
DEVICE_CLASS_POWER_FACTOR,
DEVICE_CLASS_PRECIPITATION,
DEVICE_CLASS_PRECIPITATION_INTENSITY,
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_REACTIVE_POWER,
DEVICE_CLASS_SIGNAL_STRENGTH,
DEVICE_CLASS_SOUND_PRESSURE,
DEVICE_CLASS_SPEED,
DEVICE_CLASS_SULPHUR_DIOXIDE,
DEVICE_CLASS_TEMPERATURE,

View file

@ -29,21 +29,25 @@ from esphome.const import (
CONF_WINDOW_SIZE,
CONF_MQTT_ID,
CONF_FORCE_UPDATE,
DEVICE_CLASS_DISTANCE,
DEVICE_CLASS_DURATION,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_APPARENT_POWER,
DEVICE_CLASS_AQI,
DEVICE_CLASS_ATMOSPHERIC_PRESSURE,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_CARBON_DIOXIDE,
DEVICE_CLASS_CARBON_MONOXIDE,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_DATA_RATE,
DEVICE_CLASS_DATA_SIZE,
DEVICE_CLASS_DATE,
DEVICE_CLASS_DISTANCE,
DEVICE_CLASS_DURATION,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_ENERGY,
DEVICE_CLASS_FREQUENCY,
DEVICE_CLASS_GAS,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_IRRADIANCE,
DEVICE_CLASS_MOISTURE,
DEVICE_CLASS_MONETARY,
DEVICE_CLASS_NITROGEN_DIOXIDE,
@ -60,6 +64,7 @@ from esphome.const import (
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_REACTIVE_POWER,
DEVICE_CLASS_SIGNAL_STRENGTH,
DEVICE_CLASS_SOUND_PRESSURE,
DEVICE_CLASS_SPEED,
DEVICE_CLASS_SULPHUR_DIOXIDE,
DEVICE_CLASS_TEMPERATURE,
@ -68,8 +73,8 @@ from esphome.const import (
DEVICE_CLASS_VOLTAGE,
DEVICE_CLASS_VOLUME,
DEVICE_CLASS_WATER,
DEVICE_CLASS_WIND_SPEED,
DEVICE_CLASS_WEIGHT,
DEVICE_CLASS_WIND_SPEED,
)
from esphome.core import CORE, coroutine_with_priority
from esphome.cpp_generator import MockObjClass
@ -78,21 +83,25 @@ from esphome.util import Registry
CODEOWNERS = ["@esphome/core"]
DEVICE_CLASSES = [
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_APPARENT_POWER,
DEVICE_CLASS_AQI,
DEVICE_CLASS_ATMOSPHERIC_PRESSURE,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_CARBON_DIOXIDE,
DEVICE_CLASS_CARBON_MONOXIDE,
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_DATA_RATE,
DEVICE_CLASS_DATA_SIZE,
DEVICE_CLASS_DATE,
DEVICE_CLASS_DISTANCE,
DEVICE_CLASS_DURATION,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_ENERGY,
DEVICE_CLASS_FREQUENCY,
DEVICE_CLASS_GAS,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_IRRADIANCE,
DEVICE_CLASS_MOISTURE,
DEVICE_CLASS_MONETARY,
DEVICE_CLASS_NITROGEN_DIOXIDE,
@ -109,6 +118,7 @@ DEVICE_CLASSES = [
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_REACTIVE_POWER,
DEVICE_CLASS_SIGNAL_STRENGTH,
DEVICE_CLASS_SOUND_PRESSURE,
DEVICE_CLASS_SPEED,
DEVICE_CLASS_SULPHUR_DIOXIDE,
DEVICE_CLASS_TEMPERATURE,

View file

@ -916,80 +916,87 @@ UNIT_VOLT_AMPS_REACTIVE_HOURS = "VARh"
UNIT_WATT = "W"
UNIT_WATT_HOURS = "Wh"
# device classes of binary_sensor component
DEVICE_CLASS_BATTERY_CHARGING = "battery_charging"
DEVICE_CLASS_COLD = "cold"
DEVICE_CLASS_CONNECTIVITY = "connectivity"
DEVICE_CLASS_DOOR = "door"
DEVICE_CLASS_GARAGE_DOOR = "garage_door"
DEVICE_CLASS_HEAT = "heat"
DEVICE_CLASS_LIGHT = "light"
DEVICE_CLASS_LOCK = "lock"
DEVICE_CLASS_MOTION = "motion"
DEVICE_CLASS_MOVING = "moving"
DEVICE_CLASS_OCCUPANCY = "occupancy"
DEVICE_CLASS_OPENING = "opening"
DEVICE_CLASS_PLUG = "plug"
DEVICE_CLASS_PRESENCE = "presence"
DEVICE_CLASS_PROBLEM = "problem"
DEVICE_CLASS_RUNNING = "running"
DEVICE_CLASS_SAFETY = "safety"
DEVICE_CLASS_SMOKE = "smoke"
DEVICE_CLASS_SOUND = "sound"
DEVICE_CLASS_TAMPER = "tamper"
DEVICE_CLASS_VIBRATION = "vibration"
DEVICE_CLASS_WINDOW = "window"
# device classes of both binary_sensor and sensor component
DEVICE_CLASS_EMPTY = ""
DEVICE_CLASS_BATTERY = "battery"
DEVICE_CLASS_CARBON_MONOXIDE = "carbon_monoxide"
DEVICE_CLASS_GAS = "gas"
DEVICE_CLASS_MOISTURE = "moisture"
DEVICE_CLASS_POWER = "power"
# device classes of sensor component
# device classes
DEVICE_CLASS_APPARENT_POWER = "apparent_power"
DEVICE_CLASS_AQI = "aqi"
DEVICE_CLASS_ATMOSPHERIC_PRESSURE = "atmospheric_pressure"
DEVICE_CLASS_AWNING = "awning"
DEVICE_CLASS_BATTERY = "battery"
DEVICE_CLASS_BATTERY_CHARGING = "battery_charging"
DEVICE_CLASS_BLIND = "blind"
DEVICE_CLASS_CARBON_DIOXIDE = "carbon_dioxide"
DEVICE_CLASS_CARBON_MONOXIDE = "carbon_monoxide"
DEVICE_CLASS_COLD = "cold"
DEVICE_CLASS_CONNECTIVITY = "connectivity"
DEVICE_CLASS_CURRENT = "current"
DEVICE_CLASS_CURTAIN = "curtain"
DEVICE_CLASS_DAMPER = "damper"
DEVICE_CLASS_DATA_RATE = "data_rate"
DEVICE_CLASS_DATA_SIZE = "data_size"
DEVICE_CLASS_DATE = "date"
DEVICE_CLASS_DISTANCE = "distance"
DEVICE_CLASS_DOOR = "door"
DEVICE_CLASS_DURATION = "duration"
DEVICE_CLASS_EMPTY = ""
DEVICE_CLASS_ENERGY = "energy"
DEVICE_CLASS_FREQUENCY = "frequency"
DEVICE_CLASS_GARAGE = "garage"
DEVICE_CLASS_GARAGE_DOOR = "garage_door"
DEVICE_CLASS_GAS = "gas"
DEVICE_CLASS_GATE = "gate"
DEVICE_CLASS_HEAT = "heat"
DEVICE_CLASS_HUMIDITY = "humidity"
DEVICE_CLASS_ILLUMINANCE = "illuminance"
DEVICE_CLASS_IRRADIANCE = "irradiance"
DEVICE_CLASS_LIGHT = "light"
DEVICE_CLASS_LOCK = "lock"
DEVICE_CLASS_MOISTURE = "moisture"
DEVICE_CLASS_MONETARY = "monetary"
DEVICE_CLASS_MOTION = "motion"
DEVICE_CLASS_MOVING = "moving"
DEVICE_CLASS_NITROGEN_DIOXIDE = "nitrogen_dioxide"
DEVICE_CLASS_NITROGEN_MONOXIDE = "nitrogen_monoxide"
DEVICE_CLASS_NITROUS_OXIDE = "nitrous_oxide"
DEVICE_CLASS_OCCUPANCY = "occupancy"
DEVICE_CLASS_OPENING = "opening"
DEVICE_CLASS_OUTLET = "outlet"
DEVICE_CLASS_OZONE = "ozone"
DEVICE_CLASS_PLUG = "plug"
DEVICE_CLASS_PM1 = "pm1"
DEVICE_CLASS_PM10 = "pm10"
DEVICE_CLASS_PM25 = "pm25"
DEVICE_CLASS_POWER = "power"
DEVICE_CLASS_POWER_FACTOR = "power_factor"
DEVICE_CLASS_PRECIPITATION = "precipitation"
DEVICE_CLASS_PRECIPITATION_INTENSITY = "precipitation_intensity"
DEVICE_CLASS_PRESENCE = "presence"
DEVICE_CLASS_PRESSURE = "pressure"
DEVICE_CLASS_PROBLEM = "problem"
DEVICE_CLASS_REACTIVE_POWER = "reactive_power"
DEVICE_CLASS_RESTART = "restart"
DEVICE_CLASS_RUNNING = "running"
DEVICE_CLASS_SAFETY = "safety"
DEVICE_CLASS_SHADE = "shade"
DEVICE_CLASS_SHUTTER = "shutter"
DEVICE_CLASS_SIGNAL_STRENGTH = "signal_strength"
DEVICE_CLASS_SMOKE = "smoke"
DEVICE_CLASS_SOUND = "sound"
DEVICE_CLASS_SOUND_PRESSURE = "sound_pressure"
DEVICE_CLASS_SPEED = "speed"
DEVICE_CLASS_SULPHUR_DIOXIDE = "sulphur_dioxide"
DEVICE_CLASS_SWITCH = "switch"
DEVICE_CLASS_TAMPER = "tamper"
DEVICE_CLASS_TEMPERATURE = "temperature"
DEVICE_CLASS_TIMESTAMP = "timestamp"
DEVICE_CLASS_UPDATE = "update"
DEVICE_CLASS_VIBRATION = "vibration"
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
DEVICE_CLASS_VOLTAGE = "voltage"
DEVICE_CLASS_VOLUME = "volume"
DEVICE_CLASS_WATER = "water"
DEVICE_CLASS_WIND_SPEED = "wind_speed"
DEVICE_CLASS_WEIGHT = "weight"
# device classes of both binary_sensor and button component
DEVICE_CLASS_UPDATE = "update"
# device classes of button component
DEVICE_CLASS_RESTART = "restart"
# device classes of switch component
DEVICE_CLASS_OUTLET = "outlet"
DEVICE_CLASS_SWITCH = "switch"
DEVICE_CLASS_WINDOW = "window"
DEVICE_CLASS_WIND_SPEED = "wind_speed"
# state classes
STATE_CLASS_NONE = ""

67
script/sync-device_class.py Executable file
View file

@ -0,0 +1,67 @@
#!/usr/bin/env python3
import re
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
from homeassistant.components.button import ButtonDeviceClass
from homeassistant.components.cover import CoverDeviceClass
from homeassistant.components.number import NumberDeviceClass
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.components.switch import SwitchDeviceClass
BLOCKLIST = (
# requires special support on HA side
"enum",
)
DOMAINS = {
"binary_sensor": BinarySensorDeviceClass,
"button": ButtonDeviceClass,
"cover": CoverDeviceClass,
"number": NumberDeviceClass,
"sensor": SensorDeviceClass,
"switch": SwitchDeviceClass,
}
def sub(path, pattern, repl):
with open(path, "r") as handle:
content = handle.read()
content = re.sub(pattern, repl, content, flags=re.MULTILINE, count=1)
with open(path, "w") as handle:
handle.write(content)
def main():
classes = {"EMPTY": ""}
allowed = {}
for domain, enum in DOMAINS.items():
available = {
cls.value.upper(): cls.value for cls in enum if cls.value not in BLOCKLIST
}
classes.update(available)
allowed[domain] = list(available.keys()) + ["EMPTY"]
# replace constant defines in const.py
out = ""
for cls in sorted(classes):
out += f'DEVICE_CLASS_{cls.upper()} = "{classes[cls]}"\n'
sub("esphome/const.py", '(DEVICE_CLASS_\w+ = "\w*"\r?\n)+', out)
for domain in sorted(allowed):
# replace imports
out = ""
for item in sorted(allowed[domain]):
out += f" DEVICE_CLASS_{item.upper()},\n"
sub(
f"esphome/components/{domain}/__init__.py",
"( DEVICE_CLASS_\w+,\r?\n)+",
out,
)
if __name__ == "__main__":
main()