Apply changes for new pyhon version
This commit is contained in:
		@@ -17,7 +17,7 @@ _LOGGER = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
@dataclass
 | 
			
		||||
class HonBinarySensorEntityDescriptionMixin:
 | 
			
		||||
    on_value: str = ""
 | 
			
		||||
    on_value: str | float = ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@dataclass
 | 
			
		||||
@@ -41,14 +41,14 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="doorLockStatus",
 | 
			
		||||
            name="Door Lock",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.LOCK,
 | 
			
		||||
            on_value="0",
 | 
			
		||||
            on_value=0,
 | 
			
		||||
            translation_key="door_lock",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
            key="doorStatus",
 | 
			
		||||
            name="Door",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="door_open",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
@@ -82,7 +82,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="doorStatus",
 | 
			
		||||
            name="Door",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="door_open",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
@@ -102,7 +102,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="attributes.parameters.onOffStatus",
 | 
			
		||||
            name="On",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.RUNNING,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            icon="mdi:power-cycle",
 | 
			
		||||
            translation_key="on",
 | 
			
		||||
        ),
 | 
			
		||||
@@ -120,7 +120,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="attributes.parameters.onOffStatus",
 | 
			
		||||
            name="On",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.RUNNING,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            icon="mdi:power-cycle",
 | 
			
		||||
            translation_key="on",
 | 
			
		||||
        ),
 | 
			
		||||
@@ -128,13 +128,13 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="hotStatus",
 | 
			
		||||
            name="Hot Status",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.HEAT,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="still_hot",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
            key="panStatus",
 | 
			
		||||
            name="Pan Status",
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            icon="mdi:pot-mix",
 | 
			
		||||
            translation_key="pan_status",
 | 
			
		||||
        ),
 | 
			
		||||
@@ -142,7 +142,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="hobLockStatus",
 | 
			
		||||
            name="Hob Lock",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.LOCK,
 | 
			
		||||
            on_value="0",
 | 
			
		||||
            on_value=0,
 | 
			
		||||
            translation_key="child_lock",
 | 
			
		||||
        ),
 | 
			
		||||
    ),
 | 
			
		||||
@@ -151,7 +151,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="saltStatus",
 | 
			
		||||
            name="Salt",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.PROBLEM,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            icon="mdi:shaker-outline",
 | 
			
		||||
            translation_key="salt_level",
 | 
			
		||||
        ),
 | 
			
		||||
@@ -159,7 +159,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="rinseAidStatus",
 | 
			
		||||
            name="Rinse Aid",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.PROBLEM,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            icon="mdi:spray-bottle",
 | 
			
		||||
            translation_key="rinse_aid",
 | 
			
		||||
        ),
 | 
			
		||||
@@ -174,7 +174,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="doorStatus",
 | 
			
		||||
            name="Door",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="door_open",
 | 
			
		||||
        ),
 | 
			
		||||
    ),
 | 
			
		||||
