- removed target select

- added dehumidifier entity
- sdk version bump
This commit is contained in:
Jack Simbach 2023-07-31 00:11:02 -04:00
parent 0d9cb8f934
commit 296f81dfb2
11 changed files with 199 additions and 69 deletions

View File

@ -15,8 +15,7 @@ from ..entities import (
GeErdPropertySensor,
GeErdSwitch,
ErdOnOffBoolConverter,
DehumidifierTargetHumiditySelect,
DehumidifierFanSettingOptionsConverter
GeDehumidifier
)
_LOGGER = logging.getLogger(__name__)
@ -31,11 +30,12 @@ class DehumidifierApi(ApplianceApi):
dhum_entities = [
GeErdSwitch(self, ErdCode.AC_POWER_STATUS, bool_converter=ErdOnOffBoolConverter(), icon_on_override="mdi:power-on", icon_off_override="mdi:power-off"),
GeErdSelect(self, ErdCode.AC_FAN_SETTING, DehumidifierFanSettingOptionsConverter(), icon_override="mdi:fan"),
GeErdSensor(self, ErdCode.DHUM_CURRENT_HUMIDITY, uom_override="%", icon_override="mdi:water-percent"),
DehumidifierTargetHumiditySelect(self, ErdCode.DHUM_TARGET_HUMIDITY, icon_override="mdi:water-percent"),
GeErdSensor(self, ErdCode.AC_FAN_SETTING, icon_override="mdi:fan"),
GeErdSensor(self, ErdCode.DHUM_CURRENT_HUMIDITY),
GeErdSensor(self, ErdCode.DHUM_TARGET_HUMIDITY),
GeErdPropertySensor(self, ErdCode.DHUM_MAINTENANCE, "empty_bucket", device_class_override="problem"),
GeErdPropertySensor(self, ErdCode.DHUM_MAINTENANCE, "clean_filter", device_class_override="problem")
GeErdPropertySensor(self, ErdCode.DHUM_MAINTENANCE, "clean_filter", device_class_override="problem"),
GeDehumidifier(self)
]
entities = base_entities + dhum_entities

View File

@ -13,4 +13,5 @@ from .ge_erd_button import GeErdButton
from .ge_erd_number import GeErdNumber
from .ge_water_heater import GeAbstractWaterHeater
from .ge_erd_select import GeErdSelect
from .ge_climate import GeClimate
from .ge_climate import GeClimate
from .ge_humidifier import GeHumidifier

View File

@ -145,5 +145,7 @@ class GeErdEntity(GeEntity):
return "mdi:water"
if self.erd_code_class == ErdCodeClass.CCM_SENSOR:
return "mdi:coffee-maker"
if self.erd_code_class == ErdCodeClass.HUMIDITY:
return "mdi:water-percent"
return None

View File

@ -9,6 +9,7 @@ from homeassistant.const import (
DEVICE_CLASS_TEMPERATURE,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_POWER_FACTOR,
DEVICE_CLASS_HUMIDITY,
TEMP_FAHRENHEIT,
)
from gehomesdk import ErdCodeType, ErdCodeClass
@ -111,6 +112,8 @@ class GeErdSensor(GeErdEntity, SensorEntity):
return "%"
if self.device_class == DEVICE_CLASS_POWER_FACTOR:
return "%"
if self.erd_code_class == ErdCodeClass.HUMIDITY:
return "%"
if self.erd_code_class == ErdCodeClass.FLOW_RATE:
#if self._measurement_system == ErdMeasurementUnits.METRIC:
# return "lpm"
@ -135,6 +138,8 @@ class GeErdSensor(GeErdEntity, SensorEntity):
return DEVICE_CLASS_POWER
if self.erd_code_class == ErdCodeClass.ENERGY:
return DEVICE_CLASS_ENERGY
if self.erd_code_class == ErdCodeClass.HUMIDITY:
return DEVICE_CLASS_HUMIDITY
return None
@ -144,7 +149,7 @@ class GeErdSensor(GeErdEntity, SensorEntity):
if self.device_class in [DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_ENERGY]:
return SensorStateClass.MEASUREMENT
if self.erd_code_class in [ErdCodeClass.FLOW_RATE, ErdCodeClass.PERCENTAGE]:
if self.erd_code_class in [ErdCodeClass.FLOW_RATE, ErdCodeClass.PERCENTAGE, ErdCodeClass.HUMIDITY]:
return SensorStateClass.MEASUREMENT
if self.erd_code_class in [ErdCodeClass.LIQUID_VOLUME]:
return SensorStateClass.TOTAL_INCREASING

View File

