Compare commits
	
		
			10 Commits
		
	
	
		
			v0.8.0-bet
			...
			v0.8
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4b95accf02 | |||
| 998b691a8e | |||
| 6084e4a034 | |||
| 5bc3120000 | |||
| 0f9f0dee4c | |||
| 80b3741f2f | |||
| c433714a94 | |||
| 228cf3cf73 | |||
| 1a50e8112d | |||
| 57ecd7c3a5 | 
							
								
								
									
										38
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								README.md
									
									
									
									
									
								
							| @ -12,9 +12,10 @@ Home Assistant integration for [Haier's mobile app hOn](https://hon-smarthome.co | |||||||
| - [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer) | - [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer) | ||||||
| - [Oven](https://github.com/Andre0512/hon#oven) | - [Oven](https://github.com/Andre0512/hon#oven) | ||||||
| - [Dish Washer](https://github.com/Andre0512/hon#dish-washer) | - [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] | - [Hob](https://github.com/Andre0512/hon#hob) [BETA] | ||||||
| - [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA] | - [Hood](https://github.com/Andre0512/hon#hood) [BETA] | ||||||
| - [Fridge](https://github.com/Andre0512/hon#fridge) [BETA] |  | ||||||
|  |  | ||||||
| ## Installation | ## Installation | ||||||
| **Method 1:** [](https://my.home-assistant.io/redirect/hacs_repository/?owner=Andre0512&repository=hon&category=integration) | **Method 1:** [](https://my.home-assistant.io/redirect/hacs_repository/?owner=Andre0512&repository=hon&category=integration) | ||||||
| @ -61,10 +62,14 @@ Translation of internal names like programs are available for all languages whic | |||||||
| ## Supported Models | ## 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). | 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 AD105S2SM3FA | ||||||
|  | - Haier AS20HPL1HRA | ||||||
| - Haier AS25PBAHRA | - Haier AS25PBAHRA | ||||||
|  | - Haier AS25S2SF1FA-WH | ||||||
| - Haier AS25TADHRA-2 | - Haier AS25TADHRA-2 | ||||||
| - Haier AS35TADHRA-2 | - Haier AS35TADHRA-2 | ||||||
| - Haier EG9012B19SU1JD | - Haier EG9012B19SU1JD | ||||||
|  | - Haier HA2MTSJ68MC | ||||||
|  | - Haier HADG6DS46BWIFI | ||||||
| - Haier HD80-A3959 | - Haier HD80-A3959 | ||||||
| - Haier HW90-B14TEAM5 | - Haier HW90-B14TEAM5 | ||||||
| - Haier HW100-B14959U1 | - Haier HW100-B14959U1 | ||||||
| @ -76,6 +81,7 @@ Support has been confirmed for these models, but many more will work. Please add | |||||||
| - Candy CCE4T620EWU | - Candy CCE4T620EWU | ||||||
| - Candy CIS633SCTTWIFI | - Candy CIS633SCTTWIFI | ||||||
| - Candy CSOE C10DE-80 | - Candy CSOE C10DE-80 | ||||||
|  | - Candy RO44 1286DWMC4-07 | ||||||
| - Candy ROE H9A3TCEX-S | - Candy ROE H9A3TCEX-S | ||||||
| - Candy RPW41066BWMR/1-S | - Candy RPW41066BWMR/1-S | ||||||
| - Hoover H-WASH 500 | - Hoover H-WASH 500 | ||||||
| @ -225,6 +231,34 @@ For every device exists a hidden button which can be used to log all infos of yo | |||||||
| | Rinse Aid | `spray-bottle` | `binary_sensor` | `rinseAidStatus` | | | Rinse Aid | `spray-bottle` | `binary_sensor` | `rinseAidStatus` | | ||||||
| | Salt | `shaker-outline` | `binary_sensor` | `saltStatus` | | | Salt | `shaker-outline` | `binary_sensor` | `saltStatus` | | ||||||
|  |  | ||||||
|  | ### Hood | ||||||
|  | #### Controls | ||||||
|  | | Name | Icon | Entity | Key | | ||||||
|  | | --- | --- | --- | --- | | ||||||
|  | | Start Program | `hvac` | `button` | `startProgram` | | ||||||
|  | | Stop Program | `hvac-off` | `button` | `stopProgram` | | ||||||
|  | #### Configs | ||||||
|  | | Name | Icon | Entity | Key | | ||||||
|  | | --- | --- | --- | --- | | ||||||
|  | | Light status | `lightbulb` | `number` | `startProgram.lightStatus` | | ||||||
|  | | Wind speed | `fan` | `number` | `startProgram.windSpeed` | | ||||||
|  | #### Sensors | ||||||
|  | | Name | Icon | Entity | Key | | ||||||
|  | | --- | --- | --- | --- | | ||||||
|  | | Delay time | `clock-start` | `sensor` | `delayTime` | | ||||||
|  | | Delay time status | `clock-start` | `sensor` | `delayTimeStatus` | | ||||||
|  | | Errors | `alert-circle` | `sensor` | `errors` | | ||||||
|  | | Filter Cleaning Alarm Status |  | `sensor` | `filterCleaningAlarmStatus` | | ||||||
|  | | Filter Cleaning Status |  | `sensor` | `filterCleaningStatus` | | ||||||
|  | | Last Work Time | `clock-start` | `sensor` | `lastWorkTime` | | ||||||
|  | | Light Status | `lightbulb` | `sensor` | `lightStatus` | | ||||||
|  | | Mach Mode |  | `sensor` | `machMode` | | ||||||
|  | | On / Off Status | `lightbulb` | `sensor` | `onOffStatus` | | ||||||
|  | | Quick Delay Time Status |  | `sensor` | `quickDelayTimeStatus` | | ||||||
|  | | RGB Light Color | `lightbulb` | `sensor` | `rgbLightColors` | | ||||||
|  | | RGB Light Status | `lightbulb` | `sensor` | `rgbLightStatus` | | ||||||
|  | | Wind Speed | `fan` | `sensor` | `windSpeed` | | ||||||
|  |  | ||||||
| ### Hob | ### Hob | ||||||
| #### Controls | #### Controls | ||||||
| | Name | Icon | Entity | Key | | | Name | Icon | Entity | Key | | ||||||
|  | |||||||
| @ -271,9 +271,10 @@ class HonBinarySensorEntity(HonEntity, BinarySensorEntity): | |||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     @callback |     @callback | ||||||
|     def _handle_coordinator_update(self): |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         self._attr_native_value = ( |         self._attr_native_value = ( | ||||||
|             self._device.get(self.entity_description.key, "") |             self._device.get(self.entity_description.key, "") | ||||||
|             == self.entity_description.on_value |             == self.entity_description.on_value | ||||||
|         ) |         ) | ||||||
|         self.async_write_ha_state() |         if update: | ||||||
|  |             self.async_write_ha_state() | ||||||
|  | |||||||
| @ -35,6 +35,20 @@ BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = { | |||||||
|             translation_key="stop_program", |             translation_key="stop_program", | ||||||
|         ), |         ), | ||||||
|     ), |     ), | ||||||
|  |     "HO": ( | ||||||
|  |         ButtonEntityDescription( | ||||||
|  |             key="startProgram", | ||||||
|  |             name="Start Program", | ||||||
|  |             icon="mdi:hvac", | ||||||
|  |             translation_key="start_program", | ||||||
|  |         ), | ||||||
|  |         ButtonEntityDescription( | ||||||
|  |             key="stopProgram", | ||||||
|  |             name="Stop Program", | ||||||
|  |             icon="mdi:hvac-off", | ||||||
|  |             translation_key="stop_program", | ||||||
|  |         ), | ||||||
|  |     ), | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,8 +1,6 @@ | |||||||
| import logging | import logging | ||||||
| from dataclasses import dataclass | from dataclasses import dataclass | ||||||
|  |  | ||||||
| from pyhon.appliance import HonAppliance |  | ||||||
|  |  | ||||||
| from homeassistant.components.climate import ( | from homeassistant.components.climate import ( | ||||||
|     ClimateEntity, |     ClimateEntity, | ||||||
|     ClimateEntityDescription, |     ClimateEntityDescription, | ||||||
| @ -22,6 +20,8 @@ from homeassistant.const import ( | |||||||
|     TEMP_CELSIUS, |     TEMP_CELSIUS, | ||||||
| ) | ) | ||||||
| from homeassistant.core import callback | from homeassistant.core import callback | ||||||
|  | from pyhon.appliance import HonAppliance | ||||||
|  |  | ||||||
| from .const import HON_HVAC_MODE, HON_FAN, HON_HVAC_PROGRAM, DOMAIN | from .const import HON_HVAC_MODE, HON_FAN, HON_HVAC_PROGRAM, DOMAIN | ||||||
| from .hon import HonEntity | from .hon import HonEntity | ||||||
|  |  | ||||||
| @ -103,12 +103,12 @@ class HonACClimateEntity(HonEntity, ClimateEntity): | |||||||
|         self._attr_max_temp = device.settings["settings.tempSel"].max |         self._attr_max_temp = device.settings["settings.tempSel"].max | ||||||
|         self._attr_min_temp = device.settings["settings.tempSel"].min |         self._attr_min_temp = device.settings["settings.tempSel"].min | ||||||
|  |  | ||||||
|         self._attr_hvac_modes = [HVACMode.OFF] + [ |         self._attr_hvac_modes = [HVACMode.OFF] | ||||||
|             HON_HVAC_MODE[mode] for mode in device.settings["settings.machMode"].values |         for mode in device.settings["settings.machMode"].values: | ||||||
|         ] |             self._attr_hvac_modes.append(HON_HVAC_MODE[mode]) | ||||||
|         self._attr_fan_modes = [FAN_OFF] + [ |         self._attr_fan_modes = [FAN_OFF] | ||||||
|             HON_FAN[mode] for mode in device.settings["settings.windSpeed"].values |         for mode in device.settings["settings.windSpeed"].values: | ||||||
|         ] |             self._attr_fan_modes.append(HON_FAN[mode]) | ||||||
|         self._attr_swing_modes = [ |         self._attr_swing_modes = [ | ||||||
|             SWING_OFF, |             SWING_OFF, | ||||||
|             SWING_VERTICAL, |             SWING_VERTICAL, | ||||||
| @ -123,6 +123,23 @@ class HonACClimateEntity(HonEntity, ClimateEntity): | |||||||
|  |  | ||||||
|         self._handle_coordinator_update(update=False) |         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 |     @property | ||||||
|     def hvac_mode(self) -> HVACMode | str | None: |     def hvac_mode(self) -> HVACMode | str | None: | ||||||
|         if self._device.get("onOffStatus") == "0": |         if self._device.get("onOffStatus") == "0": | ||||||
| @ -131,24 +148,44 @@ class HonACClimateEntity(HonEntity, ClimateEntity): | |||||||
|             return HON_HVAC_MODE[self._device.get("machMode")] |             return HON_HVAC_MODE[self._device.get("machMode")] | ||||||
|  |  | ||||||
|     async def async_set_hvac_mode(self, hvac_mode): |     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 |         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() |         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): |     async def async_set_fan_mode(self, fan_mode): | ||||||
|         mode_number = list(HON_FAN.values()).index(fan_mode) |         mode_number = list(HON_FAN.values()).index(fan_mode) | ||||||
|         self._device.settings["settings.windSpeed"].value = list(HON_FAN.keys())[ |         mode = list(HON_FAN.keys())[mode_number] | ||||||
|             mode_number |         self._device.settings["settings.windSpeed"].value = mode | ||||||
|         ] |         self._attr_fan_mode = fan_mode | ||||||
|         await self._device.commands["settings"].send() |         await self._device.commands["settings"].send() | ||||||
|         self.async_write_ha_state() |         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): |     async def async_set_swing_mode(self, swing_mode): | ||||||
|         horizontal = self._device.settings["settings.windDirectionHorizontal"] |         horizontal = self._device.settings["settings.windDirectionHorizontal"] | ||||||
|         vertical = self._device.settings["settings.windDirectionVertical"] |         vertical = self._device.settings["settings.windDirectionVertical"] | ||||||
| @ -164,35 +201,13 @@ class HonACClimateEntity(HonEntity, ClimateEntity): | |||||||
|         await self._device.commands["settings"].send() |         await self._device.commands["settings"].send() | ||||||
|         self.async_write_ha_state() |         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 |     @callback | ||||||
|     def _handle_coordinator_update(self, update=True) -> None: |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         self._attr_target_temperature = int(float(self._device.get("tempSel"))) |         self._attr_target_temperature = self.target_temperature | ||||||
|         self._attr_current_temperature = float(self._device.get("tempIndoor")) |         self._attr_current_temperature = self.current_temperature | ||||||
|  |         self._attr_hvac_mode = self.hvac_mode | ||||||
|         if self._device.get("onOffStatus") == "0": |         self._attr_fan_mode = self.fan_mode | ||||||
|             self._attr_hvac_mode = HVACMode.OFF |         self._attr_swing_mode = self.swing_mode | ||||||
|         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 |  | ||||||
|         if update: |         if update: | ||||||
|             self.async_write_ha_state() |             self.async_write_ha_state() | ||||||
|  |  | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ from homeassistant.components.climate import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| DOMAIN = "hon" | DOMAIN = "hon" | ||||||
|  | UPDATE_INTERVAL = 10 | ||||||
|  |  | ||||||
| PLATFORMS = [ | PLATFORMS = [ | ||||||
|     "sensor", |     "sensor", | ||||||
| @ -110,8 +111,9 @@ TUMBLE_DRYER_PR_PHASE = { | |||||||
|     "1": "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE", |     "1": "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE", | ||||||
|     "2": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE", |     "2": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE", | ||||||
|     "3": "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN", |     "3": "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN", | ||||||
|  |     "8": "unknown", | ||||||
|     "11": "WASHING_CMD&CTRL.PHASE_READY.TITLE", |     "11": "WASHING_CMD&CTRL.PHASE_READY.TITLE", | ||||||
|     "12": "unkown", |     "12": "unknown", | ||||||
|     "13": "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN", |     "13": "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN", | ||||||
|     "14": "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE", |     "14": "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE", | ||||||
|     "15": "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE", |     "15": "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE", | ||||||
|  | |||||||
| @ -1,12 +1,13 @@ | |||||||
| import logging | import logging | ||||||
| from datetime import timedelta | from datetime import timedelta | ||||||
|  |  | ||||||
|  | from homeassistant.core import callback | ||||||
| from homeassistant.helpers.entity import DeviceInfo | from homeassistant.helpers.entity import DeviceInfo | ||||||
| from homeassistant.helpers.update_coordinator import CoordinatorEntity | from homeassistant.helpers.update_coordinator import CoordinatorEntity | ||||||
| from homeassistant.helpers.update_coordinator import DataUpdateCoordinator | from homeassistant.helpers.update_coordinator import DataUpdateCoordinator | ||||||
| from pyhon.appliance import HonAppliance | from pyhon.appliance import HonAppliance | ||||||
|  |  | ||||||
| from .const import DOMAIN | from .const import DOMAIN, UPDATE_INTERVAL | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @ -21,13 +22,14 @@ class HonEntity(CoordinatorEntity): | |||||||
|         self._hon = hass.data[DOMAIN][entry.unique_id] |         self._hon = hass.data[DOMAIN][entry.unique_id] | ||||||
|         self._hass = hass |         self._hass = hass | ||||||
|         self._coordinator = coordinator |         self._coordinator = coordinator | ||||||
|         self._device = device |         self._device: HonAppliance = device | ||||||
|  |  | ||||||
|         if description is not None: |         if description is not None: | ||||||
|             self.entity_description = description |             self.entity_description = description | ||||||
|             self._attr_unique_id = f"{self._device.unique_id}{description.key}" |             self._attr_unique_id = f"{self._device.unique_id}{description.key}" | ||||||
|         else: |         else: | ||||||
|             self._attr_unique_id = self._device.unique_id |             self._attr_unique_id = self._device.unique_id | ||||||
|  |         self._handle_coordinator_update(update=False) | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def device_info(self): |     def device_info(self): | ||||||
| @ -41,6 +43,11 @@ class HonEntity(CoordinatorEntity): | |||||||
|             sw_version=self._device.get("fwVersion", ""), |             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): | class HonCoordinator(DataUpdateCoordinator): | ||||||
|     def __init__(self, hass, device: HonAppliance): |     def __init__(self, hass, device: HonAppliance): | ||||||
| @ -49,7 +56,7 @@ class HonCoordinator(DataUpdateCoordinator): | |||||||
|             hass, |             hass, | ||||||
|             _LOGGER, |             _LOGGER, | ||||||
|             name=device.unique_id, |             name=device.unique_id, | ||||||
|             update_interval=timedelta(seconds=30), |             update_interval=timedelta(seconds=UPDATE_INTERVAL), | ||||||
|         ) |         ) | ||||||
|         self._device = device |         self._device = device | ||||||
|  |  | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ | |||||||
|   "iot_class": "cloud_polling", |   "iot_class": "cloud_polling", | ||||||
|   "issue_tracker": "https://github.com/Andre0512/hon/issues", |   "issue_tracker": "https://github.com/Andre0512/hon/issues", | ||||||
|   "requirements": [ |   "requirements": [ | ||||||
|     "pyhOn==0.12.0" |     "pyhOn==0.12.4" | ||||||
|   ], |   ], | ||||||
|   "version": "0.8.0-beta.8" |   "version": "0.8.1" | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ from homeassistant.components.number import ( | |||||||
| from homeassistant.config_entries import ConfigEntry | from homeassistant.config_entries import ConfigEntry | ||||||
| from homeassistant.const import UnitOfTime, UnitOfTemperature | from homeassistant.const import UnitOfTime, UnitOfTemperature | ||||||
| from homeassistant.core import callback | 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 pyhon.parameter.range import HonParameterRange | ||||||
|  |  | ||||||
| from .const import DOMAIN | from .const import DOMAIN | ||||||
| @ -162,6 +162,20 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | |||||||
|             translation_key="freezer_temp_sel", |             translation_key="freezer_temp_sel", | ||||||
|         ), |         ), | ||||||
|     ), |     ), | ||||||
|  |     "HO": ( | ||||||
|  |         HonNumberEntityDescription( | ||||||
|  |             key="startProgram.windSpeed", | ||||||
|  |             name="Wind speed", | ||||||
|  |             icon="mdi:fan", | ||||||
|  |             entity_category=EntityCategory.CONFIG, | ||||||
|  |         ), | ||||||
|  |         HonNumberEntityDescription( | ||||||
|  |             key="startProgram.lightStatus", | ||||||
|  |             name="Light status", | ||||||
|  |             icon="mdi:lightbulb", | ||||||
|  |             entity_category=EntityCategory.CONFIG, | ||||||
|  |         ), | ||||||
|  |     ), | ||||||
| } | } | ||||||
|  |  | ||||||
| NUMBERS["WD"] = unique_entities(NUMBERS["WM"], NUMBERS["TD"]) | NUMBERS["WD"] = unique_entities(NUMBERS["WM"], NUMBERS["TD"]) | ||||||
| @ -209,14 +223,15 @@ class HonNumberEntity(HonEntity, NumberEntity): | |||||||
|         await self.coordinator.async_refresh() |         await self.coordinator.async_refresh() | ||||||
|  |  | ||||||
|     @callback |     @callback | ||||||
|     def _handle_coordinator_update(self): |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         setting = self._device.settings[self.entity_description.key] |         setting = self._device.settings[self.entity_description.key] | ||||||
|         if isinstance(setting, HonParameterRange): |         if isinstance(setting, HonParameterRange): | ||||||
|             self._attr_native_max_value = setting.max |             self._attr_native_max_value = setting.max | ||||||
|             self._attr_native_min_value = setting.min |             self._attr_native_min_value = setting.min | ||||||
|             self._attr_native_step = setting.step |             self._attr_native_step = setting.step | ||||||
|         self._attr_native_value = setting.value |         self._attr_native_value = setting.value | ||||||
|         self.async_write_ha_state() |         if update: | ||||||
|  |             self.async_write_ha_state() | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def available(self) -> bool: |     def available(self) -> bool: | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio | |||||||
| from homeassistant.config_entries import ConfigEntry | from homeassistant.config_entries import ConfigEntry | ||||||
| from homeassistant.const import UnitOfTemperature, UnitOfTime, REVOLUTIONS_PER_MINUTE | from homeassistant.const import UnitOfTemperature, UnitOfTime, REVOLUTIONS_PER_MINUTE | ||||||
| from homeassistant.core import callback | 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.appliance import HonAppliance | ||||||
| from pyhon.parameter.fixed import HonParameterFixed | from pyhon.parameter.fixed import HonParameterFixed | ||||||
|  |  | ||||||
| @ -179,7 +179,7 @@ class HonSelectEntity(HonEntity, SelectEntity): | |||||||
|         await self.coordinator.async_refresh() |         await self.coordinator.async_refresh() | ||||||
|  |  | ||||||
|     @callback |     @callback | ||||||
|     def _handle_coordinator_update(self): |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         setting = self._device.settings.get(self.entity_description.key) |         setting = self._device.settings.get(self.entity_description.key) | ||||||
|         if setting is None: |         if setting is None: | ||||||
|             self._attr_available = False |             self._attr_available = False | ||||||
| @ -189,7 +189,8 @@ class HonSelectEntity(HonEntity, SelectEntity): | |||||||
|             self._attr_available = True |             self._attr_available = True | ||||||
|             self._attr_options: list[str] = setting.values |             self._attr_options: list[str] = setting.values | ||||||
|             self._attr_native_value = setting.value |             self._attr_native_value = setting.value | ||||||
|         self.async_write_ha_state() |         if update: | ||||||
|  |             self.async_write_ha_state() | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def available(self) -> bool: |     def available(self) -> bool: | ||||||
|  | |||||||
| @ -1,8 +1,6 @@ | |||||||
| import logging | import logging | ||||||
| from dataclasses import dataclass | from dataclasses import dataclass | ||||||
|  |  | ||||||
| from pyhon.appliance import HonAppliance |  | ||||||
|  |  | ||||||
| from homeassistant.components.sensor import ( | from homeassistant.components.sensor import ( | ||||||
|     SensorEntity, |     SensorEntity, | ||||||
|     SensorDeviceClass, |     SensorDeviceClass, | ||||||
| @ -22,7 +20,8 @@ from homeassistant.const import ( | |||||||
| ) | ) | ||||||
| from homeassistant.core import callback | from homeassistant.core import callback | ||||||
| from homeassistant.helpers.entity import EntityCategory | from homeassistant.helpers.entity import EntityCategory | ||||||
| from homeassistant.helpers.typing import StateType | from pyhon.appliance import HonAppliance | ||||||
|  |  | ||||||
| from . import const | from . import const | ||||||
| from .const import DOMAIN | from .const import DOMAIN | ||||||
| from .hon import HonEntity, unique_entities | from .hon import HonEntity, unique_entities | ||||||
| @ -535,6 +534,71 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | |||||||
|             key="errors", name="Error", icon="mdi:math-log", translation_key="errors" |             key="errors", name="Error", icon="mdi:math-log", translation_key="errors" | ||||||
|         ), |         ), | ||||||
|     ), |     ), | ||||||
|  |     "HO": ( | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="delayTime", | ||||||
|  |             name="Delay time", | ||||||
|  |             icon="mdi:clock-start", | ||||||
|  |             state_class=SensorStateClass.MEASUREMENT, | ||||||
|  |             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="delayTimeStatus", | ||||||
|  |             name="Delay time status", | ||||||
|  |             icon="mdi:clock-start", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="errors", | ||||||
|  |             name="Errors", | ||||||
|  |             icon="mdi:alert-circle", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="filterCleaningAlarmStatus", | ||||||
|  |             name="Filter Cleaning Alarm Status", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="filterCleaningStatus", | ||||||
|  |             name="Filter Cleaning Status", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="lastWorkTime", | ||||||
|  |             name="Last Work Time", | ||||||
|  |             icon="mdi:clock-start", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="lightStatus", | ||||||
|  |             name="Light Status", | ||||||
|  |             icon="mdi:lightbulb", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="machMode", | ||||||
|  |             name="Mach Mode", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="onOffStatus", | ||||||
|  |             name="On / Off Status", | ||||||
|  |             icon="mdi:lightbulb", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="quickDelayTimeStatus", | ||||||
|  |             name="Quick Delay Time Status", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="rgbLightColors", | ||||||
|  |             name="RGB Light Color", | ||||||
|  |             icon="mdi:lightbulb", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="rgbLightStatus", | ||||||
|  |             name="RGB Light Status", | ||||||
|  |             icon="mdi:lightbulb", | ||||||
|  |         ), | ||||||
|  |         HonSensorEntityDescription( | ||||||
|  |             key="windSpeed", | ||||||
|  |             name="Wind Speed", | ||||||
|  |             icon="mdi:fan", | ||||||
|  |         ), | ||||||
|  |     ), | ||||||
| } | } | ||||||
| SENSORS["WD"] = unique_entities(SENSORS["WM"], SENSORS["TD"]) | SENSORS["WD"] = unique_entities(SENSORS["WM"], SENSORS["TD"]) | ||||||
|  |  | ||||||
| @ -570,19 +634,20 @@ class HonSensorEntity(HonEntity, SensorEntity): | |||||||
|             ).values + ["No Program"] |             ).values + ["No Program"] | ||||||
|  |  | ||||||
|     @callback |     @callback | ||||||
|     def _handle_coordinator_update(self): |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         value = self._device.get(self.entity_description.key, "") |         value = self._device.get(self.entity_description.key, "") | ||||||
|         if not value and self.entity_description.state_class is not None: |         if not value and self.entity_description.state_class is not None: | ||||||
|             self._attr_native_value = 0 |             self._attr_native_value = 0 | ||||||
|         self._attr_native_value = value |         self._attr_native_value = value | ||||||
|         self.async_write_ha_state() |         if update: | ||||||
|  |             self.async_write_ha_state() | ||||||
|  |  | ||||||
|  |  | ||||||
| class HonConfigSensorEntity(HonEntity, SensorEntity): | class HonConfigSensorEntity(HonEntity, SensorEntity): | ||||||
|     entity_description: HonConfigSensorEntityDescription |     entity_description: HonConfigSensorEntityDescription | ||||||
|  |  | ||||||
|     @callback |     @callback | ||||||
|     def _handle_coordinator_update(self): |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         value = self._device.settings.get(self.entity_description.key, None) |         value = self._device.settings.get(self.entity_description.key, None) | ||||||
|         if self.entity_description.state_class is not None: |         if self.entity_description.state_class is not None: | ||||||
|             if value and value.value: |             if value and value.value: | ||||||
| @ -593,4 +658,5 @@ class HonConfigSensorEntity(HonEntity, SensorEntity): | |||||||
|                 self._attr_native_value = 0 |                 self._attr_native_value = 0 | ||||||
|         else: |         else: | ||||||
|             self._attr_native_value = value.value |             self._attr_native_value = value.value | ||||||
|         self.async_write_ha_state() |         if update: | ||||||
|  |             self.async_write_ha_state() | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| import logging | import logging | ||||||
| from dataclasses import dataclass | from dataclasses import dataclass | ||||||
|  | from datetime import datetime, timedelta | ||||||
| from typing import Any | from typing import Any | ||||||
|  |  | ||||||
| from homeassistant.components.switch import SwitchEntityDescription, SwitchEntity | from homeassistant.components.switch import SwitchEntityDescription, SwitchEntity | ||||||
| @ -394,10 +395,11 @@ class HonSwitchEntity(HonEntity, SwitchEntity): | |||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     @callback |     @callback | ||||||
|     def _handle_coordinator_update(self): |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         value = self._device.get(self.entity_description.key, "0") |         value = self._device.get(self.entity_description.key, "0") | ||||||
|         self._attr_state = value == "1" |         self._attr_state = value == "1" | ||||||
|         self.async_write_ha_state() |         if update: | ||||||
|  |             self.async_write_ha_state() | ||||||
|  |  | ||||||
|  |  | ||||||
| class HonControlSwitchEntity(HonEntity, SwitchEntity): | class HonControlSwitchEntity(HonEntity, SwitchEntity): | ||||||
| @ -410,9 +412,13 @@ class HonControlSwitchEntity(HonEntity, SwitchEntity): | |||||||
|  |  | ||||||
|     async def async_turn_on(self, **kwargs: Any) -> None: |     async def async_turn_on(self, **kwargs: Any) -> None: | ||||||
|         await self._device.commands[self.entity_description.turn_on_key].send() |         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: |     async def async_turn_off(self, **kwargs: Any) -> None: | ||||||
|         await self._device.commands[self.entity_description.turn_off_key].send() |         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 |     @property | ||||||
|     def available(self) -> bool: |     def available(self) -> bool: | ||||||
| @ -423,6 +429,18 @@ class HonControlSwitchEntity(HonEntity, SwitchEntity): | |||||||
|             and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED" |             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): | class HonConfigSwitchEntity(HonEntity, SwitchEntity): | ||||||
|     entity_description: HonConfigSwitchEntityDescription |     entity_description: HonConfigSwitchEntityDescription | ||||||
| @ -454,7 +472,8 @@ class HonConfigSwitchEntity(HonEntity, SwitchEntity): | |||||||
|         await self.coordinator.async_refresh() |         await self.coordinator.async_refresh() | ||||||
|  |  | ||||||
|     @callback |     @callback | ||||||
|     def _handle_coordinator_update(self): |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         value = self._device.settings.get(self.entity_description.key, "0") |         value = self._device.settings.get(self.entity_description.key, "0") | ||||||
|         self._attr_state = value == "1" |         self._attr_state = value == "1" | ||||||
|         self.async_write_ha_state() |         if update: | ||||||
|  |             self.async_write_ha_state() | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Sušení", |                     "20": "Sušení", | ||||||
|                     "11": "Připraveno", |                     "11": "Připraveno", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Fáze" |                 "name": "Fáze" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Trocknen", |                     "20": "Trocknen", | ||||||
|                     "11": "Bereit", |                     "11": "Bereit", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Phase" |                 "name": "Phase" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Στέγνωμα", |                     "20": "Στέγνωμα", | ||||||
|                     "11": "Ετοιμος", |                     "11": "Ετοιμος", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Φάση" |                 "name": "Φάση" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -127,7 +127,7 @@ | |||||||
|                     "20": "Drying", |                     "20": "Drying", | ||||||
|                     "11": "Ready", |                     "11": "Ready", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Phase" |                 "name": "Phase" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Secado", |                     "20": "Secado", | ||||||
|                     "11": "Listo", |                     "11": "Listo", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Fase" |                 "name": "Fase" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Séchage", |                     "20": "Séchage", | ||||||
|                     "11": "Prêt", |                     "11": "Prêt", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Phase" |                 "name": "Phase" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "יִבּוּשׁ", |                     "20": "יִבּוּשׁ", | ||||||
|                     "11": "מוּכָן", |                     "11": "מוּכָן", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "שלב" |                 "name": "שלב" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Sušenje", |                     "20": "Sušenje", | ||||||
|                     "11": "Spremno", |                     "11": "Spremno", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Faza" |                 "name": "Faza" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -117,7 +117,7 @@ | |||||||
|                     "20": "Asciugatura", |                     "20": "Asciugatura", | ||||||
|                     "11": "Pronta", |                     "11": "Pronta", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Fase" |                 "name": "Fase" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Drogen", |                     "20": "Drogen", | ||||||
|                     "11": "Klaar", |                     "11": "Klaar", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Fase" |                 "name": "Fase" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Suszenie", |                     "20": "Suszenie", | ||||||
|                     "11": "Gotowe", |                     "11": "Gotowe", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Faza" |                 "name": "Faza" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Secagem", |                     "20": "Secagem", | ||||||
|                     "11": "Pronto", |                     "11": "Pronto", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Fase" |                 "name": "Fase" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Uscare", |                     "20": "Uscare", | ||||||
|                     "11": "Pregătit", |                     "11": "Pregătit", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Fază" |                 "name": "Fază" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Сушка", |                     "20": "Сушка", | ||||||
|                     "11": "Готово", |                     "11": "Готово", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Фаза" |                 "name": "Фаза" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Sušenie", |                     "20": "Sušenie", | ||||||
|                     "11": "Pripravené", |                     "11": "Pripravené", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Fáza" |                 "name": "Fáza" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Sušenje", |                     "20": "Sušenje", | ||||||
|                     "11": "Pripravljen", |                     "11": "Pripravljen", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Faza" |                 "name": "Faza" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Sušenje", |                     "20": "Sušenje", | ||||||
|                     "11": "Spremno", |                     "11": "Spremno", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Faza" |                 "name": "Faza" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "Kurutma", |                     "20": "Kurutma", | ||||||
|                     "11": "Hazır", |                     "11": "Hazır", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "Aşama" |                 "name": "Aşama" | ||||||
|             }, |             }, | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ | |||||||
|                     "20": "烘干", |                     "20": "烘干", | ||||||
|                     "11": "就绪", |                     "11": "就绪", | ||||||
|                     "17": "unknown", |                     "17": "unknown", | ||||||
|                     "12": "unkown" |                     "12": "unknown" | ||||||
|                 }, |                 }, | ||||||
|                 "name": "阶段" |                 "name": "阶段" | ||||||
|             }, |             }, | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								info.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								info.md
									
									
									
									
									
								
							| @ -9,10 +9,11 @@ Support for home appliances of Haier's mobile app hOn. | |||||||
