From 5f9dbef4fc74e99fe04a733bbd6a07e8ba200fd1 Mon Sep 17 00:00:00 2001 From: Andre Basche Date: Sun, 16 Apr 2023 21:46:17 +0200 Subject: [PATCH] Add dishwasher #21 --- README.md | 3 +- custom_components/hon/binary_sensor.py | 28 +++++ custom_components/hon/manifest.json | 2 +- custom_components/hon/number.py | 15 +++ custom_components/hon/select.py | 8 ++ custom_components/hon/sensor.py | 64 ++++++++++++ custom_components/hon/switch.py | 61 +++++++++-- custom_components/hon/translations/en.json | 116 +++++++++++++++++++++ 8 files changed, 285 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 858567f..5b19aee 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,12 @@ [![Home Assistant installs](https://img.shields.io/badge/dynamic/json?color=blue&label=usage&suffix=%20installs&cacheSeconds=15600&url=https://analytics.home-assistant.io/custom_integrations.json&query=$.hon.total)](https://analytics.home-assistant.io/) Home Assistant integration for Haier hOn: support for Haier/Candy/Hoover home appliances like washing machines. ## Supported Appliances +- Washing Machine - Tumble Dryer - Washer Dryer -- Washing Machine - Oven - Hob +- Dish Washer ## 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) diff --git a/custom_components/hon/binary_sensor.py b/custom_components/hon/binary_sensor.py index b119722..9b3202c 100644 --- a/custom_components/hon/binary_sensor.py +++ b/custom_components/hon/binary_sensor.py @@ -159,6 +159,34 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { on_value="0", ), ), + "DW": ( + HonBinarySensorEntityDescription( + key="saltStatus", + name="Salt", + device_class=BinarySensorDeviceClass.PROBLEM, + on_value="1", + icon="mdi:shaker-outline", + ), + HonBinarySensorEntityDescription( + key="rinseAidStatus", + name="Rinse Aid", + device_class=BinarySensorDeviceClass.PROBLEM, + on_value="1", + icon="mdi:spray-bottle", + ), + HonBinarySensorEntityDescription( + key="attributes.lastConnEvent.category", + name="Connection", + device_class=BinarySensorDeviceClass.CONNECTIVITY, + on_value="CONNECTED", + ), + HonBinarySensorEntityDescription( + key="doorStatus", + name="Door", + device_class=BinarySensorDeviceClass.DOOR, + on_value="1", + ), + ), } diff --git a/custom_components/hon/manifest.json b/custom_components/hon/manifest.json index 1d1aba5..8ad79ae 100644 --- a/custom_components/hon/manifest.json +++ b/custom_components/hon/manifest.json @@ -7,5 +7,5 @@ "iot_class": "cloud_polling", "issue_tracker": "https://github.com/Andre0512/hon/issues", "requirements": ["pyhOn==0.8.0b5"], - "version": "0.6.0-beta.4" + "version": "0.6.0-beta.5" } diff --git a/custom_components/hon/number.py b/custom_components/hon/number.py index 67f8045..1e5e4fc 100644 --- a/custom_components/hon/number.py +++ b/custom_components/hon/number.py @@ -120,6 +120,21 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { icon="mdi:timelapse", ), ), + "DW": ( + NumberEntityDescription( + key="startProgram.delayTime", + name="Delay time", + icon="mdi:timer-plus", + entity_category=EntityCategory.CONFIG, + native_unit_of_measurement=UnitOfTime.MINUTES, + ), + NumberEntityDescription( + key="startProgram.waterHard", + name="Water hard", + icon="mdi:water", + entity_category=EntityCategory.CONFIG, + ), + ), } diff --git a/custom_components/hon/select.py b/custom_components/hon/select.py index cb3e640..cd9849d 100644 --- a/custom_components/hon/select.py +++ b/custom_components/hon/select.py @@ -84,6 +84,14 @@ SELECTS = { translation_key="programs", ), ), + "DW": ( + SelectEntityDescription( + key="startProgram.program", + name="Program", + entity_category=EntityCategory.CONFIG, + translation_key="programs_dw", + ), + ), } diff --git a/custom_components/hon/sensor.py b/custom_components/hon/sensor.py index 729ba93..d90b24d 100644 --- a/custom_components/hon/sensor.py +++ b/custom_components/hon/sensor.py @@ -21,6 +21,7 @@ from homeassistant.const import ( from homeassistant.core import callback from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.typing import StateType +from homeassistant.const import PERCENTAGE from .const import DOMAIN from .hon import HonCoordinator, HonEntity @@ -237,6 +238,69 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { ), SensorEntityDescription(key="errors", name="Error", icon="mdi:math-log"), ), + "DW": ( + SensorEntityDescription( + key="startProgram.ecoIndex", + name="Eco Index", + icon="mdi:sprout", + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.CONFIG, + ), + SensorEntityDescription( + key="startProgram.waterEfficiency", + name="Water Efficiency", + icon="mdi:water", + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.CONFIG, + ), + SensorEntityDescription( + key="startProgram.waterSaving", + name="Water Saving", + icon="mdi:water-percent", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=PERCENTAGE, + entity_category=EntityCategory.CONFIG, + ), + SensorEntityDescription( + key="startProgram.temp", + name="Temperature", + icon="mdi:thermometer", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + entity_category=EntityCategory.CONFIG, + ), + SensorEntityDescription( + key="startProgram.energyLabel", + name="Energy Label", + icon="mdi:lightning-bolt-circle", + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.CONFIG, + ), + SensorEntityDescription( + key="startProgram.remainingTime", + name="Time", + icon="mdi:timer", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTime.MINUTES, + entity_category=EntityCategory.CONFIG, + ), + SensorEntityDescription( + key="machMode", + name="Machine Status", + icon="mdi:information", + translation_key="mode_dw", + ), + SensorEntityDescription( + key="errors", name="Error", icon="mdi:math-log", translation_key="errors" + ), + SensorEntityDescription( + key="remainingTimeMM", + name="Remaining Time", + icon="mdi:timer", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTime.MINUTES, + ), + ), } diff --git a/custom_components/hon/switch.py b/custom_components/hon/switch.py index b2dcc0b..08ab8ea 100644 --- a/custom_components/hon/switch.py +++ b/custom_components/hon/switch.py @@ -1,5 +1,4 @@ import logging - from dataclasses import dataclass from typing import Any @@ -90,6 +89,51 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { turn_off_key="resumeProgram", ), ), + "DW": ( + HonSwitchEntityDescription( + key="active", + name="Dish Washer", + icon="mdi:dishwasher", + turn_on_key="startProgram", + turn_off_key="stopProgram", + ), + HonSwitchEntityDescription( + key="startProgram.extraDry", + name="Extra Dry", + icon="mdi:hair-dryer", + entity_category=EntityCategory.CONFIG, + ), + HonSwitchEntityDescription( + key="startProgram.halfLoad", + name="Half Load", + icon="mdi:fraction-one-half", + entity_category=EntityCategory.CONFIG, + ), + HonSwitchEntityDescription( + key="startProgram.openDoor", + name="Open Door", + icon="mdi:door-open", + entity_category=EntityCategory.CONFIG, + ), + HonSwitchEntityDescription( + key="startProgram.threeInOne", + name="Three in One", + icon="mdi:numeric-3-box-outline", + entity_category=EntityCategory.CONFIG, + ), + HonSwitchEntityDescription( + key="startProgram.ecoExpress", + name="Eco Express", + icon="mdi:sprout", + entity_category=EntityCategory.CONFIG, + ), + HonSwitchEntityDescription( + key="startProgram.addDish", + name="Add Dish", + icon="mdi:silverware-fork-knife", + entity_category=EntityCategory.CONFIG, + ), + ), } @@ -139,13 +183,6 @@ class HonSwitchEntity(HonEntity, SwitchEntity): self.entity_description = description self._attr_unique_id = f"{super().unique_id}{description.key}" - def available(self) -> bool: - if self.entity_category == EntityCategory.CONFIG: - return ( - self._device.settings[self.entity_description.key].typology != "fixed" - ) - return True - @property def is_on(self) -> bool | None: """Return True if entity is on.""" @@ -161,7 +198,9 @@ class HonSwitchEntity(HonEntity, SwitchEntity): async def async_turn_on(self, **kwargs: Any) -> None: if self.entity_category == EntityCategory.CONFIG: setting = self._device.settings[self.entity_description.key] - setting.value = setting.max + setting.value = ( + setting.max if isinstance(setting, HonParameterRange) else "1" + ) self.async_write_ha_state() else: await self._device.commands[self.entity_description.turn_on_key].send() @@ -169,7 +208,9 @@ class HonSwitchEntity(HonEntity, SwitchEntity): async def async_turn_off(self, **kwargs: Any) -> None: if self.entity_category == EntityCategory.CONFIG: setting = self._device.settings[self.entity_description.key] - setting.value = setting.min + setting.value = ( + setting.min if isinstance(setting, HonParameterRange) else "0" + ) self.async_write_ha_state() else: await self._device.commands[self.entity_description.turn_off_key].send() diff --git a/custom_components/hon/translations/en.json b/custom_components/hon/translations/en.json index cafd100..6225013 100644 --- a/custom_components/hon/translations/en.json +++ b/custom_components/hon/translations/en.json @@ -72,6 +72,16 @@ "13": "Ready to Store H-2", "14": "Extra Dry H-3" } + }, + "mode_dw": { + "state": { + "0": "Disconnected", + "1": "Ready", + "2": "Running", + "3": "Delayed start", + "5": "Delayed start cancelled", + "7": "Finished" + } } }, "select": { @@ -461,6 +471,112 @@ "iot_standard_melting": "Melting", "iot_standard_simmering": "Simmering" } + }, + "programs_dw": { + "state": { + "59_min": "Rapid 59'", + "auto_care": "Auto Care", + "auto_care_soil": "Auto Care", + "auto_hygiene": "Auto Hygiene", + "auto_plus": "AutoPlus", + "auto_rapid": "Auto Rapid", + "auto_sensor": "Auto Sensor", + "auto_sensor_soil": "Auto Sensor", + "auto_universal": "Auto Universal 50 - 60°C", + "auto_universal_plus": "Auto Universal+ 65 - 75°C", + "auto_universal_plus_soil": "Auto Universal+ 65 - 75°C", + "auto_universal_soil": "Auto Universal 50 - 60°C", + "auto_wash": "Auto Wash", + "auto_wash_soil": "Auto Wash", + "classe_a_59": "A Wash 59' 65°C", + "delicate": "Delicate 45°C", + "dishwasher_care": "Limescale cleaning", + "eco": "Eco", + "eco_asynch": "Eco 45°C", + "eco_bldc": "Eco 45°C", + "eco_synch": "Eco 45°C", + "gentle_wash": "Gentle wash", + "glass": "Glass", + "glassware": "Glassware 45°C", + "glass_care": "Glass Care", + "hygiene": "Hygiene", + "hygiene_plus": "Hygiene+ 75°C", + "intensive": "Intensive", + "intensive_rapid": "Intensive Rapid", + "iot_auto_sensor": "Auto Sensor", + "iot_auto_universal_soil": "Auto Universal 50 - 60°C", + "iot_auto_wash_soil": "Auto Wash", + "iot_baby_care": "Baby Care", + "iot_breakfast": "Breakfast", + "iot_checkup": "Check-Up", + "iot_china_crystals": "China Crystals", + "iot_classe_a_59": "Rapid 59'", + "iot_cocktail_glasses": "Coktail Glasses", + "iot_cocktail_glasses_soil": "Coktail Glasses", + "iot_daily_care": "Daily Care", + "iot_daily_care_soil": "Daily Care", + "iot_delicate": "Delicate 45°C", + "iot_dinner_for_two": "Dinner for 2", + "iot_dinner_for_two_soil": "Dinner for 2", + "iot_dreft_quick_cycle": "Dreft Quick", + "iot_eco_asynch": "Eco 45°C", + "iot_eco_bldc": "Eco 45°C", + "iot_eco_synch": "Eco 45°C", + "iot_extra_hygiene": "Extra Hygiene", + "iot_fairy_quick_cycle": "Fairy Short", + "iot_happy_hour": "Happy Hour", + "iot_jar_quick_cycle": "Jar Quick", + "iot_party": "Party", + "iot_party_soil": "Party", + "iot_pizza_menu": "Pizza Menu", + "iot_pizza_menu_soil": "Pizza Menu", + "iot_plastic_tupperware": "Plastic & Tupperware", + "iot_porcelain": "Porcelain", + "iot_pot_and_pans": "Pot & Pans", + "iot_pot_and_pans_soil": "Pot & Pans", + "iot_power_mix_wash": "Power Mix Wash", + "iot_power_mix_wash_soil": "Power Mix Wash", + "iot_prewash": "Pre-wash", + "iot_pyrex_and_glassware": "Pyrex & Glassware", + "iot_rapid_29": "Rapid 29'", + "iot_rapid_39": "Rapid 39' 60°C", + "iot_single": "Single", + "iot_steam": "Steam 75°C", + "iot_super_flash": "Super Flash", + "iot_super_wash": "Super Wash", + "iot_turbopower": "TurboPower", + "iot_universal": "Universal 60°C", + "iot_wok_grids_maxi_pans": "Special Pans (Wok, Grids & Maxi Pans)", + "iot_wok_grids_maxi_pans_soil": "Special Pans (Wok, Grids & Maxi Pans)", + "iot_yes_quick_cycle": "Yes Quick", + "night": "Night 55°C", + "prewash": "Pre-wash", + "rapid_20": "Rapid 20'", + "rapid_24": "Rapid 24'", + "rapid_29": "Rapid 29' 50°C", + "rapid_35": "Wash&Dry 35'", + "rapid_39": "Rapid 39' 60°C", + "rapid_49": "Rapid 49'", + "rapid_59": "Rapid 59'", + "sanitising": "Sanitising", + "silence": "Silence", + "silent": "Silent", + "silent_care": "Silent Care", + "smart_ai": "Smart AI", + "smart_ai_pro": "Smart AI Pro", + "smart_ai_rapid": "Smart AI Rapid", + "special": "Special", + "special_pw_prz": "Special", + "steam": "Steam 75°C", + "steam_plus": "Steam Plus 75°C", + "total_care": "Total Care 50°C", + "ultra_silence": "Ultra Silence 55°C", + "ultra_silent": "Ultra Silent 55°C", + "universal": "Universal 60°C", + "universal_plus": "Universal Plus 70°C", + "zone_wash": "Flex Zone Wash", + "zoom_39": "Zoom 39 min" + } } } }