diff --git a/ge_kitchen/entities/common/ge_entity.py b/ge_kitchen/entities/common/ge_entity.py index 2d3d820..ceaf893 100644 --- a/ge_kitchen/entities/common/ge_entity.py +++ b/ge_kitchen/entities/common/ge_entity.py @@ -40,6 +40,14 @@ class GeEntity: def name(self) -> Optional[str]: raise NotImplementedError + @property + def icon(self) -> Optional[str]: + return self._get_icon() + + @property + def device_class(self) -> Optional[str]: + return self._get_device_class() + def _stringify(self, value: any, **kwargs) -> Optional[str]: if isinstance(timedelta): return str(value)[:-3] if value else "" @@ -49,3 +57,9 @@ class GeEntity: def _boolify(self, value: any) -> Optional[bool]: return self.appliance.boolify_erd_value(value) + + def _get_icon(self) -> Optional[str]: + return None + + def _get_device_class(self) -> Optional[str]: + return None \ No newline at end of file diff --git a/ge_kitchen/entities/common/ge_erd_binary_sensor.py b/ge_kitchen/entities/common/ge_erd_binary_sensor.py index 51ad8dd..0260c0e 100644 --- a/ge_kitchen/entities/common/ge_erd_binary_sensor.py +++ b/ge_kitchen/entities/common/ge_erd_binary_sensor.py @@ -2,23 +2,37 @@ from typing import Optional from homeassistant.components.binary_sensor import BinarySensorEntity +from gekitchen import ErdCode, ErdCodeType, ErdCodeClass +from ge_kitchen.devices import ApplianceApi from .ge_erd_entity import GeErdEntity class GeErdBinarySensor(GeErdEntity, BinarySensorEntity): + def __init__(self, api: ApplianceApi, erd_code: ErdCodeType, erd_override: str, icon_on_override: str, icon_off_override: str, device_class_override: str): + super().__init__(api, erd_code, erd_override=erd_override, icon_override=icon_on_override, device_class_override=device_class_override) + self._icon_on_override = icon_on_override + self._icon_off_override = icon_off_override + """GE Entity for binary sensors""" @property def is_on(self) -> bool: """Return True if entity is on.""" - return bool(self.appliance.get_erd_value(self.erd_code)) + return self._boolify(self.appliance.get_erd_value(self.erd_code)) - @property - def icon(self) -> Optional[str]: - return get_erd_icon(self.erd_code, self.is_on) + def _get_erd_icon(self): + if self._icon_on_override and self.is_on: + return self._icon_on_override + if self._icon_off_override and not self.is_on: + return self._icon_off_override + + if self._erd_code_class == ErdCodeClass.DOOR or self.device_class == "door": + return "mdi:door-open" if self.is_on else "mdi:door-closed" - @property - def device_class(self) -> Optional[str]: - if self.erd_code in DOOR_ERD_CODES: - return "door" return None + def _get_device_class(self) -> Optional[str]: + if self._device_class_override: + return self._device_class_override + if self._erd_code_class == ErdCodeClass.DOOR: + return "door" + return None diff --git a/ge_kitchen/entities/common/ge_erd_entity.py b/ge_kitchen/entities/common/ge_erd_entity.py index fbe4bcb..9b0d99d 100644 --- a/ge_kitchen/entities/common/ge_erd_entity.py +++ b/ge_kitchen/entities/common/ge_erd_entity.py @@ -1,7 +1,8 @@ from datetime import timedelta from typing import Optional -from gekitchen import ErdCode, ErdCodeType, ErdCodeClass +from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT +from gekitchen import ErdCode, ErdCodeType, ErdCodeClass, ErdMeasurementUnits from ge_kitchen.const import DOMAIN from ge_kitchen.devices import ApplianceApi @@ -48,11 +49,8 @@ class GeErdEntity(GeEntity): def unique_id(self) -> Optional[str]: return f"{DOMAIN}_{self.serial_number}_{self.erd_string.lower()}" - @property - def icon(self) -> Optional[str]: - return get_erd_icon(self.erd_code) - def _stringify(self, value: any, **kwargs) -> Optional[str]: + """ Stringify a value """ # perform special processing before passing over to the default method if self.erd_code == ErdCode.CLOCK_TIME: return value.strftime("%H:%M:%S") if value else None @@ -65,3 +63,43 @@ class GeErdEntity(GeEntity): if value is None: return None return self.appliance.stringify_erd_value(value, kwargs) + + @property + def _temp_measurement_system(self) -> Optional[ErdMeasurementUnits]: + try: + value = self.appliance.get_erd_value(ErdCode.TEMPERATURE_UNIT) + except KeyError: + return None + return value + + def _get_icon(self): + """Select an appropriate icon.""" + + if self._icon_override: + return self._icon_override + if not isinstance(self.erd_code, ErdCode): + return None + if self.erd_code_class == ErdCodeClass.CLOCK: + return "mdi:clock" + if self.erd_code_class == ErdCodeClass.DOOR: + return "mdi:door" + if self.erd_code_class == ErdCodeClass.TIMER: + return "mdi:timer-outline" + if self.erd_code_class == ErdCodeClass.LOCK_CONTROL: + return "mdi:lock-outline" + if self.erd_code_class == ErdCodeClass.SABBATH_CONTROL: + return "mdi:judaism" + if self.erd_code_class == ErdCodeClass.COOLING_CONTROL: + return "mdi:snowflake" + if self.erd_code_class == ErdCodeClass.OVEN_SENSOR: + return "mdi:stove" + if self.erd_code_class == ErdCodeClass.FRIDGE_SENSOR: + return "mdi:fridge-bottom" + if self.erd_code_class == ErdCodeClass.FREEZER_SENSOR: + return "mdi:fridge-top" + if self.erd_code_class == ErdCodeClass.DISPENSER_SENSOR: + return "mdi:cup-water" + if self.erd_code_class == ErdCodeClass.DISWASHER_SENSOR: + return "mdi:dishwasher" + + return None diff --git a/ge_kitchen/entities/common/ge_erd_property_binary_sensor.py b/ge_kitchen/entities/common/ge_erd_property_binary_sensor.py index f2df631..b6d8983 100644 --- a/ge_kitchen/entities/common/ge_erd_property_binary_sensor.py +++ b/ge_kitchen/entities/common/ge_erd_property_binary_sensor.py @@ -7,8 +7,8 @@ from .ge_erd_binary_sensor import GeErdBinarySensor class GeErdPropertyBinarySensor(GeErdBinarySensor): """GE Entity for property binary sensors""" - def __init__(self, api: "ApplianceApi", erd_code: ErdCodeType, erd_property: str): - super().__init__(api, erd_code) + def __init__(self, api: ApplianceApi, erd_code: ErdCodeType, erd_property: str, erd_override: str, icon_on_override: str, icon_off_override: str, device_class_override: str): + super().__init__(api, erd_code, erd_override, icon_on_override, icon_off_override, device_class_override) self.erd_property = erd_property self._erd_property_cleansed = erd_property.replace(".","_").replace("[","_").replace("]","_") @@ -21,10 +21,6 @@ class GeErdPropertyBinarySensor(GeErdBinarySensor): return None return self._boolify(self.erd_code, value) - @property - def icon(self) -> Optional[str]: - return get_erd_icon(self.erd_code, self.is_on) - @property def unique_id(self) -> Optional[str]: return f"{super().unique_id}_{self._erd_property_cleansed}" diff --git a/ge_kitchen/entities/common/ge_erd_property_sensor.py b/ge_kitchen/entities/common/ge_erd_property_sensor.py index 689cf87..3b80398 100644 --- a/ge_kitchen/entities/common/ge_erd_property_sensor.py +++ b/ge_kitchen/entities/common/ge_erd_property_sensor.py @@ -8,8 +8,8 @@ from .ge_erd_sensor import GeErdSensor class GeErdPropertySensor(GeErdSensor): """GE Entity for sensors""" - def __init__(self, api: ApplianceApi, erd_code: ErdCodeType, erd_property: str): - super().__init__(api, erd_code) + def __init__(self, api: ApplianceApi, erd_code: ErdCodeType, erd_property: str, erd_override: str, icon_override: str, device_class_override: str): + super().__init__(api, erd_code, erd_override=erd_override, icon_override=icon_override, device_class_override=device_class_override) self.erd_property = erd_property self._erd_property_cleansed = erd_property.replace(".","_").replace("[","_").replace("]","_") @@ -30,17 +30,3 @@ class GeErdPropertySensor(GeErdSensor): except KeyError: return None return self._stringify(value, units=self.units) - - @property - def measurement_system(self) -> Optional[ErdMeasurementUnits]: - return self.appliance.get_erd_value(ErdCode.TEMPERATURE_UNIT) - - @property - def units(self) -> Optional[str]: - return get_erd_units(self.erd_code, self.measurement_system) - - @property - def device_class(self) -> Optional[str]: - if self.erd_code in TEMPERATURE_ERD_CODES: - return "temperature" - return None diff --git a/ge_kitchen/entities/common/ge_erd_sensor.py b/ge_kitchen/entities/common/ge_erd_sensor.py index 678d6ba..7152631 100644 --- a/ge_kitchen/entities/common/ge_erd_sensor.py +++ b/ge_kitchen/entities/common/ge_erd_sensor.py @@ -1,6 +1,12 @@ from typing import Optional -from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT +from homeassistant.const import ( + DEVICE_CLASS_TEMPERATURE, + DEVICE_CLASS_BATTERY, + DEVICE_CLASS_POWER_FACTOR, + TEMP_CELSIUS, + TEMP_FAHRENHEIT +) from homeassistant.helpers.entity import Entity from gekitchen import ErdCode, ErdCodeClass, ErdMeasurementUnits @@ -17,28 +23,27 @@ class GeErdSensor(GeErdEntity, Entity): return self._stringify(value, units=self.units) @property - def measurement_system(self) -> Optional[ErdMeasurementUnits]: - try: - value = self.appliance.get_erd_value(ErdCode.TEMPERATURE_UNIT) - except KeyError: - return None - return value + def unit_of_measurement(self) -> Optional[str]: + return self._get_uom() - @property - def units(self) -> Optional[str]: - return get_erd_units(self.erd_code, self.measurement_system) - - @property - def device_class(self) -> Optional[str]: - if self.erd_code_class in [ErdCodeClass.RAW_TEMPERATURE, ErdCodeClass.NON_ZERO_TEMPERATURE]: - return DEVICE_CLASS_TEMPERATURE + def _get_uom(self): + """ Select appropriate units """ + if self.erd_code_class == ErdCodeClass.TEMPERATURE or self.device_class == DEVICE_CLASS_TEMPERATURE: + if self._temp_measurement_system == ErdMeasurementUnits.METRIC: + return TEMP_CELSIUS + return TEMP_FAHRENHEIT + if self.erd_code_class == ErdCodeClass.BATTERY or self.device_class == DEVICE_CLASS_BATTERY: + return "%" + if self.device_class == DEVICE_CLASS_POWER_FACTOR: + return "%" return None - @property - def icon(self) -> Optional[str]: - return get_erd_icon(self.erd_code, self.state) + def _get_device_class(self) -> Optional[str]: + if self._device_class_override: + return self._device_class_override + if self.erd_code_class in [ErdCodeClass.RAW_TEMPERATURE, ErdCodeClass.NON_ZERO_TEMPERATURE]: + return DEVICE_CLASS_TEMPERATURE + if self.erd_code_class == ErdCodeClass.BATTERY: + return DEVICE_CLASS_BATTERY - @property - def unit_of_measurement(self) -> Optional[str]: - if self.device_class == DEVICE_CLASS_TEMPERATURE: - return self.units + return None diff --git a/ge_kitchen/entities/entities.py b/ge_kitchen/entities/entities.py deleted file mode 100644 index 0c03e2a..0000000 --- a/ge_kitchen/entities/entities.py +++ /dev/null @@ -1,105 +0,0 @@ -"""Define all of the entity types""" - -import logging -from typing import Any, Dict, Optional, TYPE_CHECKING - -from gekitchen import ErdCodeType, GeAppliance, translate_erd_code -from gekitchen.erd_types import * -from gekitchen.erd_constants import * -from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT -from homeassistant.core import HomeAssistant - - -from .const import DOMAIN -from .erd_string_utils import * - -if TYPE_CHECKING: - from .appliance_api import ApplianceApi - - -_LOGGER = logging.getLogger(__name__) - -DOOR_ERD_CODES = { - ErdCode.DOOR_STATUS -} -RAW_TEMPERATURE_ERD_CODES = { - ErdCode.LOWER_OVEN_RAW_TEMPERATURE, - ErdCode.LOWER_OVEN_USER_TEMP_OFFSET, - ErdCode.UPPER_OVEN_RAW_TEMPERATURE, - ErdCode.UPPER_OVEN_USER_TEMP_OFFSET, - ErdCode.CURRENT_TEMPERATURE, - ErdCode.TEMPERATURE_SETTING, -} -NONZERO_TEMPERATURE_ERD_CODES = { - ErdCode.HOT_WATER_SET_TEMP, - ErdCode.LOWER_OVEN_DISPLAY_TEMPERATURE, - ErdCode.LOWER_OVEN_PROBE_DISPLAY_TEMP, - ErdCode.UPPER_OVEN_DISPLAY_TEMPERATURE, - ErdCode.UPPER_OVEN_PROBE_DISPLAY_TEMP, -} -TEMPERATURE_ERD_CODES = RAW_TEMPERATURE_ERD_CODES.union(NONZERO_TEMPERATURE_ERD_CODES) -TIMER_ERD_CODES = { - ErdCode.LOWER_OVEN_ELAPSED_COOK_TIME, - ErdCode.LOWER_OVEN_KITCHEN_TIMER, - ErdCode.LOWER_OVEN_DELAY_TIME_REMAINING, - ErdCode.LOWER_OVEN_COOK_TIME_REMAINING, - ErdCode.LOWER_OVEN_ELAPSED_COOK_TIME, - ErdCode.ELAPSED_ON_TIME, - ErdCode.TIME_REMAINING, - ErdCode.UPPER_OVEN_ELAPSED_COOK_TIME, - ErdCode.UPPER_OVEN_KITCHEN_TIMER, - ErdCode.UPPER_OVEN_DELAY_TIME_REMAINING, - ErdCode.UPPER_OVEN_ELAPSED_COOK_TIME, - ErdCode.UPPER_OVEN_COOK_TIME_REMAINING, -} - - -def get_erd_units(erd_code: ErdCodeType, measurement_units: ErdMeasurementUnits): - """Get the units for a sensor.""" - erd_code = translate_erd_code(erd_code) - if not measurement_units: - return None - - if erd_code in TEMPERATURE_ERD_CODES or erd_code in {ErdCode.LOWER_OVEN_COOK_MODE, ErdCode.UPPER_OVEN_COOK_MODE}: - if measurement_units == ErdMeasurementUnits.METRIC: - return TEMP_CELSIUS - return TEMP_FAHRENHEIT - return None - - -def get_erd_icon(erd_code: ErdCodeType, value: Any = None) -> Optional[str]: - """Select an appropriate icon.""" - erd_code = translate_erd_code(erd_code) - if not isinstance(erd_code, ErdCode): - return None - if erd_code in TIMER_ERD_CODES: - return "mdi:timer-outline" - if erd_code in { - ErdCode.LOWER_OVEN_COOK_MODE, - ErdCode.LOWER_OVEN_CURRENT_STATE, - ErdCode.LOWER_OVEN_WARMING_DRAWER_STATE, - ErdCode.UPPER_OVEN_COOK_MODE, - ErdCode.UPPER_OVEN_CURRENT_STATE, - ErdCode.UPPER_OVEN_WARMING_DRAWER_STATE, - ErdCode.WARMING_DRAWER_STATE, - }: - return "mdi:stove" - if erd_code in { - ErdCode.TURBO_COOL_STATUS, - ErdCode.TURBO_FREEZE_STATUS, - }: - return "mdi:snowflake" - if erd_code == ErdCode.SABBATH_MODE: - return "mdi:judaism" - - # Let binary sensors assign their own. Might be worth passing - # the actual entity in if we want to do more of this. - if erd_code in DOOR_ERD_CODES and isinstance(value, str): - if "open" in value.lower(): - return "mdi:door-open" - return "mdi:door-closed" - - return None - - -