| - [Tumble Dryer](https://github.com/Andre0512/hon#tumble-dryer) | - [Tumble Dryer](https://github.com/Andre0512/hon#tumble-dryer) | ||||||
| - [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer) | - [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer) | ||||||
| - [Oven](https://github.com/Andre0512/hon#oven) | - [Oven](https://github.com/Andre0512/hon#oven) | ||||||
| - [Hob](https://github.com/Andre0512/hon#hob) |  | ||||||
| - [Dish Washer](https://github.com/Andre0512/hon#dish-washer) | - [Dish Washer](https://github.com/Andre0512/hon#dish-washer) | ||||||
| - [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA] | - [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) | ||||||
| - [Fridge](https://github.com/Andre0512/hon#fridge) [BETA] | - [Fridge](https://github.com/Andre0512/hon#fridge) | ||||||
|  | - [Hob](https://github.com/Andre0512/hon#hob) [BETA] | ||||||
|  | - [Hood](https://github.com/Andre0512/hon#hood) [BETA] | ||||||
|  |  | ||||||
| ## Configuration | ## Configuration | ||||||
|  |  | ||||||
| @ -50,10 +51,14 @@ Translation of internal names like programs are available for all languages whic | |||||||
| ## Supported Models | ## 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). | 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 AD105S2SM3FA | ||||||
|  | - Haier AS20HPL1HRA | ||||||
| - Haier AS25PBAHRA | - Haier AS25PBAHRA | ||||||
|  | - Haier AS25S2SF1FA-WH | ||||||
| - Haier AS25TADHRA-2 | - Haier AS25TADHRA-2 | ||||||
| - Haier AS35TADHRA-2 | - Haier AS35TADHRA-2 | ||||||
| - Haier EG9012B19SU1JD | - Haier EG9012B19SU1JD | ||||||
|  | - Haier HA2MTSJ68MC | ||||||
|  | - Haier HADG6DS46BWIFI | ||||||
| - Haier HD80-A3959 | - Haier HD80-A3959 | ||||||
| - Haier HW90-B14TEAM5 | - Haier HW90-B14TEAM5 | ||||||
| - Haier HW100-B14959U1 | - Haier HW100-B14959U1 | ||||||
| @ -65,6 +70,7 @@ Support has been confirmed for these models, but many more will work. Please add | |||||||
| - Candy CCE4T620EWU | - Candy CCE4T620EWU | ||||||
| - Candy CIS633SCTTWIFI | - Candy CIS633SCTTWIFI | ||||||
| - Candy CSOE C10DE-80 | - Candy CSOE C10DE-80 | ||||||
|  | - Candy RO44 1286DWMC4-07 | ||||||
| - Candy ROE H9A3TCEX-S | - Candy ROE H9A3TCEX-S | ||||||
| - Candy RPW41066BWMR/1-S | - Candy RPW41066BWMR/1-S | ||||||
| - Hoover H-WASH 500 | - Hoover H-WASH 500 | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	