Compare commits

...

5 Commits

Author SHA1 Message Date
f89e2361df Use wm program translation keys 2023-03-11 00:30:38 +01:00
075d34b5e2 Fix many bugs 2023-03-08 23:00:55 +01:00
88c76b8056 Add contribution instructions to readme 2023-03-06 18:41:13 +01:00
03a1e40b6e Rename repo 2023-03-06 13:41:58 +01:00
9d8b17b2cf Add sensors, renamed repo 2023-03-06 00:20:52 +01:00
18 changed files with 508 additions and 120 deletions

17
.github/workflows/hacs_check.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: HACS Action
on:
push:
pull_request:
schedule:
- cron: "0 0 * * *"
jobs:
hacs:
name: HACS Action
runs-on: "ubuntu-latest"
steps:
- name: HACS Action
uses: "hacs/action@main"
with:
category: "integration"

14
.github/workflows/validate.yml vendored Normal file
View File

@ -0,0 +1,14 @@
name: Validate with hassfest
on:
push:
pull_request:
schedule:
- cron: '0 0 * * *'
jobs:
validate:
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v3"
- uses: "home-assistant/actions/hassfest@master"

View File

@ -1,10 +1,13 @@
# hOn # Haier hOn
Home Assistant component supporting hOn cloud. [![hacs_badge](https://img.shields.io/badge/HACS-Custom-41BDF5.svg)](https://github.com/hacs/integration)
Home Assistant component supporting devices of Haier's mobile app **hOn**.
## Installation ## Installation
1. Installing via HACS #### Installing via HACS
1. You need to have installed [HACS](https://hacs.xyz/)
2. Go to HACS->Integrations 2. Go to HACS->Integrations
3. Add this repo into your HACS custom repositories 3. Add this repo (`https://github.com/Andre0512/hon.git`) into your HACS custom repositories
4. Search for Haier hOn and Download it 4. Search for Haier hOn and Download it
5. Restart your HomeAssistant 5. Restart your HomeAssistant
6. Go to Settings->Devices & Services 6. Go to Settings->Devices & Services
@ -13,6 +16,51 @@ Home Assistant component supporting hOn cloud.
9. Search for Haier hOn 9. Search for Haier hOn
10. Type your username used in the hOn App and hit submit 10. Type your username used in the hOn App and hit submit
## Contribute
Any kind of contribution is welcome!
#### Add appliances or additional attributes
1. Install [pyhOn](https://github.com/Andre0512/pyhOn)
```commandline
$ pip install pyhOn
```
2. Use the commandline tool to read out all appliance data from your account
```commandline
$ pyhOn
User for hOn account: user.name@example.com
Password for hOn account: ********
========== WM - Washing Machine ==========
commands:
pauseProgram: pauseProgram command
resumeProgram: resumeProgram command
startProgram: startProgram command
stopProgram: stopProgram command
data:
actualWeight: 0
airWashTempLevel: 0
airWashTime: 0
antiAllergyStatus: 0
...
```
3. Fork this repository and clone it to your local machine
4. Add the keys of the attributes you'd like to have as `EntityDescription` into this Repository
_Example: Add pause button_
```python
BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = {
"WM": ( # WM is the applianceTypeName
ButtonEntityDescription(
key="pauseProgram", # key from pyhOn
name="Pause Program", # name in home assistant
icon="mdi:pause", # icon in home assistant
...
),
...
```
5. Create a [pull request](https://github.com/Andre0512/hon/pulls)
#### Tips and Tricks
- If you want to have some states humanreadable, have a look at the `translation_key` parameter of the `EntityDescription`
- If you need to implement some more logic, create a pull request to the underlying library. There we collect special requirements in the `appliances` directory.
## Supported Appliances ## Supported Appliances
- Washing Machine - Washing Machine

View File

@ -1,10 +0,0 @@
{
"domain": "hon",
"name": "hOn",
"config_flow": true,
"version": "0.1.0",
"codeowners": ["@Andre0512"],
"iot_class": "cloud_polling",
"requirements": ["pyhOn==0.2.4"],
"documentation": "https://github.com/Andre0512/hOn/"
}

View File

@ -1,34 +0,0 @@
{
"config": {
"step": {
"user": {
"title": "hOn",
"description": "Please enters your hOn credentials",
"data": {
"email": "Email Address",
"password": "Password"
}
}
}
},
"entity": {
"sensor": {
"mode": {
"state": {
"1": "Ready",
"2": "Running",
"5": "Scheduled",
"6": "Error",
"7": "Finished"
}
},
"errors": {
"state": {
"00": "No error",
"100000000000": "E2: Check if the door is closed",
"8000000000000": "E4: Check the water supply"
}
}
}
}
}

View File

@ -26,16 +26,16 @@ class HonBinarySensorEntityDescription(HonBinarySensorEntityDescriptionMixin, Bi
BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
"WM": ( "WM": (
HonBinarySensorEntityDescription( HonBinarySensorEntityDescription(
key="lastConnEvent.category", key="attributes.lastConnEvent.category",
name="Connection", name="Connection",
device_class=BinarySensorDeviceClass.CONNECTIVITY, device_class=BinarySensorDeviceClass.CONNECTIVITY,
on_value="CONNECTED", on_value="CONNECTED",
), ),
HonBinarySensorEntityDescription( HonBinarySensorEntityDescription(
key="doorLockStatus", key="doorLockStatus",
name="Door Locked", name="Door",
device_class=BinarySensorDeviceClass.DOOR, device_class=BinarySensorDeviceClass.DOOR,
on_value="1", on_value="0",
), ),
) )
} }
@ -53,9 +53,9 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
if descriptions := BINARY_SENSORS.get(device.appliance_type_name): if descriptions := BINARY_SENSORS.get(device.appliance_type):
for description in descriptions: for description in descriptions:
if not device.data.get(description.key): if not device.get(description.key):
_LOGGER.info("Can't setup %s", description.key) _LOGGER.info("Can't setup %s", description.key)
continue continue
appliances.extend([ appliances.extend([
@ -78,9 +78,9 @@ class HonBinarySensorEntity(HonEntity, BinarySensorEntity):
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
return self._device.data.get(self.entity_description.key, "") == self.entity_description.on_value return self._device.get(self.entity_description.key, "") == self.entity_description.on_value
@callback @callback
def _handle_coordinator_update(self): def _handle_coordinator_update(self):
self._attr_native_value = self._device.data.get(self.entity_description.key, "") self._attr_native_value = self._device.get(self.entity_description.key, "") == self.entity_description.on_value
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -9,16 +9,16 @@ from .hon import HonCoordinator, HonEntity
BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = { BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = {
"WM": ( "WM": (
ButtonEntityDescription( # ButtonEntityDescription(
key="pauseProgram", # key="pauseProgram",
name="Pause Program", # name="Pause Program",
icon="mdi:pause", # icon="mdi:pause",
), # ),
ButtonEntityDescription( # ButtonEntityDescription(
key="resumeProgram", # key="resumeProgram",
name="Resume Program", # name="Resume Program",
icon="mdi:play-pause", # icon="mdi:play-pause",
), # ),
), ),
} }
@ -35,7 +35,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
if descriptions := BUTTONS.get(device.appliance_type_name): if descriptions := BUTTONS.get(device.appliance_type):
for description in descriptions: for description in descriptions:
if not device.commands.get(description.key): if not device.commands.get(description.key):
continue continue

View File

@ -11,7 +11,6 @@ _LOGGER = logging.getLogger(__name__)
class HonFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): class HonFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1 VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL

View File

View File

@ -28,10 +28,10 @@ class HonEntity(CoordinatorEntity):
def device_info(self): def device_info(self):
return DeviceInfo( return DeviceInfo(
identifiers={(DOMAIN, self._device.mac_address)}, identifiers={(DOMAIN, self._device.mac_address)},
manufacturer=self._device.brand, manufacturer=self._device.get("brand", ""),
name=self._device.nick_name if self._device.nick_name else self._device.model_name, name=self._device.nick_name if self._device.nick_name else self._device.model_name,
model=self._device.model_name, model=self._device.model_name,
sw_version=self._device.fw_version, sw_version=self._device.get("fwVersion", ""),
) )

View File

@ -0,0 +1,12 @@
{
"domain": "hon",
"name": "Haier hOn",
"codeowners": ["@Andre0512"],
"config_flow": true,
"documentation": "https://github.com/Andre0512/hon/",
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/Andre0512/hon/issues",
"requirements": ["pyhOn==0.3.4"],
"version": "0.2.1"
}

View File

@ -20,19 +20,20 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
NumberEntityDescription( NumberEntityDescription(
key="startProgram.delayTime", key="startProgram.delayTime",
name="Delay Time", name="Delay Time",
icon="mdi:timer", icon="mdi:timer-plus",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.MINUTES native_unit_of_measurement=UnitOfTime.MINUTES
), ),
NumberEntityDescription( NumberEntityDescription(
key="startProgram.rinseIterations", key="startProgram.rinseIterations",
name="Rinse Iterations", name="Rinse Iterations",
icon="mdi:rotate-right",
entity_category=EntityCategory.CONFIG entity_category=EntityCategory.CONFIG
), ),
NumberEntityDescription( NumberEntityDescription(
key="startProgram.mainWashTime", key="startProgram.mainWashTime",
name="Main Wash Time", name="Main Wash Time",
icon="mdi:timer", icon="mdi:clock-start",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.MINUTES native_unit_of_measurement=UnitOfTime.MINUTES
), ),
@ -52,7 +53,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
if descriptions := NUMBERS.get(device.appliance_type_name): if descriptions := NUMBERS.get(device.appliance_type):
for description in descriptions: for description in descriptions:
appliances.extend([ appliances.extend([
HonNumberEntity(hass, coordinator, entry, device, description)] HonNumberEntity(hass, coordinator, entry, device, description)]
@ -66,6 +67,7 @@ class HonNumberEntity(HonEntity, NumberEntity):
super().__init__(hass, entry, coordinator, device) super().__init__(hass, entry, coordinator, device)
self._coordinator = coordinator self._coordinator = coordinator
self._device = device
self._data = device.settings[description.key] self._data = device.settings[description.key]
self.entity_description = description self.entity_description = description
self._attr_unique_id = f"{super().unique_id}{description.key}" self._attr_unique_id = f"{super().unique_id}{description.key}"
@ -77,18 +79,18 @@ class HonNumberEntity(HonEntity, NumberEntity):
@property @property
def native_value(self) -> float | None: def native_value(self) -> float | None:
return self._data.value return self._device.get(self.entity_description.key)
async def async_set_native_value(self, value: float) -> None: async def async_set_native_value(self, value: float) -> None:
self._data.value = value self._device.settings[self.entity_description.key].value = value
await self.coordinator.async_request_refresh() await self.coordinator.async_request_refresh()
@callback @callback
def _handle_coordinator_update(self): def _handle_coordinator_update(self):
self._data = self._device.settings[self.entity_description.key] setting = self._device.settings[self.entity_description.key]
if isinstance(self._data, HonParameterRange): if isinstance(setting, HonParameterRange):
self._attr_native_max_value = self._data.max self._attr_native_max_value = setting.max
self._attr_native_min_value = self._data.min self._attr_native_min_value = setting.min
self._attr_native_step = self._data.step self._attr_native_step = setting.step
self._attr_native_value = self._data.value self._attr_native_value = setting.value
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -1,4 +1,3 @@
"""Support for Tuya select."""
from __future__ import annotations from __future__ import annotations
from pyhon import HonConnection from pyhon import HonConnection
@ -11,10 +10,9 @@ from homeassistant.const import UnitOfTemperature, REVOLUTIONS_PER_MINUTE
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity import EntityCategory
from .const import DOMAIN
from .hon import HonEntity, HonCoordinator from .hon import HonEntity, HonCoordinator
DOMAIN = "hon"
SELECTS = { SELECTS = {
"WM": ( "WM": (
SelectEntityDescription( SelectEntityDescription(
@ -33,8 +31,9 @@ SELECTS = {
), ),
SelectEntityDescription( SelectEntityDescription(
key="startProgram.program", key="startProgram.program",
name="Programme", name="Program",
entity_category=EntityCategory.CONFIG entity_category=EntityCategory.CONFIG,
translation_key="programs"
), ),
) )
} }
@ -52,9 +51,9 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
if descriptions := SELECTS.get(device.appliance_type_name): if descriptions := SELECTS.get(device.appliance_type):
for description in descriptions: for description in descriptions:
if not device.data.get(description.key): if not device.get(description.key):
continue continue
appliances.extend([ appliances.extend([
HonSelectEntity(hass, coordinator, entry, device, description)] HonSelectEntity(hass, coordinator, entry, device, description)]
@ -68,32 +67,31 @@ class HonSelectEntity(HonEntity, SelectEntity):
self._coordinator = coordinator self._coordinator = coordinator
self._device = device self._device = device
self._data = device.settings[description.key]
self.entity_description = description self.entity_description = description
self._attr_unique_id = f"{super().unique_id}{description.key}" self._attr_unique_id = f"{super().unique_id}{description.key}"
if not isinstance(self._data, HonParameterFixed): if not isinstance(self._device.settings[description.key], HonParameterFixed):
self._attr_options: list[str] = self._data.values self._attr_options: list[str] = device.settings[description.key].values
else: else:
self._attr_options = [self._data.value] self._attr_options: list[str] = [device.settings[description.key].value]
@property @property
def current_option(self) -> str | None: def current_option(self) -> str | None:
value = self._data.value value = self._device.settings[self.entity_description.key].value
if value is None or value not in self._attr_options: if value is None or value not in self._attr_options:
return None return None
return value return value
async def async_select_option(self, option: str) -> None: async def async_select_option(self, option: str) -> None:
self._data.value = option self._device.settings[self.entity_description.key].value = option
await self.coordinator.async_request_refresh() await self.coordinator.async_request_refresh()
@callback @callback
def _handle_coordinator_update(self): def _handle_coordinator_update(self):
self._data = self._device.settings[self.entity_description.key] setting = self._device.settings[self.entity_description.key]
if not isinstance(self._data, HonParameterFixed): if not isinstance(self._device.settings[self.entity_description.key], HonParameterFixed):
self._attr_options: list[str] = self._data.values self._attr_options: list[str] = setting.values
else: else:
self._attr_options = [self._data.value] self._attr_options = [setting.value]
self._attr_native_value = self._data.value self._attr_native_value = setting.value
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -9,7 +9,7 @@ from homeassistant.components.sensor import (
SensorEntityDescription, SensorEntityDescription,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import UnitOfEnergy, UnitOfVolume, UnitOfMass, UnitOfPower from homeassistant.const import UnitOfEnergy, UnitOfVolume, UnitOfMass, UnitOfPower, UnitOfTime
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 homeassistant.helpers.typing import StateType
@ -65,17 +65,30 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
), ),
SensorEntityDescription( SensorEntityDescription(
key="machMode", key="machMode",
name="Machine Last Status", name="Machine Status",
icon="mdi:information", icon="mdi:information",
translation_key="mode" translation_key="mode"
), ),
SensorEntityDescription( SensorEntityDescription(
key="errors", key="errors",
name="Last Error", name="Error",
icon="mdi:math-log", icon="mdi:math-log",
translation_key="errors" translation_key="errors"
), ),
SensorEntityDescription(
key="remainingTimeMM",
name="Remaining Time",
icon="mdi:timer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
),
SensorEntityDescription(
key="spinSpeed",
name="Spin Speed",
icon="mdi:timer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
),
) )
} }
@ -92,9 +105,9 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
if descriptions := SENSORS.get(device.appliance_type_name): if descriptions := SENSORS.get(device.appliance_type):
for description in descriptions: for description in descriptions:
if not device.data.get(description.key): if not device.get(description.key):
continue continue
appliances.extend([ appliances.extend([
HonSensorEntity(hass, coordinator, entry, device, description)] HonSensorEntity(hass, coordinator, entry, device, description)]
@ -114,9 +127,9 @@ class HonSensorEntity(HonEntity, SensorEntity):
@property @property
def native_value(self) -> StateType: def native_value(self) -> StateType:
return self._device.data.get(self.entity_description.key, "") return self._device.get(self.entity_description.key, "")
@callback @callback
def _handle_coordinator_update(self): def _handle_coordinator_update(self):
self._attr_native_value = self._device.data.get(self.entity_description.key, "") self._attr_native_value = self._device.get(self.entity_description.key, "")
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -1,13 +1,11 @@
from collections.abc import Callable, Coroutine
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any from typing import Any
from pyhon import HonConnection
from pyhon.device import HonDevice
from homeassistant.components.switch import SwitchEntityDescription, SwitchEntity from homeassistant.components.switch import SwitchEntityDescription, SwitchEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory
from pyhon import HonConnection
from pyhon.device import HonDevice
from .const import DOMAIN from .const import DOMAIN
from .hon import HonCoordinator, HonEntity from .hon import HonCoordinator, HonEntity
@ -29,20 +27,29 @@ class HonSwitchEntityDescription(HonSwitchEntityDescriptionMixin,
SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
"WM": ( "WM": (
HonSwitchEntityDescription( HonSwitchEntityDescription(
key="startProgram", key="active",
name="Start Program", name="Washing Machine",
icon="mdi:play", icon="mdi:washing-machine",
turn_on_key="startProgram", turn_on_key="startProgram",
turn_off_key="stopProgram", turn_off_key="stopProgram",
), ),
HonSwitchEntityDescription(
key="pause",
name="Pause Washing Machine",
icon="mdi:pause",
turn_on_key="pauseProgram",
turn_off_key="resumeProgram",
),
HonSwitchEntityDescription( HonSwitchEntityDescription(
key="startProgram.delayStatus", key="startProgram.delayStatus",
name="Delay Status", name="Delay Status",
icon="mdi:timer-check",
entity_category=EntityCategory.CONFIG entity_category=EntityCategory.CONFIG
), ),
HonSwitchEntityDescription( HonSwitchEntityDescription(
key="startProgram.haier_SoakPrewashSelection", key="startProgram.haier_SoakPrewashSelection",
name="Soak Prewash Selection", name="Soak Prewash Selection",
icon="mdi:tshirt-crew",
entity_category=EntityCategory.CONFIG entity_category=EntityCategory.CONFIG
), ),
), ),
@ -61,9 +68,9 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
if descriptions := SWITCHES.get(device.appliance_type_name): if descriptions := SWITCHES.get(device.appliance_type):
for description in descriptions: for description in descriptions:
if device.data.get(description.key) is not None or device.commands.get(description.key) is not None: if device.get(description.key) is not None or device.commands.get(description.key) is not None:
appliances.extend([ appliances.extend([
HonSwitchEntity(hass, coordinator, entry, device, description)] HonSwitchEntity(hass, coordinator, entry, device, description)]
) )
@ -83,7 +90,7 @@ class HonSwitchEntity(HonEntity, SwitchEntity):
def available(self) -> bool: def available(self) -> bool:
if self.entity_category == EntityCategory.CONFIG: if self.entity_category == EntityCategory.CONFIG:
return self._device.settings[self.entity_description.key].typology == "fixed" return self._device.settings[self.entity_description.key].typology != "fixed"
return True return True
@property @property
@ -92,7 +99,7 @@ class HonSwitchEntity(HonEntity, SwitchEntity):
if self.entity_category == EntityCategory.CONFIG: if self.entity_category == EntityCategory.CONFIG:
setting = self._device.settings[self.entity_description.key] setting = self._device.settings[self.entity_description.key]
return setting.value == "1" or hasattr(setting, "min") and setting.value != setting.min return setting.value == "1" or hasattr(setting, "min") and setting.value != setting.min
return self._device.data.get(self.entity_description.key, "") return self._device.get(self.entity_description.key, False)
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
if self.entity_category == EntityCategory.CONFIG: if self.entity_category == EntityCategory.CONFIG:

View File

@ -0,0 +1,322 @@
{
"config": {
"step": {
"user": {
"description": "Please enters your hOn credentials",
"data": {
"email": "Email Address",
"password": "Password"
}
}
}
},
"entity": {
"sensor": {
"mode": {
"state": {
"0": "Disconnected",
"1": "Ready",
"2": "Running",
"3": "Paused",
"5": "Scheduled",
"6": "Error",
"7": "Finished"
}
},
"errors": {
"state": {
"00": "No error",
"100000000000": "E2: Check if the door is closed",
"8000000000000": "E4: Check the water supply"
}
}
},
"select": {
"programs": {
"state": {
"PROGRAMS.WM_WD.20_DEGREES_COLOURED_COTTONS": "20° Colored and Cottons",
"PROGRAMS.WM_WD.20_DEGREES_NEW_ENERGY_LABEL": "20°C",
"PROGRAMS.WM_WD.ACTIVE_STEAM": "Steam",
"PROGRAMS.WM_WD.ACTIVE_WASH": "Active Wash",
"PROGRAMS.WM_WD.ACTIVE_WASH_STEAM": "Active Wash + Steam",
"PROGRAMS.WM_WD.ALLERGY_CARE": "Allergy Care",
"PROGRAMS.WM_WD.ALLERGY_CARE_PRO": "Allergy Care Pro",
"PROGRAMS.WM_WD.ALL_IN_ONE_49": "All in One 49'",
"PROGRAMS.WM_WD.ALL_IN_ONE_59": "All in One 59'",
"PROGRAMS.WM_WD.ALL_IN_ONE_59_STEAM": "Active Wash + Steam",
"PROGRAMS.WM_WD.AUTOCARE": "Autocare",
"PROGRAMS.WM_WD.AUTOCLEAN": "Drum Cleaning",
"PROGRAMS.WM_WD.BABY_60": "All Baby 60°C",
"PROGRAMS.WM_WD.CARE_14": "Rapid Care 14'",
"PROGRAMS.WM_WD.CARE_30": "Rapid Care 30'",
"PROGRAMS.WM_WD.CARE_44": "Rapid Care 44'",
"PROGRAMS.WM_WD.CHECKUP": "Check-Up",
"PROGRAMS.WM_WD.COLOUR_59": "Colored 59'",
"PROGRAMS.WM_WD.COLOUR_59_STEAM": "Colored 59' + Steam",
"PROGRAMS.WM_WD.COTTONS": "Cotton",
"PROGRAMS.WM_WD.COTTONS_PREWASH": "Cottons + Prewash",
"PROGRAMS.WM_WD.COTTONS_STEAM": "Cotton + Steam",
"PROGRAMS.WM_WD.COTTON_CARE_59": "Cotton Care 59'",
"PROGRAMS.WM_WD.DELICATE_59": "Delicate 59'",
"PROGRAMS.WM_WD.DELICATE_SILK": "Delicate and Silk",
"PROGRAMS.WM_WD.DELICATE_SILK_STEAM": "Delicate and Silk + Steam",
"PROGRAMS.WM_WD.DELICATI_59": "Delicate 59'",
"PROGRAMS.WM_WD.DELICATI_59_STEAM": "Delicate 59' + Steam",
"PROGRAMS.WM_WD.DRAIN_SPIN": "Drain + Spin",
"PROGRAMS.WM_WD.EASY_IRON": "Easy Iron",
"PROGRAMS.WM_WD.ECO_40_60_NEW_ENERGY_LABEL": "Eco 40-60",
"PROGRAMS.WM_WD.EXTRA_CARE": "Extra Care",
"PROGRAMS.WM_WD.FITNESS": "Fitness Care",
"PROGRAMS.WM_WD.FITNESS_CARE": "Fitness Care",
"PROGRAMS.WM_WD.FRESH_CARE": "Fresh Care",
"PROGRAMS.WM_WD.FRESH_CARE_STEAM": "Fresh Care + Steam",
"PROGRAMS.WM_WD.HANDWASH_WOOL": "Hand Wash + Wool",
"PROGRAMS.WM_WD.HIGH_DRY": "High Heat Dry",
"PROGRAMS.WM_WD.HQD_20_DEGREES": "Cotton 20℃",
"PROGRAMS.WM_WD.HQD_ALLERGY": "Allergy Care",
"PROGRAMS.WM_WD.HQD_AUTOCLEAN": "Drum Cleaning",
"PROGRAMS.WM_WD.HQD_BABYCARE": "Baby Care",
"PROGRAMS.WM_WD.HQD_CHECKUP": "Check-Up",
"PROGRAMS.WM_WD.HQD_COTTONS": "Cotton",
"PROGRAMS.WM_WD.HQD_DELICATE": "Delicate",
"PROGRAMS.WM_WD.HQD_DELICATE_CRADLE": "Delicate",
"PROGRAMS.WM_WD.HQD_DRY": "Cotton Dry",
"PROGRAMS.WM_WD.HQD_DRY_SYNTHETICS": "Low Heat Dry",
"PROGRAMS.WM_WD.HQD_DUVET": "Duvet",
"PROGRAMS.WM_WD.HQD_ECO_40_60_DEGREES": "Eco 40-60",
"PROGRAMS.WM_WD.HQD_HANDWASH_WOOL": "Wool",
"PROGRAMS.WM_WD.HQD_I_REFRESH": "i-Refresh",
"PROGRAMS.WM_WD.HQD_MIX": "Mix",
"PROGRAMS.WM_WD.HQD_QUICK_15": "Quick 15'",
"PROGRAMS.WM_WD.HQD_QUICK_WASH_57": "Quick Wash 57'",
"PROGRAMS.WM_WD.HQD_RAPID_WASH_AND_DRY": "Wash and dry",
"PROGRAMS.WM_WD.HQD_REFRESH": "Refresh",
"PROGRAMS.WM_WD.HQD_RINSE": "Rinses",
"PROGRAMS.WM_WD.HQD_SHIRTS": "Shirts",
"PROGRAMS.WM_WD.HQD_SMART": "Smart A.I.",
"PROGRAMS.WM_WD.HQD_SPIN": "Spin",
"PROGRAMS.WM_WD.HQD_SPORT": "Sport",
"PROGRAMS.WM_WD.HQD_SUPER_FAST": "Super Fast 39'",
"PROGRAMS.WM_WD.HQD_SYNTHETIC_AND_COLOURED": "Synthetics",
"PROGRAMS.WM_WD.HYGIENE_59": "Hygiene Plus 59'",
"PROGRAMS.WM_WD.HYGIENE_60": "Hygiene 60°C",
"PROGRAMS.WM_WD.HYGIENE_PLUS_59": "Hygiene Plus 59'",
"PROGRAMS.WM_WD.HYGIENE_PLUS_59_MIN": "Hygiene Plus 59'",
"PROGRAMS.WM_WD.HYGIENE_PRO_4_MIN": "Hygiene Pro 49'",
"PROGRAMS.WM_WD.HYGIENE_PRO_49_MIN": "Hygiene Pro 49'",
"PROGRAMS.WM_WD.HYGIENE_PRO_STEAM": "Hygiene Pro + Steam",
"PROGRAMS.WM_WD.INTENSIVE_40": "Intensive 40°C",
"PROGRAMS.WM_WD.INTENSIVE_40_STEAM": "Intensive 40°C + Steam",
"PROGRAMS.WM_WD.IOT_CHECKUP": "Check-Up",
"PROGRAMS.WM_WD.IOT_DRY_AIR_REFRESH": "Air Refresh",
"PROGRAMS.WM_WD.IOT_DRY_ANTI_MITES": "Anti-mite",
"PROGRAMS.WM_WD.IOT_DRY_BABY": "Baby",
"PROGRAMS.WM_WD.IOT_DRY_BACKPACKS": "Backpacks",
"PROGRAMS.WM_WD.IOT_DRY_BATHROBE": "Bathrobes",
"PROGRAMS.WM_WD.IOT_DRY_BED_LINEN": "Bed Linen",
"PROGRAMS.WM_WD.IOT_DRY_COTTON_DRY": "Cotton Dry",
"PROGRAMS.WM_WD.IOT_DRY_CUDDLY_TOYS": "Cuddly Toys",
"PROGRAMS.WM_WD.IOT_DRY_CURTAINS": "Curtains",
"PROGRAMS.WM_WD.IOT_DRY_DEHUMIDIFIER": "Humidity Remover",
"PROGRAMS.WM_WD.IOT_DRY_DELICATES_ANTIALLERGY": "Delicates Anti-allergy",
"PROGRAMS.WM_WD.IOT_DRY_DELICATE_TABLECLOTHS": "Delicate Tablecloths",
"PROGRAMS.WM_WD.IOT_DRY_DENIM_JEANS": "Denim - Jeans",
"PROGRAMS.WM_WD.IOT_DRY_EASY_IRON_COTTON": "Easy Iron - Cotton",
"PROGRAMS.WM_WD.IOT_DRY_EASY_IRON_SYNTHETICS": "Easy Iron - Synthetics",
"PROGRAMS.WM_WD.IOT_DRY_GYM_FIT": "Gym fit - Fitness",
"PROGRAMS.WM_WD.IOT_DRY_LINGERIE": "Lingerie",
"PROGRAMS.WM_WD.IOT_DRY_MIXED_DRY": "Mixed Dry",
"PROGRAMS.WM_WD.IOT_DRY_RAPID_60_MIN_DELICATES": "Rapid 60' - Delicates",
"PROGRAMS.WM_WD.IOT_DRY_SHIRTS": "Shirts",
"PROGRAMS.WM_WD.IOT_DRY_SWIMSUITS_AND_BIKINIS": "Swimsuits and Bikinis",
"PROGRAMS.WM_WD.IOT_DRY_SYNTHETICS": "Synthetic Dry",
"PROGRAMS.WM_WD.IOT_DRY_SYNTHETIC_DRY": "Synthetic Dry",
"PROGRAMS.WM_WD.IOT_DRY_TABLECLOTHS": "Tablecloths",
"PROGRAMS.WM_WD.IOT_DRY_TECHNICAL_FABRICS": "Technical Fabrics",
"PROGRAMS.WM_WD.IOT_DRY_WARM_EMBRACE": "Warm Embrace",
"PROGRAMS.WM_WD.IOT_DRY_WOOL_DRY": "Wool Dry",
"PROGRAMS.WM_WD.IOT_WASH_AND_DRY": "Wash and dry",
"PROGRAMS.WM_WD.IOT_WASH_ANTI_MITES": "Anti-mites",
"PROGRAMS.WM_WD.IOT_WASH_ANTI_ODOR": "Anti-odour",
"PROGRAMS.WM_WD.IOT_WASH_ARIEL_CLEAN_CYCLE": "Ariel Ultimate Clean",
"PROGRAMS.WM_WD.IOT_WASH_ARIEL_COLD_CYCLE": "Ariel Cold Clean",
"PROGRAMS.WM_WD.IOT_WASH_ARIEL_FRESH_CYCLE": "Ariel Fresh Clean",
"PROGRAMS.WM_WD.IOT_WASH_BABY_SANITIZER": "Sanitizer",
"PROGRAMS.WM_WD.IOT_WASH_BABY_SANITIZER_STEAM": "Sanitiser + Steam",
"PROGRAMS.WM_WD.IOT_WASH_BACKPACKS": "Backpacks",
"PROGRAMS.WM_WD.IOT_WASH_BACKPACKS_ZELIG": "Backpacks",
"PROGRAMS.WM_WD.IOT_WASH_BATHROBE": "Bathrobes and Towels",
"PROGRAMS.WM_WD.IOT_WASH_BATHROBE_STEAM": "Bathrobe and Towels + Steam",
"PROGRAMS.WM_WD.IOT_WASH_BED_LINEN": "Bed Linen",
"PROGRAMS.WM_WD.IOT_WASH_BED_LINEN_STEAM": "Bed Linen + Steam",
"PROGRAMS.WM_WD.IOT_WASH_BED_LINEN_ZELIG": "Bed Linens",
"PROGRAMS.WM_WD.IOT_WASH_BIG_SINGLE_LOAD": "Big single load",
"PROGRAMS.WM_WD.IOT_WASH_BLEACHING": "Bleaching",
"PROGRAMS.WM_WD.IOT_WASH_BLOOD_STAINS": "Bloodstains",
"PROGRAMS.WM_WD.IOT_WASH_CASHMERE": "Cashmere",
"PROGRAMS.WM_WD.IOT_WASH_CHOCOLATE_STAINS": "Chocolate stains",
"PROGRAMS.WM_WD.IOT_WASH_COLD_WASH": "Cold Wash",
"PROGRAMS.WM_WD.IOT_WASH_COLORED": "Colored",
"PROGRAMS.WM_WD.IOT_WASH_COLORED_ANTI_STAIN": "Colored Anti-stain",
"PROGRAMS.WM_WD.IOT_WASH_COLORED_DELICATE": "Colored Delicate",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED": "Colored",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED_BED_LINEN": "Colored Bed Linen",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED_BED_LINEN_STEAM": "Coloured Bed Linen + Steam",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED_CURTAINS": "Colored Curtains",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED_SHIRTS": "Colored Shirts",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED_SHIRTS_STEAM": "Colored Shirts + Steam",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED_STEAM": "Colored + Steam",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED_TABLECLOTHES": "Colored Tableclothes",
"PROGRAMS.WM_WD.IOT_WASH_COLOURED_TABLECLOTHES_STEAM": "Coloured Tablecloths + Steam",
"PROGRAMS.WM_WD.IOT_WASH_COTTON": "Cotton",
"PROGRAMS.WM_WD.IOT_WASH_COTTON_STEAM": "Cotton + Steam",
"PROGRAMS.WM_WD.IOT_WASH_CUDDLY_TOYS": "Cuddly Toys",
"PROGRAMS.WM_WD.IOT_WASH_CURTAINS": "Curtains",
"PROGRAMS.WM_WD.IOT_WASH_CURTAINS_STEAM": "Curtains + Steam",
"PROGRAMS.WM_WD.IOT_WASH_CURTAINS_ZELIG": "Curtains",
"PROGRAMS.WM_WD.IOT_WASH_DARK": "Darks",
"PROGRAMS.WM_WD.IOT_WASH_DARKS_AND_COLOURED_44": "Darks and Colored 44'",
"PROGRAMS.WM_WD.IOT_WASH_DARKS_AND_COLOURED_59": "Darks and Colored 59'",
"PROGRAMS.WM_WD.IOT_WASH_DARKS_AND_COLOURED_XL": "Darks and Colored XL",
"PROGRAMS.WM_WD.IOT_WASH_DARK_STEAM": "Darks + Steam",
"PROGRAMS.WM_WD.IOT_WASH_DASH_CLEAN_CYCLE": "Dash Ultimate Clean",
"PROGRAMS.WM_WD.IOT_WASH_DASH_COLD_CYCLE": "Dash Cold Clean",
"PROGRAMS.WM_WD.IOT_WASH_DASH_FRESH_CYCLE": "Dash Fresh Clean",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE": "Delicates",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_ANTIALLERGY": "Delicate Anti-Allergy",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_ANTIALLERGY_STEAM": "Delicate Anti-Allergy + Steam",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_ANTIALLERGY_ZELIG": "Delicate Anti-Allergy",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_COLORS": "Delicate Colors",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_COLORS_STEAM": "Delicate Colors + Steam",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_DARK": "Delicate Darks",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_STEAM": "Delicates + Steam",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_TABLECLOTHS": "Delicate Tablecloths",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_TABLECLOTHS_STEAM": "Delicate Tablecloths + Steam",
"PROGRAMS.WM_WD.IOT_WASH_DELICATE_WHITES": "Delicate Whites",
"PROGRAMS.WM_WD.IOT_WASH_DENIM_JEANS": "Denim - Jeans",
"PROGRAMS.WM_WD.IOT_WASH_DIVING_SUITS": "Diving Suits",
"PROGRAMS.WM_WD.IOT_WASH_DIVING_SUITS_ZELIG": "Diving Suits",
"PROGRAMS.WM_WD.IOT_WASH_DOWN_JACKETS": "Down Jackets",
"PROGRAMS.WM_WD.IOT_WASH_DOWN_JACKETS_ZELIG": "Down Jackets",
"PROGRAMS.WM_WD.IOT_WASH_DUVET": "Duvet",
"PROGRAMS.WM_WD.IOT_WASH_FRUIT_STAINS": "Fruit stains",
"PROGRAMS.WM_WD.IOT_WASH_GYM_FIT": "Gym Fit - Fitness",
"PROGRAMS.WM_WD.IOT_WASH_HANDWASH": "Handwash",
"PROGRAMS.WM_WD.IOT_WASH_HANDWASH_COLORED": "Handwash Colored",
"PROGRAMS.WM_WD.IOT_WASH_HANDWASH_DARK": "Handwash Darks",
"PROGRAMS.WM_WD.IOT_WASH_LINGERIE": "Lingerie",
"PROGRAMS.WM_WD.IOT_WASH_MASKS_REFRESH": "Masks Refresh",
"PROGRAMS.WM_WD.IOT_WASH_MASKS_SANIFICATION": "Masks Sanitization",
"PROGRAMS.WM_WD.IOT_WASH_MASKS_SANIFICATION_STEAM": "Mask Sanitisation + Steam",
"PROGRAMS.WM_WD.IOT_WASH_MATS": "Mats",
"PROGRAMS.WM_WD.IOT_WASH_MEN_S_TROUSERS": "Trousers",
"PROGRAMS.WM_WD.IOT_WASH_MIXED": "Mixed",
"PROGRAMS.WM_WD.IOT_WASH_MIXED_STEAM": "Mixed + Steam",
"PROGRAMS.WM_WD.IOT_WASH_MIX_AND_COLOURED_44": "Mix and Colored 44'",
"PROGRAMS.WM_WD.IOT_WASH_MIX_AND_COLOURED_59": "Mix and Colored 59'",
"PROGRAMS.WM_WD.IOT_WASH_MIX_AND_COLOURED_XL": "Mix and colored XL",
"PROGRAMS.WM_WD.IOT_WASH_NEW_CLOTHES": "New Clothes",
"PROGRAMS.WM_WD.IOT_WASH_PERFECT_WHITE": "Perfect White",
"PROGRAMS.WM_WD.IOT_WASH_PERFECT_WHITE_STEAM": "Perfect White + Steam",
"PROGRAMS.WM_WD.IOT_WASH_PETS": "Pet Accessories",
"PROGRAMS.WM_WD.IOT_WASH_PETS_HAIR_REMOVAL": "Pets Hair Removal",
"PROGRAMS.WM_WD.IOT_WASH_PETS_ODOURS_STAINS_REMOVAL": "Pets Odours and Stains Removal",
"PROGRAMS.WM_WD.IOT_WASH_PETS_STEAM": "Pet Accessories + Steam",
"PROGRAMS.WM_WD.IOT_WASH_PLAYSUITS": "Playsuits",
"PROGRAMS.WM_WD.IOT_WASH_PLAYSUITS_STEAM": "Playsuits + Steam",
"PROGRAMS.WM_WD.IOT_WASH_QUICK_DRUM_CLEANER": "Quick drum cleaner",
"PROGRAMS.WM_WD.IOT_WASH_RAPID_14": "Rapid 14",
"PROGRAMS.WM_WD.IOT_WASH_RAPID_30": "Rapid 30",
"PROGRAMS.WM_WD.IOT_WASH_RAPID_44": "Rapid 44'",
"PROGRAMS.WM_WD.IOT_WASH_RAPID_59": "Rapid 59'",
"PROGRAMS.WM_WD.IOT_WASH_RAPID_59_STEAM": "Rapid 59' + Steam",
"PROGRAMS.WM_WD.IOT_WASH_REFRESH_14_MIN": "Refresh 14'",
"PROGRAMS.WM_WD.IOT_WASH_RESISTANT_COLORED": "Resistant Colored",
"PROGRAMS.WM_WD.IOT_WASH_RESISTANT_DARK": "Resistant Darks",
"PROGRAMS.WM_WD.IOT_WASH_RESISTANT_WHITES": "Resistant Whites",
"PROGRAMS.WM_WD.IOT_WASH_RINSE": "Rinses",
"PROGRAMS.WM_WD.IOT_WASH_SHIRTS": "Shirts",
"PROGRAMS.WM_WD.IOT_WASH_SHIRTS_STEAM": "Shirts + Steam",
"PROGRAMS.WM_WD.IOT_WASH_SILK": "Silk",
"PROGRAMS.WM_WD.IOT_WASH_SKI_SUIT": "Ski Suit",
"PROGRAMS.WM_WD.IOT_WASH_SKI_SUIT_ZELIG": "Ski Suit",
"PROGRAMS.WM_WD.IOT_WASH_SPIN": "Spin",
"PROGRAMS.WM_WD.IOT_WASH_SPORT": "Sport",
"PROGRAMS.WM_WD.IOT_WASH_SPORT_ANTI_ODOR": "Anti-odour Sportswear",
"PROGRAMS.WM_WD.IOT_WASH_SPORT_ANTI_ODOR_ZELIG": "Anti-odour Sportswear",
"PROGRAMS.WM_WD.IOT_WASH_STAINS_REMOVER": "Stain Remover",
"PROGRAMS.WM_WD.IOT_WASH_SWIMSUITS_AND_BIKINIS": "Swimsuits and Bikinis",
"PROGRAMS.WM_WD.IOT_WASH_SYNTHETIC": "Synthetics",
"PROGRAMS.WM_WD.IOT_WASH_SYNTHETIC_STEAM": "Synthetics + Steam",
"PROGRAMS.WM_WD.IOT_WASH_TABLECLOTHS": "Tablecloths",
"PROGRAMS.WM_WD.IOT_WASH_TABLECLOTHS_STEAM": "Tablecloths + Steam",
"PROGRAMS.WM_WD.IOT_WASH_TECHNICAL_FABRICS": "Technical Fabrics",
"PROGRAMS.WM_WD.IOT_WASH_TECHNICAL_FABRICS_ZELIG": "Technical Fabrics",
"PROGRAMS.WM_WD.IOT_WASH_TECHNICAL_JACKETS": "Technical Jackets",
"PROGRAMS.WM_WD.IOT_WASH_TECHNICAL_JACKETS_ZELIG": "Technical Jackets",
"PROGRAMS.WM_WD.IOT_WASH_TRAINERS": "Trainers",
"PROGRAMS.WM_WD.IOT_WASH_WHITES": "Whites",
"PROGRAMS.WM_WD.IOT_WASH_WHITES_44": "Whites 44'",
"PROGRAMS.WM_WD.IOT_WASH_WHITES_59": "Whites 59'",
"PROGRAMS.WM_WD.IOT_WASH_WHITES_XL": "Whites XL",
"PROGRAMS.WM_WD.IOT_WASH_WINE_STAINS": "Wine Stains",
"PROGRAMS.WM_WD.IOT_WASH_WOOL": "Wool",
"PROGRAMS.WM_WD.JEANS": "Jeans",
"PROGRAMS.WM_WD.JEANS_60": "Jeans",
"PROGRAMS.WM_WD.LOW_DRY": "Low Heat Dry",
"PROGRAMS.WM_WD.MIXED": "Mixed",
"PROGRAMS.WM_WD.MIXED_AND_COLORED_59": "Mixed and Colored 59'",
"PROGRAMS.WM_WD.MIXED_STEAM": "Mixed + Steam",
"PROGRAMS.WM_WD.MIX_AND_COLOUR_59": "Mixed and Colored 59'",
"PROGRAMS.WM_WD.MIX_AND_COLOUR_59_STEAM": "Mixed and Coloured 59' + Steam",
"PROGRAMS.WM_WD.NIGHT_AND_DAY": "Night and Day",
"PROGRAMS.WM_WD.NIGHT_WASH": "Night Wash",
"PROGRAMS.WM_WD.PERFECT_59": "Perfect 59'",
"PROGRAMS.WM_WD.PERFECT_COTTON_59": "Perfect Cotton 59'",
"PROGRAMS.WM_WD.PERFECT_COTTON_59_STEAM": "Perfect Cotton 59' + Steam",
"PROGRAMS.WM_WD.PERFECT_WHITES_59": "Perfect White 59'",
"PROGRAMS.WM_WD.RAPID_14_MIN": "Rapid 14'",
"PROGRAMS.WM_WD.RAPID_30_MIN": "Rapid 30'",
"PROGRAMS.WM_WD.RAPID_44_MIN": "Rapid 44'",
"PROGRAMS.WM_WD.RAPID_A_CLASS_60": "Rapid 59' A Class",
"PROGRAMS.WM_WD.RAPID_A_CLASS_60_STEAM": "Rapid 59' A Class + Steam",
"PROGRAMS.WM_WD.RAPID_WASH_AND_DRY_59_MIN": "Wash and Dry 59'",
"PROGRAMS.WM_WD.RESISTANT_COTTON": "Resistant Cotton",
"PROGRAMS.WM_WD.RESISTANT_COTTON_STEAM": "Resistant Cotton + Steam",
"PROGRAMS.WM_WD.RINSE": "Rinse",
"PROGRAMS.WM_WD.SHIRTS_STEAM": "Shirts + Steam",
"PROGRAMS.WM_WD.SILENT_NIGHT": "Silent Night",
"PROGRAMS.WM_WD.SINGLE_ITEM": "Single Item",
"PROGRAMS.WM_WD.SINGLE_ITEM_STEAM": "Single Item + Steam",
"PROGRAMS.WM_WD.SMART_WASH": "Smart Wash",
"PROGRAMS.WM_WD.SOFT_CARE": "Soft Care",
"PROGRAMS.WM_WD.SOFT_CARE_STEAM_TITLE": "Soft Care + Steam",
"PROGRAMS.WM_WD.SPECIAL_39": "Special 39'",
"PROGRAMS.WM_WD.SPECIAL_39_FULL_LOAD": "Special 39'",
"PROGRAMS.WM_WD.SPECIAL_39_FULL_LOAD_STEAM": "Special 39' + Steam",
"PROGRAMS.WM_WD.SPECIAL_49": "Special 49'",
"PROGRAMS.WM_WD.SPORT_39": "Sport 39'",
"PROGRAMS.WM_WD.SPORT_PLUS_29": "Sport Plus 29'",
"PROGRAMS.WM_WD.SPORT_PLUS_39": "Sport Plus 39'",
"PROGRAMS.WM_WD.STEAM_39": "Steam 39'",
"PROGRAMS.WM_WD.STEAM_CARE_PRO": "Steam Care Pro",
"PROGRAMS.WM_WD.STEAM_CARE_PRO_COTTON": "Steam Care Pro - Cottons",
"PROGRAMS.WM_WD.STEAM_CARE_PRO_DELICATES": "Steam Care Pro - Delicates",
"PROGRAMS.WM_WD.STEAM_CARE_PRO_SYNTHETIC": "Steam Care Pro - Synthetics",
"PROGRAMS.WM_WD.STEAM_HYGIENE_PLUS": "Hygiene Plus + Steam",
"PROGRAMS.WM_WD.SYNTHETICS": "Synthetics",
"PROGRAMS.WM_WD.SYNTHETIC_AND_COLOURED": "Synthetic and Colored",
"PROGRAMS.WM_WD.SYNTHETIC_AND_COLOURED_STEAM": "Synthetic and Coloured + Steam",
"PROGRAMS.WM_WD.TAILORED_RESISTANT_COTTON": "Tailored Resistant Cotton",
"PROGRAMS.WM_WD.TAILORED_SYNTHETIC_AND_COLOURED": "Tailored Synthetic Colored",
"PROGRAMS.WM_WD.TOTAL_CARE": "Total Care",
"PROGRAMS.WM_WD.TUMBLING": "Tumbling",
"PROGRAMS.WM_WD.WOOL": "Wool",
"PROGRAMS.WM_WD.WOOL_AND_DELICATES_49": "Wool and Delicates 49'",
"PROGRAMS.WM_WD.WOOL_DRY": "Wool Dry",
"PROGRAMS.WM_WD.WOOL_SOFT_CARE": "Wool and Soft Car"
}
}
}
}
}

View File

@ -1,5 +1,5 @@
{ {
"name": "hOn", "name": "Haier hOn",
"render_readme": false, "render_readme": true,
"homeassistant": "2023.2.0" "homeassistant": "2023.2.0"
} }