Compare commits
	
		
			7 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0afbfe997d | |||
| 6828f3e9a8 | |||
| a56d3e5f88 | |||
| 240dc85ff3 | |||
| 44794c35ca | |||
| a5c7b99569 | |||
| 6935f5f07f | 
							
								
								
									
										45
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								README.md
									
									
									
									
									
								
							| @ -40,6 +40,7 @@ Support was confirmed for these models. If a supported model is missing, please | |||||||
| - Candy CIS633SCTTWIFI | - Candy CIS633SCTTWIFI | ||||||
| - Haier XIB 3B2SFS-80 | - Haier XIB 3B2SFS-80 | ||||||
| - Haier XIB 6B2D3FB | - Haier XIB 6B2D3FB | ||||||
|  | - Hoover HSOT3161WG | ||||||
|  |  | ||||||
| ## Supported Languages | ## Supported Languages | ||||||
| Translation of internal names like programs are available for all languages which are official supported by the hOn app: | Translation of internal names like programs are available for all languages which are official supported by the hOn app: | ||||||
| @ -138,19 +139,19 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| #### Configs | #### Configs | ||||||
| | Name | Icon | Entity | Key | | | Name | Icon | Entity | Key | | ||||||
| | --- | --- | --- | --- | | | --- | --- | --- | --- | | ||||||
| | 10° Heating |  | `switch` | `startProgram.10degreeHeatingStatus` | | | 10° Heating | `heat-wave` | `switch` | `settings.10degreeHeatingStatus` | | ||||||
| | Echo |  | `switch` | `startProgram.echoStatus` | | | Echo | `account-voice` | `switch` | `settings.echoStatus` | | ||||||
| | Eco Mode |  | `switch` | `startProgram.ecoMode` | | | Eco Mode |  | `switch` | `settings.ecoMode` | | ||||||
| | Eco Pilot |  | `select` | `startProgram.humanSensingStatus` | | | Eco Pilot | `run` | `select` | `settings.humanSensingStatus` | | ||||||
| | Health Mode |  | `switch` | `startProgram.healthMode` | | | Health Mode | `medication-outline` | `switch` | `settings.healthMode` | | ||||||
| | Mute |  | `switch` | `startProgram.muteStatus` | | | Mute | `volume-off` | `switch` | `settings.muteStatus` | | ||||||
| | Program |  | `select` | `startProgram.program` | | | Program |  | `select` | `startProgram.program` | | ||||||
| | Rapid Mode |  | `switch` | `startProgram.rapidMode` | | | Rapid Mode | `run-fast` | `switch` | `settings.rapidMode` | | ||||||
| | Screen Display |  | `switch` | `startProgram.screenDisplayStatus` | | | Screen Display | `monitor-small` | `switch` | `settings.screenDisplayStatus` | | ||||||
| | Self Cleaning |  | `switch` | `startProgram.selfCleaningStatus` | | | Self Cleaning | `air-filter` | `switch` | `settings.selfCleaningStatus` | | ||||||
| | Self Cleaning 56 |  | `switch` | `startProgram.selfCleaning56Status` | | | Self Cleaning 56 | `air-filter` | `switch` | `settings.selfCleaning56Status` | | ||||||
| | Silent Sleep |  | `switch` | `startProgram.silentSleepStatus` | | | Silent Sleep | `bed` | `switch` | `settings.silentSleepStatus` | | ||||||
| | Target Temperature | `thermometer` | `number` | `startProgram.tempSel` | | | Target Temperature | `thermometer` | `number` | `settings.tempSel` | | ||||||
|  |  | ||||||
| ### Dish washer | ### Dish washer | ||||||
| #### Controls | #### Controls | ||||||
| @ -209,7 +210,6 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Pan Status | `pot-mix` | `binary_sensor` | `panStatus` | | | Pan Status | `pot-mix` | `binary_sensor` | `panStatus` | | ||||||
| | Power | `lightning-bolt` | `sensor` | `power` | | | Power | `lightning-bolt` | `sensor` | `power` | | ||||||
| | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | ||||||
| | Remote Control | `remote` | `binary_sensor` | `attributes.parameters.remoteCtrValid` | |  | ||||||
| | Temperature | `thermometer` | `sensor` | `temp` | | | Temperature | `thermometer` | `sensor` | `temp` | | ||||||
|  |  | ||||||
| ### Oven | ### Oven | ||||||
| @ -231,7 +231,6 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Connection | `wifi` | `binary_sensor` | `attributes.lastConnEvent.category` | | | Connection | `wifi` | `binary_sensor` | `attributes.lastConnEvent.category` | | ||||||
| | On | `power-cycle` | `binary_sensor` | `attributes.parameters.onOffStatus` | | | On | `power-cycle` | `binary_sensor` | `attributes.parameters.onOffStatus` | | ||||||
| | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | ||||||
| | Remote Control | `remote` | `binary_sensor` | `attributes.parameters.remoteCtrValid` | |  | ||||||
| | Start Time | `clock-start` | `sensor` | `delayTime` | | | Start Time | `clock-start` | `sensor` | `delayTime` | | ||||||
| | Temperature | `thermometer` | `sensor` | `temp` | | | Temperature | `thermometer` | `sensor` | `temp` | | ||||||
| | Temperature Selected | `thermometer` | `sensor` | `tempSel` | | | Temperature Selected | `thermometer` | `sensor` | `tempSel` | | ||||||
| @ -293,10 +292,10 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Dry Time | `timer` | `select` | `startProgram.dryTimeMM` | | | Dry Time | `timer` | `select` | `startProgram.dryTimeMM` | | ||||||
| | Dry level | `hair-dryer` | `select` | `startProgram.dryLevel` | | | Dry level | `hair-dryer` | `select` | `startProgram.dryLevel` | | ||||||
| | Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` | | | Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` | | ||||||
| | Extra Rinse 1 | `numeric-1-box-multiple-outline` | `switch` | `extraRinse1` | | | Extra Rinse 1 | `numeric-1-box-multiple-outline` | `switch` | `startProgram.extraRinse1` | | ||||||
| | Extra Rinse 2 | `numeric-2-box-multiple-outline` | `switch` | `extraRinse2` | | | Extra Rinse 2 | `numeric-2-box-multiple-outline` | `switch` | `startProgram.extraRinse2` | | ||||||
| | Extra Rinse 3 | `numeric-3-box-multiple-outline` | `switch` | `extraRinse3` | | | Extra Rinse 3 | `numeric-3-box-multiple-outline` | `switch` | `startProgram.extraRinse3` | | ||||||
| | Good Night | `weather-night` | `switch` | `goodNight` | | | Good Night | `weather-night` | `switch` | `startProgram.goodNight` | | ||||||
| | Keep Fresh | `refresh-circle` | `switch` | `startProgram.autoSoftenerStatus` | | | Keep Fresh | `refresh-circle` | `switch` | `startProgram.autoSoftenerStatus` | | ||||||
| | Liquid Detergent Dose | `cup-water` | `sensor` | `startProgram.liquidDetergentDose` | | | Liquid Detergent Dose | `cup-water` | `sensor` | `startProgram.liquidDetergentDose` | | ||||||
| | Main Wash Time | `clock-start` | `number` | `startProgram.mainWashTime` | | | Main Wash Time | `clock-start` | `number` | `startProgram.mainWashTime` | | ||||||
| @ -323,6 +322,7 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Acqua Plus |  | `binary_sensor` | `acquaplus` | | | Acqua Plus |  | `binary_sensor` | `acquaplus` | | ||||||
| | Anti-Crease |  | `binary_sensor` | `anticrease` | | | Anti-Crease |  | `binary_sensor` | `anticrease` | | ||||||
| | Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` | | | Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` | | ||||||
|  | | Current Temperature | `thermometer` | `sensor` | `temp` | | ||||||
| | Current Water Used | `water` | `sensor` | `currentWaterUsed` | | | Current Water Used | `water` | `sensor` | `currentWaterUsed` | | ||||||
| | Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` | | | Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` | | ||||||
| | Door |  | `binary_sensor` | `doorStatus` | | | Door |  | `binary_sensor` | `doorStatus` | | ||||||
| @ -361,10 +361,10 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Delay Status | `timer-check` | `switch` | `startProgram.delayStatus` | | | Delay Status | `timer-check` | `switch` | `startProgram.delayStatus` | | ||||||
| | Delay Time | `timer-plus` | `number` | `startProgram.delayTime` | | | Delay Time | `timer-plus` | `number` | `startProgram.delayTime` | | ||||||
| | Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` | | | Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` | | ||||||
| | Extra Rinse 1 | `numeric-1-box-multiple-outline` | `switch` | `extraRinse1` | | | Extra Rinse 1 | `numeric-1-box-multiple-outline` | `switch` | `startProgram.extraRinse1` | | ||||||
| | Extra Rinse 2 | `numeric-2-box-multiple-outline` | `switch` | `extraRinse2` | | | Extra Rinse 2 | `numeric-2-box-multiple-outline` | `switch` | `startProgram.extraRinse2` | | ||||||
| | Extra Rinse 3 | `numeric-3-box-multiple-outline` | `switch` | `extraRinse3` | | | Extra Rinse 3 | `numeric-3-box-multiple-outline` | `switch` | `startProgram.extraRinse3` | | ||||||
| | Good Night | `weather-night` | `switch` | `goodNight` | | | Good Night | `weather-night` | `switch` | `startProgram.goodNight` | | ||||||
| | Keep Fresh | `refresh-circle` | `switch` | `startProgram.autoSoftenerStatus` | | | Keep Fresh | `refresh-circle` | `switch` | `startProgram.autoSoftenerStatus` | | ||||||
| | Liquid Detergent Dose | `cup-water` | `sensor` | `startProgram.liquidDetergentDose` | | | Liquid Detergent Dose | `cup-water` | `sensor` | `startProgram.liquidDetergentDose` | | ||||||
| | Main Wash Time | `clock-start` | `number` | `startProgram.mainWashTime` | | | Main Wash Time | `clock-start` | `number` | `startProgram.mainWashTime` | | ||||||
| @ -385,6 +385,7 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | --- | --- | --- | --- | | | --- | --- | --- | --- | | ||||||
| | Acqua Plus |  | `binary_sensor` | `acquaplus` | | | Acqua Plus |  | `binary_sensor` | `acquaplus` | | ||||||
| | Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` | | | Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` | | ||||||
|  | | Current Temperature | `thermometer` | `sensor` | `temp` | | ||||||
| | Current Water Used | `water` | `sensor` | `currentWaterUsed` | | | Current Water Used | `water` | `sensor` | `currentWaterUsed` | | ||||||
| | Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` | | | Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` | | ||||||
| | Door |  | `binary_sensor` | `doorStatus` | | | Door |  | `binary_sensor` | `doorStatus` | | ||||||
|  | |||||||
| @ -99,14 +99,6 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { | |||||||
|             icon="mdi:wifi", |             icon="mdi:wifi", | ||||||
|             translation_key="connection", |             translation_key="connection", | ||||||
|         ), |         ), | ||||||
|         HonBinarySensorEntityDescription( |  | ||||||
|             key="attributes.parameters.remoteCtrValid", |  | ||||||
|             name="Remote Control", |  | ||||||
|             device_class=BinarySensorDeviceClass.CONNECTIVITY, |  | ||||||
|             on_value="1", |  | ||||||
|             icon="mdi:remote", |  | ||||||
|             translation_key="remote_control", |  | ||||||
|         ), |  | ||||||
|         HonBinarySensorEntityDescription( |         HonBinarySensorEntityDescription( | ||||||
|             key="attributes.parameters.onOffStatus", |             key="attributes.parameters.onOffStatus", | ||||||
|             name="On", |             name="On", | ||||||
| @ -125,14 +117,6 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { | |||||||
|             icon="mdi:wifi", |             icon="mdi:wifi", | ||||||
|             translation_key="connection", |             translation_key="connection", | ||||||
|         ), |         ), | ||||||
|         HonBinarySensorEntityDescription( |  | ||||||
|             key="attributes.parameters.remoteCtrValid", |  | ||||||
|             name="Remote Control", |  | ||||||
|             device_class=BinarySensorDeviceClass.CONNECTIVITY, |  | ||||||
|             on_value="1", |  | ||||||
|             icon="mdi:remote", |  | ||||||
|             translation_key="remote_control", |  | ||||||
|         ), |  | ||||||
|         HonBinarySensorEntityDescription( |         HonBinarySensorEntityDescription( | ||||||
|             key="attributes.parameters.onOffStatus", |             key="attributes.parameters.onOffStatus", | ||||||
|             name="On", |             name="On", | ||||||
|  | |||||||
| @ -64,6 +64,11 @@ class HonButtonEntity(HonEntity, ButtonEntity): | |||||||
|     async def async_press(self) -> None: |     async def async_press(self) -> None: | ||||||
|         await self._device.commands[self.entity_description.key].send() |         await self._device.commands[self.entity_description.key].send() | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def available(self) -> bool: | ||||||
|  |         """Return True if entity is available.""" | ||||||
|  |         return super().available and self._device.get("remoteCtrValid") == "1" | ||||||
|  |  | ||||||
|  |  | ||||||
| class HonFeatureRequestButton(HonEntity, ButtonEntity): | class HonFeatureRequestButton(HonEntity, ButtonEntity): | ||||||
|     def __init__(self, hass, coordinator, entry, device: HonAppliance) -> None: |     def __init__(self, hass, coordinator, entry, device: HonAppliance) -> None: | ||||||
| @ -78,5 +83,5 @@ class HonFeatureRequestButton(HonEntity, ButtonEntity): | |||||||
|  |  | ||||||
|     async def async_press(self) -> None: |     async def async_press(self) -> None: | ||||||
|         pyhon_version = pkg_resources.get_distribution("pyhon").version |         pyhon_version = pkg_resources.get_distribution("pyhon").version | ||||||
|         info = f"Device Info:\n{self._device.diagnose}pyhOnVersion: {pyhon_version}" |         info = f"Device Info:\n{self._device.diagnose()}pyhOnVersion: {pyhon_version}" | ||||||
|         _LOGGER.error(info) |         _LOGGER.error(info) | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ from .hon import HonEntity, HonCoordinator | |||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| CLIMATES = { | CLIMATES = { | ||||||
|     "AC": (ClimateEntityDescription(key="startProgram"),), |     "AC": (ClimateEntityDescription(key="startProgram", icon="mdi:air-conditioner"),), | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -47,7 +47,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | |||||||
|  |  | ||||||
|         if descriptions := CLIMATES.get(device.appliance_type): |         if descriptions := CLIMATES.get(device.appliance_type): | ||||||
|             for description in descriptions: |             for description in descriptions: | ||||||
|                 if description.key not in device.available_settings: |                 if description.key not in list(device.commands): | ||||||
|                     continue |                     continue | ||||||
|                 appliances.extend( |                 appliances.extend( | ||||||
|                     [HonClimateEntity(hass, coordinator, entry, device, description)] |                     [HonClimateEntity(hass, coordinator, entry, device, description)] | ||||||
| @ -61,21 +61,21 @@ class HonClimateEntity(HonEntity, ClimateEntity): | |||||||
|     ) -> None: |     ) -> None: | ||||||
|         super().__init__(hass, entry, coordinator, device) |         super().__init__(hass, entry, coordinator, device) | ||||||
|         self._coordinator = coordinator |         self._coordinator = coordinator | ||||||
|         self._device = coordinator.device |         self._device = device | ||||||
|         self.entity_description = description |         self.entity_description = description | ||||||
|         self._hass = hass |         self._hass = hass | ||||||
|         self._attr_unique_id = f"{super().unique_id}climate" |         self._attr_unique_id = f"{super().unique_id}climate" | ||||||
|  |  | ||||||
|         self._attr_temperature_unit = TEMP_CELSIUS |         self._attr_temperature_unit = TEMP_CELSIUS | ||||||
|         self._attr_target_temperature_step = PRECISION_WHOLE |         self._attr_target_temperature_step = PRECISION_WHOLE | ||||||
|         self._attr_max_temp = device.settings["tempSel"].max |         self._attr_max_temp = device.settings["settings.tempSel"].max | ||||||
|         self._attr_min_temp = device.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["machMode"].values |             HON_HVAC_MODE[mode] for mode in device.settings["settings.machMode"].values | ||||||
|         ] |         ] | ||||||
|         self._attr_fan_modes = [FAN_OFF] + [ |         self._attr_fan_modes = [FAN_OFF] + [ | ||||||
|             HON_FAN[mode] for mode in device.settings["windSpeed"].values |             HON_FAN[mode] for mode in device.settings["settings.windSpeed"].values | ||||||
|         ] |         ] | ||||||
|         self._attr_swing_modes = [ |         self._attr_swing_modes = [ | ||||||
|             SWING_OFF, |             SWING_OFF, | ||||||
| @ -89,22 +89,28 @@ class HonClimateEntity(HonEntity, ClimateEntity): | |||||||
|             | ClimateEntityFeature.SWING_MODE |             | ClimateEntityFeature.SWING_MODE | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |         self._handle_coordinator_update() | ||||||
|  |  | ||||||
|     async def async_set_hvac_mode(self, hvac_mode): |     async def async_set_hvac_mode(self, hvac_mode): | ||||||
|         if hvac_mode == HVACMode.OFF: |         if hvac_mode == HVACMode.OFF: | ||||||
|             self._device.commands["stopProgram"].send() |             await self._device.commands["stopProgram"].send() | ||||||
|         else: |         else: | ||||||
|             self._device.settings["program"].value = HON_HVAC_PROGRAM[hvac_mode] |             self._device.settings["startProgram.program"].value = HON_HVAC_PROGRAM[ | ||||||
|             self._device.commands["startProgram"].send() |                 hvac_mode | ||||||
|  |             ] | ||||||
|  |             await self._device.commands["startProgram"].send() | ||||||
|         self._attr_hvac_mode = hvac_mode |         self._attr_hvac_mode = hvac_mode | ||||||
|  |  | ||||||
|     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["windSpeed"].value = list(HON_FAN.keys())[mode_number] |         self._device.settings["settings.windSpeed"].value = list(HON_FAN.keys())[ | ||||||
|         self._device.commands["startProgram"].send() |             mode_number | ||||||
|  |         ] | ||||||
|  |         await self._device.commands["settings"].send() | ||||||
|  |  | ||||||
|     async def async_set_swing_mode(self, swing_mode): |     async def async_set_swing_mode(self, swing_mode): | ||||||
|         horizontal = self._device.settings["windDirectionHorizontal"] |         horizontal = self._device.settings["settings.windDirectionHorizontal"] | ||||||
|         vertical = self._device.settings["windDirectionVertical"] |         vertical = self._device.settings["settings.windDirectionVertical"] | ||||||
|         if swing_mode in [SWING_BOTH, SWING_HORIZONTAL]: |         if swing_mode in [SWING_BOTH, SWING_HORIZONTAL]: | ||||||
|             horizontal.value = "7" |             horizontal.value = "7" | ||||||
|         if swing_mode in [SWING_BOTH, SWING_VERTICAL]: |         if swing_mode in [SWING_BOTH, SWING_VERTICAL]: | ||||||
| @ -114,30 +120,30 @@ class HonClimateEntity(HonEntity, ClimateEntity): | |||||||
|         if swing_mode in [SWING_OFF, SWING_VERTICAL] and horizontal.value == "7": |         if swing_mode in [SWING_OFF, SWING_VERTICAL] and horizontal.value == "7": | ||||||
|             horizontal.value = "0" |             horizontal.value = "0" | ||||||
|         self._attr_swing_mode = swing_mode |         self._attr_swing_mode = swing_mode | ||||||
|         self._device.commands["startProgram"].send() |         await self._device.commands["settings"].send() | ||||||
|  |  | ||||||
|     async def async_set_temperature(self, **kwargs): |     async def async_set_temperature(self, **kwargs): | ||||||
|         if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None: |         if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None: | ||||||
|             return False |             return False | ||||||
|         self._device.settings["selTemp"].value = temperature |         self._device.settings["settings.selTemp"].value = temperature | ||||||
|         self._device.commands["startProgram"].send() |         await self._device.commands["settings"].send() | ||||||
|  |  | ||||||
|     @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 = int(float(self._device.get("tempSel"))) | ||||||
|         self._attr_current_temperature = float(self._device.get("tempIndoor")) |         self._attr_current_temperature = float(self._device.get("tempIndoor")) | ||||||
|         self._attr_max_temp = self._device.settings["tempSel"].max |         self._attr_max_temp = self._device.settings["settings.tempSel"].max | ||||||
|         self._attr_min_temp = self._device.settings["tempSel"].min |         self._attr_min_temp = self._device.settings["settings.tempSel"].min | ||||||
|  |  | ||||||
|         if self._device.get("onOffStatus") == "0": |         if self._device.get("onOffStatus") == "0": | ||||||
|             self._attr_hvac_mode = HVACMode.OFF |             self._attr_hvac_mode = HVACMode.OFF | ||||||
|         else: |         else: | ||||||
|             self._attr_hvac_mode = HON_HVAC_MODE[self._device.get("machMode")] |             self._attr_hvac_mode = HON_HVAC_MODE[self._device.get("machMode") or "0"] | ||||||
|  |  | ||||||
|         self._attr_fan_mode = HON_FAN[self._device.settings["windSpeed"].value] |         self._attr_fan_mode = HON_FAN[self._device.settings["settings.windSpeed"].value] | ||||||
|  |  | ||||||
|         horizontal = self._device.settings["windDirectionHorizontal"] |         horizontal = self._device.settings["settings.windDirectionHorizontal"] | ||||||
|         vertical = self._device.settings["windDirectionVertical"] |         vertical = self._device.settings["settings.windDirectionVertical"] | ||||||
|         if horizontal == "7" and vertical == "8": |         if horizontal == "7" and vertical == "8": | ||||||
|             self._attr_swing_mode = SWING_BOTH |             self._attr_swing_mode = SWING_BOTH | ||||||
|         elif horizontal == "7": |         elif horizontal == "7": | ||||||
|  | |||||||
| @ -120,6 +120,19 @@ TUMBLE_DRYER_PR_PHASE = { | |||||||
|     "19": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE", |     "19": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE", | ||||||
|     "20": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE", |     "20": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE", | ||||||
| } | } | ||||||
|  | DIRTY_LEVEL = { | ||||||
|  |     "1": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.LITTLE", | ||||||
|  |     "2": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.NORMAL", | ||||||
|  |     "3": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.VERY", | ||||||
|  | } | ||||||
|  |  | ||||||
|  | STEAM_LEVEL = { | ||||||
|  |     "0": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.NO_STEAM", | ||||||
|  |     "1": "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_FABRICS.COTTON_TITLE", | ||||||
|  |     "2": "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_FABRICS.DELICATE_TITLE", | ||||||
|  |     "3": "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_FABRICS.SYNTHETIC_TITLE", | ||||||
|  | } | ||||||
|  |  | ||||||
| DISHWASHER_PR_PHASE = { | DISHWASHER_PR_PHASE = { | ||||||
|     "0": "WASHING_CMD&CTRL.PHASE_READY.TITLE", |     "0": "WASHING_CMD&CTRL.PHASE_READY.TITLE", | ||||||
|     "1": "WASHING_CMD&CTRL.PHASE_PREWASH.TITLE", |     "1": "WASHING_CMD&CTRL.PHASE_PREWASH.TITLE", | ||||||
|  | |||||||
| @ -6,6 +6,6 @@ | |||||||
|   "documentation": "https://github.com/Andre0512/hon/", |   "documentation": "https://github.com/Andre0512/hon/", | ||||||
|   "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": ["pyhOn==0.10.4"], |  "requirements": ["pyhOn==0.10.6"], | ||||||
|   "version": "0.7.1" |   "version": "0.7.3" | ||||||
| } | } | ||||||
|  | |||||||
| @ -146,7 +146,7 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | |||||||
|     ), |     ), | ||||||
|     "AC": ( |     "AC": ( | ||||||
|         NumberEntityDescription( |         NumberEntityDescription( | ||||||
|             key="startProgram.tempSel", |             key="settings.tempSel", | ||||||
|             name="Target Temperature", |             name="Target Temperature", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             icon="mdi:thermometer", |             icon="mdi:thermometer", | ||||||
|  | |||||||
| @ -98,8 +98,9 @@ SELECTS = { | |||||||
|             translation_key="programs_ac", |             translation_key="programs_ac", | ||||||
|         ), |         ), | ||||||
|         SelectEntityDescription( |         SelectEntityDescription( | ||||||
|             key="startProgram.humanSensingStatus", |             key="settings.humanSensingStatus", | ||||||
|             name="Eco Pilot", |             name="Eco Pilot", | ||||||
|  |             icon="mdi:run", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="eco_pilot", |             translation_key="eco_pilot", | ||||||
|         ), |         ), | ||||||
|  | |||||||
| @ -161,6 +161,14 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | |||||||
|             native_unit_of_measurement=UnitOfMass.KILOGRAMS, |             native_unit_of_measurement=UnitOfMass.KILOGRAMS, | ||||||
|             translation_key="suggested_load", |             translation_key="suggested_load", | ||||||
|         ), |         ), | ||||||
|  |         SensorEntityDescription( | ||||||
|  |             key="temp", | ||||||
|  |             name="Current Temperature", | ||||||
|  |             icon="mdi:thermometer", | ||||||
|  |             state_class=SensorStateClass.MEASUREMENT, | ||||||
|  |             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||||
|  |             translation_key="temperature", | ||||||
|  |         ), | ||||||
|     ), |     ), | ||||||
|     "TD": ( |     "TD": ( | ||||||
|         SensorEntityDescription( |         SensorEntityDescription( | ||||||
|  | |||||||
| @ -82,28 +82,28 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | |||||||
|             translation_key="acqua_plus", |             translation_key="acqua_plus", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="extraRinse1", |             key="startProgram.extraRinse1", | ||||||
|             name="Extra Rinse 1", |             name="Extra Rinse 1", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             icon="mdi:numeric-1-box-multiple-outline", |             icon="mdi:numeric-1-box-multiple-outline", | ||||||
|             translation_key="extra_rinse_1", |             translation_key="extra_rinse_1", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="extraRinse2", |             key="startProgram.extraRinse2", | ||||||
|             name="Extra Rinse 2", |             name="Extra Rinse 2", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             icon="mdi:numeric-2-box-multiple-outline", |             icon="mdi:numeric-2-box-multiple-outline", | ||||||
|             translation_key="extra_rinse_2", |             translation_key="extra_rinse_2", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="extraRinse3", |             key="startProgram.extraRinse3", | ||||||
|             name="Extra Rinse 3", |             name="Extra Rinse 3", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             icon="mdi:numeric-3-box-multiple-outline", |             icon="mdi:numeric-3-box-multiple-outline", | ||||||
|             translation_key="extra_rinse_3", |             translation_key="extra_rinse_3", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="goodNight", |             key="startProgram.goodNight", | ||||||
|             name="Good Night", |             name="Good Night", | ||||||
|             icon="mdi:weather-night", |             icon="mdi:weather-night", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
| @ -237,59 +237,68 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | |||||||
|     ), |     ), | ||||||
|     "AC": ( |     "AC": ( | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.10degreeHeatingStatus", |             key="settings.10degreeHeatingStatus", | ||||||
|             name="10° Heating", |             name="10° Heating", | ||||||
|  |             icon="mdi:heat-wave", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="10_degree_heating", |             translation_key="10_degree_heating", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.echoStatus", |             key="settings.echoStatus", | ||||||
|             name="Echo", |             name="Echo", | ||||||
|  |             icon="mdi:account-voice", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.ecoMode", |             key="settings.ecoMode", | ||||||
|             name="Eco Mode", |             name="Eco Mode", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="eco_mode", |             translation_key="eco_mode", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.healthMode", |             key="settings.healthMode", | ||||||
|             name="Health Mode", |             name="Health Mode", | ||||||
|  |             icon="mdi:medication-outline", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.muteStatus", |             key="settings.muteStatus", | ||||||
|             name="Mute", |             name="Mute", | ||||||
|  |             icon="mdi:volume-off", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="mute_mode", |             translation_key="mute_mode", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.rapidMode", |             key="settings.rapidMode", | ||||||
|             name="Rapid Mode", |             name="Rapid Mode", | ||||||
|  |             icon="mdi:run-fast", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="rapid_mode", |             translation_key="rapid_mode", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.screenDisplayStatus", |             key="settings.screenDisplayStatus", | ||||||
|             name="Screen Display", |             name="Screen Display", | ||||||
|  |             icon="mdi:monitor-small", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.selfCleaning56Status", |             key="settings.selfCleaning56Status", | ||||||
|             name="Self Cleaning 56", |             name="Self Cleaning 56", | ||||||
|  |             icon="mdi:air-filter", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="self_clean_56", |             translation_key="self_clean_56", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.selfCleaningStatus", |             key="settings.selfCleaningStatus", | ||||||
|             name="Self Cleaning", |             name="Self Cleaning", | ||||||
|  |             icon="mdi:air-filter", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="self_clean", |             translation_key="self_clean", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.silentSleepStatus", |             key="settings.silentSleepStatus", | ||||||
|             name="Silent Sleep", |             name="Silent Sleep", | ||||||
|  |             icon="mdi:bed", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="silent_mode", |             translation_key="silent_mode", | ||||||
|         ), |         ), | ||||||
| @ -314,10 +323,18 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | |||||||
|  |  | ||||||
|         if descriptions := SWITCHES.get(device.appliance_type): |         if descriptions := SWITCHES.get(device.appliance_type): | ||||||
|             for description in descriptions: |             for description in descriptions: | ||||||
|                 if ( |                 if description.entity_category == EntityCategory.CONFIG: | ||||||
|                     device.get(description.key) is not None |                     if description.key not in device.available_settings: | ||||||
|                     or description.key in device.available_settings |                         continue | ||||||
|  |                 else: | ||||||
|  |                     if not any( | ||||||
|  |                         [ | ||||||
|  |                             device.get(description.key) is not None, | ||||||
|  |                             description.turn_on_key in list(device.commands), | ||||||
|  |                             description.turn_off_key in list(device.commands), | ||||||
|  |                         ] | ||||||
|                     ): |                     ): | ||||||
|  |                         continue | ||||||
|                 appliances.extend( |                 appliances.extend( | ||||||
|                     [HonSwitchEntity(hass, coordinator, entry, device, description)] |                     [HonSwitchEntity(hass, coordinator, entry, device, description)] | ||||||
|                 ) |                 ) | ||||||
| @ -379,3 +396,11 @@ class HonSwitchEntity(HonEntity, SwitchEntity): | |||||||
|             await self.coordinator.async_refresh() |             await self.coordinator.async_refresh() | ||||||
|         else: |         else: | ||||||
|             await self._device.commands[self.entity_description.turn_off_key].send() |             await self._device.commands[self.entity_description.turn_off_key].send() | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def available(self) -> bool: | ||||||
|  |         """Return True if entity is available.""" | ||||||
|  |         if self.entity_category == EntityCategory.CONFIG: | ||||||
|  |             return super().available | ||||||
|  |         else: | ||||||
|  |             return super().available and self._device.get("remoteCtrValid") == "1" | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								info.md
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								info.md
									
									
									
									
									
								
							| @ -29,6 +29,7 @@ Support was confirmed for these models. If a supported model is missing, please | |||||||
| - Candy CIS633SCTTWIFI | - Candy CIS633SCTTWIFI | ||||||
| - Haier XIB 3B2SFS-80 | - Haier XIB 3B2SFS-80 | ||||||
| - Haier XIB 6B2D3FB | - Haier XIB 6B2D3FB | ||||||
|  | - Hoover HSOT3161WG | ||||||
|  |  | ||||||
| ## Supported Languages | ## Supported Languages | ||||||
| Translation of internal names like programs are available for all languages which are official supported by the hOn app: | Translation of internal names like programs are available for all languages which are official supported by the hOn app: | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	