diff --git a/custom_components/ge_home/devices/__init__.py b/custom_components/ge_home/devices/__init__.py index 6d1affd..a262944 100644 --- a/custom_components/ge_home/devices/__init__.py +++ b/custom_components/ge_home/devices/__init__.py @@ -10,7 +10,7 @@ from .dishwasher import DishwasherApi from .washer import WasherApi from .dryer import DryerApi from .washer_dryer import WasherDryerApi -from .waterfilter import WaterFilterApi +from .water_filter import WaterFilterApi _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/ge_home/devices/waterfilter.py b/custom_components/ge_home/devices/water_filter.py similarity index 68% rename from custom_components/ge_home/devices/waterfilter.py rename to custom_components/ge_home/devices/water_filter.py index dcce390..6a59641 100644 --- a/custom_components/ge_home/devices/waterfilter.py +++ b/custom_components/ge_home/devices/water_filter.py @@ -1,17 +1,15 @@ -from homeassistant.components.select import SelectEntity import logging from typing import List from homeassistant.helpers.entity import Entity -from gehomesdk.erd import ErdCode, ErdApplianceType +from gehomesdk import ErdCode, ErdApplianceType from .base import ApplianceApi from ..entities import ( GeErdSensor, + GeErdPropertySensor, GeErdBinarySensor, - ErdFlowRateSensor, - ErdFilterLifeRemainingSensor, - ErdFilterPositionSelect, + GeErdFilterPositionSelect, ) _LOGGER = logging.getLogger(__name__) @@ -28,11 +26,11 @@ class WaterFilterApi(ApplianceApi): wf_entities = [ GeErdSensor(self, ErdCode.WH_FILTER_MODE), GeErdSensor(self, ErdCode.WH_FILTER_VALVE_STATE), - ErdFilterPositionSelect(self, ErdCode.WH_FILTER_POSITION), + GeErdFilterPositionSelect(self, ErdCode.WH_FILTER_POSITION), GeErdBinarySensor(self, ErdCode.WH_FILTER_MANUAL_MODE), - ErdFlowRateSensor(self, ErdCode.WH_FILTER_FLOW_RATE), + GeErdPropertySensor(self, ErdCode.WH_FILTER_FLOW_RATE, 'flow_rate'), GeErdSensor(self, ErdCode.WH_FILTER_DAY_USAGE), - ErdFilterLifeRemainingSensor(self, ErdCode.WH_FILTER_LIFE_REMAINING), + GeErdPropertySensor(self, ErdCode.WH_FILTER_LIFE_REMAINING, 'life_remaining'), GeErdBinarySensor(self, ErdCode.WH_FILTER_FLOW_ALERT), ] entities = base_entities + wf_entities diff --git a/custom_components/ge_home/entities/__init__.py b/custom_components/ge_home/entities/__init__.py index 3befece..2fc8567 100644 --- a/custom_components/ge_home/entities/__init__.py +++ b/custom_components/ge_home/entities/__init__.py @@ -2,4 +2,4 @@ from .common import * from .dishwasher import * from .fridge import * from .oven import * -from .waterfilter import * +from .water_filter import * diff --git a/custom_components/ge_home/entities/common/__init__.py b/custom_components/ge_home/entities/common/__init__.py index eaff1ec..81a07ab 100644 --- a/custom_components/ge_home/entities/common/__init__.py +++ b/custom_components/ge_home/entities/common/__init__.py @@ -6,4 +6,4 @@ from .ge_erd_sensor import GeErdSensor from .ge_erd_property_sensor import GeErdPropertySensor from .ge_erd_switch import GeErdSwitch from .ge_water_heater import GeWaterHeater -from .ge_erd_select import GeErdSelect +from .ge_erd_select import GeErdSelect, OptionsConverter \ No newline at end of file diff --git a/custom_components/ge_home/entities/common/ge_erd_entity.py b/custom_components/ge_home/entities/common/ge_erd_entity.py index 799e924..7dbce1c 100644 --- a/custom_components/ge_home/entities/common/ge_erd_entity.py +++ b/custom_components/ge_home/entities/common/ge_erd_entity.py @@ -1,7 +1,6 @@ from datetime import timedelta from typing import Optional -from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT from gehomesdk import ErdCode, ErdCodeType, ErdCodeClass, ErdMeasurementUnits from ...const import DOMAIN @@ -116,5 +115,7 @@ class GeErdEntity(GeEntity): return "mdi:dishwasher" if self.erd_code_class == ErdCodeClass.WATERFILTER_SENSOR: return "mdi:water" + if self.erd_code_class == ErdCodeClass.FLOW_RATE: + return "mdi:water" return None diff --git a/custom_components/ge_home/entities/common/ge_erd_select.py b/custom_components/ge_home/entities/common/ge_erd_select.py index 25e3699..1b8dfc1 100644 --- a/custom_components/ge_home/entities/common/ge_erd_select.py +++ b/custom_components/ge_home/entities/common/ge_erd_select.py @@ -1,11 +1,35 @@ + import logging +from typing import Any, List from homeassistant.components.select import SelectEntity +from gehomesdk import ErdCodeType + +from ...devices import ApplianceApi +from .ge_erd_entity import GeErdEntity _LOGGER = logging.getLogger(__name__) - -class GeErdSelect(SelectEntity): - """Switches for boolean ERD codes.""" - +class OptionsConverter: + @property + def options(self) -> List[str]: + return [] + def from_option_string(self, value: str) -> Any: + return value + +class GeErdSelect(GeErdEntity, SelectEntity): + """ERD-based selector entity""" device_class = "select" + + def __init__(self, api: ApplianceApi, erd_code: ErdCodeType, converter: OptionsConverter, erd_override: str = None, icon_override: str = None, device_class_override: str = None): + super().__init__(api, erd_code, erd_override=erd_override, icon_override=icon_override, device_class_override=device_class_override) + self._converter = converter + + def options(self) -> List[str]: + "Return a list of options" + return self._converter.options + + async def async_select_option(self, option: str) -> None: + """Change the selected option.""" + if option != self.current_option: + await self.appliance.async_set_erd_value(self.erd_code, self._converter.from_option_string(option)) diff --git a/custom_components/ge_home/entities/common/ge_erd_sensor.py b/custom_components/ge_home/entities/common/ge_erd_sensor.py index 036e8e4..fffe853 100644 --- a/custom_components/ge_home/entities/common/ge_erd_sensor.py +++ b/custom_components/ge_home/entities/common/ge_erd_sensor.py @@ -55,6 +55,11 @@ class GeErdSensor(GeErdEntity, Entity): return "%" if self.device_class == DEVICE_CLASS_POWER_FACTOR: return "%" + if self.erd_code_class == ErdCodeClass.FLOW_RATE: + if self._temp_measurement_system == ErdMeasurementUnits.METRIC: + return "lpm" + return "gpm" + return None def _get_device_class(self) -> Optional[str]: diff --git a/custom_components/ge_home/entities/water_filter/__init__.py b/custom_components/ge_home/entities/water_filter/__init__.py new file mode 100644 index 0000000..1d37958 --- /dev/null +++ b/custom_components/ge_home/entities/water_filter/__init__.py @@ -0,0 +1 @@ +from .filter_position import GeErdFilterPositionSelect diff --git a/custom_components/ge_home/entities/water_filter/filter_position.py b/custom_components/ge_home/entities/water_filter/filter_position.py new file mode 100644 index 0000000..ad191f1 --- /dev/null +++ b/custom_components/ge_home/entities/water_filter/filter_position.py @@ -0,0 +1,27 @@ +import logging +from typing import List, Any + +from gehomesdk import ErdCodeType, ErdWaterFilterPosition +from ...devices import ApplianceApi +from ..common import GeErdSelect, OptionsConverter + +_LOGGER = logging.getLogger(__name__) + +class FilterPositionOptionsConverter(OptionsConverter): + def options(self) -> List[str]: + return [i.name.title() for i in ErdWaterFilterPosition].remove("Unknown") + def from_option_string(self, value: str) -> Any: + try: + return ErdWaterFilterPosition[value] + except: + return ErdWaterFilterPosition.UNKNOWN + +class GeErdFilterPositionSelect(GeErdSelect): + def __init__(self, api: ApplianceApi, erd_code: ErdCodeType): + super().__init__(api, erd_code, FilterPositionOptionsConverter()) + + async def async_select_option(self, option: str) -> None: + value = self._converter.from_option_string(option) + if value in [ErdWaterFilterPosition.UNKNOWN, ErdWaterFilterPosition.READY]: + return + return await super().async_select_option(option) diff --git a/custom_components/ge_home/entities/waterfilter/__init__.py b/custom_components/ge_home/entities/waterfilter/__init__.py deleted file mode 100644 index 96610ce..0000000 --- a/custom_components/ge_home/entities/waterfilter/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .flow_rate_sensor import ErdFlowRateSensor -from .filter_life_remaining import ErdFilterLifeRemainingSensor -from .filter_position import ErdFilterPositionSelect diff --git a/custom_components/ge_home/entities/waterfilter/filter_life_remaining.py b/custom_components/ge_home/entities/waterfilter/filter_life_remaining.py deleted file mode 100644 index 8fd5697..0000000 --- a/custom_components/ge_home/entities/waterfilter/filter_life_remaining.py +++ /dev/null @@ -1,19 +0,0 @@ -from gehomesdk import ErdCode, ErdOperatingMode -from gehomesdk.erd.values.common.erd_measurement_units import ErdMeasurementUnits -from typing import Optional - -from ..common import GeErdSensor - - -class ErdFilterLifeRemainingSensor(GeErdSensor): - @property - def state(self) -> Optional[int]: - try: - value = self.appliance.get_erd_value(self.erd_code) - except KeyError: - return None - return value.life_remaining - - @property - def unit_of_measurement(self) -> Optional[str]: - return "%" diff --git a/custom_components/ge_home/entities/waterfilter/filter_position.py b/custom_components/ge_home/entities/waterfilter/filter_position.py deleted file mode 100644 index 4eb2bb9..0000000 --- a/custom_components/ge_home/entities/waterfilter/filter_position.py +++ /dev/null @@ -1,51 +0,0 @@ -from homeassistant.components.ge_home.entities.common.ge_erd_select import GeErdSelect -from homeassistant.components.ge_home.entities.common.ge_erd_entity import GeErdEntity -from homeassistant.components.ge_home.devices.base import ApplianceApi -import logging -from typing import Optional, Dict, Any - -from gehomesdk import ErdCode, ErdCodeClass, ErdCodeType -from gehomesdk.erd.values.waterfilter.erd_waterfilter_position import ( - ErdWaterFilterPosition, -) - -from ...const import DOMAIN - -_LOGGER = logging.getLogger(__name__) - - -class ErdFilterPositionSelect(GeErdEntity, GeErdSelect): - def __init__( - self, - api: ApplianceApi, - erd_code: ErdCodeType, - ): - super().__init__(api=api, erd_code=erd_code) - self._attr_hass = api._hass - self.hass = api._hass - self._attr_unique_id = self.unique_id - self._attr_name = self.name - self._attr_current_option = ErdWaterFilterPosition.UNKNOWN.name - self._attr_icon = self.icon - self._attr_device_class = self.device_class - self._attr_options = [ - ErdWaterFilterPosition.BYPASS.name, - ErdWaterFilterPosition.OFF.name, - ErdWaterFilterPosition.FILTERED.name, - ErdWaterFilterPosition.READY.name, - ] - self._attr_device_info = self.device_info - - async def async_select_option(self, option: str) -> None: - if ( - option == ErdWaterFilterPosition.READY.name - or option == ErdWaterFilterPosition.UNKNOWN.name - ): - return - await self.api.appliance.async_set_erd_value( - self.erd_code, ErdWaterFilterPosition[option] - ) - - @property - def icon(self) -> str: - return "mdi:water" diff --git a/custom_components/ge_home/entities/waterfilter/flow_rate_sensor.py b/custom_components/ge_home/entities/waterfilter/flow_rate_sensor.py deleted file mode 100644 index 065270b..0000000 --- a/custom_components/ge_home/entities/waterfilter/flow_rate_sensor.py +++ /dev/null @@ -1,21 +0,0 @@ -from gehomesdk import ErdCode, ErdOperatingMode -from gehomesdk.erd.values.common.erd_measurement_units import ErdMeasurementUnits -from typing import Optional - -from ..common import GeErdSensor - - -class ErdFlowRateSensor(GeErdSensor): - @property - def state(self) -> Optional[float]: - try: - value = self.appliance.get_erd_value(self.erd_code) - except KeyError: - return None - return value.flow_rate - - @property - def unit_of_measurement(self) -> Optional[str]: - if self._temp_measurement_system == ErdMeasurementUnits.METRIC: - return "lpm" - return "gpm" diff --git a/custom_components/ge_home/select.py b/custom_components/ge_home/select.py index 22ff7ae..bfa6b0b 100644 --- a/custom_components/ge_home/select.py +++ b/custom_components/ge_home/select.py @@ -1,4 +1,4 @@ -"""GE Home Sensor Entities""" +"""GE Home Select Entities""" import async_timeout import logging from typing import Callable