python
This commit is contained in:
128
custom_components/yandex_station/sensor.py
Normal file
128
custom_components/yandex_station/sensor.py
Normal file
@@ -0,0 +1,128 @@
|
||||
import logging
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
CONCENTRATION_PARTS_PER_MILLION,
|
||||
LIGHT_LUX,
|
||||
PERCENTAGE,
|
||||
UnitOfElectricCurrent,
|
||||
UnitOfElectricPotential,
|
||||
UnitOfEnergy,
|
||||
UnitOfLength,
|
||||
UnitOfPower,
|
||||
UnitOfPressure,
|
||||
UnitOfTemperature,
|
||||
UnitOfVolume,
|
||||
)
|
||||
|
||||
from .core.entity import YandexCustomEntity
|
||||
from .hass import hass_utils
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# https://yandex.ru/dev/dialogs/smart-home/doc/concepts/device-type-sensor.html
|
||||
INCLUDE_TYPES = (
|
||||
"devices.types.sensor",
|
||||
"devices.types.sensor.button",
|
||||
"devices.types.sensor.climate",
|
||||
"devices.types.sensor.gas",
|
||||
"devices.types.sensor.illumination",
|
||||
"devices.types.sensor.motion",
|
||||
"devices.types.sensor.open",
|
||||
"devices.types.sensor.smoke",
|
||||
"devices.types.sensor.vibration",
|
||||
"devices.types.sensor.water_leak",
|
||||
"devices.types.smart_meter",
|
||||
"devices.types.smart_meter.cold_water",
|
||||
"devices.types.smart_meter.electricity",
|
||||
"devices.types.smart_meter.gas",
|
||||
"devices.types.smart_meter.heat",
|
||||
"devices.types.smart_meter.hot_water",
|
||||
"devices.types.socket",
|
||||
"devices.types.remote_car", # fuel_level, petrol_mileage
|
||||
"devices.types.remote.ir", # temperature, humidity
|
||||
"devices.types.smart_speaker.yandex.station.pickle", # co2_level, temp., hum.
|
||||
"devices.types.smart_speaker.yandex.station.plum", # battery
|
||||
)
|
||||
INCLUDE_PROPERTIES = ("devices.properties.float", "devices.properties.event")
|
||||
|
||||
SENSOR = SensorDeviceClass # just to reduce the code
|
||||
|
||||
ENTITY_DESCRIPTIONS: dict[str, dict] = {
|
||||
"temperature": {"class": SENSOR.TEMPERATURE, "units": UnitOfTemperature.CELSIUS},
|
||||
"humidity": {"class": SENSOR.HUMIDITY, "units": PERCENTAGE},
|
||||
"pm2.5_density": {
|
||||
"class": SENSOR.PM25,
|
||||
"units": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
},
|
||||
"pm10_density": {
|
||||
"class": SENSOR.PM10,
|
||||
"units": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
},
|
||||
"co2_level": {"class": SENSOR.CO2, "units": CONCENTRATION_PARTS_PER_MILLION},
|
||||
"illumination": {"class": SENSOR.ILLUMINANCE, "units": LIGHT_LUX},
|
||||
"battery_level": {"class": SENSOR.BATTERY, "units": PERCENTAGE},
|
||||
"pressure": {"class": SENSOR.PRESSURE, "units": UnitOfPressure.MMHG},
|
||||
"voltage": {"class": SENSOR.VOLTAGE, "units": UnitOfElectricPotential.VOLT},
|
||||
"power": {"class": SENSOR.POWER, "units": UnitOfPower.WATT},
|
||||
"amperage": {"class": SENSOR.CURRENT, "units": UnitOfElectricCurrent.AMPERE},
|
||||
"vibration": {"class": SENSOR.ENUM},
|
||||
"open": {"class": SENSOR.ENUM},
|
||||
"button": {"class": SENSOR.ENUM},
|
||||
"motion": {"class": SENSOR.ENUM},
|
||||
"smoke": {"class": SENSOR.ENUM},
|
||||
"gas": {"class": SENSOR.ENUM},
|
||||
"food_level": {"class": SENSOR.ENUM},
|
||||
"water_level": {"class": SENSOR.ENUM},
|
||||
"water_leak": {"class": SENSOR.ENUM},
|
||||
"electricity_meter": {"class": SENSOR.ENERGY, "units": UnitOfEnergy.KILO_WATT_HOUR},
|
||||
"gas_meter": {"class": SENSOR.GAS, "units": UnitOfVolume.CUBIC_METERS},
|
||||
"water_meter": {"class": SENSOR.WATER, "units": UnitOfVolume.CUBIC_METERS},
|
||||
# there is no better option than a battery for fuel_level
|
||||
"fuel_level": {"class": SENSOR.BATTERY, "units": PERCENTAGE},
|
||||
"petrol_mileage": {"class": SENSOR.DISTANCE, "units": UnitOfLength.KILOMETERS},
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry, async_add_entities):
|
||||
entities = []
|
||||
|
||||
for quasar, device, config in hass_utils.incluce_devices(hass, entry):
|
||||
if "properties" in config:
|
||||
instances = config["properties"]
|
||||
elif device["type"] in INCLUDE_TYPES:
|
||||
instances = ENTITY_DESCRIPTIONS.keys() # all supported instances
|
||||
else:
|
||||
continue
|
||||
|
||||
for instance in device["properties"]:
|
||||
if instance["type"] not in INCLUDE_PROPERTIES:
|
||||
continue
|
||||
if instance["parameters"]["instance"] in instances:
|
||||
entities.append(YandexCustomSensor(quasar, device, instance))
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
# noinspection PyAbstractClass
|
||||
class YandexCustomSensor(SensorEntity, YandexCustomEntity):
|
||||
def internal_init(self, capabilities: dict, properties: dict):
|
||||
if desc := ENTITY_DESCRIPTIONS.get(self.instance):
|
||||
self._attr_device_class = desc["class"]
|
||||
if "units" in desc:
|
||||
self._attr_native_unit_of_measurement = desc["units"]
|
||||
self._attr_state_class = SensorStateClass.MEASUREMENT
|
||||
try:
|
||||
if self.config["parameters"]["range"]["precision"] == 1:
|
||||
self._attr_suggested_display_precision = 0
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def internal_update(self, capabilities: dict, properties: dict):
|
||||
if self.instance in properties:
|
||||
self._attr_native_value = properties[self.instance]
|
||||
Reference in New Issue
Block a user