@ -0,0 +1,98 @@
import abc
import logging
from typing import Coroutine, Any, Optional
from homeassistant.components.humidifier import HumidifierEntity, HumidifierDeviceClass
from homeassistant.components.humidifier.const import HumidifierEntityFeature
from gehomesdk import ErdCodeType, ErdOnOff
from ...const import DOMAIN
from ...devices import ApplianceApi
from .ge_entity import GeEntity
from .options_converter import OptionsConverter
_LOGGER = logging.getLogger(__name__)
class GeHumidifier(GeEntity, HumidifierEntity, metaclass=abc.ABCMeta):
"""GE Humidifier Abstract Entity """
def __init__(
self,
api: ApplianceApi,
device_class: HumidifierDeviceClass,
power_status_erd_code: ErdCodeType,
target_humidity_erd_code: ErdCodeType,
current_humidity_erd_code: ErdCodeType,
range_min: int,
range_max: int
):
super().__init__(api)
self._device_class = device_class
self._power_status_erd_code = power_status_erd_code
self._target_humidity_erd_code = target_humidity_erd_code
self._current_humidity_erd_code = current_humidity_erd_code
self._range_min = range_min
self._range_max = range_max
@property
def unique_id(self) -> str:
return f"{DOMAIN}_{self.serial_or_mac}_{self._device_class}"
@property
def name(self) -> Optional[str]:
return f"{self.serial_or_mac} {self._device_class.title()}"
@property
def target_humidity(self) -> int | None:
return int(self.appliance.get_erd_value(self._target_humidity_erd_code))
@property
def current_humidity(self) -> int | None:
return int(self.appliance.get_erd_value(self._current_humidity_erd_code))
@property
def min_humidity(self) -> int:
return self._range_min
@property
def max_humidity(self) -> int:
return self._range_max
@property
def supported_features(self) -> HumidifierEntityFeature:
return HumidifierEntityFeature(HumidifierEntityFeature.MODES)
@property
def is_on(self) -> bool:
return self.appliance.get_erd_value(self.power_status_erd_code) == ErdOnOff.ON
@property
def device_class(self):
return self.device_class
async def async_set_humidity(self, humidity: int) -> Coroutine[Any, Any, None]:
if self.target_humidity == humidity:
return
_LOGGER.debug(f"Setting Target Humidity from {self.target_humidity} to {humidity}")
# make sure we're on
if not self.is_on:
await self.async_turn_on()
# set the mode
await self.appliance.async_set_erd_value(
self.target_humidity_erd_code,
self.humidity,
)
async def async_turn_on(self):
await self.appliance.async_set_erd_value(
self.power_status_erd_code, ErdOnOff.ON
)
async def async_turn_off(self):
await self.appliance.async_set_erd_value(
self.power_status_erd_code, ErdOnOff.OFF
)

View File

@ -1,2 +1 @@
from .dehumidifier_target_select import DehumidifierTargetHumiditySelect
from .dehumidifier_fan_options import DehumidifierFanSettingOptionsConverter
from .dehumidifier import GeDehumidifier

View File

@ -0,0 +1,3 @@
SMART_DRY = "Smart Dry"
DEFAULT_MIN_HUMIDITY = 35
DEFAULT_MAX_HUMIDITY = 80

View File

@ -0,0 +1,74 @@
"""GE Home Dehumidifier"""
import logging
from homeassistant.components.humidifier import HumidifierDeviceClass
from homeassistant.components.humidifier.const import HumidifierEntityFeature
from gehomesdk import ErdCode, DehumidifierTargetRange
from ...devices import ApplianceApi
from ..common import GeHumidifier
from .const import *
from .dehumidifier_fan_options import DehumidifierFanSettingOptionsConverter
_LOGGER = logging.getLogger(__name__)
class GeDehumidifier(GeHumidifier):
"""GE Dehumidifier"""
icon = "mdi:air-humidifier"
def __init__(self, api: ApplianceApi):
#try to get the range
range: DehumidifierTargetRange = api.try_get_erd_value(ErdCode.DHUM_TARGET_HUMIDITY_RANGE)
low = DEFAULT_MIN_HUMIDITY if range is None else range.min_humidity
high = DEFAULT_MAX_HUMIDITY if range is None else range.max_humidity
#try to get the fan mode and determine feature
mode = api.try_get_erd_value(ErdCode.AC_FAN_SETTING)
self._has_fan = mode is not None
self._mode_converter = DehumidifierFanSettingOptionsConverter()
#initialize the dehumidifier
super().__init__(api,
HumidifierDeviceClass.DEHUMIDIFIER,
ErdCode.AC_POWER_STATUS,
ErdCode.DHUM_TARGET_HUMIDITY,
ErdCode.DHUM_CURRENT_HUMIDITY,
low,
high
)
@property
def supported_features(self) -> HumidifierEntityFeature:
if self._has_fan:
return HumidifierEntityFeature(HumidifierEntityFeature.MODES)
else:
return HumidifierEntityFeature(0)
@property
def mode(self) -> str | None:
if not self._has_fan:
raise NotImplementedError()
return self._mode_converter.to_option_string(
self.appliance.get_erd_value(ErdCode.AC_FAN_SETTING)
)
@property
def available_modes(self) -> list[str] | None:
if not self._has_fan:
raise NotImplementedError()
return self._mode_converter.options
async def async_set_mode(self, mode: str) -> None:
if not self._has_fan:
raise NotImplementedError()
"""Change the selected mode."""
_LOGGER.debug(f"Setting mode from {self.mode} to {mode}")
new_state = self._mode_converter.from_option_string(mode)
await self.appliance.async_set_erd_value(self.erd_code, new_state)