@@ -183,13 +183,13 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            key="filterChangeStatusLocal",
 | 
			
		||||
            name="Filter Replacement",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.PROBLEM,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="filter_replacement",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
            key="ch2oCleaningStatus",
 | 
			
		||||
            name="Ch2O Cleaning",
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
        ),
 | 
			
		||||
    ),
 | 
			
		||||
    "REF": (
 | 
			
		||||
@@ -198,7 +198,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            name="Super Cool",
 | 
			
		||||
            icon="mdi:snowflake",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.RUNNING,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="super_cool",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
@@ -206,7 +206,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            name="Super Freeze",
 | 
			
		||||
            icon="mdi:snowflake-variant",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.RUNNING,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="super_freeze",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
@@ -214,7 +214,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            name="Door Status Freezer",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
			
		||||
            icon="mdi:fridge-top",
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="freezer_door",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
@@ -222,7 +222,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            name="Door Status Fridge",
 | 
			
		||||
            icon="mdi:fridge-bottom",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="fridge_door",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
@@ -230,7 +230,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            name="Auto-Set Mode",
 | 
			
		||||
            icon="mdi:thermometer-auto",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.RUNNING,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="auto_set",
 | 
			
		||||
        ),
 | 
			
		||||
        HonBinarySensorEntityDescription(
 | 
			
		||||
@@ -238,13 +238,12 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
			
		||||
            name="Holiday Mode",
 | 
			
		||||
            icon="mdi:palm-tree",
 | 
			
		||||
            device_class=BinarySensorDeviceClass.RUNNING,
 | 
			
		||||
            on_value="1",
 | 
			
		||||
            on_value=1,
 | 
			
		||||
            translation_key="holiday_mode",
 | 
			
		||||
        ),
 | 
			
		||||
    ),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BINARY_SENSORS["WD"] = unique_entities(BINARY_SENSORS["WM"], BINARY_SENSORS["TD"])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -252,7 +251,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
 | 
			
		||||
    entities = []
 | 
			
		||||
    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
			
		||||
        for description in BINARY_SENSORS.get(device.appliance_type, []):
 | 
			
		||||
            if not device.get(description.key):
 | 
			
		||||
            if device.get(description.key) is None:
 | 
			
		||||
                continue
 | 
			
		||||
            entity = HonBinarySensorEntity(hass, entry, device, description)
 | 
			
		||||
            await entity.coordinator.async_config_entry_first_refresh()
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,7 @@ class HonButtonEntity(HonEntity, ButtonEntity):
 | 
			
		||||
        """Return True if entity is available."""
 | 
			
		||||
        return (
 | 
			
		||||
            super().available
 | 
			
		||||
            and self._device.get("remoteCtrValid", "1") == "1"
 | 
			
		||||
            and int(self._device.get("remoteCtrValid", "1")) == 1
 | 
			
		||||
            and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -121,10 +121,10 @@ class HonACClimateEntity(HonEntity, ClimateEntity):
 | 
			
		||||
 | 
			
		||||
        self._attr_hvac_modes = [HVACMode.OFF]
 | 
			
		||||
        for mode in device.settings["settings.machMode"].values:
 | 
			
		||||
            self._attr_hvac_modes.append(HON_HVAC_MODE[mode])
 | 
			
		||||
            self._attr_hvac_modes.append(HON_HVAC_MODE[int(mode)])
 | 
			
		||||
        self._attr_fan_modes = [FAN_OFF]
 | 
			
		||||
        for mode in device.settings["settings.windSpeed"].values:
 | 
			
		||||
            self._attr_fan_modes.append(HON_FAN[mode])
 | 
			
		||||
            self._attr_fan_modes.append(HON_FAN[int(mode)])
 | 
			
		||||
        self._attr_swing_modes = [
 | 
			
		||||
            SWING_OFF,
 | 
			
		||||
            SWING_VERTICAL,
 | 
			
		||||
@@ -142,12 +142,12 @@ class HonACClimateEntity(HonEntity, ClimateEntity):
 | 
			
		||||
    @property
 | 
			
		||||
    def target_temperature(self) -> int | None:
 | 
			
		||||
        """Return the temperature we try to reach."""
 | 
			
		||||
        return int(float(self._device.get("tempSel")))
 | 
			
		||||
        return self._device.get("tempSel")
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def current_temperature(self) -> float | None:
 | 
			
		||||
        """Return the current temperature."""
 | 
			
		||||
        return float(self._device.get("tempIndoor"))
 | 
			
		||||
        return self._device.get("tempIndoor")
 | 
			
		||||
 | 
			
		||||
    async def async_set_temperature(self, **kwargs):
 | 
			
		||||
        if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
 | 
			
		||||
@@ -158,7 +158,7 @@ class HonACClimateEntity(HonEntity, ClimateEntity):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def hvac_mode(self) -> HVACMode | str | None:
 | 
			
		||||
        if self._device.get("onOffStatus") == "0":
 | 
			
		||||
        if self._device.get("onOffStatus") == 0:
 | 
			
		||||
            return HVACMode.OFF
 | 
			
		||||
        else:
 | 
			
		||||
            return HON_HVAC_MODE[self._device.get("machMode")]
 | 
			
		||||
@@ -193,11 +193,11 @@ class HonACClimateEntity(HonEntity, ClimateEntity):
 | 
			
		||||
        """Return the swing setting."""
 | 
			
		||||
        horizontal = self._device.get("windDirectionHorizontal")
 | 
			
		||||
        vertical = self._device.get("windDirectionVertical")
 | 
			
		||||
        if horizontal == "7" and vertical == "8":
 | 
			
		||||
        if horizontal == 7 and vertical == 8:
 | 
			
		||||
            return SWING_BOTH
 | 
			
		||||
        elif horizontal == "7":
 | 
			
		||||
        elif horizontal == 7:
 | 
			
		||||
            return SWING_HORIZONTAL
 | 
			
		||||
        elif vertical == "8":
 | 
			
		||||
        elif vertical == 8:
 | 
			
		||||
            return SWING_VERTICAL
 | 
			
		||||
        else:
 | 
			
		||||
            return SWING_OFF
 | 
			
		||||
@@ -263,13 +263,13 @@ class HonClimateEntity(HonEntity, ClimateEntity):
 | 
			
		||||
    @property
 | 
			
		||||
    def target_temperature(self) -> float | None:
 | 
			
		||||
        """Return the temperature we try to reach."""
 | 
			
		||||
        return float(self._device.get(self.entity_description.key))
 | 
			
		||||
        return self._device.get(self.entity_description.key)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def current_temperature(self) -> float | None:
 | 
			
		||||
        """Return the current temperature."""
 | 
			
		||||
        temp_key = self.entity_description.key.split(".")[-1].replace("Sel", "")
 | 
			
		||||
        return float(self._device.get(temp_key))
 | 
			
		||||
        return self._device.get(temp_key)
 | 
			
		||||
 | 
			
		||||
    async def async_set_temperature(self, **kwargs):
 | 
			
		||||
        if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
 | 
			
		||||
@@ -280,7 +280,7 @@ class HonClimateEntity(HonEntity, ClimateEntity):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def hvac_mode(self) -> HVACMode | str | None:
 | 
			
		||||
        if self._device.get("onOffStatus") == "0":
 | 
			
		||||
        if self._device.get("onOffStatus") == 0:
 | 
			
		||||
            return HVACMode.OFF
 | 
			
		||||
        else:
 | 
			
		||||
            return self.entity_description.mode
 | 
			
		||||
 
 | 
			
		||||
@@ -21,13 +21,13 @@ PLATFORMS = [
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
HON_HVAC_MODE = {
 | 
			
		||||
    "0": HVACMode.AUTO,
 | 
			
		||||
    "1": HVACMode.COOL,
 | 
			
		||||
    "2": HVACMode.DRY,
 | 
			
		||||
    "3": HVACMode.DRY,
 | 
			
		||||
    "4": HVACMode.HEAT,
 | 
			
		||||
    "5": HVACMode.FAN_ONLY,
 | 
			
		||||
    "6": HVACMode.FAN_ONLY,
 | 
			
		||||
    0: HVACMode.AUTO,
 | 
			
		||||
    1: HVACMode.COOL,
 | 
			
		||||
    2: HVACMode.DRY,
 | 
			
		||||
    3: HVACMode.DRY,
 | 
			
		||||
    4: HVACMode.HEAT,
 | 
			
		||||
    5: HVACMode.FAN_ONLY,
 | 
			
		||||
    6: HVACMode.FAN_ONLY,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HON_HVAC_PROGRAM = {
 | 
			
		||||
@@ -39,11 +39,11 @@ HON_HVAC_PROGRAM = {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HON_FAN = {
 | 
			
		||||
    "1": FAN_HIGH,
 | 
			
		||||
    "2": FAN_MEDIUM,
 | 
			
		||||
    "3": FAN_LOW,
 | 
			
		||||
    "4": FAN_AUTO,
 | 
			
		||||
    "5": FAN_AUTO,
 | 
			
		||||
    1: FAN_HIGH,
 | 
			
		||||
    2: FAN_MEDIUM,
 | 
			
		||||
    3: FAN_LOW,
 | 
			
		||||
    4: FAN_AUTO,
 | 
			
		||||
    5: FAN_AUTO,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# These languages are official supported by hOn
 | 
			
		||||
@@ -70,121 +70,121 @@ LANGUAGES = [
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
WASHING_PR_PHASE = {
 | 
			
		||||
    "0": "ready",
 | 
			
		||||
    "1": "washing",
 | 
			
		||||
    "2": "washing",
 | 
			
		||||
    "3": "spin",
 | 
			
		||||
    "4": "rinse",
 | 
			
		||||
    "5": "rinse",
 | 
			
		||||
    "6": "rinse",
 | 
			
		||||
    "7": "drying",
 | 
			
		||||
    "9": "steam",
 | 
			
		||||
    "10": "ready",
 | 
			
		||||
    "11": "spin",
 | 
			
		||||
    "12": "weighting",
 | 
			
		||||
    "13": "weighting",
 | 
			
		||||
    "14": "washing",
 | 
			
		||||
    "15": "washing",
 | 
			
		||||
    "16": "washing",
 | 
			
		||||
    "17": "rinse",
 | 
			
		||||
    "18": "rinse",
 | 
			
		||||
    "19": "scheduled",
 | 
			
		||||
    "20": "tumbling",
 | 
			
		||||
    "24": "refresh",
 | 
			
		||||
    "25": "washing",
 | 
			
		||||
    "26": "heating",
 | 
			
		||||
    "27": "washing",
 | 
			
		||||
    0: "ready",
 | 
			
		||||
    1: "washing",
 | 
			
		||||
    2: "washing",
 | 
			
		||||
    3: "spin",
 | 
			
		||||
    4: "rinse",
 | 
			
		||||
    5: "rinse",
 | 
			
		||||
    6: "rinse",
 | 
			
		||||
    7: "drying",
 | 
			
		||||
    9: "steam",
 | 
			
		||||
    10: "ready",
 | 
			
		||||
    11: "spin",
 | 
			
		||||
    12: "weighting",
 | 
			
		||||
    13: "weighting",
 | 
			
		||||
    14: "washing",
 | 
			
		||||
    15: "washing",
 | 
			
		||||
    16: "washing",
 | 
			
		||||
    17: "rinse",
 | 
			
		||||
    18: "rinse",
 | 
			
		||||
    19: "scheduled",
 | 
			
		||||
    20: "tumbling",
 | 
			
		||||
    24: "refresh",
 | 
			
		||||
    25: "washing",
 | 
			
		||||
    26: "heating",
 | 
			
		||||
    27: "washing",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MACH_MODE = {
 | 
			
		||||
    "0": "ready",  # NO_STATE
 | 
			
		||||
    "1": "ready",  # SELECTION_MODE
 | 
			
		||||
    "2": "running",  # EXECUTION_MODE
 | 
			
		||||
    "3": "pause",  # PAUSE_MODE
 | 
			
		||||
    "4": "scheduled",  # DELAY_START_SELECTION_MODE
 | 
			
		||||
    "5": "scheduled",  # DELAY_START_EXECUTION_MODE
 | 
			
		||||
    "6": "error",  # ERROR_MODE
 | 
			
		||||
    "7": "ready",  # END_MODE
 | 
			
		||||
    "8": "test",  # TEST_MODE
 | 
			
		||||
    "9": "ending",  # STOP_MODE
 | 
			
		||||
    0: "ready",  # NO_STATE
 | 
			
		||||
    1: "ready",  # SELECTION_MODE
 | 
			
		||||
    2: "running",  # EXECUTION_MODE
 | 
			
		||||
    3: "pause",  # PAUSE_MODE
 | 
			
		||||
    4: "scheduled",  # DELAY_START_SELECTION_MODE
 | 
			
		||||
    5: "scheduled",  # DELAY_START_EXECUTION_MODE
 | 
			
		||||
    6: "error",  # ERROR_MODE
 | 
			
		||||
    7: "ready",  # END_MODE
 | 
			
		||||
    8: "test",  # TEST_MODE
 | 
			
		||||
    9: "ending",  # STOP_MODE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TUMBLE_DRYER_PR_PHASE = {
 | 
			
		||||
    "0": "ready",
 | 
			
		||||
    "1": "heat_stroke",
 | 
			
		||||
    "2": "drying",
 | 
			
		||||
    "3": "cooldown",
 | 
			
		||||
    "8": "unknown",
 | 
			
		||||
    "11": "ready",
 | 
			
		||||
    "12": "unknown",
 | 
			
		||||
    "13": "cooldown",
 | 
			
		||||
    "14": "heat_stroke",
 | 
			
		||||
    "15": "heat_stroke",
 | 
			
		||||
    "16": "cooldown",
 | 
			
		||||
    "17": "unknown",
 | 
			
		||||
    "18": "tumbling",
 | 
			
		||||
    "19": "drying",
 | 
			
		||||
    "20": "drying",
 | 
			
		||||
    0: "ready",
 | 
			
		||||
    1: "heat_stroke",
 | 
			
		||||
    2: "drying",
 | 
			
		||||
    3: "cooldown",
 | 
			
		||||
    8: "unknown",
 | 
			
		||||
    11: "ready",
 | 
			
		||||
    12: "unknown",
 | 
			
		||||
    13: "cooldown",
 | 
			
		||||
    14: "heat_stroke",
 | 
			
		||||
    15: "heat_stroke",
 | 
			
		||||
    16: "cooldown",
 | 
			
		||||
    17: "unknown",
 | 
			
		||||
    18: "tumbling",
 | 
			
		||||
    19: "drying",
 | 
			
		||||
    20: "drying",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DIRTY_LEVEL = {
 | 
			
		||||
    "0": "unknown",
 | 
			
		||||
    "1": "little",
 | 
			
		||||
    "2": "normal",
 | 
			
		||||
    "3": "very",
 | 
			
		||||
    0: "unknown",
 | 
			
		||||
    1: "little",
 | 
			
		||||
    2: "normal",
 | 
			
		||||
    3: "very",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
STEAM_LEVEL = {
 | 
			
		||||
    "0": "no_steam",
 | 
			
		||||
    "1": "cotton",
 | 
			
		||||
    "2": "delicate",
 | 
			
		||||
    "3": "synthetic",
 | 
			
		||||
    0: "no_steam",
 | 
			
		||||
    1: "cotton",
 | 
			
		||||
    2: "delicate",
 | 
			
		||||
    3: "synthetic",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DISHWASHER_PR_PHASE = {
 | 
			
		||||
    "0": "ready",
 | 
			
		||||
    "1": "prewash",
 | 
			
		||||
    "2": "washing",
 | 
			
		||||
    "3": "rinse",
 | 
			
		||||
    "4": "drying",
 | 
			
		||||
    "5": "ready",
 | 
			
		||||
    "6": "hot_rinse",
 | 
			
		||||
    0: "ready",
 | 
			
		||||
    1: "prewash",
 | 
			
		||||
    2: "washing",
 | 
			
		||||
    3: "rinse",
 | 
			
		||||
    4: "drying",
 | 
			
		||||
    5: "ready",
 | 
			
		||||
    6: "hot_rinse",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TUMBLE_DRYER_DRY_LEVEL = {
 | 
			
		||||
    "0": "no_dry",
 | 
			
		||||
    "1": "iron_dry",
 | 
			
		||||
    "2": "no_dry_iron",
 | 
			
		||||
    "3": "cupboard_dry",
 | 
			
		||||
    "4": "extra_dry",
 | 
			
		||||
    "11": "no_dry",
 | 
			
		||||
    "12": "iron_dry",
 | 
			
		||||
    "13": "cupboard_dry",
 | 
			
		||||
    "14": "ready_to_wear",
 | 
			
		||||
    "15": "extra_dry",
 | 
			
		||||
    0: "no_dry",
 | 
			
		||||
    1: "iron_dry",
 | 
			
		||||
    2: "no_dry_iron",
 | 
			
		||||
    3: "cupboard_dry",
 | 
			
		||||
    4: "extra_dry",
 | 
			
		||||
    11: "no_dry",
 | 
			
		||||
    12: "iron_dry",
 | 
			
		||||
    13: "cupboard_dry",
 | 
			
		||||
    14: "ready_to_wear",
 | 
			
		||||
    15: "extra_dry",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AC_MACH_MODE = {
 | 
			
		||||
    "0": "auto",
 | 
			
		||||
    "1": "cool",
 | 
			
		||||
    "2": "cool",
 | 
			
		||||
    "3": "dry",
 | 
			
		||||
    "4": "heat",
 | 
			
		||||
    "5": "fan",
 | 
			
		||||
    "6": "fan",
 | 
			
		||||
    0: "auto",
 | 
			
		||||
    1: "cool",
 | 
			
		||||
    2: "cool",
 | 
			
		||||
    3: "dry",
 | 
			
		||||
    4: "heat",
 | 
			
		||||
    5: "fan",
 | 
			
		||||
    6: "fan",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AC_FAN_MODE = {
 | 
			
		||||
    "1": "high",
 | 
			
		||||
    "2": "mid",
 | 
			
		||||
    "3": "low",
 | 
			
		||||
    "4": "auto",
 | 
			
		||||
    "5": "auto",
 | 
			
		||||
    1: "high",
 | 
			
		||||
    2: "mid",
 | 
			
		||||
    3: "low",
 | 
			
		||||
    4: "auto",
 | 
			
		||||
    5: "auto",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AC_HUMAN_SENSE = {
 | 
			
		||||
    "0": "touch_off",
 | 
			
		||||
    "1": "avoid_touch",
 | 
			
		||||
    "2": "follow_touch",
 | 
			
		||||
    "3": "unknown",
 | 
			
		||||
    0: "touch_off",
 | 
			
		||||
    1: "avoid_touch",
 | 
			
		||||
    2: "follow_touch",
 | 
			
		||||
    3: "unknown",
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,8 +44,8 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
 | 
			
		||||
    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
			
		||||
        for description in FANS.get(device.appliance_type, []):
 | 
			
		||||
            if isinstance(description, HonFanEntityDescription):
 | 
			
		||||
                if description.key not in device.available_settings or not device.get(
 | 
			
		||||
                    description.key.split(".")[-1]
 | 
			
		||||
                if description.key not in device.available_settings or device.get(
 | 
			
		||||
                    description.key.split(".")[-1] is None
 | 
			
		||||
                ):
 | 
			
		||||
                    continue
 | 
			
		||||
                entity = HonFanEntity(hass, entry, device, description)
 | 
			
		||||
@@ -74,7 +74,7 @@ class HonFanEntity(HonEntity, FanEntity):
 | 
			
		||||
    @property
 | 
			
		||||
    def percentage(self) -> int | None:
 | 
			
		||||
        """Return the current speed."""
 | 
			
		||||
        value = int(self._device.get(self._parameter, "0"))
 | 
			
		||||
        value = self._device.get(self._parameter, 0)
 | 
			
		||||
        return ranged_value_to_percentage(self._speed_range, value)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import logging
 | 
			
		||||
from contextlib import suppress
 | 
			
		||||
from datetime import timedelta
 | 
			
		||||
 | 
			
		||||
from homeassistant.core import callback
 | 
			
		||||
@@ -81,3 +82,8 @@ def get_coordinator(hass, appliance):
 | 
			
		||||
        coordinator = HonCoordinator(hass, appliance)
 | 
			
		||||
        hass.data[DOMAIN]["coordinators"][appliance.unique_id] = coordinator
 | 
			
		||||
    return coordinator
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_readable(description, value):
 | 
			
		||||
    with suppress(ValueError):
 | 
			
		||||
        return description.option_list.get(int(value), value)
 | 
			
		||||
 
 | 
			
		||||
@@ -232,7 +232,7 @@ class HonNumberEntity(HonEntity, NumberEntity):
 | 
			
		||||
        """Return True if entity is available."""
 | 
			
		||||
        return (
 | 
			
		||||
            super().available
 | 
			
		||||
            and self._device.get("remoteCtrValid", "1") == "1"
 | 
			
		||||
            and int(self._device.get("remoteCtrValid", 1)) == 1
 | 
			
		||||
            and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
from __future__ import annotations
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
from contextlib import suppress
 | 
			
		||||
from dataclasses import dataclass
 | 
			
		||||
from typing import Dict, List
 | 
			
		||||
 | 
			
		||||
@@ -13,20 +14,20 @@ from pyhon.appliance import HonAppliance
 | 
			
		||||
 | 
			
		||||
from . import const
 | 
			
		||||
from .const import DOMAIN
 | 
			
		||||
from .hon import HonEntity, unique_entities
 | 
			
		||||
from .hon import HonEntity, unique_entities, get_readable
 | 
			
		||||
 | 
			
		||||
_LOGGER = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@dataclass
 | 
			
		||||
class HonSelectEntityDescription(SelectEntityDescription):
 | 
			
		||||
    option_list: Dict[str, str] = None
 | 
			
		||||
    option_list: Dict[int, str] = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@dataclass
 | 
			
		||||
class HonConfigSelectEntityDescription(SelectEntityDescription):
 | 
			
		||||
    entity_category: EntityCategory = EntityCategory.CONFIG
 | 
			
		||||
    option_list: Dict[str, str] = None
 | 
			
		||||
    option_list: Dict[int, str] = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SELECTS = {
 | 
			
		||||
@@ -180,19 +181,18 @@ class HonSelectEntity(HonEntity, SelectEntity):
 | 
			
		||||
        setting = self._device.settings.get(self.entity_description.key)
 | 
			
		||||
        if setting is None:
 | 
			
		||||
            self._attr_available = False
 | 
			
		||||
            self._attr_options: List[str] = []
 | 
			
		||||
            options = []
 | 
			
		||||
            value = None
 | 
			
		||||
        else:
 | 
			
		||||
            self._attr_available = True
 | 
			
		||||
            self._attr_options: List[str] = setting.values
 | 
			
		||||
            options = setting.values
 | 
			
		||||
            value = setting.value
 | 
			
		||||
        if self.entity_description.option_list is not None:
 | 
			
		||||
            self._attr_options = [
 | 
			
		||||
                self.entity_description.option_list.get(k, k)
 | 
			
		||||
                for k in self._attr_options
 | 
			
		||||
            ]
 | 
			
		||||
            with suppress(ValueError):
 | 
			
		||||
                options = [get_readable(self.entity_description, k) for k in options]
 | 
			
		||||
            if value is not None:
 | 
			
		||||
                value = self.entity_description.option_list.get(value, value)
 | 
			
		||||
                value = get_readable(self.entity_description, value)
 | 
			
		||||
        self._attr_options: List[str] = options
 | 
			
		||||
        self._attr_native_value = value
 | 
			
		||||
        if update:
 | 
			
		||||
            self.async_write_ha_state()
 | 
			
		||||
@@ -202,7 +202,7 @@ class HonSelectEntity(HonEntity, SelectEntity):
 | 
			
		||||
        """Return True if entity is available."""
 | 
			
		||||
        return (
 | 
			
		||||
            super().available
 | 
			
		||||
            and self._device.get("remoteCtrValid", "1") == "1"
 | 
			
		||||
            and int(self._device.get("remoteCtrValid", 1)) == 1
 | 
			
		||||
            and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ from homeassistant.helpers.entity import EntityCategory
 | 
			
		||||
 | 
			
		||||
from . import const
 | 
			
		||||
from .const import DOMAIN
 | 
			
		||||
from .hon import HonEntity, unique_entities
 | 
			
		||||
from .hon import HonEntity, unique_entities, get_readable
 | 
			
		||||
 | 
			
		||||
_LOGGER = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
@@ -32,12 +32,12 @@ _LOGGER = logging.getLogger(__name__)
 | 
			
		||||
@dataclass
 | 
			
		||||
class HonConfigSensorEntityDescription(SensorEntityDescription):
 | 
			
		||||
    entity_category: EntityCategory = EntityCategory.CONFIG
 | 
			
		||||
    option_list: Dict[str, str] = None
 | 
			
		||||
    option_list: Dict[int, str] = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@dataclass
 | 
			
		||||
class HonSensorEntityDescription(SensorEntityDescription):
 | 
			
		||||
    option_list: Dict[str, str] = None
 | 
			
		||||
    option_list: Dict[int, str] = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
 | 
			
		||||
@@ -692,7 +692,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
 | 
			
		||||
    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
			
		||||
        for description in SENSORS.get(device.appliance_type, []):
 | 
			
		||||
            if isinstance(description, HonSensorEntityDescription):
 | 
			
		||||
                if not device.get(description.key):
 | 
			
		||||
                if device.get(description.key) is None:
 | 
			
		||||
                    continue
 | 
			
		||||
                entity = HonSensorEntity(hass, entry, device, description)
 | 
			
		||||
            elif isinstance(description, HonConfigSensorEntityDescription):
 | 
			
		||||
@@ -719,7 +719,7 @@ class HonSensorEntity(HonEntity, SensorEntity):
 | 
			
		||||
            ).values + ["No Program"]
 | 
			
		||||
        elif self.entity_description.option_list is not None:
 | 
			
		||||
            self._attr_options = list(self.entity_description.option_list.values())
 | 
			
		||||
            value = self.entity_description.option_list.get(value, value)
 | 
			
		||||
            value = get_readable(self.entity_description, value)
 | 
			
		||||
        if not value and self.entity_description.state_class is not None:
 | 
			
		||||
            self._attr_native_value = 0
 | 
			
		||||
        self._attr_native_value = value
 | 
			
		||||
@@ -744,7 +744,7 @@ class HonConfigSensorEntity(HonEntity, SensorEntity):
 | 
			
		||||
            value = value.value
 | 
			
		||||
        if self.entity_description.option_list is not None and not value == 0:
 | 
			
		||||
            self._attr_options = list(self.entity_description.option_list.values())
 | 
			
		||||
            value = self.entity_description.option_list.get(value, value)
 | 
			
		||||
            value = get_readable(self.entity_description, value)
 | 
			
		||||
        self._attr_native_value = value
 | 
			
		||||
        if update:
 | 
			
		||||
            self.async_write_ha_state()
 | 
			
		||||
 
 | 
			
		||||
@@ -358,7 +358,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
 | 
			
		||||
            elif isinstance(description, HonSwitchEntityDescription):
 | 
			
		||||
                if (
 | 
			
		||||
                    f"settings.{description.key}" not in device.available_settings
 | 
			
		||||
                    or not device.get(description.key)
 | 
			
		||||
                    or device.get(description.key) is None
 | 
			
		||||
                ):
 | 
			
		||||
                    continue
 | 
			
		||||
                entity = HonSwitchEntity(hass, entry, device, description)
 | 
			
		||||
@@ -376,7 +376,7 @@ class HonSwitchEntity(HonEntity, SwitchEntity):
 | 
			
		||||
    @property
 | 
			
		||||
    def is_on(self) -> bool | None:
 | 
			
		||||
        """Return True if entity is on."""
 | 
			
		||||
        return self._device.get(self.entity_description.key, "0") == "1"
 | 
			
		||||
        return self._device.get(self.entity_description.key, 0) == 1
 | 
			
		||||
 | 
			
		||||
    async def async_turn_on(self, **kwargs: Any) -> None:
 | 
			
		||||
        setting = self._device.settings[f"settings.{self.entity_description.key}"]
 | 
			
		||||
@@ -401,14 +401,14 @@ class HonSwitchEntity(HonEntity, SwitchEntity):
 | 
			
		||||
        """Return True if entity is available."""
 | 
			
		||||
        return (
 | 
			
		||||
            super().available
 | 
			
		||||
            and self._device.get("remoteCtrValid", "1") == "1"
 | 
			
		||||
            and int(self._device.get("remoteCtrValid", 1)) == 1
 | 
			
		||||
            and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @callback
 | 
			
		||||
    def _handle_coordinator_update(self, update=True) -> None:
 | 
			
		||||
        value = self._device.get(self.entity_description.key, "0")
 | 
			
		||||
        self._attr_state = value == "1"
 | 
			
		||||
        value = self._device.get(self.entity_description.key, 0)
 | 
			
		||||
        self._attr_state = value == 1
 | 
			
		||||
        if update:
 | 
			
		||||
            self.async_write_ha_state()
 | 
			
		||||
 | 
			
		||||
@@ -436,7 +436,7 @@ class HonControlSwitchEntity(HonEntity, SwitchEntity):
 | 
			
		||||
        """Return True if entity is available."""
 | 
			
		||||
        return (
 | 
			
		||||
            super().available
 | 
			
		||||
            and self._device.get("remoteCtrValid", "1") == "1"
 | 
			
		||||
            and int(self._device.get("remoteCtrValid", 1)) == 1
 | 
			
		||||
            and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
@@ -444,8 +444,8 @@ class HonControlSwitchEntity(HonEntity, SwitchEntity):
 | 
			
		||||
    def extra_state_attributes(self) -> dict[str, Any]:
 | 
			
		||||
        """Return the optional state attributes."""
 | 
			
		||||
        result = {}
 | 
			
		||||
        if remaining_time := int(self._device.get("remainingTimeMM", 0)):
 | 
			
		||||
            delay_time = int(self._device.get("delayTime", 0))
 | 
			
		||||
        if remaining_time := self._device.get("remainingTimeMM", 0):
 | 
			
		||||
            delay_time = self._device.get("delayTime", 0)
 | 
			
		||||
            result["start_time"] = datetime.now() + timedelta(minutes=delay_time)
 | 
			
		||||
            result["end_time"] = datetime.now() + timedelta(
 | 
			
		||||
                minutes=delay_time + remaining_time
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user