Compare commits

...

9 Commits

Author SHA1 Message Date
d3503af158 Bump version 2023-06-10 07:13:07 +02:00
d81b1ae712 Add td phase 8, #64 2023-06-10 07:00:57 +02:00
eb5ba43707 Add wine cellar 2023-06-10 06:44:19 +02:00
efcac321b8 Bump version 2023-06-09 06:04:05 +02:00
79b43b8695 Use fan entity for wind speed 2023-06-09 05:56:52 +02:00
5bc3120000 Bump version 2023-06-08 22:07:56 +02:00
0f9f0dee4c Fix issues when changing climate mode #52 2023-06-08 21:46:36 +02:00
80b3741f2f Reduce lagging update 2023-06-08 20:01:55 +02:00
c433714a94 Refactor and update for lagging climate 2023-06-08 19:59:43 +02:00
33 changed files with 1034 additions and 160 deletions

View File

@ -12,10 +12,11 @@ Home Assistant integration for [Haier's mobile app hOn](https://hon-smarthome.co
- [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer)
- [Oven](https://github.com/Andre0512/hon#oven)
- [Dish Washer](https://github.com/Andre0512/hon#dish-washer)
- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner)
- [Fridge](https://github.com/Andre0512/hon#fridge)
- [Hob](https://github.com/Andre0512/hon#hob) [BETA]
- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA]
- [Fridge](https://github.com/Andre0512/hon#fridge) [BETA]
- [Hood](https://github.com/Andre0512/hon#hood) [BETA]
- [Wine Cellar](https://github.com/Andre0512/hon#wine-cellar) [BETA]
## Installation
**Method 1:** [![Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=Andre0512&repository=hon&category=integration)
@ -61,41 +62,18 @@ Translation of internal names like programs are available for all languages whic
## Supported Models
Support has been confirmed for these models, but many more will work. Please add already supported devices [with this form to complete the list](https://forms.gle/bTSD8qFotdZFytbf8).
- Haier AD105S2SM3FA
- Haier AS25PBAHRA
- Haier AS25S2SF1FA-WH
- Haier AS25TADHRA-2
- Haier AS35TADHRA-2
- Haier EG9012B19SU1JD
- Haier HA2MTSJ68MC
- Haier HADG6DS46BWIFI
- Haier HD80-A3959
- Haier HW90-B14TEAM5
- Haier HW100-B14959U1
- Haier HWD100-B14979
- Haier HWO60SM2F3XH
- Haier XIB 3B2SFS-80
- Haier XIB 6B2D3FB
- Candy BCTDH7A1TE
- Candy CCE4T620EWU
- Candy CIS633SCTTWIFI
- Candy CSOE C10DE-80
- Candy RO44 1286DWMC4-07
- Candy ROE H9A3TCEX-S
- Candy RPW41066BWMR/1-S
- Hoover H-WASH 500
- Hoover H-DRY 500
- Hoover H7W4 48MBC-S
- Hoover H9A3TCBEXS-S
- Hoover HFB 6B2S3FX
- Hoover HLE C10DCE-80
- Hoover HSOT3161WG
- Hoover HW 68AMC/1-80
- Hoover HWPD 69AMBC/1-S
- Hoover HWPS4954DAMR-11
- Hoover NDE H10A2TCE-80
- Hoover NDE H9A2TSBEXS-S
- Hoover NDPHY10A2TCBEXSS
| | **Haier** | **Hoover** | **Candy** |
|--------------------|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
| **Washing Machine** | HW90-B14TEAM5 <br/> HW100-B14959U1 | H-WASH 500 <br/> H7W4 48MBC-S | RO44 1286DWMC4-07 <br/> HW 68AMC/1-80 <br/> HWPD 69AMBC/1-S |
| **Tumble Dryer** | HD80-A3959 | H-DRY 500 <br/> H9A3TCBEXS-S <br/> HLE C10DCE-80 <br/> NDE H10A2TCE-80 <br/> NDE H9A2TSBEXS-S <br/> NDPHY10A2TCBEXSS | BCTDH7A1TE <br/> CSOE C10DE-80 <br/> ROE H9A3TCEX-S |
| **Washer Dryer** | HWD100-B14979 | HWPS4954DAMR-11 | RPW41066BWMR/1-S |
| **Oven** | HWO60SM2F3XH | HSOT3161WG | |
| **Dish Washer** | XIB 3B2SFS-80 <br/> XIB 6B2D3FB | HFB 6B2S3FX | |
| **Air conditioner** | AD105S2SM3FA <br/> AS20HPL1HRA <br/> AS25PBAHRA <br/> AS25S2SF1FA-WH <br/> AS25TADHRA-2 <br/> AS35TADHRA-2 <br/> | | |
| **Fridge** | HFW7720ENMB | | CCE4T620EWU |
| **Hob** | HA2MTSJ68MC | | CIS633SCTTWIFI |
| **Hood** | HADG6DS46BWIFI | | |
## Contribute
Any kind of contribution is welcome!
@ -236,11 +214,11 @@ For every device exists a hidden button which can be used to log all infos of yo
| --- | --- | --- | --- |
| Start Program | `hvac` | `button` | `startProgram` |
| Stop Program | `hvac-off` | `button` | `stopProgram` |
| Wind Speed | | `fan` | `settings.windSpeed` |
#### Configs
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Light status | `lightbulb` | `number` | `startProgram.lightStatus` |
| Wind speed | `fan` | `number` | `startProgram.windSpeed` |
#### Sensors
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
@ -256,7 +234,6 @@ For every device exists a hidden button which can be used to log all infos of yo
| Quick Delay Time Status | | `sensor` | `quickDelayTimeStatus` |
| RGB Light Color | `lightbulb` | `sensor` | `rgbLightColors` |
| RGB Light Status | `lightbulb` | `sensor` | `rgbLightStatus` |
| Wind Speed | `fan` | `sensor` | `windSpeed` |
### Hob
#### Controls
@ -380,6 +357,27 @@ For every device exists a hidden button which can be used to log all infos of yo
| Steam level | `smoke` | `sensor` | `steamLevel` |
| Temperature level | `thermometer` | `sensor` | `tempLevel` |
### Wine Cellar
#### Controls
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Light | `lightbulb` | `switch` | `lightStatus` |
| Sabbath Mode | `palm-tree` | `switch` | `sabbathStatus` |
| Wine Cellar | `thermometer` | `climate` | `settings.tempSel` |
| Wine Cellar | `thermometer` | `climate` | `settings.tempSelZ2` |
#### Sensors
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Error | `math-log` | `sensor` | `errors` |
| Humidity | `water-percent` | `sensor` | `humidityZ1` |
| Humidity 2 | `water-percent` | `sensor` | `humidityZ2` |
| Program | `play` | `sensor` | `programName` |
| Room Temperature | `home-thermometer-outline` | `sensor` | `tempEnv` |
| Selected Temperature | `thermometer` | `sensor` | `tempSel` |
| Selected Temperature 2 | `thermometer` | `sensor` | `tempSelZ2` |
| Temperature | `thermometer` | `sensor` | `temp` |
| Temperature 2 | `thermometer` | `sensor` | `tempZ2` |
### Washer dryer
#### Controls
| Name | Icon | Entity | Key |

View File

@ -271,9 +271,10 @@ class HonBinarySensorEntity(HonEntity, BinarySensorEntity):
)
@callback
def _handle_coordinator_update(self):
def _handle_coordinator_update(self, update=True) -> None:
self._attr_native_value = (
self._device.get(self.entity_description.key, "")
== self.entity_description.on_value
)
if update:
self.async_write_ha_state()

View File

@ -1,8 +1,6 @@
import logging
from dataclasses import dataclass
from pyhon.appliance import HonAppliance
from homeassistant.components.climate import (
ClimateEntity,
ClimateEntityDescription,
@ -22,6 +20,8 @@ from homeassistant.const import (
TEMP_CELSIUS,
)
from homeassistant.core import callback
from pyhon.appliance import HonAppliance
from .const import HON_HVAC_MODE, HON_FAN, HON_HVAC_PROGRAM, DOMAIN
from .hon import HonEntity
@ -72,6 +72,22 @@ CLIMATES = {
translation_key="oven",
),
),
"WC": (
HonClimateEntityDescription(
key="settings.tempSel",
mode=HVACMode.COOL,
name="Wine Cellar",
icon="mdi:thermometer",
translation_key="wine",
),
HonClimateEntityDescription(
key="settings.tempSelZ2",
mode=HVACMode.COOL,
name="Wine Cellar",
icon="mdi:thermometer",
translation_key="wine",
),
),
}
@ -103,12 +119,12 @@ class HonACClimateEntity(HonEntity, ClimateEntity):
self._attr_max_temp = device.settings["settings.tempSel"].max
self._attr_min_temp = device.settings["settings.tempSel"].min
self._attr_hvac_modes = [HVACMode.OFF] + [
HON_HVAC_MODE[mode] for mode in device.settings["settings.machMode"].values
]
self._attr_fan_modes = [FAN_OFF] + [
HON_FAN[mode] for mode in device.settings["settings.windSpeed"].values
]
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_fan_modes = [FAN_OFF]
for mode in device.settings["settings.windSpeed"].values:
self._attr_fan_modes.append(HON_FAN[mode])
self._attr_swing_modes = [
SWING_OFF,
SWING_VERTICAL,
@ -123,6 +139,23 @@ class HonACClimateEntity(HonEntity, ClimateEntity):
self._handle_coordinator_update(update=False)
@property
def target_temperature(self) -> int | None:
"""Return the temperature we try to reach."""
return int(float(self._device.get("tempSel")))
@property
def current_temperature(self) -> float | None:
"""Return the current temperature."""
return float(self._device.get("tempIndoor"))
async def async_set_temperature(self, **kwargs):
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
return False
self._device.settings["settings.tempSel"].value = str(int(temperature))
await self._device.commands["settings"].send()
self.async_write_ha_state()
@property
def hvac_mode(self) -> HVACMode | str | None:
if self._device.get("onOffStatus") == "0":
@ -131,24 +164,44 @@ class HonACClimateEntity(HonEntity, ClimateEntity):
return HON_HVAC_MODE[self._device.get("machMode")]
async def async_set_hvac_mode(self, hvac_mode):
if hvac_mode == HVACMode.OFF:
await self._device.commands["stopProgram"].send()
else:
self._device.settings["startProgram.program"].value = HON_HVAC_PROGRAM[
hvac_mode
]
await self._device.commands["startProgram"].send()
self._attr_hvac_mode = hvac_mode
if hvac_mode == HVACMode.OFF:
command = "stopProgram"
else:
mode = HON_HVAC_PROGRAM[hvac_mode]
self._device.settings["startProgram.program"].value = mode
command = "startProgram"
await self._device.commands[command].send()
self._device.sync_command(command, "settings")
self.async_write_ha_state()
@property
def fan_mode(self) -> str | None:
"""Return the fan setting."""
return HON_FAN[self._device.get("windSpeed")]
async def async_set_fan_mode(self, fan_mode):
mode_number = list(HON_FAN.values()).index(fan_mode)
self._device.settings["settings.windSpeed"].value = list(HON_FAN.keys())[
mode_number
]
mode = list(HON_FAN.keys())[mode_number]
self._device.settings["settings.windSpeed"].value = mode
self._attr_fan_mode = fan_mode
await self._device.commands["settings"].send()
self.async_write_ha_state()
@property
def swing_mode(self) -> str | None:
"""Return the swing setting."""
horizontal = self._device.get("windDirectionHorizontal")
vertical = self._device.get("windDirectionVertical")
if horizontal == "7" and vertical == "8":
return SWING_BOTH
elif horizontal == "7":
return SWING_HORIZONTAL
elif vertical == "8":
return SWING_VERTICAL
else:
return SWING_OFF
async def async_set_swing_mode(self, swing_mode):
horizontal = self._device.settings["settings.windDirectionHorizontal"]
vertical = self._device.settings["settings.windDirectionVertical"]
@ -164,41 +217,19 @@ class HonACClimateEntity(HonEntity, ClimateEntity):
await self._device.commands["settings"].send()
self.async_write_ha_state()
async def async_set_temperature(self, **kwargs):
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
return False
self._device.settings["settings.tempSel"].value = str(int(temperature))
await self._device.commands["settings"].send()
self.async_write_ha_state()
@callback
def _handle_coordinator_update(self, update=True) -> None:
self._attr_target_temperature = int(float(self._device.get("tempSel")))
self._attr_current_temperature = float(self._device.get("tempIndoor"))
if self._device.get("onOffStatus") == "0":
self._attr_hvac_mode = HVACMode.OFF
else:
self._attr_hvac_mode = HON_HVAC_MODE[self._device.get("machMode")]
self._attr_fan_mode = HON_FAN[self._device.get("windSpeed")]
horizontal = self._device.get("windDirectionHorizontal")
vertical = self._device.get("windDirectionVertical")
if horizontal == "7" and vertical == "8":
self._attr_swing_mode = SWING_BOTH
elif horizontal == "7":
self._attr_swing_mode = SWING_HORIZONTAL
elif vertical == "8":
self._attr_swing_mode = SWING_VERTICAL
else:
self._attr_swing_mode = SWING_OFF
self._attr_target_temperature = self.target_temperature
self._attr_current_temperature = self.current_temperature
self._attr_hvac_mode = self.hvac_mode
self._attr_fan_mode = self.fan_mode
self._attr_swing_mode = self.swing_mode
if update:
self.async_write_ha_state()
class HonClimateEntity(HonEntity, ClimateEntity):
entity_description = HonClimateEntityDescription
entity_description: HonClimateEntityDescription
def __init__(self, hass, entry, device: HonAppliance, description) -> None:
super().__init__(hass, entry, device, description)
@ -211,7 +242,7 @@ class HonClimateEntity(HonEntity, ClimateEntity):
)
self._attr_hvac_modes = [description.mode]
if device.get("onOffStatus"):
if "stopProgram" in device.commands:
self._attr_hvac_modes += [HVACMode.OFF]
modes = []
else:
@ -230,15 +261,15 @@ class HonClimateEntity(HonEntity, ClimateEntity):
self._handle_coordinator_update(update=False)
@property
def target_temperature(self) -> int | None:
def target_temperature(self) -> float | None:
"""Return the temperature we try to reach."""
return int(self._device.get(self.entity_description.key))
return float(self._device.get(self.entity_description.key))
@property
def current_temperature(self) -> int | None:
def current_temperature(self) -> float | None:
"""Return the current temperature."""
temp_key = self.entity_description.key.split(".")[-1].replace("Sel", "")
return int(self._device.get(temp_key))
return float(self._device.get(temp_key))
async def async_set_temperature(self, **kwargs):
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:

View File

@ -7,6 +7,7 @@ from homeassistant.components.climate import (
)
DOMAIN = "hon"
UPDATE_INTERVAL = 10
PLATFORMS = [
"sensor",
@ -16,6 +17,7 @@ PLATFORMS = [
"button",
"binary_sensor",
"climate",
"fan",
]
HON_HVAC_MODE = {
@ -110,6 +112,7 @@ TUMBLE_DRYER_PR_PHASE = {
"1": "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE",
"2": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE",
"3": "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN",
"8": "unknown",
"11": "WASHING_CMD&CTRL.PHASE_READY.TITLE",
"12": "unknown",
"13": "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN",

View File

@ -0,0 +1,122 @@
import logging
import math
from dataclasses import dataclass
from typing import Any
from homeassistant.components.fan import (
FanEntityDescription,
FanEntity,
FanEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import callback
from homeassistant.util.percentage import (
percentage_to_ranged_value,
ranged_value_to_percentage,
)
from pyhon.appliance import HonAppliance
from pyhon.parameter.range import HonParameterRange
from .const import DOMAIN
from .hon import HonEntity
_LOGGER = logging.getLogger(__name__)
@dataclass
class HonFanEntityDescription(FanEntityDescription):
pass
FANS = {
"HO": (
HonFanEntityDescription(
key="settings.windSpeed",
name="Wind Speed",
translation_key="air_extraction",
),
),
}
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
entities = []
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]
):
continue
entity = HonFanEntity(hass, entry, device, description)
else:
continue
await entity.coordinator.async_config_entry_first_refresh()
entities.append(entity)
async_add_entities(entities)
class HonFanEntity(HonEntity, FanEntity):
entity_description: HonFanEntityDescription
def __init__(self, hass, entry, device: HonAppliance, description) -> None:
self._attr_supported_features = FanEntityFeature.SET_SPEED
self._wind_speed: HonParameterRange = device.settings.get(description.key)
self._speed_range = (
int(self._wind_speed.values[1]),
int(self._wind_speed.values[-1]),
)
self._command, self._parameter = description.key.split(".")
super().__init__(hass, entry, device, description)
self._handle_coordinator_update(update=False)
@property
def percentage(self) -> int | None:
"""Return the current speed."""
value = int(self._device.get(self._parameter, "0"))
return ranged_value_to_percentage(self._speed_range, value)
@property
def speed_count(self) -> int:
"""Return the number of speeds the fan supports."""
return len(self._wind_speed.values[1:])
async def async_set_percentage(self, percentage: int) -> None:
"""Set the speed percentage of the fan."""
mode = math.ceil(percentage_to_ranged_value(self._speed_range, percentage))
self._device.settings[self.entity_description.key].value = mode
await self._device.commands[self._command].send()
self.async_write_ha_state()
@property
def is_on(self) -> bool | None:
"""Return true if device is on."""
mode = math.ceil(percentage_to_ranged_value(self._speed_range, self.percentage))
return mode > self._wind_speed.min
async def async_turn_on(
self,
percentage: int | None = None,
preset_mode: str | None = None,
**kwargs: Any,
) -> None:
"""Turn the entity on."""
if percentage is None:
percentage = ranged_value_to_percentage(
self._speed_range, int(self._wind_speed.values[1])
)
await self.async_set_percentage(percentage)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off."""
self._device.settings[self.entity_description.key].value = 0
await self._device.commands[self._command].send()
self.async_write_ha_state()
@callback
def _handle_coordinator_update(self, update=True) -> None:
self._wind_speed = self._device.settings.get(self.entity_description.key)
self._attr_percentage = self.percentage
if update:
self.async_write_ha_state()

View File

@ -1,12 +1,13 @@
import logging
from datetime import timedelta
from homeassistant.core import callback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from pyhon.appliance import HonAppliance
from .const import DOMAIN
from .const import DOMAIN, UPDATE_INTERVAL
_LOGGER = logging.getLogger(__name__)
@ -21,13 +22,14 @@ class HonEntity(CoordinatorEntity):
self._hon = hass.data[DOMAIN][entry.unique_id]
self._hass = hass
self._coordinator = coordinator
self._device = device
self._device: HonAppliance = device
if description is not None:
self.entity_description = description
self._attr_unique_id = f"{self._device.unique_id}{description.key}"
else:
self._attr_unique_id = self._device.unique_id
self._handle_coordinator_update(update=False)
@property
def device_info(self):
@ -41,6 +43,11 @@ class HonEntity(CoordinatorEntity):
sw_version=self._device.get("fwVersion", ""),
)
@callback
def _handle_coordinator_update(self, update: bool = True) -> None:
if update:
self.async_write_ha_state()
class HonCoordinator(DataUpdateCoordinator):
def __init__(self, hass, device: HonAppliance):
@ -49,7 +56,7 @@ class HonCoordinator(DataUpdateCoordinator):
hass,
_LOGGER,
name=device.unique_id,
update_interval=timedelta(seconds=30),
update_interval=timedelta(seconds=UPDATE_INTERVAL),
)
self._device = device

View File

@ -9,7 +9,7 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/Andre0512/hon/issues",
"requirements": [
"pyhOn==0.12.1"
"pyhOn==0.13.0"
],
"version": "0.8.0-beta.9"
"version": "0.9.0-beta.1"
}

View File

@ -9,7 +9,7 @@ from homeassistant.components.number import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import UnitOfTime, UnitOfTemperature
from homeassistant.core import callback
from homeassistant.helpers.entity import EntityCategory, Entity
from homeassistant.helpers.entity import EntityCategory
from pyhon.parameter.range import HonParameterRange
from .const import DOMAIN
@ -163,12 +163,6 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
),
),
"HO": (
HonNumberEntityDescription(
key="startProgram.windSpeed",
name="Wind speed",
icon="mdi:fan",
entity_category=EntityCategory.CONFIG,
),
HonNumberEntityDescription(
key="startProgram.lightStatus",
name="Light status",
@ -223,13 +217,14 @@ class HonNumberEntity(HonEntity, NumberEntity):
await self.coordinator.async_refresh()
@callback
def _handle_coordinator_update(self):
def _handle_coordinator_update(self, update=True) -> None:
setting = self._device.settings[self.entity_description.key]
if isinstance(setting, HonParameterRange):
self._attr_native_max_value = setting.max
self._attr_native_min_value = setting.min
self._attr_native_step = setting.step
self._attr_native_value = setting.value
if update:
self.async_write_ha_state()
@property

View File

@ -7,7 +7,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import UnitOfTemperature, UnitOfTime, REVOLUTIONS_PER_MINUTE
from homeassistant.core import callback
from homeassistant.helpers.entity import EntityCategory, Entity
from homeassistant.helpers.entity import EntityCategory
from pyhon.appliance import HonAppliance
from pyhon.parameter.fixed import HonParameterFixed
@ -179,7 +179,7 @@ class HonSelectEntity(HonEntity, SelectEntity):
await self.coordinator.async_refresh()
@callback
def _handle_coordinator_update(self):
def _handle_coordinator_update(self, update=True) -> None:
setting = self._device.settings.get(self.entity_description.key)
if setting is None:
self._attr_available = False
@ -189,6 +189,7 @@ class HonSelectEntity(HonEntity, SelectEntity):
self._attr_available = True
self._attr_options: list[str] = setting.values
self._attr_native_value = setting.value
if update:
self.async_write_ha_state()
@property

View File

@ -1,8 +1,6 @@
import logging
from dataclasses import dataclass
from pyhon.appliance import HonAppliance
from homeassistant.components.sensor import (
SensorEntity,
SensorDeviceClass,
@ -22,7 +20,8 @@ from homeassistant.const import (
)
from homeassistant.core import callback
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.typing import StateType
from pyhon.appliance import HonAppliance
from . import const
from .const import DOMAIN
from .hon import HonEntity, unique_entities
@ -485,6 +484,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="target_temperature",
),
HonSensorEntityDescription(
key="programName",
@ -594,10 +594,78 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
name="RGB Light Status",
icon="mdi:lightbulb",
),
),
"WC": (
HonSensorEntityDescription(
key="windSpeed",
name="Wind Speed",
icon="mdi:fan",
key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
),
HonSensorEntityDescription(
key="humidityZ1",
name="Humidity",
icon="mdi:water-percent",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
translation_key="humidity",
),
HonSensorEntityDescription(
key="humidityZ2",
name="Humidity 2",
icon="mdi:water-percent",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
translation_key="humidity",
),
HonSensorEntityDescription(
key="temp",
name="Temperature",
icon="mdi:thermometer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="temperature",
),
HonSensorEntityDescription(
key="tempEnv",
name="Room Temperature",
icon="mdi:home-thermometer-outline",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="room_temperature",
),
HonSensorEntityDescription(
key="tempSel",
name="Selected Temperature",
icon="mdi:thermometer",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="target_temperature",
),
HonSensorEntityDescription(
key="tempSelZ2",
name="Selected Temperature 2",
icon="mdi:thermometer",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="target_temperature",
),
HonSensorEntityDescription(
key="tempZ2",
name="Temperature 2",
icon="mdi:thermometer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="temperature",
),
HonSensorEntityDescription(
key="programName",
name="Program",
icon="mdi:play",
device_class=SensorDeviceClass.ENUM,
translation_key="programs_wc",
),
),
}
@ -635,11 +703,12 @@ class HonSensorEntity(HonEntity, SensorEntity):
).values + ["No Program"]
@callback
def _handle_coordinator_update(self):
def _handle_coordinator_update(self, update=True) -> None:
value = self._device.get(self.entity_description.key, "")
if not value and self.entity_description.state_class is not None:
self._attr_native_value = 0
self._attr_native_value = value
if update:
self.async_write_ha_state()
@ -647,7 +716,7 @@ class HonConfigSensorEntity(HonEntity, SensorEntity):
entity_description: HonConfigSensorEntityDescription
@callback
def _handle_coordinator_update(self):
def _handle_coordinator_update(self, update=True) -> None:
value = self._device.settings.get(self.entity_description.key, None)
if self.entity_description.state_class is not None:
if value and value.value:
@ -658,4 +727,5 @@ class HonConfigSensorEntity(HonEntity, SensorEntity):
self._attr_native_value = 0
else:
self._attr_native_value = value.value
if update:
self.async_write_ha_state()

View File

@ -1,5 +1,6 @@
import logging
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Any
from homeassistant.components.switch import SwitchEntityDescription, SwitchEntity
@ -321,6 +322,17 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
translation_key="holiday_mode",
),
),
"WC": (
HonSwitchEntityDescription(
key="sabbathStatus",
name="Sabbath Mode",
icon="mdi:palm-tree",
translation_key="holiday_mode",
),
HonSwitchEntityDescription(
key="lightStatus", name="Light", icon="mdi:lightbulb"
),
),
}
SWITCHES["WD"] = unique_entities(SWITCHES["WD"], SWITCHES["WM"])
@ -394,9 +406,10 @@ class HonSwitchEntity(HonEntity, SwitchEntity):
)
@callback
def _handle_coordinator_update(self):
def _handle_coordinator_update(self, update=True) -> None:
value = self._device.get(self.entity_description.key, "0")
self._attr_state = value == "1"
if update:
self.async_write_ha_state()
@ -410,9 +423,13 @@ class HonControlSwitchEntity(HonEntity, SwitchEntity):
async def async_turn_on(self, **kwargs: Any) -> None:
await self._device.commands[self.entity_description.turn_on_key].send()
self._device.attributes[self.entity_description.key] = True
self.async_write_ha_state()
async def async_turn_off(self, **kwargs: Any) -> None:
await self._device.commands[self.entity_description.turn_off_key].send()
self._device.attributes[self.entity_description.key] = False
self.async_write_ha_state()
@property
def available(self) -> bool:
@ -423,6 +440,18 @@ class HonControlSwitchEntity(HonEntity, SwitchEntity):
and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED"
)
@property
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))
result["start_time"] = datetime.now() + timedelta(minutes=delay_time)
result["end_time"] = datetime.now() + timedelta(
minutes=delay_time + remaining_time
)
return result
class HonConfigSwitchEntity(HonEntity, SwitchEntity):
entity_description: HonConfigSwitchEntityDescription
@ -454,7 +483,8 @@ class HonConfigSwitchEntity(HonEntity, SwitchEntity):
await self.coordinator.async_refresh()
@callback
def _handle_coordinator_update(self):
def _handle_coordinator_update(self, update=True) -> None:
value = self._device.settings.get(self.entity_description.key, "0")
self._attr_state = value == "1"
if update:
self.async_write_ha_state()

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Šampaňské",
"iot_dessert": "Dezertní",
"iot_fortified": "Strukturované",
"iot_rose": "Růžové",
"iot_whisky": "Whisky",
"red": "Červené",
"sparkling": "Šumivé",
"white": "Bílé"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Vinný sklípek",
"state": {
"iot_champagne": "Šampaňské",
"iot_dessert": "Dezertní",
"iot_fortified": "Strukturované",
"iot_rose": "Růžové",
"iot_whisky": "Whisky",
"red": "Červené",
"sparkling": "Šumivé",
"white": "Bílé"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Odsávání vzduchu"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Programm"
},
"programs_wc": {
"state": {
"iot_champagne": "Champagner",
"iot_dessert": "Dessert",
"iot_fortified": "Strukturiert",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Rot",
"sparkling": "Sekt",
"white": "Weiß"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Weinklimaschrank",
"state": {
"iot_champagne": "Champagner",
"iot_dessert": "Dessert",
"iot_fortified": "Strukturiert",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Rot",
"sparkling": "Sekt",
"white": "Weiß"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Dunstabzug"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Πρόγραμμα"
},
"programs_wc": {
"state": {
"iot_champagne": "Σαμπάνια",
"iot_dessert": "Επιδόρπιο",
"iot_fortified": "Δομημένο",
"iot_rose": "Ροζέ",
"iot_whisky": "Ουίσκι",
"red": "Κόκκινο",
"sparkling": "Αφρώδες",
"white": "Λευκό"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Κάβα",
"state": {
"iot_champagne": "Σαμπάνια",
"iot_dessert": "Επιδόρπιο",
"iot_fortified": "Δομημένο",
"iot_rose": "Ροζέ",
"iot_whisky": "Ουίσκι",
"red": "Κόκκινο",
"sparkling": "Αφρώδες",
"white": "Λευκό"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Εξαγωγή αέρα"
}
}
},

View File

@ -944,6 +944,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Champagne",
"iot_dessert": "Dessert",
"iot_fortified": "Fortified",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Red",
"sparkling": "Sparkling",
"white": "White"
}
}
},
"switch": {
@ -2055,6 +2067,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Wine Cellar",
"state": {
"iot_champagne": "Champagne",
"iot_dessert": "Dessert",
"iot_fortified": "Fortified",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Red",
"sparkling": "Sparkling",
"white": "White"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Air extraction"
}
}
}

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Programa"
},
"programs_wc": {
"state": {
"iot_champagne": "Champán",
"iot_dessert": "Postre",
"iot_fortified": "Estructurado",
"iot_rose": "Rosado",
"iot_whisky": "Whisky",
"red": "Tinto",
"sparkling": "Espumoso",
"white": "Blanco"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Cámara de vino",
"state": {
"iot_champagne": "Champán",
"iot_dessert": "Postre",
"iot_fortified": "Estructurado",
"iot_rose": "Rosado",
"iot_whisky": "Whisky",
"red": "Tinto",
"sparkling": "Espumoso",
"white": "Blanco"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Extracción de aire"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Programme"
},
"programs_wc": {
"state": {
"iot_champagne": "Champagne",
"iot_dessert": "Dessert",
"iot_fortified": "Corsé",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Rouge",
"sparkling": "Pétillant",
"white": "Blanc"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Cave à vin",
"state": {
"iot_champagne": "Champagne",
"iot_dessert": "Dessert",
"iot_fortified": "Corsé",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Rouge",
"sparkling": "Pétillant",
"white": "Blanc"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Extraction de l'air"
}
}
},

View File

@ -444,6 +444,9 @@
"tea": "Cold drinks or Beverages"
},
"name": "Program"
},
"programs_wc": {
"state": {}
}
},
"select": {
@ -1064,6 +1067,19 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Wine Cellar",
"state": {}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Air extraction"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Šampanjac",
"iot_dessert": "Desertno",
"iot_fortified": "Strukturirano",
"iot_rose": "Rosé",
"iot_whisky": "Viski",
"red": "Crno",
"sparkling": "Pjenušavo vino",
"white": "Bijelo vino"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Vinski hladnjak",
"state": {
"iot_champagne": "Šampanjac",
"iot_dessert": "Desertno",
"iot_fortified": "Strukturirano",
"iot_rose": "Rosé",
"iot_whisky": "Viski",
"red": "Crno",
"sparkling": "Pjenušavo vino",
"white": "Bijelo vino"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Odvođenje zraka"
}
}
},

View File

@ -929,6 +929,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Programma"
},
"programs_wc": {
"state": {
"iot_champagne": "Champagne",
"iot_dessert": "Dolce",
"iot_fortified": "Strutturato",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Rosso",
"sparkling": "Bollicine",
"white": "Bianco"
}
}
},
"select": {
@ -2030,6 +2042,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Cantinetta",
"state": {
"iot_champagne": "Champagne",
"iot_dessert": "Dolce",
"iot_fortified": "Strutturato",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Rosso",
"sparkling": "Bollicine",
"white": "Bianco"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Aspirazione aria"
}
}
}

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Programma"
},
"programs_wc": {
"state": {
"iot_champagne": "Champagne",
"iot_dessert": "Dessert",
"iot_fortified": "Gestructureerd",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Rood",
"sparkling": "Mousserend",
"white": "Wit"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Wijnkelder",
"state": {
"iot_champagne": "Champagne",
"iot_dessert": "Dessert",
"iot_fortified": "Gestructureerd",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Rood",
"sparkling": "Mousserend",
"white": "Wit"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Luchtafvoer"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Szampan",
"iot_dessert": "Deser",
"iot_fortified": "Struktura",
"iot_rose": "Różowe",
"iot_whisky": "Whisky",
"red": "Czerwony",
"sparkling": "Musujące",
"white": "Białe"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Piwniczka z winami",
"state": {
"iot_champagne": "Szampan",
"iot_dessert": "Deser",
"iot_fortified": "Struktura",
"iot_rose": "Różowe",
"iot_whisky": "Whisky",
"red": "Czerwony",
"sparkling": "Musujące",
"white": "Białe"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Wyciąg powietrza"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Programa"
},
"programs_wc": {
"state": {
"iot_champagne": "Champanhe",
"iot_dessert": "Digestivo",
"iot_fortified": "Encorpado",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Vermelho",
"sparkling": "Espumante",
"white": "Branco"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Garrafeira",
"state": {
"iot_champagne": "Champanhe",
"iot_dessert": "Digestivo",
"iot_fortified": "Encorpado",
"iot_rose": "Rosé",
"iot_whisky": "Whisky",
"red": "Vermelho",
"sparkling": "Espumante",
"white": "Branco"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Extração de ar"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Șampanie",
"iot_dessert": "Desert",
"iot_fortified": "Structurat",
"iot_rose": "Roze",
"iot_whisky": "Whisky",
"red": "Roșu",
"sparkling": "Spumant",
"white": "Alb"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Cramă",
"state": {
"iot_champagne": "Șampanie",
"iot_dessert": "Desert",
"iot_fortified": "Structurat",
"iot_rose": "Roze",
"iot_whisky": "Whisky",
"red": "Roșu",
"sparkling": "Spumant",
"white": "Alb"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Extracția aerului"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Программа"
},
"programs_wc": {
"state": {
"iot_champagne": "Шампанское",
"iot_dessert": "Десертное",
"iot_fortified": "Структурированное",
"iot_rose": "Розовое",
"iot_whisky": "Виски",
"red": "Красное",
"sparkling": "Игристое",
"white": "Белое"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Винный шкаф",
"state": {
"iot_champagne": "Шампанское",
"iot_dessert": "Десертное",
"iot_fortified": "Структурированное",
"iot_rose": "Розовое",
"iot_whisky": "Виски",
"red": "Красное",
"sparkling": "Игристое",
"white": "Белое"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Отвод воздуха"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Šampanské",
"iot_dessert": "Dezertné",
"iot_fortified": "Štruktúrované",
"iot_rose": "Ružové",
"iot_whisky": "Whisky",
"red": "Červené",
"sparkling": "Šumivé",
"white": "Biele"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Vinotéka",
"state": {
"iot_champagne": "Šampanské",
"iot_dessert": "Dezertné",
"iot_fortified": "Štruktúrované",
"iot_rose": "Ružové",
"iot_whisky": "Whisky",
"red": "Červené",
"sparkling": "Šumivé",
"white": "Biele"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Odsávanie vzduchu"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Šampanjec",
"iot_dessert": "Sladica",
"iot_fortified": "Strukturirano",
"iot_rose": "Rose",
"iot_whisky": "Viski",
"red": "Rdeče",
"sparkling": "Peneče vino",
"white": "Belo"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Vinska klet",
"state": {
"iot_champagne": "Šampanjec",
"iot_dessert": "Sladica",
"iot_fortified": "Strukturirano",
"iot_rose": "Rose",
"iot_whisky": "Viski",
"red": "Rdeče",
"sparkling": "Peneče vino",
"white": "Belo"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Odvajanje zraka"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Šampanjac",
"iot_dessert": "Desert",
"iot_fortified": "Strukturisano",
"iot_rose": "Rosé",
"iot_whisky": "Viski",
"red": "Crvena",
"sparkling": "Penušavo",
"white": "Belo"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Vinska vitrina",
"state": {
"iot_champagne": "Šampanjac",
"iot_dessert": "Desert",
"iot_fortified": "Strukturisano",
"iot_rose": "Rosé",
"iot_whisky": "Viski",
"red": "Crvena",
"sparkling": "Penušavo",
"white": "Belo"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Usisavanje vazduha"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "Program"
},
"programs_wc": {
"state": {
"iot_champagne": "Şampanya",
"iot_dessert": "Tatlı",
"iot_fortified": "Gövdeli",
"iot_rose": "Roze",
"iot_whisky": "Viski",
"red": "Kırmızı",
"sparkling": "Köpüklü",
"white": "Beyaz"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "Şarap Mahzeni",
"state": {
"iot_champagne": "Şampanya",
"iot_dessert": "Tatlı",
"iot_fortified": "Gövdeli",
"iot_rose": "Roze",
"iot_whisky": "Viski",
"red": "Kırmızı",
"sparkling": "Köpüklü",
"white": "Beyaz"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "Hava tahliyesi"
}
}
},

View File

@ -877,6 +877,18 @@
"zero_fresh": "0° Fresh"
},
"name": "程序"
},
"programs_wc": {
"state": {
"iot_champagne": "香槟",
"iot_dessert": "甜点",
"iot_fortified": "结构化",
"iot_rose": "桃红",
"iot_whisky": "威士忌",
"red": "红",
"sparkling": "起泡酒",
"white": "白葡萄酒"
}
}
},
"select": {
@ -1978,6 +1990,28 @@
}
}
}
},
"wine": {
"state_attributes": {
"preset_mode": {
"name": "酒窖",
"state": {
"iot_champagne": "香槟",
"iot_dessert": "甜点",
"iot_fortified": "结构化",
"iot_rose": "桃红",
"iot_whisky": "威士忌",
"red": "红",
"sparkling": "起泡酒",
"white": "白葡萄酒"
}
}
}
}
},
"fan": {
"air_extraction": {
"name": "抽气"
}
}
},

52
info.md
View File

@ -10,10 +10,11 @@ Support for home appliances of Haier's mobile app hOn.
- [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer)
- [Oven](https://github.com/Andre0512/hon#oven)
- [Dish Washer](https://github.com/Andre0512/hon#dish-washer)
- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner)
- [Fridge](https://github.com/Andre0512/hon#fridge)
- [Hob](https://github.com/Andre0512/hon#hob) [BETA]
- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA]
- [Fridge](https://github.com/Andre0512/hon#fridge) [BETA]
- [Hood](https://github.com/Andre0512/hon#hood) [BETA]
- [Wine Cellar](https://github.com/Andre0512/hon#wine-cellar) [BETA]
## Configuration
@ -50,41 +51,18 @@ Translation of internal names like programs are available for all languages whic
## Supported Models
Support has been confirmed for these models, but many more will work. Please add already supported devices [with this form to complete the list](https://forms.gle/bTSD8qFotdZFytbf8).
- Haier AD105S2SM3FA
- Haier AS25PBAHRA
- Haier AS25S2SF1FA-WH
- Haier AS25TADHRA-2
- Haier AS35TADHRA-2
- Haier EG9012B19SU1JD
- Haier HA2MTSJ68MC
- Haier HADG6DS46BWIFI
- Haier HD80-A3959
- Haier HW90-B14TEAM5
- Haier HW100-B14959U1
- Haier HWD100-B14979
- Haier HWO60SM2F3XH
- Haier XIB 3B2SFS-80
- Haier XIB 6B2D3FB
- Candy BCTDH7A1TE
- Candy CCE4T620EWU
- Candy CIS633SCTTWIFI
- Candy CSOE C10DE-80
- Candy RO44 1286DWMC4-07
- Candy ROE H9A3TCEX-S
- Candy RPW41066BWMR/1-S
- Hoover H-WASH 500
- Hoover H-DRY 500
- Hoover H7W4 48MBC-S
- Hoover H9A3TCBEXS-S
- Hoover HFB 6B2S3FX
- Hoover HLE C10DCE-80
- Hoover HSOT3161WG
- Hoover HW 68AMC/1-80
- Hoover HWPD 69AMBC/1-S
- Hoover HWPS4954DAMR-11
- Hoover NDE H10A2TCE-80
- Hoover NDE H9A2TSBEXS-S
- Hoover NDPHY10A2TCBEXSS
| | **Haier** | **Hoover** | **Candy** |
|--------------------|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
| **Washing Machine** | HW90-B14TEAM5 <br/> HW100-B14959U1 | H-WASH 500 <br/> H7W4 48MBC-S | RO44 1286DWMC4-07 <br/> HW 68AMC/1-80 <br/> HWPD 69AMBC/1-S |
| **Tumble Dryer** | HD80-A3959 | H-DRY 500 <br/> H9A3TCBEXS-S <br/> HLE C10DCE-80 <br/> NDE H10A2TCE-80 <br/> NDE H9A2TSBEXS-S <br/> NDPHY10A2TCBEXSS | BCTDH7A1TE <br/> CSOE C10DE-80 <br/> ROE H9A3TCEX-S |
| **Washer Dryer** | HWD100-B14979 | HWPS4954DAMR-11 | RPW41066BWMR/1-S |
| **Oven** | HWO60SM2F3XH | HSOT3161WG | |
| **Dish Washer** | XIB 3B2SFS-80 <br/> XIB 6B2D3FB | HFB 6B2S3FX | |
| **Air conditioner** | AD105S2SM3FA <br/> AS20HPL1HRA <br/> AS25PBAHRA <br/> AS25S2SF1FA-WH <br/> AS25TADHRA-2 <br/> AS35TADHRA-2 <br/> | | |
| **Fridge** | HFW7720ENMB | | CCE4T620EWU |
| **Hob** | HA2MTSJ68MC | | CIS633SCTTWIFI |
| **Hood** | HADG6DS46BWIFI | | |
## Contribute
Want to help us to support more appliances? Or add more sensors? Or help with translating? Or beautify some icons or captions?

View File

@ -47,6 +47,7 @@ PROGRAMS = {
"programs_td": "PROGRAMS.TD",
"programs_wm": "PROGRAMS.WM_WD",
"programs_ref": "PROGRAMS.REF",
"programs_wc": "PROGRAMS.WC",
},
}
@ -78,6 +79,12 @@ CLIMATE = {
"state": "PROGRAMS.OV",
}
},
"wine": {
"preset_mode": {
"name": "WC.NAME",
"state": "PROGRAMS.WC",
}
},
}
NAMES = {
@ -248,6 +255,7 @@ NAMES = {
"freezer": "REF.ZONES.FREEZER",
"oven": "GLOBALS.APPLIANCES_NAME.OV",
},
"fan": {"air_extraction": "HO.DASHBOARD.AIR_EXTRACTION_TITLE"},
}

View File

@ -14,6 +14,7 @@ from custom_components.hon.climate import CLIMATES
from custom_components.hon.number import NUMBERS
from custom_components.hon.select import SELECTS
from custom_components.hon.sensor import SENSORS
from custom_components.hon.fan import FANS
from custom_components.hon.switch import (
SWITCHES,
HonControlSwitchEntityDescription,
@ -48,6 +49,7 @@ entities = {
"sensor": SENSORS,
"switch": SWITCHES,
"climate": CLIMATES,
"fan": FANS,
}
result = {}