View File

@ -3,16 +3,19 @@ from typing import List, Any, Optional
from gehomesdk import ErdAcFanSetting
from ..common import OptionsConverter
from .const import SMART_DRY
_LOGGER = logging.getLogger(__name__)
class DehumidifierFanSettingOptionsConverter(OptionsConverter):
@property
def options(self) -> List[str]:
return [i.stringify() for i in [ErdAcFanSetting.DEFAULT, ErdAcFanSetting.LOW, ErdAcFanSetting.MED, ErdAcFanSetting.HIGH]]
return [SMART_DRY] + [i.stringify() for i in [ErdAcFanSetting.LOW, ErdAcFanSetting.MED, ErdAcFanSetting.HIGH]]
def from_option_string(self, value: str) -> Any:
try:
if value == SMART_DRY:
return ErdAcFanSetting.DEFAULT
return ErdAcFanSetting[value.upper()]
except:
_LOGGER.warn(f"Could not set fan setting to {value.upper()}")
@ -20,7 +23,7 @@ class DehumidifierFanSettingOptionsConverter(OptionsConverter):
def to_option_string(self, value: ErdAcFanSetting) -> Optional[str]:
try:
if value is not None:
return value.stringify()
return SMART_DRY if value == ErdAcFanSetting.DEFAULT else value.stringify()
except:
pass
return ErdAcFanSetting.DEFAULT.stringify()
return SMART_DRY

View File

@ -1,55 +0,0 @@
import logging
from typing import List, Any, Optional
from gehomesdk import ErdCodeType, DehumidifierTargetRange
from ...devices import ApplianceApi
from ..common import GeErdSelect, OptionsConverter
_LOGGER = logging.getLogger(__name__)
DEFAULT_MIN_HUMIDITY = 35
DEFAULT_MAX_HUMIDITY = 80
class DehumidifierTargetOptionsConverter(OptionsConverter):
def __init__(self, min = DEFAULT_MIN_HUMIDITY, max = DEFAULT_MAX_HUMIDITY) -> None:
super().__init__()
self._min = min
self._max = max
@property
def options(self) -> List[str]:
return [str(i) for i in range(min,max) if i % 5 == 0]
def from_option_string(self, value: str) -> Any:
return int(value)
def to_option_string(self, value: int) -> Optional[str]:
try:
if value is not None:
return str(value)
except:
return self._min
class DehumidifierTargetHumiditySelect(GeErdSelect):
def __init__(self, api: ApplianceApi, erd_code: ErdCodeType, erd_override: str = None):
self._low = DEFAULT_MIN_HUMIDITY
self._high = DEFAULT_MAX_HUMIDITY
#try to get the range
value: DehumidifierTargetRange = api.try_get_erd_value(erd_code)
if value is not None:
self._low = value.min_humidity
self._high = value.max_humidity
super().__init__(api, erd_code, DehumidifierTargetOptionsConverter(self._low, self._high), erd_override=erd_override)
@property
def current_option(self):
return self._converter.to_option_string(self.appliance.get_erd_value(self.erd_code))
async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
_LOGGER.debug(f"Setting select from {self.current_option} to {option}")
new_state = self._converter.from_option_string(option)
await self.appliance.async_set_erd_value(self.erd_code, new_state)

View File

@ -5,7 +5,7 @@
"integration_type": "hub",
"iot_class": "cloud_push",
"documentation": "https://github.com/simbaja/ha_gehome",
"requirements": ["gehomesdk==0.5.17","magicattr==0.1.6","slixmpp==1.8.3"],
"requirements": ["gehomesdk==0.5.18","magicattr==0.1.6","slixmpp==1.8.3"],
"codeowners": ["@simbaja"],
"version": "0.6.8"
}