Compare commits

...

63 Commits

Author SHA1 Message Date
130327ad14 Fix errors, bump pyhon 2023-05-07 00:54:59 +02:00
8aa8563b9b Control air conditioners 2023-04-26 23:57:44 +02:00
8e4e491c33 Output pyhon version 2023-04-25 23:39:18 +02:00
28a8ad1672 Translate login 2023-04-24 22:40:20 +02:00
e56f2c99c0 Don't escape unicode in json files 2023-04-24 22:07:58 +02:00
e35a6ce751 Bump pyhon version 2023-04-24 21:53:37 +02:00
5bff5d2143 Add more translation keys 2023-04-24 21:38:05 +02:00
f1e16312ff Fix some bugs for hoover appliances, fix #31 2023-04-24 04:36:14 +02:00
8c1bba2468 Bump pyhon version 2023-04-23 20:18:00 +02:00
616f7babdb Faster refresh when changing configs 2023-04-23 20:04:19 +02:00
1143c47fd3 Bump pyhon version 2023-04-23 19:29:50 +02:00
c60d94a170 Improve translations and sensors for td and wm 2023-04-23 16:30:57 +02:00
c89521f169 Bump pyhon version 2023-04-23 14:42:55 +02:00
e49841608d Bump version 2023-04-23 03:40:23 +02:00
90e02428e8 start translation of entity names 2023-04-23 03:31:32 +02:00
9370cf84b8 Make scripts executable 2023-04-22 23:36:31 +02:00
e24b48d672 Update readme 2023-04-22 23:36:19 +02:00
4c3f6604d3 Change Sterilization and Anti-Crease to switch 2023-04-22 23:35:59 +02:00
13a23eb6e1 Improve translation of dryer level 2023-04-22 23:15:17 +02:00
2c93b86dfe Add flags 2023-04-22 21:52:49 +02:00
9c0b467d68 Remove invalid translation keys 2023-04-22 21:42:16 +02:00
d2cebfad67 Update readme for translations 2023-04-22 21:33:49 +02:00
7f439139d5 Add program translations 2023-04-22 21:19:32 +02:00
aa7b40a454 Auto translate pr phase and mach mode 2023-04-22 15:41:43 +02:00
e0cba7379a Fix wrong unit of current energy usage #30 2023-04-20 22:07:22 +02:00
873cc2d70f Merge pull request #29 from KiraPC/it-translation
IT translation
2023-04-20 14:27:01 +02:00
43b967cd41 Start it translation 2023-04-20 11:22:54 +02:00
2c6def8f57 update readme 2023-04-19 20:40:31 +02:00
b723744948 Merge pull request #27 from MiguelAngelLV/main
Updated oven
2023-04-19 20:32:26 +02:00
e0081bf75e Black style 2023-04-19 20:18:40 +02:00
554ce1d7ff Update manifiest 2023-04-19 19:33:35 +02:00
256c691213 Oven 2023-04-19 19:31:45 +02:00
7fb68be033 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	custom_components/hon/manifest.json
2023-04-19 18:42:17 +02:00
72c83527d5 Bump version to v0.6.0 2023-04-19 17:47:05 +02:00
75622e18a2 Bump version, update readme 2023-04-18 23:50:27 +02:00
a2d0257410 Add more sensors for #22 2023-04-18 23:50:14 +02:00
e2c7ca36db Merge pull request #23 from cylonbrain/main
Added WashingMachine sonsors to WashDryer as well
2023-04-18 12:52:54 +02:00
b33b6a40b2 Added WashingMachine sonsors to WashDryer as well
In addition to that the currentElectricityUsed is measured in kWh because it just counts the kWh for the current cycle
2023-04-18 12:47:25 +02:00
75859543aa Improve entity documentation 2023-04-17 23:18:27 +02:00
891ae51832 Bump pyhon version, fixes disapearing programs 2023-04-17 00:42:50 +02:00
102a05ffcd Bump pyhon version, fixes starting error 2023-04-17 00:15:18 +02:00
380cde5a71 List Appliance Features 2023-04-16 23:35:43 +02:00
5f9dbef4fc Add dishwasher #21 2023-04-16 21:55:47 +02:00
5dbf508519 Merged 2023-04-16 17:04:18 +02:00
7d3813b8fd Update oven 2023-04-16 16:59:37 +02:00
2aa1d3df01 Correct name for IH #22 2023-04-16 13:56:58 +02:00
e2f7f15a5f Bump pyhon for #22 2023-04-15 22:28:01 +02:00
d91b3edb40 Use unique_id instead of mac address for #22 2023-04-15 22:05:02 +02:00
83c5e3479e Add hob support #22 2023-04-15 04:34:12 +02:00
b0cd020941 Bump versions 2023-04-15 00:32:47 +02:00
593842144a Add zip release for download count 2023-04-12 23:59:09 +02:00
9a6e1155f9 Add useful links 2023-04-12 23:58:10 +02:00
365a3af171 Clean up sessions correct, fixes #19 2023-04-12 19:28:04 +02:00
6de6ff375c Bump version to v0.5.0 2023-04-12 02:11:41 +02:00
89d2fd4af1 Read out device data via ui 2023-04-11 22:08:47 +02:00
92add01a59 Bump pyhon version 2023-04-11 01:03:54 +02:00
4a685e67e0 Try to fix login issues #11 2023-04-10 20:35:22 +02:00
6303843116 Add python check action 2023-04-10 19:59:04 +02:00
907bc44533 Reformat with black 2023-04-10 19:51:16 +02:00
4901be4050 Update badges, bump version 2023-04-10 18:50:51 +02:00
c8189414b8 Use pyhon v0.6.1 2023-04-10 17:02:16 +02:00
799ac67d94 Use info.md for hacs 2023-04-10 08:17:27 +02:00
7e9202ef38 New pyhOn version 2023-04-10 07:09:54 +02:00
41 changed files with 21822 additions and 948 deletions

38
.github/workflows/python_check.yml vendored Normal file
View File

@ -0,0 +1,38 @@
name: Python check
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pylint black
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics
# - name: Analysing the code with pylint
# run: |
# pylint --max-line-length 88 $(git ls-files '*.py')
- name: Check black style
run: |
black . --check

25
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: Release
on:
release:
types: [published]
jobs:
release-zip:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: ZIP Component Dir
run: |
cd ${{ github.workspace }}/custom_components/hon
zip -r haier_hon.zip ./
- name: Upload zip to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ github.workspace }}/custom_components/hon/haier_hon.zip
asset_name: haier_hon.zip
tag: ${{ github.ref }}
overwrite: true

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
__pycache__/
test.py
.idea/
scripts/translations/
scripts/test*

288
README.md
View File

@ -1,13 +1,18 @@
# Haier hOn
[![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg)](https://github.com/hacs/integration)
[![GitHub manifest version (path)](https://img.shields.io/github/manifest-json/v/andre0512/hon?color=g&filename=custom_components%2Fhon%2Fmanifest.json)](https://github.com/Andre0512/hon/releases/latest)
[![Home Assistant installs](https://img.shields.io/badge/dynamic/json?color=41BDF5&label=usage&suffix=%20installs&cacheSeconds=15600&url=https://analytics.home-assistant.io/custom_integrations.json&query=$.hon.total)](https://analytics.home-assistant.io/)
[![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg)](https://hacs.xyz)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/Andre0512/hon?color=green)](https://github.com/Andre0512/hon/releases/latest)
[![GitHub](https://img.shields.io/github/license/Andre0512/hon?color=red)](https://github.com/Andre0512/hon/blob/main/LICENSE)
[![GitHub all releases](https://img.shields.io/github/downloads/Andre0512/hon/total?color=blue)](https://tooomm.github.io/github-release-stats/?username=Andre0512&repository=hon)
Home Assistant integration for Haier hOn: support for Haier/Candy/Hoover home appliances like washing machines.
## Supported Appliances
- Tumble Dryer
- Washer Dryer
- Washing Machine
- Oven
- [Washing Machine](https://github.com/Andre0512/hon#washing-machine)
- [Tumble Dryer](https://github.com/Andre0512/hon#tumble-dryer)
- [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer)
- [Oven](https://github.com/Andre0512/hon#oven)
- [Hob](https://github.com/Andre0512/hon#hob)
- [Dish Washer](https://github.com/Andre0512/hon#dish-washer)
- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA]
## Installation
**Method 1:** [![Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=Andre0512&repository=hon&category=integration)
@ -16,6 +21,8 @@ Home Assistant integration for Haier hOn: support for Haier/Candy/Hoover home ap
**Method 3:** Manually copy `hon` folder from [latest release](https://github.com/Andre0512/hon/releases/latest) to `config/custom_components` folder.
_Restart Home Assistant_
## Configuration
**Method 1**: [![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=hon)
@ -25,12 +32,30 @@ _If the integration is not in the list, you need to clear the browser cache._
## Contribute
Any kind of contribution is welcome!
#### Add appliances or additional attributes
### Read out device data
If you want to make a request for adding new appliances or additional attributes and don't want to use the command line, here is how you can read out your device data.
For every device exists a hidden button which can be used to log all info of your appliance.
1. Enable the "Log Device Info" button
_This button can be found in the diagnostic section of your device or in the entity overview if "show disabled entities" is enabled._
2. Press the button
3. Go to Settings > System > Logs, click _load full logs_ and scroll down
_The formatting is messy if you not load full logs_
4. Here you can find all data which can be read out via the api
```yaml
data:
appliance:
applianceId: 12-34-56-78-90-ab#2022-10-25T19:47:11Z
applianceModelId: 1569
...
```
5. Copy this data and create a [new issue](https://github.com/Andre0512/hon/issues/new) with your request
### 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
2. Use the command line tool to read out all appliance data from your account
```commandline
$ pyhOn
User for hOn account: user.name@example.com
@ -65,16 +90,259 @@ Any kind of contribution is welcome!
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 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.
- Use [pyhOn's translate command](https://github.com/Andre0512/pyhOn#translation) to read out the official translations
## Tested Devices
- Haier WD90-B14TEAM5
- Haier HD80-A3959
- Haier HWO60SM2F3XH
- Hoover H-WASH 500
- Candy CIS633SCTTWIFI
- Haier XIB 3B2SFS-80
- Haier XIB 6B2D3FB
## Supported Languages
Translation of internal names like programs are available for all languages which are official supported by the hOn app:
* 🇨🇳 Chinese
* 🇭🇷 Croatian
* 🇨🇿 Czech
* 🇳🇱 Dutch
* 🇬🇧 English
* 🇫🇷 French
* 🇩🇪 German
* 🇬🇷 Greek
* 🇮🇱 Hebrew
* 🇮🇹 Italian
* 🇵🇱 Polish
* 🇵🇹 Portuguese
* 🇷🇴 Romanian
* 🇷🇺 Russian
* 🇷🇸 Serbian
* 🇸🇰 Slovak
* 🇸🇮 Slovenian
* 🇪🇸 Spanish
* 🇹🇷 Turkish
## About this Repo
The existing integrations missed some features from the app I liked to have in HomeAssistant.
I tried to create a pull request, but in the structures of these existing repos, I find it hard to fit in my needs, so I basically rewrote everything.
I moved the api related stuff into the package [pyhOn](https://github.com/Andre0512/pyhOn).
## Appliance Features
### Air conditioner
#### Configs
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| 10° Heating | | `switch` | `startProgram.10degreeHeatingStatus` |
| Echo | | `switch` | `startProgram.echoStatus` |
| Eco Mode | | `switch` | `startProgram.ecoMode` |
| Eco Pilot | | `select` | `startProgram.humanSensingStatus` |
| Health Mode | | `switch` | `startProgram.healthMode` |
| Mute | | `switch` | `startProgram.muteStatus` |
| Program | | `select` | `startProgram.program` |
| Rapid Mode | | `switch` | `startProgram.rapidMode` |
| Screen Display | | `switch` | `startProgram.screenDisplayStatus` |
| Self Cleaning | | `switch` | `startProgram.selfCleaningStatus` |
| Self Cleaning 56 | | `switch` | `startProgram.selfCleaning56Status` |
| Silent Sleep | | `switch` | `startProgram.silentSleepStatus` |
| Target Temperature | `thermometer` | `number` | `startProgram.tempSel` |
### Dish washer
#### Controls
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Dish Washer | `dishwasher` | `switch` | `startProgram` / `stopProgram` |
#### Configs
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Add Dish | `silverware-fork-knife` | `switch` | `startProgram.addDish` |
| Delay time | `timer-plus` | `number` | `startProgram.delayTime` |
| Eco Express | `sprout` | `switch` | `startProgram.ecoExpress` |
| Eco Index | `sprout` | `sensor` | `startProgram.ecoIndex` |
| Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` |
| Extra Dry | `hair-dryer` | `switch` | `startProgram.extraDry` |
| Half Load | `fraction-one-half` | `switch` | `startProgram.halfLoad` |
| Open Door | `door-open` | `switch` | `startProgram.openDoor` |
| Program | | `select` | `startProgram.program` |
| Temperature | `thermometer` | `sensor` | `startProgram.temp` |
| Three in One | `numeric-3-box-outline` | `switch` | `startProgram.threeInOne` |
| Time | `timer` | `sensor` | `startProgram.remainingTime` |
| Water Efficiency | `water` | `sensor` | `startProgram.waterEfficiency` |
| Water Saving | `water-percent` | `sensor` | `startProgram.waterSaving` |
| Water hard | `water` | `number` | `startProgram.waterHard` |
#### Sensors
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Connection | | `binary_sensor` | `attributes.lastConnEvent.category` |
| Door | | `binary_sensor` | `doorStatus` |
| Error | `math-log` | `sensor` | `errors` |
| Machine Status | `information` | `sensor` | `machMode` |
| Program Phase | `washing-machine` | `sensor` | `prPhase` |
| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
| Rinse Aid | `spray-bottle` | `binary_sensor` | `rinseAidStatus` |
| Salt | `shaker-outline` | `binary_sensor` | `saltStatus` |
### Hob
#### Controls
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Start Program | `pot-steam` | `button` | `startProgram` |
#### Configs
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Power Management | `timelapse` | `number` | `startProgram.powerManagement` |
| Program | | `select` | `startProgram.program` |
| Temperature | `thermometer` | `number` | `startProgram.temp` |
#### Sensors
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Connection | `wifi` | `binary_sensor` | `attributes.lastConnEvent.category` |
| Error | `math-log` | `sensor` | `errors` |
| Hob Lock | | `binary_sensor` | `hobLockStatus` |
| Hot Status | | `binary_sensor` | `hotStatus` |
| On | `power-cycle` | `binary_sensor` | `attributes.parameters.onOffStatus` |
| Pan Status | `pot-mix` | `binary_sensor` | `panStatus` |
| Power | `lightning-bolt` | `sensor` | `power` |
| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
| Remote Control | `remote` | `binary_sensor` | `attributes.parameters.remoteCtrValid` |
| Temperature | `thermometer` | `sensor` | `temp` |
### Oven
#### Controls
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Oven | `toaster-oven` | `switch` | `startProgram` / `stopProgram` |
#### Configs
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Delay time | `timer-plus` | `number` | `startProgram.delayTime` |
| Preheat | `thermometer-chevron-up` | `switch` | `startProgram.preheatStatus` |
| Program | | `select` | `startProgram.program` |
| Program Duration | `timelapse` | `number` | `startProgram.prTime` |
| Target Temperature | `thermometer` | `number` | `startProgram.tempSel` |
#### Sensors
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Connection | `wifi` | `binary_sensor` | `attributes.lastConnEvent.category` |
| On | `power-cycle` | `binary_sensor` | `attributes.parameters.onOffStatus` |
| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
| Remote Control | `remote` | `binary_sensor` | `attributes.parameters.remoteCtrValid` |
| Start Time | `clock-start` | `sensor` | `delayTime` |
| Temperature | `thermometer` | `sensor` | `temp` |
| Temperature Selected | `thermometer` | `sensor` | `tempSel` |
### Tumble dryer
#### Controls
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Pause Tumble Dryer | `pause` | `switch` | `pauseProgram` / `resumeProgram` |
| Tumble Dryer | `tumble-dryer` | `switch` | `startProgram` / `stopProgram` |
#### Configs
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Anti-Crease | `timer` | `switch` | `startProgram.antiCreaseTime` |
| Anti-Crease | `timer` | `switch` | `startProgram.anticrease` |
| Delay time | `timer-plus` | `number` | `startProgram.delayTime` |
| Dry Time | | `number` | `startProgram.dryTime` |
| Dry Time | `timer` | `select` | `startProgram.dryTimeMM` |
| Dry level | `hair-dryer` | `select` | `startProgram.dryLevel` |
| Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` |
| Program | | `select` | `startProgram.program` |
| Sterilization | `clock-start` | `switch` | `startProgram.sterilizationStatus` |
| Suggested Load | `weight-kilogram` | `sensor` | `startProgram.suggestedLoadD` |
| Temperature level | `thermometer` | `number` | `startProgram.tempLevel` |
#### Sensors
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Connection | | `binary_sensor` | `attributes.lastConnEvent.category` |
| Door | | `binary_sensor` | `doorStatus` |
| Dry level | `hair-dryer` | `sensor` | `dryLevel` |
| Error | `math-log` | `sensor` | `errors` |
| Machine Status | `information` | `sensor` | `machMode` |
| Program | `tumble-dryer` | `sensor` | `prCode` |
| Program Phase | `washing-machine` | `sensor` | `prPhase` |
| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
| Start Time | `clock-start` | `sensor` | `delayTime` |
| Temperature level | `thermometer` | `sensor` | `tempLevel` |
### Washer dryer
#### Controls
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Pause Washing Machine | `pause` | `switch` | `pauseProgram` / `resumeProgram` |
| Washing Machine | `washing-machine` | `switch` | `startProgram` / `stopProgram` |
#### Configs
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Delay Time | `timer-plus` | `number` | `startProgram.delayTime` |
| Program | | `select` | `startProgram.program` |
| Suggested weight | `weight-kilogram` | `sensor` | `startProgram.weight` |
#### Sensors
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Acqua Plus | | `binary_sensor` | `acquaplus` |
| Anti-Crease | | `binary_sensor` | `anticrease` |
| Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` |
| Current Program | `tumble-dryer` | `sensor` | `prCode` |
| Current Temperature | `thermometer` | `sensor` | `temp` |
| Current Water Used | `water` | `sensor` | `currentWaterUsed` |
| Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` |
| Dry level | `hair-dryer` | `sensor` | `dryLevel` |
| Extra Rinse 1 | | `binary_sensor` | `extraRinse1` |
| Extra Rinse 2 | | `binary_sensor` | `extraRinse2` |
| Extra Rinse 3 | | `binary_sensor` | `extraRinse3` |
| Good Night Mode | | `binary_sensor` | `goodNight` |
| Machine Status | `information` | `sensor` | `machMode` |
| Pre Wash | | `binary_sensor` | `startProgram.prewash` |
| Program Phase | `washing-machine` | `sensor` | `prPhase` |
| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
| Remote Control | `remote` | `binary_sensor` | `attributes.lastConnEvent.category` |
| Spin Speed | `fast-forward-outline` | `sensor` | `spinSpeed` |
| Steam level | `smoke` | `sensor` | `steamLevel` |
| Total Power | | `sensor` | `totalElectricityUsed` |
| Total Wash Cycle | `counter` | `sensor` | `totalWashCycle` |
| Total Water | | `sensor` | `totalWaterUsed` |
### Washing machine
#### Controls
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Pause Washing Machine | `pause` | `switch` | `pauseProgram` / `resumeProgram` |
| Washing Machine | `washing-machine` | `switch` | `startProgram` / `stopProgram` |
#### Configs
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Delay Status | `timer-check` | `switch` | `startProgram.delayStatus` |
| Delay Time | `timer-plus` | `number` | `startProgram.delayTime` |
| Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` |
| Keep Fresh | `refresh-circle` | `switch` | `startProgram.autoSoftenerStatus` |
| Liquid Detergent Dose | `cup-water` | `sensor` | `startProgram.liquidDetergentDose` |
| Main Wash Time | `clock-start` | `number` | `startProgram.mainWashTime` |
| Powder Detergent Dose | `cup` | `sensor` | `startProgram.powderDetergentDose` |
| Program | | `select` | `startProgram.program` |
| Remaining Time | `timer` | `sensor` | `startProgram.remainingTime` |
| Rinse Iterations | `rotate-right` | `number` | `startProgram.rinseIterations` |
| Soak Prewash Selection | `tshirt-crew` | `switch` | `startProgram.haier_SoakPrewashSelection` |
| Spin speed | `numeric` | `select` | `startProgram.spinSpeed` |
| Suggested weight | `weight-kilogram` | `sensor` | `startProgram.weight` |
| Temperature | `thermometer` | `select` | `startProgram.temp` |
#### Sensors
| Name | Icon | Entity | Key |
| --- | --- | --- | --- |
| Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` |
| Current Water Used | `water` | `sensor` | `currentWaterUsed` |
| Door | | `binary_sensor` | `doorStatus` |
| Door Lock | | `binary_sensor` | `doorLockStatus` |
| Error | `math-log` | `sensor` | `errors` |
| Machine Status | `information` | `sensor` | `machMode` |
| Program Phase | `washing-machine` | `sensor` | `prPhase` |
| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
| Remote Control | `remote` | `binary_sensor` | `attributes.lastConnEvent.category` |
| Spin Speed | `speedometer` | `sensor` | `spinSpeed` |
| Total Power | | `sensor` | `totalElectricityUsed` |
| Total Wash Cycle | `counter` | `sensor` | `totalWashCycle` |
| Total Water | | `sensor` | `totalWaterUsed` |

View File

@ -1,7 +1,7 @@
import logging
import voluptuous as vol
from pyhon import HonConnection
from pyhon import Hon
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
@ -28,8 +28,9 @@ CONFIG_SCHEMA = vol.Schema(
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
session = aiohttp_client.async_get_clientsession(hass)
hon = HonConnection(entry.data["email"], entry.data["password"], session)
await hon.setup()
hon = await Hon(
entry.data["email"], entry.data["password"], session=session
).create()
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.unique_id] = hon
hass.data[DOMAIN]["coordinators"] = {}

View File

@ -1,10 +1,13 @@
import logging
from dataclasses import dataclass
from pyhon import HonConnection
from pyhon import Hon
from homeassistant.components.binary_sensor import BinarySensorEntityDescription, BinarySensorDeviceClass, \
BinarySensorEntity
from homeassistant.components.binary_sensor import (
BinarySensorEntityDescription,
BinarySensorDeviceClass,
BinarySensorEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import callback
from .const import DOMAIN
@ -19,7 +22,9 @@ class HonBinarySensorEntityDescriptionMixin:
@dataclass
class HonBinarySensorEntityDescription(HonBinarySensorEntityDescriptionMixin, BinarySensorEntityDescription):
class HonBinarySensorEntityDescription(
HonBinarySensorEntityDescriptionMixin, BinarySensorEntityDescription
):
pass
@ -30,19 +35,22 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
name="Remote Control",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
on_value="CONNECTED",
icon="mdi:remote"
icon="mdi:remote",
translation_key="remote_control",
),
HonBinarySensorEntityDescription(
key="doorLockStatus",
name="Door Lock",
device_class=BinarySensorDeviceClass.LOCK,
on_value="0",
translation_key="door_lock",
),
HonBinarySensorEntityDescription(
key="doorStatus",
name="Door",
device_class=BinarySensorDeviceClass.DOOR,
on_value="1",
translation_key="door_open",
),
),
"TD": (
@ -51,12 +59,14 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
name="Connection",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
on_value="CONNECTED",
translation_key="connection",
),
HonBinarySensorEntityDescription(
key="doorStatus",
name="Door",
device_class=BinarySensorDeviceClass.DOOR,
on_value="1",
translation_key="door_open",
),
),
"WD": (
@ -65,82 +75,164 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
name="Remote Control",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
on_value="CONNECTED",
icon="mdi:remote"
icon="mdi:remote",
translation_key="remote_control",
),
HonBinarySensorEntityDescription(
key="startProgram.prewash",
name="Pre Wash",
key="startProgram.prewash", name="Pre Wash", translation_key="prewash"
),
HonBinarySensorEntityDescription(
key="extraRinse1",
name="Extra Rinse 1",
key="extraRinse1", name="Extra Rinse 1", translation_key="extra_rinse_1"
),
HonBinarySensorEntityDescription(
key="extraRinse2",
name="Extra Rinse 2",
key="extraRinse2", name="Extra Rinse 2", translation_key="extra_rinse_2"
),
HonBinarySensorEntityDescription(
key="extraRinse3",
name="Extra Rinse 3",
key="extraRinse3", name="Extra Rinse 3", translation_key="extra_rinse_3"
),
HonBinarySensorEntityDescription(
key="goodNight",
name="Good Night Mode",
key="goodNight", name="Good Night Mode", translation_key="good_night"
),
HonBinarySensorEntityDescription(
key="acquaplus",
name="Acqua Plus",
key="acquaplus", name="Acqua Plus", translation_key="aqua_plus"
),
HonBinarySensorEntityDescription(
key="anticrease",
name="Anti-Crease",
key="anticrease", name="Anti-Crease", translation_key="anti_crease"
),
),
"OV": (
HonBinarySensorEntityDescription(
key="attributes.lastConnEvent.category",
name="Online",
name="Connection",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
on_value="CONNECTED",
icon="mdi:wifi"
icon="mdi:wifi",
translation_key="connection",
),
HonBinarySensorEntityDescription(
key="attributes.parameters.remoteCtrValid",
name="On",
name="Remote Control",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
on_value="1",
icon="mdi:remote"
icon="mdi:remote",
translation_key="remote_control",
),
HonBinarySensorEntityDescription(
key="attributes.parameters.onOffStatus",
name="On",
device_class=BinarySensorDeviceClass.RUNNING,
on_value="1",
icon="mdi:power-cycle"
icon="mdi:power-cycle",
translation_key="on",
),
),
"IH": (
HonBinarySensorEntityDescription(
key="attributes.lastConnEvent.category",
name="Connection",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
on_value="CONNECTED",
icon="mdi:wifi",
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(
key="attributes.parameters.onOffStatus",
name="On",
device_class=BinarySensorDeviceClass.RUNNING,
on_value="1",
icon="mdi:power-cycle",
translation_key="on",
),
HonBinarySensorEntityDescription(
key="hotStatus",
name="Hot Status",
device_class=BinarySensorDeviceClass.HEAT,
on_value="1",
translation_key="still_hot",
),
HonBinarySensorEntityDescription(
key="panStatus",
name="Pan Status",
on_value="1",
icon="mdi:pot-mix",
translation_key="pan_status",
),
HonBinarySensorEntityDescription(
key="hobLockStatus",
name="Hob Lock",
device_class=BinarySensorDeviceClass.LOCK,
on_value="0",
translation_key="child_lock",
),
),
"DW": (
HonBinarySensorEntityDescription(
key="saltStatus",
name="Salt",
device_class=BinarySensorDeviceClass.PROBLEM,
on_value="1",
icon="mdi:shaker-outline",
translation_key="salt_level",
),
HonBinarySensorEntityDescription(
key="rinseAidStatus",
name="Rinse Aid",
device_class=BinarySensorDeviceClass.PROBLEM,
on_value="1",
icon="mdi:spray-bottle",
translation_key="rinse_aid",
),
HonBinarySensorEntityDescription(
key="attributes.lastConnEvent.category",
name="Connection",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
on_value="CONNECTED",
translation_key="connection",
),
HonBinarySensorEntityDescription(
key="doorStatus",
name="Door",
device_class=BinarySensorDeviceClass.DOOR,
on_value="1",
translation_key="door_open",
),
),
}
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
hon: HonConnection = hass.data[DOMAIN][entry.unique_id]
hon: Hon = hass.data[DOMAIN][entry.unique_id]
coordinators = hass.data[DOMAIN]["coordinators"]
appliances = []
for device in hon.devices:
if device.mac_address in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
for device in hon.appliances:
if device.unique_id in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
else:
coordinator = HonCoordinator(hass, device)
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
await coordinator.async_config_entry_first_refresh()
if descriptions := BINARY_SENSORS.get(device.appliance_type):
for description in descriptions:
if not device.get(description.key):
_LOGGER.warning("[%s] Can't setup %s", device.appliance_type, description.key)
_LOGGER.warning(
"[%s] Can't setup %s", device.appliance_type, description.key
)
continue
appliances.extend([
HonBinarySensorEntity(hass, coordinator, entry, device, description)]
appliances.extend(
[
HonBinarySensorEntity(
hass, coordinator, entry, device, description
)
]
)
async_add_entities(appliances)
@ -159,9 +251,15 @@ class HonBinarySensorEntity(HonEntity, BinarySensorEntity):
@property
def is_on(self) -> bool:
return self._device.get(self.entity_description.key, "") == self.entity_description.on_value
return (
self._device.get(self.entity_description.key, "")
== self.entity_description.on_value
)
@callback
def _handle_coordinator_update(self):
self._attr_native_value = self._device.get(self.entity_description.key, "") == self.entity_description.on_value
self._attr_native_value = (
self._device.get(self.entity_description.key, "")
== self.entity_description.on_value
)
self.async_write_ha_state()

View File

@ -1,52 +1,59 @@
import logging
import urllib
from urllib.parse import quote
import pkg_resources
from homeassistant.components.button import ButtonEntityDescription, ButtonEntity
from homeassistant.config_entries import ConfigEntry
from pyhon import HonConnection
from pyhon.device import HonDevice
from pyhon import Hon
from pyhon.appliance import HonAppliance
from homeassistant.const import EntityCategory
from .const import DOMAIN
from .hon import HonCoordinator, HonEntity
_LOGGER = logging.getLogger(__name__)
BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = {
"OV": (
"IH": (
ButtonEntityDescription(
key="startProgram",
name="Start Program",
icon="mdi:power-cycle",
icon="mdi:pot-steam",
translation_key="induction_hob",
),
ButtonEntityDescription(
key="stopProgram",
name="Stop Program",
icon="mdi:power-off",
),
)
}
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
hon: HonConnection = hass.data[DOMAIN][entry.unique_id]
hon: Hon = hass.data[DOMAIN][entry.unique_id]
coordinators = hass.data[DOMAIN]["coordinators"]
appliances = []
for device in hon.devices:
if device.mac_address in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
for device in hon.appliances:
if device.unique_id in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
else:
coordinator = HonCoordinator(hass, device)
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
await coordinator.async_config_entry_first_refresh()
if descriptions := BUTTONS.get(device.appliance_type):
for description in descriptions:
if not device.commands.get(description.key):
continue
appliances.extend([
HonButtonEntity(hass, coordinator, entry, device, description)]
appliances.extend(
[HonButtonEntity(hass, coordinator, entry, device, description)]
)
appliances.extend([HonFeatureRequestButton(hass, coordinator, entry, device)])
async_add_entities(appliances)
class HonButtonEntity(HonEntity, ButtonEntity):
def __init__(self, hass, coordinator, entry, device: HonDevice, description) -> None:
def __init__(
self, hass, coordinator, entry, device: HonAppliance, description
) -> None:
super().__init__(hass, entry, coordinator, device)
self._coordinator = coordinator
@ -56,3 +63,20 @@ class HonButtonEntity(HonEntity, ButtonEntity):
async def async_press(self) -> None:
await self._device.commands[self.entity_description.key].send()
class HonFeatureRequestButton(HonEntity, ButtonEntity):
def __init__(self, hass, coordinator, entry, device: HonAppliance) -> None:
super().__init__(hass, entry, coordinator, device)
self._device = device
self._attr_unique_id = f"{super().unique_id}_log_device_info"
self._attr_icon = "mdi:information"
self._attr_name = "Log Device Info"
self._attr_entity_category = EntityCategory.DIAGNOSTIC
self._attr_entity_registry_enabled_default = False
async def async_press(self) -> None:
pyhon_version = pkg_resources.get_distribution("pyhon").version
info = f"Device Info:\n{self._device.diagnose}pyhOnVersion: {pyhon_version}"
_LOGGER.error(info)

View File

@ -0,0 +1,148 @@
import logging
from homeassistant.components.climate import (
ClimateEntity,
ClimateEntityDescription,
)
from homeassistant.components.climate.const import (
FAN_OFF,
SWING_OFF,
SWING_BOTH,
SWING_VERTICAL,
SWING_HORIZONTAL,
ClimateEntityFeature,
HVACMode,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_TEMPERATURE,
PRECISION_WHOLE,
TEMP_CELSIUS,
)
from homeassistant.core import callback
from pyhon import Hon
from pyhon.appliance import HonAppliance
from .const import HON_HVAC_MODE, HON_FAN, HON_HVAC_PROGRAM, DOMAIN
from .hon import HonEntity, HonCoordinator
_LOGGER = logging.getLogger(__name__)
CLIMATES = {
"AC": (ClimateEntityDescription(key="startProgram"),),
}
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
hon: Hon = hass.data[DOMAIN][entry.unique_id]
coordinators = hass.data[DOMAIN]["coordinators"]
appliances = []
for device in hon.appliances:
if device.unique_id in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
else:
coordinator = HonCoordinator(hass, device)
hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
await coordinator.async_config_entry_first_refresh()
if descriptions := CLIMATES.get(device.appliance_type):
for description in descriptions:
if description.key not in device.available_settings:
continue
appliances.extend(
[HonClimateEntity(hass, coordinator, entry, device, description)]
)
async_add_entities(appliances)
class HonClimateEntity(HonEntity, ClimateEntity):
def __init__(
self, hass, coordinator, entry, device: HonAppliance, description
) -> None:
super().__init__(hass, entry, coordinator, device)
self._coordinator = coordinator
self._device = coordinator.device
self.entity_description = description
self._hass = hass
self._attr_unique_id = f"{super().unique_id}climate"
self._attr_temperature_unit = TEMP_CELSIUS
self._attr_target_temperature_step = PRECISION_WHOLE
self._attr_max_temp = device.settings["tempSel"].max
self._attr_min_temp = device.settings["tempSel"].min
self._attr_hvac_modes = [HVACMode.OFF] + [
HON_HVAC_MODE[mode] for mode in device.settings["machMode"].values
]
self._attr_fan_modes = [FAN_OFF] + [
HON_FAN[mode] for mode in device.settings["windSpeed"].values
]
self._attr_swing_modes = [
SWING_OFF,
SWING_VERTICAL,
SWING_HORIZONTAL,
SWING_BOTH,
]
self._attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.FAN_MODE
| ClimateEntityFeature.SWING_MODE
)
async def async_set_hvac_mode(self, hvac_mode):
if hvac_mode == HVACMode.OFF:
self._device.commands["stopProgram"].send()
else:
self._device.settings["program"].value = HON_HVAC_PROGRAM[hvac_mode]
self._device.commands["startProgram"].send()
self._attr_hvac_mode = hvac_mode
async def async_set_fan_mode(self, fan_mode):
mode_number = list(HON_FAN.values()).index(fan_mode)
self._device.settings["windSpeed"].value = list(HON_FAN.keys())[mode_number]
self._device.commands["startProgram"].send()
async def async_set_swing_mode(self, swing_mode):
horizontal = self._device.settings["windDirectionHorizontal"]
vertical = self._device.settings["windDirectionVertical"]
if swing_mode in [SWING_BOTH, SWING_HORIZONTAL]:
horizontal.value = "7"
if swing_mode in [SWING_BOTH, SWING_VERTICAL]:
vertical.value = "8"
if swing_mode in [SWING_OFF, SWING_HORIZONTAL] and vertical.value == "8":
vertical.value = "5"
if swing_mode in [SWING_OFF, SWING_VERTICAL] and horizontal.value == "7":
horizontal.value = "0"
self._attr_swing_mode = swing_mode
self._device.commands["startProgram"].send()
async def async_set_temperature(self, **kwargs):
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
return False
self._device.settings["selTemp"].value = temperature
self._device.commands["startProgram"].send()
@callback
def _handle_coordinator_update(self, update=True) -> None:
self._attr_target_temperature = int(float(self._device.get("tempSel")))
self._attr_current_temperature = float(self._device.get("tempIndoor"))
self._attr_max_temp = self._device.settings["tempSel"].max
self._attr_min_temp = self._device.settings["tempSel"].min
if self._device.get("onOffStatus") == "0":
self._attr_hvac_mode = HVACMode.OFF
else:
self._attr_hvac_mode = HON_HVAC_MODE[self._device.get("machMode")]
self._attr_fan_mode = HON_FAN[self._device.settings["windSpeed"].value]
horizontal = self._device.settings["windDirectionHorizontal"]
vertical = self._device.settings["windDirectionVertical"]
if horizontal == "7" and vertical == "8":
self._attr_swing_mode = SWING_BOTH
elif horizontal == "7":
self._attr_swing_mode = SWING_HORIZONTAL
elif vertical == "8":
self._attr_swing_mode = SWING_VERTICAL
else:
self._attr_swing_mode = SWING_OFF

View File

@ -20,8 +20,12 @@ class HonFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
async def async_step_user(self, user_input=None):
if user_input is None:
return self.async_show_form(step_id="user", data_schema=vol.Schema(
{vol.Required(CONF_EMAIL): str, vol.Required(CONF_PASSWORD): str}))
return self.async_show_form(
step_id="user",
data_schema=vol.Schema(
{vol.Required(CONF_EMAIL): str, vol.Required(CONF_PASSWORD): str}
),
)
self._email = user_input[CONF_EMAIL]
self._password = user_input[CONF_PASSWORD]

View File

@ -1,3 +1,11 @@
from homeassistant.components.climate import (
HVACMode,
FAN_LOW,
FAN_MEDIUM,
FAN_HIGH,
FAN_AUTO,
)
DOMAIN = "hon"
PLATFORMS = [
@ -7,4 +15,31 @@ PLATFORMS = [
"switch",
"button",
"binary_sensor",
"climate",
]
HON_HVAC_MODE = {
"0": HVACMode.AUTO,
"1": HVACMode.COOL,
"2": HVACMode.COOL,
"3": HVACMode.DRY,
"4": HVACMode.HEAT,
"5": HVACMode.FAN_ONLY,
"6": HVACMode.FAN_ONLY,
}
HON_HVAC_PROGRAM = {
HVACMode.AUTO: "iot_auto",
HVACMode.COOL: "iot_cool",
HVACMode.DRY: "iot_dry",
HVACMode.HEAT: "iot_heat",
HVACMode.FAN_ONLY: "iot_fan",
}
HON_FAN = {
"1": FAN_HIGH,
"2": FAN_MEDIUM,
"3": FAN_LOW,
"4": FAN_AUTO,
"5": FAN_AUTO,
}

View File

@ -1,7 +1,7 @@
import logging
from datetime import timedelta
from pyhon.device import HonDevice
from pyhon.appliance import HonAppliance
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -15,30 +15,37 @@ _LOGGER = logging.getLogger(__name__)
class HonEntity(CoordinatorEntity):
_attr_has_entity_name = True
def __init__(self, hass, entry, coordinator, device: HonDevice) -> None:
def __init__(self, hass, entry, coordinator, device: HonAppliance) -> None:
super().__init__(coordinator)
self._hon = hass.data[DOMAIN][entry.unique_id]
self._hass = hass
self._device = device
self._attr_unique_id = self._device.mac_address
self._attr_unique_id = self._device.unique_id
@property
def device_info(self):
return DeviceInfo(
identifiers={(DOMAIN, self._device.mac_address)},
identifiers={(DOMAIN, self._device.unique_id)},
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,
sw_version=self._device.get("fwVersion", ""),
)
class HonCoordinator(DataUpdateCoordinator):
def __init__(self, hass, device: HonDevice):
def __init__(self, hass, device: HonAppliance):
"""Initialize my coordinator."""
super().__init__(hass, _LOGGER, name=device.mac_address, update_interval=timedelta(seconds=30))
super().__init__(
hass,
_LOGGER,
name=device.unique_id,
update_interval=timedelta(seconds=30),
)
self._device = device
async def _async_update_data(self):

View File

@ -6,7 +6,6 @@
"documentation": "https://github.com/Andre0512/hon/",
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/Andre0512/hon/issues",
"requirements": ["pyhOn==0.4.1"],
"version": "0.4.0"
"requirements": ["pyhOn==0.10.2"],
"version": "0.7.0-beta.8"
}

View File

@ -1,7 +1,9 @@
from __future__ import annotations
from pyhon import HonConnection
from pyhon.parameter import HonParameterRange
from pyhon import Hon
from pyhon.parameter.base import HonParameter
from pyhon.parameter.fixed import HonParameterFixed
from pyhon.parameter.range import HonParameterRange
from homeassistant.components.number import (
NumberEntity,
@ -22,20 +24,23 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
name="Delay Time",
icon="mdi:timer-plus",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.MINUTES
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="delay_time",
),
NumberEntityDescription(
key="startProgram.rinseIterations",
name="Rinse Iterations",
icon="mdi:rotate-right",
entity_category=EntityCategory.CONFIG
entity_category=EntityCategory.CONFIG,
translation_key="rinse_iterations",
),
NumberEntityDescription(
key="startProgram.mainWashTime",
name="Main Wash Time",
icon="mdi:clock-start",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.MINUTES
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="wash_time",
),
),
"TD": (
@ -44,34 +49,21 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
name="Delay time",
icon="mdi:timer-plus",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.MINUTES
),
NumberEntityDescription(
key="startProgram.dryLevel",
name="Dry level",
entity_category=EntityCategory.CONFIG,
icon="mdi:hair-dryer",
translation_key="tumbledryerdrylevel"
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="delay_time",
),
NumberEntityDescription(
key="startProgram.tempLevel",
name="Temperature level",
entity_category=EntityCategory.CONFIG,
icon="mdi:thermometer",
translation_key="tumbledryertemplevel"
translation_key="tumbledryertemplevel",
),
NumberEntityDescription(
key="startProgram.antiCreaseTime",
name="Anti-Crease time",
key="startProgram.dryTime",
name="Dry Time",
entity_category=EntityCategory.CONFIG,
icon="mdi:timer",
native_unit_of_measurement=UnitOfTime.MINUTES
),
NumberEntityDescription(
key="startProgram.sterilizationStatus",
name="Sterilization status",
icon="mdi:clock-start",
entity_category=EntityCategory.CONFIG
translation_key="dry_time",
),
),
"WD": (
@ -80,7 +72,8 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
name="Delay Time",
icon="mdi:timer-plus",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.MINUTES
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="delay_time",
),
),
"OV": (
@ -89,45 +82,90 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
name="Delay time",
icon="mdi:timer-plus",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.MINUTES
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="delay_time",
),
NumberEntityDescription(
key="startProgram.tempSel",
name="Target Temperature",
entity_category=EntityCategory.CONFIG,
icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="target_temperature",
),
NumberEntityDescription(
key="startProgram.prTime",
name="Program Duration",
entity_category=EntityCategory.CONFIG,
icon="mdi:timelapse",
native_unit_of_measurement=UnitOfTime.MINUTES
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="program_duration",
),
),
"IH": (
NumberEntityDescription(
key="startProgram.temp",
name="Temperature",
entity_category=EntityCategory.CONFIG,
icon="mdi:thermometer",
translation_key="temperature",
),
NumberEntityDescription(
key="startProgram.powerManagement",
name="Power Management",
entity_category=EntityCategory.CONFIG,
icon="mdi:timelapse",
translation_key="power_management",
),
),
"DW": (
NumberEntityDescription(
key="startProgram.delayTime",
name="Delay time",
icon="mdi:timer-plus",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="delay_time",
),
NumberEntityDescription(
key="startProgram.waterHard",
name="Water hard",
icon="mdi:water",
entity_category=EntityCategory.CONFIG,
translation_key="water_hard",
),
),
"AC": (
NumberEntityDescription(
key="startProgram.tempSel",
name="Target Temperature",
entity_category=EntityCategory.CONFIG,
icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="target_temperature",
),
),
}
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
hon: HonConnection = hass.data[DOMAIN][entry.unique_id]
hon: Hon = hass.data[DOMAIN][entry.unique_id]
coordinators = hass.data[DOMAIN]["coordinators"]
appliances = []
for device in hon.devices:
if device.mac_address in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
for device in hon.appliances:
if device.unique_id in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
else:
coordinator = HonCoordinator(hass, device)
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
await coordinator.async_config_entry_first_refresh()
if descriptions := NUMBERS.get(device.appliance_type):
for description in descriptions:
if not device.settings.get(description.key):
if description.key not in device.available_settings:
continue
appliances.extend([
HonNumberEntity(hass, coordinator, entry, device, description)]
appliances.extend(
[HonNumberEntity(hass, coordinator, entry, device, description)]
)
async_add_entities(appliances)
@ -153,8 +191,14 @@ class HonNumberEntity(HonEntity, NumberEntity):
return self._device.get(self.entity_description.key)
async def async_set_native_value(self, value: float) -> None:
self._device.settings[self.entity_description.key].value = value
await self.coordinator.async_request_refresh()
setting = self._device.settings[self.entity_description.key]
if not (
isinstance(setting, HonParameter) or isinstance(setting, HonParameterFixed)
):
setting.value = value
if self._device.appliance_type in ["AC"]:
self._device.commands["startProgram"].send()
await self.coordinator.async_refresh()
@callback
def _handle_coordinator_update(self):

View File

@ -1,10 +1,11 @@
from __future__ import annotations
import logging
import time
from pyhon import HonConnection
from pyhon.device import HonDevice
from pyhon.parameter import HonParameterFixed
from pyhon import Hon
from pyhon.appliance import HonAppliance
from pyhon.parameter.fixed import HonParameterFixed
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.config_entries import ConfigEntry
@ -24,20 +25,22 @@ SELECTS = {
name="Spin speed",
entity_category=EntityCategory.CONFIG,
icon="mdi:numeric",
unit_of_measurement=REVOLUTIONS_PER_MINUTE
unit_of_measurement=REVOLUTIONS_PER_MINUTE,
translation_key="spin_speed",
),
SelectEntityDescription(
key="startProgram.temp",
name="Temperature",
entity_category=EntityCategory.CONFIG,
icon="mdi:thermometer",
unit_of_measurement=UnitOfTemperature.CELSIUS
unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="temperature",
),
SelectEntityDescription(
key="startProgram.program",
name="Program",
entity_category=EntityCategory.CONFIG,
translation_key="programs"
translation_key="programs_wm",
),
),
"TD": (
@ -45,14 +48,22 @@ SELECTS = {
key="startProgram.program",
name="Program",
entity_category=EntityCategory.CONFIG,
translation_key="programs"
translation_key="programs_td",
),
SelectEntityDescription(
key="startProgram.dryTimeMM",
name="Time",
name="Dry Time",
entity_category=EntityCategory.CONFIG,
icon="mdi:timer",
unit_of_measurement=UnitOfTime.MINUTES
unit_of_measurement=UnitOfTime.MINUTES,
translation_key="dry_time",
),
SelectEntityDescription(
key="startProgram.dryLevel",
name="Dry level",
entity_category=EntityCategory.CONFIG,
icon="mdi:hair-dryer",
translation_key="dry_levels",
),
),
"WD": (
@ -60,7 +71,7 @@ SELECTS = {
key="startProgram.program",
name="Program",
entity_category=EntityCategory.CONFIG,
translation_key="programs"
translation_key="programs_wm",
),
),
"OV": (
@ -68,40 +79,68 @@ SELECTS = {
key="startProgram.program",
name="Program",
entity_category=EntityCategory.CONFIG,
translation_key="programs_ov",
),
),
"IH": (
SelectEntityDescription(
key="startProgram.program",
name="Program",
entity_category=EntityCategory.CONFIG,
translation_key="programs_ih",
),
),
"DW": (
SelectEntityDescription(
key="startProgram.program",
name="Program",
entity_category=EntityCategory.CONFIG,
translation_key="programs_dw",
),
),
"AC": (
SelectEntityDescription(
key="startProgram.program",
name="Program",
entity_category=EntityCategory.CONFIG,
translation_key="programs_ac",
),
SelectEntityDescription(
key="startProgram.preheatStatus",
name="Preheat",
entity_category=EntityCategory.CONFIG
key="startProgram.humanSensingStatus",
name="Eco Pilot",
entity_category=EntityCategory.CONFIG,
translation_key="eco_pilot",
),
),
}
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
hon: HonConnection = hass.data[DOMAIN][entry.unique_id]
hon: Hon = hass.data[DOMAIN][entry.unique_id]
coordinators = hass.data[DOMAIN]["coordinators"]
appliances = []
for device in hon.devices:
if device.mac_address in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
for device in hon.appliances:
if device.unique_id in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
else:
coordinator = HonCoordinator(hass, device)
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
await coordinator.async_config_entry_first_refresh()
if descriptions := SELECTS.get(device.appliance_type):
for description in descriptions:
if not device.settings.get(description.key):
if description.key not in device.available_settings:
continue
appliances.extend([
HonSelectEntity(hass, coordinator, entry, device, description)]
appliances.extend(
[HonSelectEntity(hass, coordinator, entry, device, description)]
)
async_add_entities(appliances)
class HonSelectEntity(HonEntity, SelectEntity):
def __init__(self, hass, coordinator, entry, device: HonDevice, description) -> None:
def __init__(
self, hass, coordinator, entry, device: HonAppliance, description
) -> None:
super().__init__(hass, entry, coordinator, device)
self._coordinator = coordinator
@ -116,21 +155,26 @@ class HonSelectEntity(HonEntity, SelectEntity):
@property
def current_option(self) -> str | None:
value = self._device.settings[self.entity_description.key].value
if value is None or value not in self._attr_options:
value = self._device.settings.get(self.entity_description.key)
if value is None or value.value not in self._attr_options:
return None
return value
return value.value
async def async_select_option(self, option: str) -> None:
self._device.settings[self.entity_description.key].value = option
await self.coordinator.async_request_refresh()
if self._device.appliance_type in ["AC"]:
self._device.commands["startProgram"].send()
await self.coordinator.async_refresh()
@callback
def _handle_coordinator_update(self):
setting = self._device.settings[self.entity_description.key]
if not isinstance(self._device.settings[self.entity_description.key], HonParameterFixed):
self._attr_options: list[str] = setting.values
setting = self._device.settings.get(self.entity_description.key)
if setting is None:
self._attr_available = False
self._attr_options: list[str] = []
self._attr_native_value = None
else:
self._attr_options = [setting.value]
self._attr_available = True
self._attr_options: list[str] = setting.values
self._attr_native_value = setting.value
self.async_write_ha_state()

View File

@ -1,6 +1,6 @@
import logging
from pyhon import HonConnection
from pyhon import Hon
from homeassistant.components.sensor import (
SensorEntity,
@ -16,11 +16,12 @@ from homeassistant.const import (
UnitOfMass,
UnitOfPower,
UnitOfTime,
UnitOfTemperature
UnitOfTemperature,
)
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
@ -29,25 +30,34 @@ _LOGGER = logging.getLogger(__name__)
SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
"WM": (
SensorEntityDescription(
key="prPhase",
name="Program Phase",
icon="mdi:washing-machine",
translation_key="program_phases_wm",
),
SensorEntityDescription(
key="totalElectricityUsed",
name="Total Power",
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
translation_key="energy_total",
),
SensorEntityDescription(
key="totalWaterUsed",
name="Total Water",
device_class=SensorDeviceClass.WATER,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfVolume.LITERS
native_unit_of_measurement=UnitOfVolume.LITERS,
translation_key="water_total",
),
SensorEntityDescription(
key="totalWashCycle",
name="Total Wash Cycle",
state_class=SensorStateClass.TOTAL_INCREASING,
icon="mdi:counter"
icon="mdi:counter",
translation_key="cycles_total",
),
SensorEntityDescription(
key="currentElectricityUsed",
@ -55,13 +65,15 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.POWER,
native_unit_of_measurement=UnitOfPower.KILO_WATT,
icon="mdi:lightning-bolt"
icon="mdi:lightning-bolt",
translation_key="energy_current",
),
SensorEntityDescription(
key="currentWaterUsed",
name="Current Water Used",
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:water"
icon="mdi:water",
translation_key="water_current",
),
SensorEntityDescription(
key="startProgram.weight",
@ -69,19 +81,17 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfMass.KILOGRAMS,
icon="mdi:weight-kilogram"
icon="mdi:weight-kilogram",
translation_key="suggested_load",
),
SensorEntityDescription(
key="machMode",
name="Machine Status",
icon="mdi:information",
translation_key="mode"
translation_key="washing_modes",
),
SensorEntityDescription(
key="errors",
name="Error",
icon="mdi:math-log",
translation_key="errors"
key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
),
SensorEntityDescription(
key="remainingTimeMM",
@ -89,6 +99,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
icon="mdi:timer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="remaining_time",
),
SensorEntityDescription(
key="spinSpeed",
@ -96,6 +107,38 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
icon="mdi:speedometer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="spin_speed",
),
SensorEntityDescription(
key="startProgram.energyLabel",
name="Energy Label",
icon="mdi:lightning-bolt-circle",
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.CONFIG,
translation_key="energy_label",
),
SensorEntityDescription(
key="startProgram.liquidDetergentDose",
name="Liquid Detergent Dose",
icon="mdi:cup-water",
entity_category=EntityCategory.CONFIG,
translation_key="det_liquid",
),
SensorEntityDescription(
key="startProgram.powderDetergentDose",
name="Powder Detergent Dose",
icon="mdi:cup",
entity_category=EntityCategory.CONFIG,
translation_key="det_dust",
),
SensorEntityDescription(
key="startProgram.remainingTime",
name="Remaining Time",
icon="mdi:timer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
entity_category=EntityCategory.CONFIG,
translation_key="remaining_time",
),
),
"TD": (
@ -103,13 +146,10 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
key="machMode",
name="Machine Status",
icon="mdi:information",
translation_key="mode"
translation_key="washing_modes",
),
SensorEntityDescription(
key="errors",
name="Error",
icon="mdi:math-log",
translation_key="errors"
key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
),
SensorEntityDescription(
key="remainingTimeMM",
@ -117,6 +157,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
icon="mdi:timer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="remaining_time",
),
SensorEntityDescription(
key="delayTime",
@ -124,38 +165,104 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
icon="mdi:clock-start",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="delay_time",
),
SensorEntityDescription(
key="prCode",
name="Program",
icon="mdi:tumble-dryer",
translation_key="tumbledryerprogram"
translation_key="tumbledryerprogram",
),
SensorEntityDescription(
key="prPhase",
name="Program Phase",
icon="mdi:tumble-dryer",
translation_key="tumbledryerprogramphase"
icon="mdi:washing-machine",
translation_key="program_phases_td",
),
SensorEntityDescription(
key="dryLevel",
name="Dry level",
icon="mdi:hair-dryer",
translation_key="tumbledryerdrylevel"
translation_key="dry_levels",
),
SensorEntityDescription(
key="tempLevel",
name="Temperature level",
icon="mdi:thermometer",
translation_key="tumbledryertemplevel"
translation_key="tumbledryertemplevel",
),
SensorEntityDescription(
key="startProgram.suggestedLoadD",
name="Suggested Load",
icon="mdi:weight-kilogram",
entity_category=EntityCategory.CONFIG,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfMass.KILOGRAMS,
translation_key="suggested_load",
),
SensorEntityDescription(
key="startProgram.energyLabel",
name="Energy Label",
icon="mdi:lightning-bolt-circle",
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.CONFIG,
translation_key="energy_label",
),
),
"WD": (
SensorEntityDescription(
key="totalElectricityUsed",
name="Total Power",
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
translation_key="energy_total",
),
SensorEntityDescription(
key="totalWaterUsed",
name="Total Water",
device_class=SensorDeviceClass.WATER,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfVolume.LITERS,
translation_key="water_total",
),
SensorEntityDescription(
key="totalWashCycle",
name="Total Wash Cycle",
state_class=SensorStateClass.TOTAL_INCREASING,
icon="mdi:counter",
translation_key="cycles_total",
),
SensorEntityDescription(
key="currentElectricityUsed",
name="Current Electricity Used",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.POWER,
native_unit_of_measurement=UnitOfPower.KILO_WATT,
icon="mdi:lightning-bolt",
translation_key="energy_current",
),
SensorEntityDescription(
key="currentWaterUsed",
name="Current Water Used",
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:water",
translation_key="water_current",
),
SensorEntityDescription(
key="startProgram.weight",
name="Suggested weight",
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfMass.KILOGRAMS,
icon="mdi:weight-kilogram",
translation_key="suggested_load",
),
SensorEntityDescription(
key="machMode",
name="Machine Status",
icon="mdi:information",
translation_key="mode"
translation_key="washing_modes",
),
SensorEntityDescription(
key="spinSpeed",
@ -163,6 +270,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
icon="mdi:fast-forward-outline",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
translation_key="spin_speed",
),
SensorEntityDescription(
key="remainingTimeMM",
@ -170,31 +278,37 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
icon="mdi:timer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="remaining_time",
),
SensorEntityDescription(
key="prCode",
name="Current Program",
icon="mdi:tumble-dryer",
translation_key="programs",
),
SensorEntityDescription(
key="prPhase",
name="Program Phase",
icon="mdi:tumble-dryer",
icon="mdi:washing-machine",
translation_key="program_phases_wm",
),
SensorEntityDescription(
key="dryLevel",
name="Dry level",
icon="mdi:hair-dryer",
translation_key="dry_levels",
),
SensorEntityDescription(
key="dirtyLevel",
name="Dirt level",
icon="mdi:liquid-spot",
translation_key="dirt_level",
),
SensorEntityDescription(
key="steamLevel",
name="Steam level",
icon="mdi:smoke",
translation_key="steam_level",
),
SensorEntityDescription(
key="temp",
@ -202,6 +316,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
icon="mdi:thermometer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="temperature",
),
),
"OV": (
@ -210,45 +325,157 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
name="Remaining Time",
icon="mdi:timer",
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="remaining_time",
),
SensorEntityDescription(
key="delayTime",
name="Start Time",
icon="mdi:clock-start",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="delay_time",
),
SensorEntityDescription(
key="temp",
name="Temperature",
icon="mdi:thermometer",
translation_key="temperature",
),
SensorEntityDescription(
key="tempSel",
name="Temperature Selected",
icon="mdi:thermometer",
translation_key="target_temperature",
),
),
"IH": (
SensorEntityDescription(
key="remainingTimeMM",
name="Remaining Time",
icon="mdi:timer",
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="remaining_time",
),
SensorEntityDescription(
key="temp",
name="Temperature",
icon="mdi:thermometer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="temperature",
),
SensorEntityDescription(
key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
),
SensorEntityDescription(
key="power",
name="Power",
icon="mdi:lightning-bolt",
state_class=SensorStateClass.MEASUREMENT,
translation_key="power",
),
),
"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,
translation_key="water_efficiency",
),
SensorEntityDescription(
key="startProgram.waterSaving",
name="Water Saving",
icon="mdi:water-percent",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.CONFIG,
translation_key="water_saving",
),
SensorEntityDescription(
key="startProgram.temp",
name="Temperature",
icon="mdi:thermometer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
entity_category=EntityCategory.CONFIG,
translation_key="temperature",
),
SensorEntityDescription(
key="startProgram.energyLabel",
name="Energy Label",
icon="mdi:lightning-bolt-circle",
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.CONFIG,
translation_key="energy_label",
),
SensorEntityDescription(
key="startProgram.remainingTime",
name="Time",
icon="mdi:timer",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
entity_category=EntityCategory.CONFIG,
translation_key="duration",
),
SensorEntityDescription(
key="machMode",
name="Machine Status",
icon="mdi:information",
translation_key="washing_modes",
),
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,
translation_key="remaining_time",
),
SensorEntityDescription(
key="prPhase",
name="Program Phase",
icon="mdi:washing-machine",
translation_key="program_phases_dw",
),
),
}
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
hon: HonConnection = hass.data[DOMAIN][entry.unique_id]
hon: Hon = hass.data[DOMAIN][entry.unique_id]
coordinators = hass.data[DOMAIN]["coordinators"]
appliances = []
for device in hon.devices:
if device.mac_address in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
for device in hon.appliances:
if device.unique_id in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
else:
coordinator = HonCoordinator(hass, device)
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
await coordinator.async_config_entry_first_refresh()
if descriptions := SENSORS.get(device.appliance_type):
for description in descriptions:
if not device.get(description.key):
_LOGGER.warning("[%s] Can't setup %s", device.appliance_type, description.key)
if not device.get(description.key) and not device.settings.get(
description.key
):
_LOGGER.warning(
"[%s] Can't setup %s", device.appliance_type, description.key
)
continue
appliances.extend([
HonSensorEntity(hass, coordinator, entry, device, description)]
appliances.extend(
[HonSensorEntity(hass, coordinator, entry, device, description)]
)
async_add_entities(appliances)
@ -265,9 +492,15 @@ class HonSensorEntity(HonEntity, SensorEntity):
@property
def native_value(self) -> StateType:
return self._device.get(self.entity_description.key, "")
value = self._device.get(self.entity_description.key, "")
if not value and self.entity_description.state_class is not None:
return 0
return value
@callback
def _handle_coordinator_update(self):
self._attr_native_value = self._device.get(self.entity_description.key, "")
value = self._device.get(self.entity_description.key, "")
if not value and self.entity_description.state_class is not None:
self._attr_native_value = 0
self._attr_native_value = value
self.async_write_ha_state()

View File

@ -1,13 +1,13 @@
import logging
from dataclasses import dataclass
from typing import Any
from homeassistant.components.switch import SwitchEntityDescription, SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from pyhon import HonConnection
from pyhon.device import HonDevice
from pyhon import Hon
from pyhon.appliance import HonAppliance
from pyhon.parameter.range import HonParameterRange
from .const import DOMAIN
from .hon import HonCoordinator, HonEntity
@ -22,9 +22,9 @@ class HonSwitchEntityDescriptionMixin:
@dataclass
class HonSwitchEntityDescription(HonSwitchEntityDescriptionMixin,
SwitchEntityDescription
):
class HonSwitchEntityDescription(
HonSwitchEntityDescriptionMixin, SwitchEntityDescription
):
pass
@ -36,6 +36,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
icon="mdi:washing-machine",
turn_on_key="startProgram",
turn_off_key="stopProgram",
translation_key="washing_machine",
),
HonSwitchEntityDescription(
key="pause",
@ -43,18 +44,28 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
icon="mdi:pause",
turn_on_key="pauseProgram",
turn_off_key="resumeProgram",
translation_key="pause",
),
HonSwitchEntityDescription(
key="startProgram.delayStatus",
name="Delay Status",
icon="mdi:timer-check",
entity_category=EntityCategory.CONFIG
entity_category=EntityCategory.CONFIG,
translation_key="delay_time",
),
HonSwitchEntityDescription(
key="startProgram.haier_SoakPrewashSelection",
name="Soak Prewash Selection",
icon="mdi:tshirt-crew",
entity_category=EntityCategory.CONFIG
entity_category=EntityCategory.CONFIG,
translation_key="prewash",
),
HonSwitchEntityDescription(
key="startProgram.autoSoftenerStatus",
name="Keep Fresh",
entity_category=EntityCategory.CONFIG,
icon="mdi:refresh-circle",
translation_key="keep_fresh",
),
),
"TD": (
@ -64,6 +75,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
icon="mdi:tumble-dryer",
turn_on_key="startProgram",
turn_off_key="stopProgram",
translation_key="tumble_dryer",
),
HonSwitchEntityDescription(
key="pause",
@ -71,6 +83,44 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
icon="mdi:pause",
turn_on_key="pauseProgram",
turn_off_key="resumeProgram",
translation_key="pause",
),
HonSwitchEntityDescription(
key="startProgram.sterilizationStatus",
name="Sterilization",
icon="mdi:clock-start",
entity_category=EntityCategory.CONFIG,
),
HonSwitchEntityDescription(
key="startProgram.antiCreaseTime",
name="Anti-Crease",
entity_category=EntityCategory.CONFIG,
icon="mdi:timer",
translation_key="anti_crease",
),
HonSwitchEntityDescription(
key="startProgram.anticrease",
name="Anti-Crease",
entity_category=EntityCategory.CONFIG,
icon="mdi:timer",
translation_key="anti_crease",
),
),
"OV": (
HonSwitchEntityDescription(
key="active",
name="Oven",
icon="mdi:toaster-oven",
turn_on_key="startProgram",
turn_off_key="stopProgram",
translation_key="oven",
),
HonSwitchEntityDescription(
key="startProgram.preheatStatus",
name="Preheat",
icon="mdi:thermometer-chevron-up",
entity_category=EntityCategory.CONFIG,
translation_key="preheat",
),
),
"WD": (
@ -80,6 +130,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
icon="mdi:washing-machine",
turn_on_key="startProgram",
turn_off_key="stopProgram",
translation_key="washer_dryer",
),
HonSwitchEntityDescription(
key="pause",
@ -87,31 +138,148 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
icon="mdi:pause",
turn_on_key="pauseProgram",
turn_off_key="resumeProgram",
translation_key="pause",
),
),
"DW": (
HonSwitchEntityDescription(
key="active",
name="Dish Washer",
icon="mdi:dishwasher",
turn_on_key="startProgram",
turn_off_key="stopProgram",
translation_key="dish_washer",
),
HonSwitchEntityDescription(
key="startProgram.extraDry",
name="Extra Dry",
icon="mdi:hair-dryer",
entity_category=EntityCategory.CONFIG,
translation_key="extra_dry",
),
HonSwitchEntityDescription(
key="startProgram.halfLoad",
name="Half Load",
icon="mdi:fraction-one-half",
entity_category=EntityCategory.CONFIG,
translation_key="half_load",
),
HonSwitchEntityDescription(
key="startProgram.openDoor",
name="Open Door",
icon="mdi:door-open",
entity_category=EntityCategory.CONFIG,
translation_key="open_door",
),
HonSwitchEntityDescription(
key="startProgram.threeInOne",
name="Three in One",
icon="mdi:numeric-3-box-outline",
entity_category=EntityCategory.CONFIG,
translation_key="three_in_one",
),
HonSwitchEntityDescription(
key="startProgram.ecoExpress",
name="Eco Express",
icon="mdi:sprout",
entity_category=EntityCategory.CONFIG,
translation_key="eco",
),
HonSwitchEntityDescription(
key="startProgram.addDish",
name="Add Dish",
icon="mdi:silverware-fork-knife",
entity_category=EntityCategory.CONFIG,
translation_key="add_dish",
),
),
"AC": (
HonSwitchEntityDescription(
key="startProgram.10degreeHeatingStatus",
name="10° Heating",
entity_category=EntityCategory.CONFIG,
translation_key="10_degree_heating",
),
HonSwitchEntityDescription(
key="startProgram.echoStatus",
name="Echo",
entity_category=EntityCategory.CONFIG,
),
HonSwitchEntityDescription(
key="startProgram.ecoMode",
name="Eco Mode",
entity_category=EntityCategory.CONFIG,
translation_key="eco_mode",
),
HonSwitchEntityDescription(
key="startProgram.healthMode",
name="Health Mode",
entity_category=EntityCategory.CONFIG,
),
HonSwitchEntityDescription(
key="startProgram.muteStatus",
name="Mute",
entity_category=EntityCategory.CONFIG,
translation_key="mute_mode",
),
HonSwitchEntityDescription(
key="startProgram.rapidMode",
name="Rapid Mode",
entity_category=EntityCategory.CONFIG,
translation_key="rapid_mode",
),
HonSwitchEntityDescription(
key="startProgram.screenDisplayStatus",
name="Screen Display",
entity_category=EntityCategory.CONFIG,
),
HonSwitchEntityDescription(
key="startProgram.selfCleaning56Status",
name="Self Cleaning 56",
entity_category=EntityCategory.CONFIG,
translation_key="self_clean_56",
),
HonSwitchEntityDescription(
key="startProgram.selfCleaningStatus",
name="Self Cleaning",
entity_category=EntityCategory.CONFIG,
translation_key="self_clean",
),
HonSwitchEntityDescription(
key="startProgram.silentSleepStatus",
name="Silent Sleep",
entity_category=EntityCategory.CONFIG,
translation_key="silent_mode",
),
),
}
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
hon: HonConnection = hass.data[DOMAIN][entry.unique_id]
hon: Hon = hass.data[DOMAIN][entry.unique_id]
coordinators = hass.data[DOMAIN]["coordinators"]
appliances = []
for device in hon.devices:
if device.mac_address in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
for device in hon.appliances:
if device.unique_id in coordinators:
coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
else:
coordinator = HonCoordinator(hass, device)
hass.data[DOMAIN]["coordinators"][device.mac_address] = coordinator
hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
await coordinator.async_config_entry_first_refresh()
if descriptions := SWITCHES.get(device.appliance_type):
for description in descriptions:
if device.get(description.key) is not None or device.commands.get(description.key) is not None:
appliances.extend([
HonSwitchEntity(hass, coordinator, entry, device, description)]
if (
device.get(description.key) is not None
or description.key in device.available_settings
):
appliances.extend(
[HonSwitchEntity(hass, coordinator, entry, device, description)]
)
else:
_LOGGER.warning("[%s] Can't setup %s", device.appliance_type, description.key)
_LOGGER.warning(
"[%s] Can't setup %s", device.appliance_type, description.key
)
async_add_entities(appliances)
@ -119,38 +287,54 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
class HonSwitchEntity(HonEntity, SwitchEntity):
entity_description: HonSwitchEntityDescription
def __init__(self, hass, coordinator, entry, device: HonDevice, description: HonSwitchEntityDescription) -> None:
def __init__(
self,
hass,
coordinator,
entry,
device: HonAppliance,
description: HonSwitchEntityDescription,
) -> None:
super().__init__(hass, entry, coordinator, device)
self._coordinator = coordinator
self._device = device
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."""
if self.entity_category == EntityCategory.CONFIG:
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.get(self.entity_description.key, False)
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()
if self._device.appliance_type in ["AC"]:
self._device.commands["startProgram"].send()
await self.coordinator.async_refresh()
else:
await self._device.commands[self.entity_description.turn_on_key].send()
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()
if self._device.appliance_type in ["AC"]:
self._device.commands["startProgram"].send()
await self.coordinator.async_refresh()
else:
await self._device.commands[self.entity_description.turn_off_key].send()

View File

@ -30,7 +30,7 @@
"8000000000000": "E4: Провери подаването на вода"
}
},
"tumbledryerprogram": {
"programs": {
"state": {
"0": "Стандартна",
"62": "Памук",
@ -49,7 +49,7 @@
"103": "Отдалечен"
}
},
"tumbledryerprogramphase": {
"program_phases_td": {
"state": {
"0": "Изчаване",
"2": "Сушене",
@ -65,7 +65,7 @@
"4": "Висока температура L-3"
}
},
"tumbledryerdrylevel": {
"dry_levels": {
"state": {
"3": "Готови за съхранение",
"12": "Готови за гладене H-1",
@ -75,334 +75,12 @@
}
},
"select": {
"programs": {
"dry_levels": {
"state": {
"20_degrees_coloured_cottons": "20° Colored and Cottons",
"20_degrees_new_energy_label": "20°C",
"active_steam": "Steam",
"active_wash": "Active Wash",
"active_wash_steam": "Active Wash + Steam",
"allergy_care": "Allergy Care",
"allergy_care_pro": "Allergy Care Pro",
"all_in_one_49": "All in One 49'",
"all_in_one_59": "All in One 59'",
"all_in_one_59_steam": "Active Wash + Steam",
"autocare": "Autocare",
"autoclean": "Drum Cleaning",
"baby_60": "All Baby 60°C",
"care_14": "Rapid Care 14'",
"care_30": "Rapid Care 30'",
"care_44": "Rapid Care 44'",
"checkup": "Check-Up",
"colour_59": "Colored 59'",
"colour_59_steam": "Colored 59' + Steam",
"cottons": "Cotton",
"cottons_prewash": "Cottons + Prewash",
"cottons_steam": "Cotton + Steam",
"cotton_care_59": "Cotton Care 59'",
"delicate_59": "Delicate 59'",
"delicate_silk": "Delicate and Silk",
"delicate_silk_steam": "Delicate and Silk + Steam",
"delicati_59": "Delicate 59'",
"delicati_59_steam": "Delicate 59' + Steam",
"drain_spin": "Drain + Spin",
"easy_iron": "Easy Iron",
"eco_40_60_new_energy_label": "Eco 40-60",
"extra_care": "Extra Care",
"fitness": "Fitness Care",
"fitness_care": "Fitness Care",
"fresh_care": "Fresh Care",
"fresh_care_steam": "Fresh Care + Steam",
"handwash_wool": "Hand Wash + Wool",
"high_dry": "High Heat Dry",
"hqd_20_degrees": "Cotton 20℃",
"hqd_allergy": "Allergy Care",
"hqd_autoclean": "Автоматично почистване",
"hqd_babycare": "Бебе",
"hqd_baby_care": "Бебе",
"hqd_bath_towel": "Хавлиени кърпи",
"hqd_bed_sheets": "Чаршафи",
"hqd_checkup": "Check-Up",
"hqd_bulky": "Обемисти",
"hqd_casual": "Ежедневни",
"hqd_cold_wind_30": "Студен бриз 30 мин",
"hqd_cold_wind_timing": "Студен бриз за време",
"hqd_cotton": "Памук",
"hqd_cottons": "Памук",
"hqd_curtain": "Пердета",
"hqd_delicate": "Деликатни",
"hqd_delicate_cradle": "Деликатни",
"hqd_diaper": "Бебешки пелени",
"hqd_dry": "Cotton Dry",
"hqd_dry_synthetics": "Low Heat Dry",
"hqd_duvet": "Олекотени завивки",
"hqd_eco_40_60_degrees": "Eco 40-60",
"hqd_feather": "Пълнеж от пера(пух)",
"hqd_handwash_wool": "Wool",
"hqd_hot_wind_timing": "Горещ въздух за време",
"hqd_hygienic": "Здравословна",
"hqd_i_refresh": "i-Refresh",
"hqd_i_refresh_pro": "i-Refresh Pro",
"hqd_jacket": "Якета",
"hqd_jeans": "Дънки",
"hqd_luxury": "Луксозно",
"hqd_mix": "Смесен тип",
"hqd_night_dry": "Сушене през ноща",
"hqd_outdoor": "Дрехи за открито",
"hqd_precious_cure": "Precious cure",
"hqd_quick_15": "Бързо 15 мин",
"hqd_quick_20": "Бързо 20 мин",
"hqd_quick_30": "Бързо 30 мин",
"hqd_quick_dry": "Бързо",
"hqd_quick_wash_57": "Quick Wash 57'",
"hqd_quilt": "Юргани",
"hqd_rapid_wash_and_dry": "Wash and dry",
"hqd_refresh": "Освежаване",
"hqd_rinse": "Rinses",
"hqd_school_uniform": "Ученически униформи",
"hqd_shirt": "Ризи",
"hqd_shirts": "Ризи",
"hqd_shoes": "Обувки",
"hqd_silk": "Коприна",
"hqd_smart": "Smart A.I.",
"hqd_spin": "Spin",
"hqd_sport": "Спорт",
"hqd_sports": "Спорт",
"hqd_synthetics": "Синтетика",
"hqd_super_fast": "Супер бързо 39 мин",
"hqd_synthetic_and_coloured": "Synthetics",
"hqd_timer": "Таймер",
"hqd_towel": "Хавлиени кърпи",
"hqd_underwear": "Бельо",
"hqd_warm_up": "Затопляне",
"hqd_wool": "Вълна",
"hqd_working_suit": "Работно облекло",
"hygiene_59": "Hygiene Plus 59'",
"hygiene_60": "Hygiene 60°C",
"hygiene_plus_59": "Hygiene Plus 59'",
"hygiene_plus_59_min": "Hygiene Plus 59'",
"hygiene_pro_4_min": "Hygiene Pro 49'",
"hygiene_pro_49_min": "Hygiene Pro 49'",
"hygiene_pro_steam": "Hygiene Pro + Steam",
"intensive_40": "Intensive 40°C",
"intensive_40_steam": "Intensive 40°C + Steam",
"iot_checkup": "Check-Up",
"iot_dry_air_refresh": "Air Refresh",
"iot_dry_anti_mites": "Anti-mite",
"iot_dry_baby": "Бебе",
"iot_dry_backpacks": "Раници",
"iot_dry_bathrobe": "Халати за баня",
"iot_dry_bed_linen": "Спално бельо",
"iot_dry_cotton": "Памук",
"iot_dry_cotton_dry": "Памук",
"iot_dry_cuddly_toys": "Плюшени играчки",
"iot_dry_curtains": "Пердета",
"iot_dry_dehumidifier": "Humidity Remover",
"iot_dry_delicates": "Деликатни",
"iot_dry_delicates_antiallergy": "Delicates Anti-allergy",
"iot_dry_delicate_tablecloths": "Delicate Tablecloths",
"iot_dry_denim_jeans": "Дънки",
"iot_dry_down_jacket": "Пухени якета",
"iot_dry_duvet": "Олекотени завивки",
"iot_dry_easy_iron_cotton": "Easy Iron - Cotton",
"iot_dry_easy_iron_synthetics": "Easy Iron - Synthetics",
"iot_dry_gym_fit": "Фитнес",
"iot_dry_lingerie": "Деликано бельо",
"iot_dry_mixed": "Смесен тип",
"iot_dry_mixed_dry": "Смесен тип",
"iot_dry_rapid_30": "Бързо 30 мин",
"iot_dry_rapid_59": "Бързо 59 мин",
"iot_dry_rapid_60_min_delicates": "Rapid 60' - Delicates",
"iot_dry_shirts": "Ризи",
"iot_dry_swimsuits_and_bikinis": "Бански",
"iot_dry_synthetics": "Синтетика",
"iot_dry_synthetic_dry": "Synthetic Dry",
"iot_dry_tablecloths": "Покривки",
"iot_dry_technical_fabrics": "Технически тъкани",
"iot_dry_warm_embrace": "Warm Embrace",
"iot_dry_wool": "Вълна",
"iot_dry_wool_dry": "Вълна",
"iot_wash_and_dry": "Wash and dry",
"iot_wash_anti_mites": "Anti-mites",
"iot_wash_anti_odor": "Anti-odour",
"iot_wash_ariel_clean_cycle": "Ariel Ultimate Clean",
"iot_wash_ariel_cold_cycle": "Ariel Cold Clean",
"iot_wash_ariel_fresh_cycle": "Ariel Fresh Clean",
"iot_wash_baby_sanitizer": "Sanitizer",
"iot_wash_baby_sanitizer_steam": "Sanitiser + Steam",
"iot_wash_backpacks": "Backpacks",
"iot_wash_backpacks_zelig": "Backpacks",
"iot_wash_bathrobe": "Bathrobes and Towels",
"iot_wash_bathrobe_steam": "Bathrobe and Towels + Steam",
"iot_wash_bed_linen": "Bed Linen",
"iot_wash_bed_linen_steam": "Bed Linen + Steam",
"iot_wash_bed_linen_zelig": "Bed Linens",
"iot_wash_big_single_load": "Big single load",
"iot_wash_bleaching": "Bleaching",
"iot_wash_blood_stains": "Bloodstains",
"iot_wash_cashmere": "Cashmere",
"iot_wash_chocolate_stains": "Chocolate stains",
"iot_wash_cold_wash": "Cold Wash",
"iot_wash_colored": "Colored",
"iot_wash_colored_anti_stain": "Colored Anti-stain",
"iot_wash_colored_delicate": "Colored Delicate",
"iot_wash_coloured": "Colored",
"iot_wash_coloured_bed_linen": "Colored Bed Linen",
"iot_wash_coloured_bed_linen_steam": "Coloured Bed Linen + Steam",
"iot_wash_coloured_curtains": "Colored Curtains",
"iot_wash_coloured_shirts": "Colored Shirts",
"iot_wash_coloured_shirts_steam": "Colored Shirts + Steam",
"iot_wash_coloured_steam": "Colored + Steam",
"iot_wash_coloured_tableclothes": "Colored Tableclothes",
"iot_wash_coloured_tableclothes_steam": "Coloured Tablecloths + Steam",
"iot_wash_cotton": "Cotton",
"iot_wash_cotton_steam": "Cotton + Steam",
"iot_wash_cuddly_toys": "Cuddly Toys",
"iot_wash_curtains": "Curtains",
"iot_wash_curtains_steam": "Curtains + Steam",
"iot_wash_curtains_zelig": "Curtains",
"iot_wash_dark": "Darks",
"iot_wash_darks_and_coloured_44": "Darks and Colored 44'",
"iot_wash_darks_and_coloured_59": "Darks and Colored 59'",
"iot_wash_darks_and_coloured_xl": "Darks and Colored XL",
"iot_wash_dark_steam": "Darks + Steam",
"iot_wash_dash_clean_cycle": "Dash Ultimate Clean",
"iot_wash_dash_cold_cycle": "Dash Cold Clean",
"iot_wash_dash_fresh_cycle": "Dash Fresh Clean",
"iot_wash_delicate": "Delicates",
"iot_wash_delicate_antiallergy": "Delicate Anti-Allergy",
"iot_wash_delicate_antiallergy_steam": "Delicate Anti-Allergy + Steam",
"iot_wash_delicate_antiallergy_zelig": "Delicate Anti-Allergy",
"iot_wash_delicate_colors": "Delicate Colors",
"iot_wash_delicate_colors_steam": "Delicate Colors + Steam",
"iot_wash_delicate_dark": "Delicate Darks",
"iot_wash_delicate_steam": "Delicates + Steam",
"iot_wash_delicate_tablecloths": "Delicate Tablecloths",
"iot_wash_delicate_tablecloths_steam": "Delicate Tablecloths + Steam",
"iot_wash_delicate_whites": "Delicate Whites",
"iot_wash_denim_jeans": "Denim - Jeans",
"iot_wash_diving_suits": "Diving Suits",
"iot_wash_diving_suits_zelig": "Diving Suits",
"iot_wash_down_jackets": "Down Jackets",
"iot_wash_down_jackets_zelig": "Down Jackets",
"iot_wash_duvet": "Duvet",
"iot_wash_fruit_stains": "Fruit stains",
"iot_wash_gym_fit": "Gym Fit - Fitness",
"iot_wash_handwash": "Handwash",
"iot_wash_handwash_colored": "Handwash Colored",
"iot_wash_handwash_dark": "Handwash Darks",
"iot_wash_lingerie": "Lingerie",
"iot_wash_masks_refresh": "Masks Refresh",
"iot_wash_masks_sanification": "Masks Sanitization",
"iot_wash_masks_sanification_steam": "Mask Sanitisation + Steam",
"iot_wash_mats": "Mats",
"iot_wash_men_s_trousers": "Trousers",
"iot_wash_mixed": "Mixed",
"iot_wash_mixed_steam": "Mixed + Steam",
"iot_wash_mix_and_coloured_44": "Mix and Colored 44'",
"iot_wash_mix_and_coloured_59": "Mix and Colored 59'",
"iot_wash_mix_and_coloured_xl": "Mix and colored XL",
"iot_wash_new_clothes": "New Clothes",
"iot_wash_perfect_white": "Perfect White",
"iot_wash_perfect_white_steam": "Perfect White + Steam",
"iot_wash_pets": "Pet Accessories",
"iot_wash_pets_hair_removal": "Pets Hair Removal",
"iot_wash_pets_odours_stains_removal": "Pets Odours and Stains Removal",
"iot_wash_pets_steam": "Pet Accessories + Steam",
"iot_wash_playsuits": "Playsuits",
"iot_wash_playsuits_steam": "Playsuits + Steam",
"iot_wash_quick_drum_cleaner": "Quick drum cleaner",
"iot_wash_rapid_14": "Rapid 14",
"iot_wash_rapid_30": "Rapid 30",
"iot_wash_rapid_44": "Rapid 44'",
"iot_wash_rapid_59": "Rapid 59'",
"iot_wash_rapid_59_steam": "Rapid 59' + Steam",
"iot_wash_refresh_14_min": "Refresh 14'",
"iot_wash_resistant_colored": "Resistant Colored",
"iot_wash_resistant_dark": "Resistant Darks",
"iot_wash_resistant_whites": "Resistant Whites",
"iot_wash_rinse": "Rinses",
"iot_wash_shirts": "Shirts",
"iot_wash_shirts_steam": "Shirts + Steam",
"iot_wash_silk": "Silk",
"iot_wash_ski_suit": "Ski Suit",
"iot_wash_ski_suit_zelig": "Ski Suit",
"iot_wash_spin": "Spin",
"iot_wash_sport": "Sport",
"iot_wash_sport_anti_odor": "Anti-odour Sportswear",
"iot_wash_sport_anti_odor_zelig": "Anti-odour Sportswear",
"iot_wash_stains_remover": "Stain Remover",
"iot_wash_swimsuits_and_bikinis": "Swimsuits and Bikinis",
"iot_wash_synthetic": "Synthetics",
"iot_wash_synthetic_steam": "Synthetics + Steam",
"iot_wash_tablecloths": "Tablecloths",
"iot_wash_tablecloths_steam": "Tablecloths + Steam",
"iot_wash_technical_fabrics": "Technical Fabrics",
"iot_wash_technical_fabrics_zelig": "Technical Fabrics",
"iot_wash_technical_jackets": "Technical Jackets",
"iot_wash_technical_jackets_zelig": "Technical Jackets",
"iot_wash_trainers": "Trainers",
"iot_wash_whites": "Whites",
"iot_wash_whites_44": "Whites 44'",
"iot_wash_whites_59": "Whites 59'",
"iot_wash_whites_xl": "Whites XL",
"iot_wash_wine_stains": "Wine Stains",
"iot_wash_wool": "Wool",
"jeans": "Jeans",
"jeans_60": "Jeans",
"low_dry": "Low Heat Dry",
"mixed": "Mixed",
"mixed_and_colored_59": "Mixed and Colored 59'",
"mixed_steam": "Mixed + Steam",
"mix_and_colour_59": "Mixed and Colored 59'",
"mix_and_colour_59_steam": "Mixed and Coloured 59' + Steam",
"night_and_day": "Night and Day",
"night_wash": "Night Wash",
"perfect_59": "Perfect 59'",
"perfect_cotton_59": "Perfect Cotton 59'",
"perfect_cotton_59_steam": "Perfect Cotton 59' + Steam",
"perfect_whites_59": "Perfect White 59'",
"rapid_14_min": "Rapid 14'",
"rapid_30_min": "Rapid 30'",
"rapid_44_min": "Rapid 44'",
"rapid_a_class_60": "Rapid 59' A Class",
"rapid_a_class_60_steam": "Rapid 59' A Class + Steam",
"rapid_wash_and_dry_59_min": "Wash and Dry 59'",
"resistant_cotton": "Resistant Cotton",
"resistant_cotton_steam": "Resistant Cotton + Steam",
"rinse": "Rinse",
"shirts_steam": "Shirts + Steam",
"silent_night": "Silent Night",
"single_item": "Single Item",
"single_item_steam": "Single Item + Steam",
"smart_wash": "Smart Wash",
"soft_care": "Soft Care",
"soft_care_steam": "Soft Care + Steam",
"soft_care_steam_title": "Soft Care + Steam",
"special_39": "Special 39'",
"special_39_full_load": "Special 39'",
"special_39_full_load_steam": "Special 39' + Steam",
"special_49": "Special 49'",
"sport_39": "Sport 39'",
"sport_plus_29": "Sport Plus 29'",
"sport_plus_39": "Sport Plus 39'",
"steam_39": "Steam 39'",
"steam_care_pro": "Steam Care Pro",
"steam_care_pro_cotton": "Steam Care Pro - Cottons",
"steam_care_pro_delicates": "Steam Care Pro - Delicates",
"steam_care_pro_synthetic": "Steam Care Pro - Synthetics",
"steam_hygiene_plus": "Hygiene Plus + Steam",
"synthetics": "Synthetics",
"synthetic_and_coloured": "Synthetic and Colored",
"synthetic_and_coloured_steam": "Synthetic and Coloured + Steam",
"tailored_resistant_cotton": "Tailored Resistant Cotton",
"tailored_synthetic_and_coloured": "Tailored Synthetic Colored",
"total_care": "Total Care",
"tumbling": "Tumbling",
"wool": "Wool",
"wool_and_delicates_49": "Wool and Delicates 49'",
"wool_dry": "Wool Dry",
"wool_soft_care": "Wool and Soft Car"
"3": "Готови за съхранение",
"12": "Готови за гладене H-1",
"13": "Готови за съхранение H-2",
"14": "Екстра сухо H-3"
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,9 @@
"config": {
"step": {
"user": {
"description": "Please enters your hOn credentials",
"description": "Do the login",
"data": {
"email": "Email Address",
"email": "Email",
"password": "Password"
}
}
@ -28,9 +28,10 @@
"00": "No error",
"100000000000": "E2: Check if the door is closed",
"8000000000000": "E4: Check the water supply"
}
},
"tumbledryerprogram": {
"name": "Error"
},
"programs": {
"state": {
"0": "Default",
"62": "Cotton",
@ -47,15 +48,8 @@
"85": "Quick Dry",
"92": "Delicate",
"103": "Remote"
}
},
"tumbledryerprogramphase": {
"state": {
"0": "Waiting",
"2": "Drying",
"3": "Cooldown",
"11": "11"
}
"name": "Current program"
},
"tumbledryertemplevel": {
"state": {
@ -65,17 +59,603 @@
"4": "High temperature L-3"
}
},
"tumbledryerdrylevel": {
"mode_dw": {
"state": {
"3": "Cupboard dry",
"12": "Ready to Iron H-1",
"13": "Ready to Store H-2",
"14": "Extra Dry H-3"
"0": "Disconnected",
"1": "Ready",
"2": "Running",
"3": "Delayed start",
"5": "Delayed start cancelled",
"7": "Finished"
}
},
"washing_modes": {
"state": {
"0": "Ready",
"1": "Ready",
"3": "Pause",
"4": "Scheduled",
"5": "Scheduled",
"6": "Error",
"7": "Ready"
}
},
"program_phases_wm": {
"state": {
"0": "Ready",
"1": "Wash",
"2": "Wash",
"3": "Spin",
"4": "Rinse",
"5": "Rinse",
"6": "Rinse",
"7": "Drying",
"9": "Steam",
"10": "Ready",
"11": "Spin",
"12": "Weighing ",
"13": "Weighing ",
"14": "Wash",
"15": "Wash",
"16": "Wash",
"17": "Rinse",
"18": "Rinse",
"19": "Scheduled",
"20": "Keep Fresh",
"24": "Refresh",
"25": "Wash",
"26": "Heating",
"27": "Wash"
},
"name": "Phase"
},
"program_phases_td": {
"state": {
"0": "Ready",
"1": "Drying",
"2": "Drying",
"3": "Cooldown",
"13": "Cooldown",
"14": "Drying",
"15": "Drying",
"16": "Cooldown",
"18": "Keep Fresh",
"19": "Drying",
"20": "Drying"
},
"name": "Phase"
},
"program_phases_dw": {
"state": {
"0": "Ready",
"1": "Prewash",
"2": "Wash",
"3": "Rinse",
"4": "Drying",
"5": "Ready",
"6": "Hot rinse"
},
"name": "Phase"
},
"dry_levels": {
"state": {
"0": "No drying",
"1": "Iron dry",
"2": "Hang",
"3": "Cupboard Dry",
"4": "Extra dry",
"12": "Iron dry",
"13": "Cupboard Dry",
"14": "Ready to wear",
"15": "Extra dry"
},
"name": "Drying level"
},
"power": {
"name": "Power level"
},
"remaining_time": {
"name": "Time remaining"
},
"temperature": {
"name": "Temperature"
},
"water_efficiency": {
"name": "Water efficiency"
},
"water_saving": {
"name": "Water savings"
},
"duration": {
"name": "Duration"
},
"target_temperature": {
"name": "Target temperature"
},
"spin_speed": {
"name": "Spin"
},
"steam_leve": {
"name": "Steam Level"
},
"dirt_level": {
"name": "Dirt level"
},
"delay_time": {
"name": "Delay Start"
},
"dry_time": {
"name": "Drying time"
},
"suggested_load": {
"name": "Load capacity"
},
"energy_label": {
"name": "Energy efficiency"
},
"det_dust": {
"name": "Powder detergent"
},
"det_liquid": {
"name": "Liquid detergent"
},
"cycles_total": {
"name": "Cycles Total"
},
"energy_total": {
"name": "Energy Consumption Total"
},
"water_total": {
"name": "Water efficiency Total"
},
"energy_current": {
"name": "Energy Consumption Current"
},
"water_current": {
"name": "Water efficiency Current"
},
"mach_modes_ac": {
"state": {
"0": "Auto",
"1": "Cool",
"2": "Cool",
"3": "Dry",
"4": "Heat",
"5": "Fan",
"6": "Fan"
}
}
},
"switch": {
"anti_crease": {
"name": "Anticrease"
},
"add_dish": {
"name": ""
},
"eco_express": {
"name": "Eco"
},
"extra_dry": {
"name": "Extra dry"
},
"half_load": {
"name": "Half load"
},
"open_door": {
"name": "Open door"
},
"three_in_one": {
"name": "3 in 1"
},
"preheat": {
"name": "Preheat"
},
"dish_washer": {
"name": "Dish washer"
},
"tumble_dryer": {
"name": "Tumble dryer"
},
"washing_machine": {
"name": "Washing machine"
},
"washer_dryer": {
"name": "Washer dryer"
},
"oven": {
"name": "Oven"
},
"prewash": {
"name": "Pre-wash "
},
"pause": {
"name": "Pause"
},
"keep_fresh": {
"name": "Keep Fresh"
},
"delay_time": {
"name": "Delay Start"
},
"rapid_mode": {
"name": "Rapid mode"
},
"eco_mode": {
"name": "ECO mode"
},
"10_degree_heating": {
"name": "10°C Heating function"
},
"self_clean": {
"name": "Self-clean"
},
"self_clean_56": {
"name": "Steri-Clean 56°C"
},
"silent_mode": {
"name": "Silent mode"
},
"mute_mode": {
"name": "Mute mode"
}
},
"select": {
"programs": {
"dry_levels": {
"state": {
"0": "No drying",
"1": "Iron dry",
"2": "Hang",
"3": "Cupboard Dry",
"4": "Extra dry",
"12": "Iron dry",
"13": "Cupboard Dry",
"14": "Ready to wear",
"15": "Extra dry"
},
"name": "Drying level"
},
"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_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"
},
"name": "Program"
},
"programs_ih": {
"state": {
"iot_special_ash_brown": "Ash brown",
"iot_special_beef_fillet": "Beef fillet",
"iot_special_beef_veal_stew": "Beef and veal stew",
"iot_special_boiled_rice": "Boiled rice",
"iot_special_chicken_breast": "Chicken breast",
"iot_special_chicken_legs": "Chicken legs",
"iot_special_chocolate_pudding": "Chocolate pudding",
"iot_special_entrecote": "Entrecote",
"iot_special_fresh_tuna": "Fresh tuna",
"iot_special_grilled_vegetables": "Grilled vegetables",
"iot_special_lamb_cutlet": "Lamb cutle",
"iot_special_meatballs": "Meatballs",
"iot_special_minestrone": "Minestrone",
"iot_special_mussels": "Mussels",
"iot_special_omelette": "Omelette",
"iot_special_pancakes": "Pancakes",
"iot_special_paris_style_peas": "Paris style peas",
"iot_special_poached_eggs": "Poached eggs",
"iot_special_pork_fillet": "Pork fillet",
"iot_special_pork_ribs": "Pork ribs",
"iot_special_prawns": "Prawns",
"iot_special_quinoa": "Quinoa",
"iot_special_ratatouille": "Ratatouille",
"iot_special_salmon_fillet": "Salmon fillet",
"iot_special_saute_potatoes": "Saute potatoes",
"iot_special_scallops": "Scallops",
"iot_special_scrambled_eggs": "Scrambled eggs",
"iot_special_spelt": "Spelt",
"iot_special_veggy_noodles": "Veggy noodles",
"iot_special_white_fish_fillet": "White fish fillet",
"iot_standard_boiling": "Boiling",
"iot_standard_frying": "Frying",
"iot_standard_keep_warm": "Keep Warm",
"iot_standard_melting": "Melting",
"iot_standard_simmering": "Simmering"
},
"name": "Program"
},
"programs_ov": {
"state": {
"bakery": "Pasta and Pastries",
"bakery_steam": "Steam-baked bread",
"bottom_heating": "Bottom Heating",
"bottom_heating_fan": "Bottom Heating + Fan",
"bread": "Bread",
"bread_steam": "Steam-baked pastries",
"combi": "Combi",
"convection_fan": "Convection + Fan",
"convection_fan_turnspit": "Convection + Fan + Turnspit",
"conventional": "Conventional",
"conventional_turnspit": "Convection + Turnspit",
"defrost": "Defrost",
"descaling": "Descaling",
"fish": "Fish",
"fish_steam": "Steam-cooked fish",
"grill_cata": "Grill",
"grill_fan_cata": "Grill fan",
"grill_fan_pyro": "Grill + Fan",
"grill_pyro": "Grill",
"h20_clean": "H2O-Clean",
"iot_bread": "Bread",
"iot_h20_clean": "h2O clean",
"leavening": "Leavening",
"light_fan": "Light Fan",
"light_fan\n": "Light Fan",
"low_temp_cooking": "Low Temperature Cooking",
"low_temp_cooking_fish": "Low Temperature Cooking - Fish",
"low_temp_cooking_fish_steam": "Low Temperature Steam Cooking - Fish",
"low_temp_cooking_meat": "Low Temperature Cooking - Meat",
"low_temp_cooking_meat_steam": "Low Temperature Steam Cooking - Meat",
"low_temp_cooking_steam": "Low Temperature Steam Cooking",
"meat": "Meat",
"meat_steam": "Steam-cooked meat",
"multi_level": "Multi-Level",
"paella": "Paella",
"pasta_and_bakery": "Pasta and Bakery",
"pizza": "Pizza",
"pyrolysis": "Pyrolysis",
"pyrolysis_plus": "Pyrolysis +",
"red_meat": "Red Meat",
"red_meat_steam": "Steam-cooked red meat",
"regenerate": "Regeneration",
"soft_plus": "Soft+",
"super_grill": "Super Grill",
"tailor_bake": "Tailor bake",
"tailor_bake_cata": "Tailor Bake",
"tailor_bake_pyro": "Tailor Bake",
"vegetables": "Vegetables",
"vegetables_cata": "Vegetables",
"vegetables_pyro": "Vegetables",
"water_discharge": "Water Drain",
"white_meat": "White Meat",
"white_meat_steam": "Steam-cooked white meat"
},
"name": "Program"
},
"programs_td": {
"state": {
"active_dry": "Active Dry",
"allergy_care": "Anti-allergy",
"all_in_one": "All in One",
"antiallergy": "Anti-allergy",
"anti_odours": "Anti-odours",
"auto_care": "Auto Care",
"baby": "Baby",
"bed_quilt": "Bed Quilt",
"care_30": "Care 30",
"care_45": "Care 45",
"care_59": "Care 59",
"coloured": "Colored",
"daily_45_min": "Daily 45'",
"daily_perfect_59_min": "Daily Perfect 59'",
"darks_and_coloured": "Darks & Colored",
"delicates": "Delicates",
"duvet": "Duvet",
"eco": "Eco Cotton",
"ecospeed_cottons": "Ecospeed Cottons",
"ecospeed_delicates": "Ecospeed Delicates",
"ecospeed_mixed": "Ecospeed Mixed",
"extra_hygiene": "Extra Hygiene",
"fitness": "Fitness",
"fresh_care": "Fresh Care",
"genius": "Genius",
"hqd_baby_care": "Baby Care",
"hqd_bath_towel": "Towels",
"hqd_bed_sheets": "Bed Sheets",
"hqd_bulky": "Bulky Items",
"hqd_casual": "Casual",
"hqd_cold_wind_30": "Cool Breeze 30 minutes",
"hqd_cold_wind_timing": "Cool Breeze ",
"hqd_cotton": "Cotton",
"hqd_curtain": "Curtains",
"hqd_delicate": "Delicates",
"hqd_diaper": "Diapers",
"hqd_duvet": "Duvet",
"hqd_feather": "Down Jackets",
"hqd_hot_wind_timing": "Hot Air",
"hqd_hygienic": "Hygienising",
"hqd_i_refresh": "I-Refresh",
"hqd_i_refresh_pro": "I-Refresh Pro",
"hqd_jacket": "Jackets",
"hqd_jeans": "Jeans",
"hqd_luxury": "Luxury",
"hqd_mix": "Mixed",
"hqd_night_dry": "Overnight drying",
"hqd_outdoor": "Outdoor",
"hqd_precious_cure": "Precious Cure",
"hqd_quick_20": "Quick 20",
"hqd_quick_30": "Quick 30",
"hqd_quick_dry": "Quick dry",
"hqd_quilt": "Quilts",
"hqd_refresh": "Refresh",
"hqd_school_uniform": "School Uniform",
"hqd_shirt": "Shirts",
"hqd_shoes": "Shoes",
"hqd_silk": "Silk",
"hqd_sports": "Sports",
"hqd_synthetics": "Synthetics",
"hqd_timer": "Timed",
"hqd_towel": "Towels",
"hqd_underwear": "Underwear",
"hqd_warm_up": "Warm up",
"hqd_wool": "Wool",
"hqd_working_suit": "Workwear",
"hygiene": "Hygiene",
"iot_checkup": "Check-Up",
"iot_dry_anti_mites": "Anti-mites",
"iot_dry_baby": "Baby",
"iot_dry_backpacks": "Backpacks",
"iot_dry_bathrobe": "Bathrobe",
"iot_dry_bed_linen": "Bed Linen",
"iot_dry_bed_quilt": "Bed Quilt",
"iot_dry_cotton": "Cotton",
"iot_dry_cuddly_toys": "Cuddly Toys",
"iot_dry_curtains": "Curtains",
"iot_dry_dehumidifier": "Humidity Remover",
"iot_dry_delicates": "Delicates",
"iot_dry_delicate_tablecloths": "Delicate Tablecloths",
"iot_dry_denim_jeans": "Denim - Jeans",
"iot_dry_down_jacket": "Jacket",
"iot_dry_duvet": "Duvet",
"iot_dry_easy_iron_cotton": "Super Easy Iron",
"iot_dry_easy_iron_synthetics": "Super Easy Iron Synthetics",
"iot_dry_gym_fit": "Gym fit - Fitness",
"iot_dry_lingerie": "Lingerie",
"iot_dry_mixed": "Mixed",
"iot_dry_playsuits": "Playsuits",
"iot_dry_rapid_30": "Rapid 30",
"iot_dry_rapid_59": "Rapid 59'",
"iot_dry_refresh": "Refresh",
"iot_dry_regenerates_waterproof": "Regenerates Waterproof",
"iot_dry_relax_creases": "Relax Creases",
"iot_dry_shirts": "Shirts",
"iot_dry_small_load": "Small Load",
"iot_dry_swimsuits_and_bikinis": "Swimsuits and Bikinis",
"iot_dry_synthetics": "Synthetics",
"iot_dry_synthetic_dry": "Synthetic Dry",
"iot_dry_tablecloths": "Tablecloths",
"iot_dry_technical_fabrics": "Technical Fabrics",
"iot_dry_warm_embrace": "Warm Embrace",
"iot_dry_wool": "Wool",
"jeans": "Jeans",
"mix_and_dry": "Mix&Dry",
"pets": "Pets",
"pre_iron": "Pre-Iron",
"rapid_30": "Rapid 30",
"rapid_45": "Rapid 45 min",
"rapid_59": "Perfect Rapid 59 Min",
"refresh": "Refresh",
"relax_creases": "Relax Creases",
"saving_30_min": "Saving 30'",
"shirts": "Shirts",
"shoes": "Shoes",
"small_load": "Small Load",
"soft_care": "Soft Care",
"sport_plus": "Sport Plus",
"super_easy_iron_misti": "Super Easy Iron Mixed",
"super_easy_iron_xxl": "Super Easy Iron XXL",
"super_fast_cottons": "Super Fast Cottons",
"super_fast_delicates": "Super Fast Delicates",
"synthetics": "Syntethics",
"total_care": "Total Care",
"trainers": "Trainers",
"ultra_care": "Ultra Care",
"waterproof_revitalize": "Waterproof Revitalize",
"whites": "Whites",
"wool": "Dry Wool",
"woolmark": "Wool",
"xxl_load": "XXL Load",
"zoom_59": "Zoom 59"
},
"name": "Program"
},
"programs_wm": {
"state": {
"20_degrees_coloured_cottons": "20° Colored and Cottons",
"20_degrees_new_energy_label": "20°C",
@ -119,74 +699,45 @@
"hqd_allergy": "Allergy Care",
"hqd_autoclean": "Drum Cleaning",
"hqd_babycare": "Baby Care",
"hqd_baby_care": "Baby care",
"hqd_bath_towel": "Bath towel",
"hqd_bed_sheets": "Bed sheets",
"hqd_bulky": "Bulky",
"hqd_casual": "Casual",
"hqd_checkup": "Check-Up",
"hqd_cold_wind_30": "Cold wind 30'",
"hqd_cold_wind_timing": "Cold wind timing",
"hqd_cotton": "Cotton",
"hqd_cottons": "Cotton",
"hqd_curtain": "Curtain",
"hqd_delicate": "Delicate",
"hqd_delicate_cradle": "Delicate",
"hqd_diaper": "Diaper",
"hqd_dry": "Cotton Dry",
"hqd_dry_synthetics": "Low Heat Dry",
"hqd_duvet": "Duvet",
"hqd_eco_40_60_degrees": "Eco 40-60",
"hqd_feather": "Feather",
"hqd_handwash_wool": "Wool",
"hqd_hot_wind_timing": "Hot wind timing",
"hqd_hygienic": "Hygienic",
"hqd_i_refresh": "i-Refresh",
"hqd_i_refresh_pro": "i-Refresh Pro",
"hqd_jacket": "Jacket",
"hqd_jeans": "Jeans",
"hqd_luxury": "Luxury",
"hqd_mix": "Mix",
"hqd_night_dry": "Night dry",
"hqd_outdoor": "Outdoor",
"hqd_precious_cure": "Precious cure",
"hqd_quick_15": "Quick 15'",
"hqd_quick_20": "Quick 20'",
"hqd_quick_30": "Quick 30'",
"hqd_quick_dry": "Quick dry",
"hqd_quick_wash_57": "Quick Wash 57'",
"hqd_quilt": "Quilt",
"hqd_rapid_wash_and_dry": "Wash and dry",
"hqd_refresh": "Refresh",
"hqd_rinse": "Rinses",
"hqd_school_uniform": "School uniform",
"hqd_shirt": "Shirt",
"hqd_shirts": "Shirts",
"hqd_shoes": "Shoes",
"hqd_silk": "Silk",
"hqd_smart": "Smart A.I.",
"hqd_spin": "Spin",
"hqd_sport": "Sport",
"hqd_sports": "Sports",
"hqd_super_fast": "Super Fast 39'",
"hqd_synthetic_and_coloured": "Synthetics",
"hqd_synthetics": "Synthetics",
"hqd_timer": "Timer",
"hqd_towel": "Towel",
"hqd_underwear": "Underwear",
"hqd_warm_up": "Warm up",
"hqd_wool": "Wool",
"hqd_working_suit": "Working suit",
"hygiene_59": "Hygiene Plus 59'",
"hygiene_60": "Hygiene 60°C",
"hygiene_plus_59": "Hygiene Plus 59'",
"hygiene_plus_59_min": "Hygiene Plus 59'",
"hygiene_pro_4_min": "Hygiene Pro 49'",
"hygiene_pro_49_min": "Hygiene Pro 49'",
"hygiene_pro_steam": "Hygiene Pro + Steam",
"intensive_40": "Intensive 40°C",
"intensive_40_steam": "Intensive 40°C + Steam",
"iot_active_steam": "Steam",
"iot_active_wash_steam": "Active Wash + Steam",
"iot_allergy_care_pro": "Allergy Care Pro",
"iot_all_in_one_59_steam": "Active Wash + Steam",
"iot_checkup": "Check-Up",
"iot_colour_59_steam": "Colored 59' + Steam",
"iot_cottons_steam": "Cotton + Steam",
"iot_delicate_silk_steam": "Delicate and Silk + Steam",
"iot_delicati_59_steam": "Delicate 59' + Steam",
"iot_dry_air_refresh": "Air Refresh",
"iot_dry_anti_mites": "Anti-mite",
"iot_dry_baby": "Baby",
@ -194,24 +745,17 @@
"iot_dry_bathrobe": "Bathrobes",
"iot_dry_bed_linen": "Bed Linen",
"iot_dry_cotton_dry": "Cotton Dry",
"iot_dry_cotton": "Cotton",
"iot_dry_cuddly_toys": "Cuddly Toys",
"iot_dry_curtains": "Curtains",
"iot_dry_dehumidifier": "Humidity Remover",
"iot_dry_delicates": "Delicates",
"iot_dry_delicates_antiallergy": "Delicates Anti-allergy",
"iot_dry_delicate_tablecloths": "Delicate Tablecloths",
"iot_dry_denim_jeans": "Denim - Jeans",
"iot_dry_down_jacket": "Down jacket",
"iot_dry_duvet": "Duvet",
"iot_dry_easy_iron_cotton": "Easy Iron - Cotton",
"iot_dry_easy_iron_synthetics": "Easy Iron - Synthetics",
"iot_dry_gym_fit": "Gym fit - Fitness",
"iot_dry_lingerie": "Lingerie",
"iot_dry_mixed": "Mixed",
"iot_dry_mixed_dry": "Mixed Dry",
"iot_dry_rapid_30": "Rapid 30'",
"iot_dry_rapid_59": "Rapid 59'",
"iot_dry_rapid_60_min_delicates": "Rapid 60' - Delicates",
"iot_dry_shirts": "Shirts",
"iot_dry_swimsuits_and_bikinis": "Swimsuits and Bikinis",
@ -220,8 +764,23 @@
"iot_dry_tablecloths": "Tablecloths",
"iot_dry_technical_fabrics": "Technical Fabrics",
"iot_dry_warm_embrace": "Warm Embrace",
"iot_dry_wool": "Wool",
"iot_dry_wool_dry": "Wool Dry",
"iot_easy_iron": "Easy Iron",
"iot_fresh_care_steam": "Fresh Care + Steam",
"iot_hygiene_pro_steam": "Hygiene Pro + Steam",
"iot_intensive_40_steam": "Intensive 40°C + Steam",
"iot_mixed_steam": "Mixed + Steam",
"iot_mix_and_colour_59_steam": "Mixed and Coloured 59' + Steam",
"iot_perfect_cotton_59_steam": "Perfect Cotton 59' + Steam",
"iot_rapid_a_class_60_steam": "Rapid 59' A Class + Steam",
"iot_resistant_cotton_steam": "Resistant Cotton + Steam",
"iot_shirts_steam": "Shirts + Steam",
"iot_single_item_steam": "Single Item + Steam",
"iot_smart_wash": "Smart Wash",
"iot_soft_care_steam": "Soft Care + Steam",
"iot_special_39_full_load_steam": "Special 39' + Steam",
"iot_steam_hygiene_plus": "Hygiene Plus + Steam",
"iot_synthetic_and_coloured_steam": "Synthetic and Coloured + Steam",
"iot_wash_and_dry": "Wash and dry",
"iot_wash_anti_mites": "Anti-mites",
"iot_wash_anti_odor": "Anti-odour",
@ -384,7 +943,7 @@
"special_39_full_load_steam": "Special 39' + Steam",
"special_49": "Special 49'",
"sport_39": "Sport 39'",
"sport_plus_29": "Sport Plus 29'",
"sport_plus_29": "Sport Plus 29\"",
"sport_plus_39": "Sport Plus 39'",
"steam_39": "Steam 39'",
"steam_care_pro": "Steam Care Pro",
@ -395,15 +954,168 @@
"synthetics": "Synthetics",
"synthetic_and_coloured": "Synthetic and Colored",
"synthetic_and_coloured_steam": "Synthetic and Coloured + Steam",
"tailored_resistant_cotton": "Tailored Resistant Cotton",
"tailored_synthetic_and_coloured": "Tailored Synthetic Colored",
"tailored_resistant_cotton": "Tailored resistant cotton",
"tailored_synthetic_and_coloured": "Tailored Synthetic Coloured",
"total_care": "Total Care",
"tumbling": "Tumbling",
"wool": "Wool",
"wool_and_delicates_49": "Wool and Delicates 49'",
"wool_dry": "Wool Dry",
"wool_soft_care": "Wool and Soft Car"
"wool_soft_care": "Wool and Soft Care"
},
"name": "Program"
},
"spin_speed": {
"name": "Spin"
},
"temperature": {
"name": "Temperature"
},
"dry_time": {
"name": "Drying time"
},
"eco_pilot": {
"state": {
"0": "Off",
"1": "Avoid touch",
"2": "Follow"
},
"name": "Eco pilot"
},
"fan_mode": {
"state": {
"1": "High",
"2": "Medium ",
"3": "Low",
"4": "Auto",
"5": "Auto"
}
},
"programs_ac": {
"state": {
"iot_10_heating": "10°C Heating function",
"iot_auto": "Auto",
"iot_cool": "Cool",
"iot_dry": "Dry",
"iot_fan": "Fan",
"iot_heat": "Heat",
"iot_nano_aqua": "Nano Aqua",
"iot_purify": "Self-purify",
"iot_self_clean": "Self-clean",
"iot_self_clean_56": "Steri-Clean 56°C",
"iot_simple_start": "Start now",
"iot_uv": "UV",
"iot_uv_and_auto": "UV + Auto",
"iot_uv_and_cool": "UV + Cold",
"iot_uv_and_dry": "UV + Dehumidifier",
"iot_uv_and_fan": "UV + Fan",
"iot_uv_and_heat": "UV + Heat"
}
}
},
"binary_sensor": {
"door_lock": {
"name": "Door lock"
},
"extra_rinse_1": {
"name": "+1 Rinse"
},
"extra_rinse_2": {
"name": "+2 Rinses"
},
"extra_rinse_3": {
"name": "+3 Rinses"
},
"good_night": {
"name": "Good Night"
},
"anti_crease": {
"name": "Anticrease"
},
"aqua_plus": {
"name": "Acquaplus"
},
"spin_speed": {
"name": "Spin"
},
"programs_dw": {
"name": "Program"
},
"programs_ih": {
"name": "Program"
},
"programs_ov": {
"name": "Program"
},
"programs_td": {
"name": "Program"
},
"programs_wm": {
"name": "Program"
},
"still_hot": {
"name": "Still hot"
},
"pan_status": {
"name": "Pan"
},
"remote_control": {
"name": "Remote control"
},
"rinse_aid": {
"name": "Rinse Aid level"
},
"salt_level": {
"name": "Salt level"
},
"door_open": {
"name": "Door open"
},
"connection": {
"name": "Appliance connection"
},
"child_lock": {
"name": "Child Lock"
},
"on": {
"name": "On"
},
"prewash": {
"name": "Pre-wash "
}
},
"number": {
"power_management": {
"name": "Power management"
},
"temperature": {
"name": "Temperature"
},
"delay_time": {
"name": "Delay Start"
},
"water_hard": {
"name": "Water hardness"
},
"program_duration": {
"name": "Program duration"
},
"target_temperature": {
"name": "Target temperature"
},
"rinse_iterations": {
"name": "Number of rinses"
},
"wash_time": {
"name": "Washing intensity"
},
"dry_time": {
"name": "Drying time"
}
},
"button": {
"induction_hob": {
"name": "Induction Hob"
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,649 @@
{
"entity": {
"sensor": {
"washing_modes": {
"state": {
"0": "מוּכָן",
"1": "מוּכָן",
"3": "הַפסָקָה",
"4": "מתוזמן",
"5": "מתוזמן",
"6": "שְׁגִיאָה",
"7": "מוּכָן"
}
},
"program_phases_wm": {
"state": {
"0": "מוּכָן",
"1": "לִשְׁטוֹף",
"2": "לִשְׁטוֹף",
"3": "Spin",
"4": "לִשְׁטוֹף",
"5": "לִשְׁטוֹף",
"6": "לִשְׁטוֹף",
"7": "יִבּוּשׁ",
"9": "קִיטוֹר",
"10": "מוּכָן",
"11": "Spin",
"12": "Weighing ",
"13": "Weighing ",
"14": "לִשְׁטוֹף",
"15": "לִשְׁטוֹף",
"16": "לִשְׁטוֹף",
"17": "לִשְׁטוֹף",
"18": "לִשְׁטוֹף",
"19": "מתוזמן",
"20": "שמור על טריות",
"24": "Refresh",
"25": "לִשְׁטוֹף",
"26": "Heating",
"27": "לִשְׁטוֹף"
},
"name": "שלב"
},
"program_phases_td": {
"state": {
"0": "מוּכָן",
"1": "Drying",
"2": "יִבּוּשׁ",
"3": "Cooldown",
"13": "Cooldown",
"14": "Drying",
"15": "Drying",
"16": "Cooldown",
"18": "Keep Fresh",
"19": "יִבּוּשׁ",
"20": "יִבּוּשׁ"
},
"name": "שלב"
},
"program_phases_dw": {
"state": {
"0": "מוּכָן",
"1": "Prewash",
"2": "לִשְׁטוֹף",
"3": "לִשְׁטוֹף",
"4": "יִבּוּשׁ",
"5": "מוּכָן",
"6": "Hot rinse"
},
"name": "שלב"
},
"dry_levels": {
"state": {
"0": "ללא ייבוש",
"1": "בַּרזֶל",
"2": "לא לייבש ברזל",
"3": "ארון יבש",
"4": "יבש במיוחד",
"12": "בַּרזֶל",
"13": "ארון יבש",
"14": "Ready to wear",
"15": "יבש במיוחד"
},
"name": "רמת ייבוש"
},
"anti_crease": {
"name": "Anticrease"
},
"power": {
"name": "Power level"
},
"remaining_time": {
"name": "זמן שנותר"
},
"temperature": {
"name": "Temperature"
},
"water_efficiency": {
"name": "Water efficiency"
},
"water_saving": {
"name": "Water savings"
},
"duration": {
"name": "מֶשֶׁך"
},
"target_temperature": {
"name": "Target temperature"
},
"spin_speed": {
"name": "סיבוב"
},
"steam_leve": {
"name": "מפלס קיטור"
},
"dirt_level": {
"name": "רמת עפר"
},
"delay_time": {
"name": "Delay Start"
},
"dry_time": {
"name": "זמן ייבוש"
},
"suggested_load": {
"name": "יכולת עומס"
},
"energy_label": {
"name": "חסכון באנרגיה"
},
"det_dust": {
"name": "Powder detergent"
},
"det_liquid": {
"name": "Liquid detergent"
},
"errors": {
"name": "Error"
},
"programs": {
"name": "Current program"
},
"cycles_total": {
"name": "מחזורים Total"
},
"energy_total": {
"name": "Energy Consumption Total"
},
"water_total": {
"name": "Water efficiency Total"
},
"energy_current": {
"name": "Energy Consumption Current"
},
"water_current": {
"name": "Water efficiency Current"
},
"mach_modes_ac": {
"state": {
"0": "Auto",
"1": "Cool",
"2": "Cool",
"3": "Dry",
"4": "Heat",
"5": "Fan",
"6": "Fan"
}
}
},
"select": {
"programs_dw": {
"state": {
"gentle_wash": "Gentle wash",
"iot_checkup": "בְּדִיקָה",
"iot_dreft_quick_cycle": "Dreft Quick",
"iot_fairy_quick_cycle": "Fairy Quick",
"iot_jar_quick_cycle": "Jar Quick",
"iot_yes_quick_cycle": "Yes Quick",
"smart_ai": "Smart AI"
},
"name": "Program"
},
"programs_ih": {
"state": {
"iot_special_grilled_vegetables": "Grilled vegetables"
},
"name": "Program"
},
"programs_ov": {
"state": {
"iot_h20_clean": "h2O clean",
"pizza": "Pizza",
"tailor_bake": "Tailor bake"
},
"name": "Program"
},
"programs_td": {
"state": {
"genius": "Genius",
"hqd_bath_towel": "Bath towel",
"hqd_bulky": "Bulky",
"hqd_cold_wind_30": "Cold wind 30 minutes",
"hqd_cold_wind_timing": "Cold wind",
"hqd_hot_wind_timing": "Hot wind",
"hqd_luxury": "Luxury",
"hqd_night_dry": "Night dry",
"hqd_refresh": "Refresh",
"hqd_timer": "תוזמן",
"hqd_warm_up": "Warm up",
"hqd_working_suit": "Working suit",
"iot_dry_synthetic_dry": "סינתטי יבש"
},
"name": "Program"
},
"programs_wm": {
"state": {
"20_degrees_new_energy_label": "20 מעלות צלזיוס",
"active_steam": "קִיטוֹר",
"active_wash": "שטיפה פעילה",
"active_wash_steam": "שטיפה פעילה",
"allergy_care": "טיפול באלרגיה",
"allergy_care_pro": "Allergy Care Pro",
"all_in_one_49": "All in One 49 '",
"all_in_one_59": "All in One 59 '",
"all_in_one_59_steam": "שטיפה פעילה",
"autocare": "טיפול אוטומטי",
"autoclean": "ניקוי אוטומטי",
"baby_60": "BABY_60",
"care_14": "טיפול מהיר 14 '",
"care_30": "טיפול מהיר 30 '",
"care_44": "טיפול מהיר 44 '",
"checkup": "בְּדִיקָה",
"cottons": "כותנה",
"cottons_prewash": "כותנה + כביסה מוקדמת",
"cotton_care_59": "Cotton Care 59 Min",
"delicate_59": "עדין 59 '",
"delicati_59": "DELICATI_59",
"delicati_59_steam": "DELICATI_59",
"drain_spin": "ניקוז + סיבוב",
"easy_iron": "גיהוץ קל",
"eco_40_60_new_energy_label": "אקו 40-60",
"extra_care": "אכפתיות מוגברת",
"fitness": "טיפול בכושר",
"fitness_care": "טיפול בכושר",
"fresh_care": "טיפול טרי",
"fresh_care_steam": "טיפול טרי",
"handwash_wool": "שטיפת ידיים + צמר",
"high_dry": "יבש בחום גבוה",
"hqd_dry_synthetics": "יבש בחום נמוך",
"hygiene_60": "היגיינה 60 מעלות צלזיוס",
"intensive_40": "40°C אינטנסיביים",
"iot_active_steam": "קִיטוֹר",
"iot_active_wash_steam": "שטיפה פעילה",
"iot_allergy_care_pro": "Allergy Care Pro",
"iot_all_in_one_59_steam": "שטיפה פעילה",
"iot_checkup": "בְּדִיקָה",
"iot_delicati_59_steam": "DELICATI_59",
"iot_dry_air_refresh": "רענון אוויר",
"iot_dry_anti_mites": "נגד קרדית",
"iot_dry_baby": "תִינוֹק",
"iot_dry_backpacks": "תיקי גב",
"iot_dry_bathrobe": "חלוקי רחצה",
"iot_dry_bed_linen": "מצעים",
"iot_dry_cotton_dry": "כותנה יבשה",
"iot_dry_cuddly_toys": "צעצועי חיבוק",
"iot_dry_curtains": "וילונות",
"iot_dry_dehumidifier": "מסיר לחות",
"iot_dry_delicates_antiallergy": "עדין נגד אלרגיה",
"iot_dry_delicate_tablecloths": "מפות עדינות",
"iot_dry_denim_jeans": "ג'ינס",
"iot_dry_easy_iron_cotton": "ברזל קל - כותנה",
"iot_dry_easy_iron_synthetics": "קל ברזל - סינתטיים",
"iot_dry_gym_fit": "כושר כושר - כושר",
"iot_dry_lingerie": "לִבנֵי נָשִׁים",
"iot_dry_mixed_dry": "מעורבב יבש",
"iot_dry_rapid_60_min_delicates": "מהיר 60 '- עדינים",
"iot_dry_shirts": "חולצות",
"iot_dry_swimsuits_and_bikinis": "בגדי ים וביקיני",
"iot_dry_synthetics": "סינתטי יבש",
"iot_dry_synthetic_dry": "סינתטי יבש",
"iot_dry_tablecloths": "מפות שולחן",
"iot_dry_technical_fabrics": "בדים טכניים",
"iot_dry_warm_embrace": "חיבוק חם",
"iot_dry_wool_dry": "צמר יבש",
"iot_easy_iron": "גיהוץ קל",
"iot_fresh_care_steam": "טיפול טרי",
"iot_synthetic_and_coloured_steam": "סינטטי וצבעוני",
"iot_wash_anti_mites": "נגד קרדית",
"iot_wash_anti_odor": "נגד ריח",
"iot_wash_ariel_clean_cycle": "Ariel Ultimate Clean",
"iot_wash_ariel_cold_cycle": "Ariel Cold Clean",
"iot_wash_ariel_fresh_cycle": "Ariel Fresh Clean",
"iot_wash_baby_sanitizer": "חיטוי לתינוקות",
"iot_wash_backpacks": "תיקי גב",
"iot_wash_bathrobe": "חלוקי רחצה ובדים נקבוביים",
"iot_wash_bed_linen": "מצעים",
"iot_wash_bed_linen_zelig": "מצעים",
"iot_wash_bleaching": "הַלבָּנָה",
"iot_wash_blood_stains": "כתמי דם",
"iot_wash_cashmere": "קשמיר",
"iot_wash_chocolate_stains": "כתמי שוקולד",
"iot_wash_cold_wash": "שטיפה קרה",
"iot_wash_colored": "צבעוני",
"iot_wash_colored_anti_stain": "נגד כתם צבעוני",
"iot_wash_colored_delicate": "צבעוני עדין",
"iot_wash_coloured": "צבעוני",
"iot_wash_cotton": "כותנה",
"iot_wash_cuddly_toys": "צעצועי חיבוק",
"iot_wash_curtains": "וילונות",
"iot_wash_curtains_zelig": "וילונות",
"iot_wash_dark": "אפל",
"iot_wash_darks_and_coloured_44": "חביבים וצבעוניים 44 '",
"iot_wash_darks_and_coloured_59": "חביבים וצבעוני 59 '",
"iot_wash_darks_and_coloured_xl": "חפצים וצבע XL",
"iot_wash_dash_clean_cycle": "Dash Ultimate Clean",
"iot_wash_dash_cold_cycle": "Dash Cold Clean",
"iot_wash_dash_fresh_cycle": "Dash Fresh Clean",
"iot_wash_delicate": "עדינים",
"iot_wash_delicate_antiallergy": "אנטי אלרגיה עדין",
"iot_wash_delicate_antiallergy_zelig": "אנטי אלרגיה עדין",
"iot_wash_delicate_colors": "צבעוני עדין",
"iot_wash_delicate_dark": "כהה עדין",
"iot_wash_delicate_tablecloths": "מפות עדינות",
"iot_wash_delicate_whites": "לבנים עדינים",
"iot_wash_denim_jeans": "ג'ינס",
"iot_wash_diving_suits": "חליפות צלילה",
"iot_wash_diving_suits_zelig": "חליפות צלילה",
"iot_wash_down_jackets": "מעילי פוך",
"iot_wash_down_jackets_zelig": "מעילי פוך",
"iot_wash_fruit_stains": "כתמי פרי",
"iot_wash_gym_fit": "כושר כושר - כושר",
"iot_wash_handwash": "שטיפת ידיים",
"iot_wash_handwash_colored": "שטיפת ידיים בצבע",
"iot_wash_handwash_dark": "שטיפת ידיים כהה",
"iot_wash_lingerie": "לִבנֵי נָשִׁים",
"iot_wash_masks_refresh": "מסכות רענן",
"iot_wash_masks_sanification": "חיטוי מסכות",
"iot_wash_mats": "מחצלות",
"iot_wash_men_s_trousers": "מכנסי גברים",
"iot_wash_mixed": "מעורב",
"iot_wash_mix_and_coloured_44": "לערבב וצבעוני 44 '",
"iot_wash_mix_and_coloured_59": "מיקס וצבעוני 59 '",
"iot_wash_mix_and_coloured_xl": "מערבבים וצבעים XL",
"iot_wash_new_clothes": "בגדים חדשים",
"iot_wash_perfect_white": "לבן מושלם",
"iot_wash_pets": "חיות מחמד",
"iot_wash_pets_steam": "חיות מחמד",
"iot_wash_playsuits": "חליפות משחק",
"iot_wash_rapid_14": "מהיר 14 '",
"iot_wash_rapid_30": "מהיר 30 '",
"iot_wash_rapid_44": "מהיר 44 '",
"iot_wash_rapid_59": "מהיר 59 '",
"iot_wash_refresh_14_min": "רענן 14 דקות",
"iot_wash_resistant_colored": "צבעוני עמיד",
"iot_wash_resistant_dark": "כהה עמיד",
"iot_wash_resistant_whites": "לבנים עמידים",
"iot_wash_rinse": "לִשְׁטוֹף",
"iot_wash_shirts": "חולצות",
"iot_wash_silk": "משי",
"iot_wash_ski_suit": "חליפת סקי",
"iot_wash_ski_suit_zelig": "חליפת סקי",
"iot_wash_spin": "סיבוב",
"iot_wash_sport": "ספּוֹרט",
"iot_wash_stains_remover": "מסיר כתמים",
"iot_wash_swimsuits_and_bikinis": "בגדי ים וביקיני",
"iot_wash_synthetic": "סינתטיים",
"iot_wash_tablecloths": "מפות שולחן",
"iot_wash_technical_fabrics": "בדים טכניים",
"iot_wash_technical_fabrics_zelig": "בדים טכניים",
"iot_wash_technical_jackets": "ז'קטים טכניים",
"iot_wash_technical_jackets_zelig": "ז'קטים טכניים",
"iot_wash_trainers": "מאמנים",
"iot_wash_whites": "לְבָנִים",
"iot_wash_whites_44": "לבנים 44 '",
"iot_wash_whites_59": "לבנים 59 '",
"iot_wash_whites_xl": "לבנים XL",
"iot_wash_wine_stains": "כתמי יין",
"iot_wash_wool": "צֶמֶר",
"jeans": "גִ'ינס",
"low_dry": "יבש בחום נמוך",
"mixed_and_colored_59": "מעורב וצבעוני 59 '",
"night_and_day": "לילה ויום",
"night_wash": "Night Wash",
"perfect_59": "מושלם 59 '",
"perfect_whites_59": "לבן מושלם",
"rapid_wash_and_dry_59_min": "לשטוף ולייבש 59 '",
"resistant_cotton": "כותנה",
"rinse": "לִשְׁטוֹף",
"silent_night": "Night Wash",
"soft_care": "טיפול רך",
"special_49": "מיוחד 49 '",
"sport_39": "ספורט 39 '",
"sport_plus_29": "ספורט פלוס 29 \"",
"steam_39": "קיטור 39 '",
"steam_care_pro": "Steam Care Pro",
"steam_care_pro_cotton": "Steam Care Pro",
"steam_care_pro_delicates": "Steam Care Pro",
"steam_care_pro_synthetic": "Steam Care Pro",
"synthetics": "סינתטיים",
"synthetic_and_coloured": "סינטטי וצבעוני",
"synthetic_and_coloured_steam": "סינטטי וצבעוני",
"tailored_resistant_cotton": "Tailored Resistant Cotton",
"tailored_synthetic_and_coloured": "Tailored Synthetic Colored",
"total_care": "טיפול טוטאלי",
"tumbling": "נופלים",
"wool_and_delicates_49": "Wool/Delicates 49'",
"wool_dry": "צמר יבש",
"wool_soft_care": "Wool & Soft Care"
},
"name": "Program"
},
"dry_levels": {
"state": {
"0": "ללא ייבוש",
"1": "בַּרזֶל",
"2": "לא לייבש ברזל",
"3": "ארון יבש",
"4": "יבש במיוחד",
"12": "בַּרזֶל",
"13": "ארון יבש",
"14": "Ready to wear",
"15": "יבש במיוחד"
},
"name": "רמת ייבוש"
},
"spin_speed": {
"name": "סיבוב"
},
"temperature": {
"name": "Temperature"
},
"dry_time": {
"name": "זמן ייבוש"
},
"eco_pilot": {
"state": {
"0": "Off",
"1": "Avoid touch",
"2": "Follow"
},
"name": "Eco pilot"
},
"fan_mode": {
"state": {
"1": "High",
"2": "Medium ",
"3": "Low",
"4": "Auto",
"5": "Auto"
}
},
"programs_ac": {
"state": {
"iot_simple_start": "התחל עכשיו"
}
}
},
"switch": {
"anti_crease": {
"name": "Anticrease"
},
"add_dish": {
"name": ""
},
"eco_express": {
"name": "Eco"
},
"extra_dry": {
"name": "Extra dry"
},
"half_load": {
"name": "Half load"
},
"open_door": {
"name": "Open door"
},
"three_in_one": {
"name": "3 in 1"
},
"preheat": {
"name": "Preheat"
},
"dish_washer": {
"name": "Dish washer"
},
"tumble_dryer": {
"name": "Tumble dryer"
},
"washing_machine": {
"name": "Washing machine"
},
"washer_dryer": {
"name": "Washer dryer"
},
"oven": {
"name": "Oven"
},
"prewash": {
"name": "שטיפה מראש"
},
"pause": {
"name": "Pause"
},
"keep_fresh": {
"name": "Keep Fresh"
},
"delay_time": {
"name": "Delay Start"
},
"rapid_mode": {
"name": "Rapid mode"
},
"eco_mode": {
"name": "ECO mode"
},
"10_degree_heating": {
"name": "10°C Heating function"
},
"self_clean": {
"name": "Self-clean"
},
"self_clean_56": {
"name": "Steri-Clean 56°C"
},
"silent_mode": {
"name": "Silent mode"
},
"mute_mode": {
"name": "Mute mode"
}
},
"binary_sensor": {
"door_lock": {
"name": "מנעול דלת"
},
"extra_rinse_1": {
"name": "+1 שטיפה"
},
"extra_rinse_2": {
"name": "+2 שטיפות"
},
"extra_rinse_3": {
"name": "+3 שטיפות"
},
"good_night": {
"name": "לילה טוב"
},
"anti_crease": {
"name": "Anticrease"
},
"aqua_plus": {
"name": "Acquaplus"
},
"spin_speed": {
"name": "סיבוב"
},
"programs_dw": {
"name": "Program"
},
"programs_ih": {
"name": "Program"
},
"programs_ov": {
"name": "Program"
},
"programs_td": {
"name": "Program"
},
"programs_wm": {
"name": "Program"
},
"still_hot": {
"name": "Still hot"
},
"pan_status": {
"name": "Pan"
},
"remote_control": {
"name": "Remote control"
},
"rinse_aid": {
"name": "Rinse Aid level"
},
"salt_level": {
"name": "Salt level"
},
"door_open": {
"name": "Door open"
},
"connection": {
"name": "Appliance connection"
},
"child_lock": {
"name": "Child Lock"
},
"on": {
"name": "עַל"
},
"prewash": {
"name": "שטיפה מראש"
}
},
"number": {
"power_management": {
"name": "Power management"
},
"temperature": {
"name": "Temperature"
},
"delay_time": {
"name": "Delay Start"
},
"water_hard": {
"name": "קשיות מים"
},
"program_duration": {
"name": "Program duration"
},
"target_temperature": {
"name": "Target temperature"
},
"rinse_iterations": {
"name": "Number of rinses"
},
"wash_time": {
"name": "Washing intensity"
},
"dry_time": {
"name": "זמן ייבוש"
}
},
"button": {
"induction_hob": {
"name": "Induction Hob"
}
}
},
"config": {
"step": {
"user": {
"description": "Do the login",
"data": {
"email": "Email",
"password": "Password"
}
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
{
"name": "Haier hOn",
"render_readme": true,
"homeassistant": "2023.2.0"
"homeassistant": "2023.2.0",
"zip_release": true,
"filename": "haier_hon.zip"
}

60
info.md Normal file
View File

@ -0,0 +1,60 @@
# Haier hOn
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/Andre0512/hon?color=green)](https://github.com/Andre0512/hon/releases/latest)
[![GitHub](https://img.shields.io/github/license/Andre0512/hon?color=red)](https://github.com/Andre0512/hon/blob/main/LICENSE)
[![GitHub all releases](https://img.shields.io/github/downloads/Andre0512/hon/total?color=blue)](https://tooomm.github.io/github-release-stats/?username=Andre0512&repository=hon)
Support for home appliances of Haier's mobile app hOn.
## Supported Appliances
- [Washing Machine](https://github.com/Andre0512/hon#washing-machine)
- [Tumble Dryer](https://github.com/Andre0512/hon#tumble-dryer)
- [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer)
- [Oven](https://github.com/Andre0512/hon#oven)
- [Hob](https://github.com/Andre0512/hon#hob)
- [Dish Washer](https://github.com/Andre0512/hon#dish-washer)
## Tested Appliances
- Haier WD90-B14TEAM5
- Haier HD80-A3959
- Haier HWO60SM2F3XH
- Hoover H-WASH 500
## Configuration
**Method 1**: [![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=hon)
**Method 2**: Settings > Devices & Services > Add Integration > **Haier hOn**
_If the integration is not in the list, you need to clear the browser cache._
## Contribute
Want to help us to support more appliances? Or add more sensors? Or help with translating? Or beautify some icons or captions?
Check out the [project on GitHub](https://github.com/Andre0512/hon), every contribution is welcome!
## Supported Languages
Translation of internal names like programs are available for all languages which are official supported by the hOn app:
* 🇨🇳 Chinese
* 🇭🇷 Croatian
* 🇨🇿 Czech
* 🇳🇱 Dutch
* 🇬🇧 English
* 🇫🇷 French
* 🇩🇪 German
* 🇬🇷 Greek
* 🇮🇱 Hebrew
* 🇮🇹 Italian
* 🇵🇱 Polish
* 🇵🇹 Portuguese
* 🇷🇴 Romanian
* 🇷🇺 Russian
* 🇷🇸 Serbian
* 🇸🇰 Slovak
* 🇸🇮 Slovenian
* 🇪🇸 Spanish
* 🇹🇷 Turkish
## Useful Links
* [GitHub repository](https://github.com/Andre0512/hon) (please add a star if you like this integration!)
* [pyhOn library](https://github.com/Andre0512/pyhOn)
* [Release notes](https://github.com/Andre0512/hon/releases)
* [Discussion and help](https://github.com/Andre0512/hon/discussions)
* [Issues](https://github.com/Andre0512/hon/issues)

3
requirements_dev.txt Normal file
View File

@ -0,0 +1,3 @@
pyhOn
black
homeassistant

372
scripts/generate_translation.py Executable file
View File

@ -0,0 +1,372 @@
#!/usr/bin/env python
import asyncio
import json
import re
from pathlib import Path
from pyhon import HonAPI
# These languages are official supported by hOn
LANGUAGES = [
"cs", # Czech
"de", # German
"el", # Greek
"en", # English
"es", # Spanish
"fr", # French
"he", # Hebrew
"hr", # Croatian
"it", # Italian
"nl", # Dutch
"pl", # Polish
"pt", # Portuguese
"ro", # Romanian
"ru", # Russian
"sk", # Slovak
"sl", # Slovenian
"sr", # Serbian
"tr", # Turkish
"zh", # Chinese
]
WASHING_PR_PHASE = {
0: "WASHING_CMD&CTRL.PHASE_READY.TITLE",
1: "WASHING_CMD&CTRL.PHASE_WASHING.TITLE",
2: "WASHING_CMD&CTRL.PHASE_WASHING.TITLE",
3: "WASHING_CMD&CTRL.PHASE_SPIN.TITLE",
4: "WASHING_CMD&CTRL.PHASE_RINSE.TITLE",
5: "WASHING_CMD&CTRL.PHASE_RINSE.TITLE",
6: "WASHING_CMD&CTRL.PHASE_RINSE.TITLE",
7: "WASHING_CMD&CTRL.PHASE_DRYING.TITLE",
9: "WASHING_CMD&CTRL.PHASE_STEAM.TITLE",
10: "WASHING_CMD&CTRL.PHASE_READY.TITLE",
11: "WASHING_CMD&CTRL.PHASE_SPIN.TITLE",
12: "WASHING_CMD&CTRL.PHASE_WEIGHTING.TITLE",
13: "WASHING_CMD&CTRL.PHASE_WEIGHTING.TITLE",
14: "WASHING_CMD&CTRL.PHASE_WASHING.TITLE",
15: "WASHING_CMD&CTRL.PHASE_WASHING.TITLE",
16: "WASHING_CMD&CTRL.PHASE_WASHING.TITLE",
17: "WASHING_CMD&CTRL.PHASE_RINSE.TITLE",
18: "WASHING_CMD&CTRL.PHASE_RINSE.TITLE",
19: "WASHING_CMD&CTRL.PHASE_SCHEDULED.TITLE",
20: "WASHING_CMD&CTRL.PHASE_TUMBLING.TITLE",
24: "WASHING_CMD&CTRL.PHASE_REFRESH.TITLE",
25: "WASHING_CMD&CTRL.PHASE_WASHING.TITLE",
26: "WASHING_CMD&CTRL.PHASE_HEATING.TITLE",
27: "WASHING_CMD&CTRL.PHASE_WASHING.TITLE",
}
MACH_MODE = {
0: "WASHING_CMD&CTRL.PHASE_READY.TITLE",
1: "WASHING_CMD&CTRL.PHASE_READY.TITLE",
3: "WASHING_CMD&CTRL.PHASE_PAUSE.TITLE",
4: "WASHING_CMD&CTRL.PHASE_SCHEDULED.TITLE",
5: "WASHING_CMD&CTRL.PHASE_SCHEDULED.TITLE",
6: "WASHING_CMD&CTRL.PHASE_ERROR.TITLE",
7: "WASHING_CMD&CTRL.PHASE_READY.TITLE",
}
TUMBLE_DRYER_PR_PHASE = {
0: "WASHING_CMD&CTRL.PHASE_READY.TITLE",
1: "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE",
2: "WASHING_CMD&CTRL.PHASE_DRYING.TITLE",
3: "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN",
13: "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN",
14: "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE",
15: "TD_CMD&CTRL.STATUS_PHASE.PHASE_HEAT_STROKE",
16: "TD_CMD&CTRL.STATUS_PHASE.PHASE_COOLDOWN",
18: "WASHING_CMD&CTRL.PHASE_TUMBLING.DASHBOARD_TITLE",
19: "WASHING_CMD&CTRL.PHASE_DRYING.TITLE",
20: "WASHING_CMD&CTRL.PHASE_DRYING.TITLE",
}
DISHWASHER_PR_PHASE = {
0: "WASHING_CMD&CTRL.PHASE_READY.TITLE",
1: "WASHING_CMD&CTRL.PHASE_PREWASH.TITLE",
2: "WASHING_CMD&CTRL.PHASE_WASHING.TITLE",
3: "WASHING_CMD&CTRL.PHASE_RINSE.TITLE",
4: "WASHING_CMD&CTRL.PHASE_DRYING.TITLE",
5: "WASHING_CMD&CTRL.PHASE_READY.TITLE",
6: "WASHING_CMD&CTRL.PHASE_HOT_RINSE.TITLE",
}
TUMBLE_DRYER_DRY_LEVEL = {
0: "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_MAIN_OPTIONS.NO_DRY",
1: "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.IRON_DRY",
2: "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_DRYING.NO_DRY_IRON_TITLE",
3: "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_DRYING.CUPBOARD_DRY_TITLE",
4: "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_DRYING.EXTRA_DRY_TITLE",
12: "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.IRON_DRY",
13: "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_DRYING.CUPBOARD_DRY_TITLE",
14: "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_DRYING.READY_TO_WEAR_TITLE",
15: "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_DRYING.EXTRA_DRY_TITLE",
}
AC_MACH_MODE = {
0: "PROGRAMS.AC.IOT_AUTO",
1: "PROGRAMS.AC.IOT_COOL",
2: "PROGRAMS.AC.IOT_COOL",
3: "PROGRAMS.AC.IOT_DRY",
4: "PROGRAMS.AC.IOT_HEAT",
5: "PROGRAMS.AC.IOT_FAN",
6: "PROGRAMS.AC.IOT_FAN",
}
AC_FAN_MODE = {
1: "AC.PROGRAM_CARD.WIND_SPEED_HIGH",
2: "AC.PROGRAM_CARD.WIND_SPEED_MID",
3: "AC.PROGRAM_CARD.WIND_SPEED_LOW",
4: "AC.PROGRAM_CARD.WIND_SPEED_AUTO",
5: "AC.PROGRAM_CARD.WIND_SPEED_AUTO",
}
AC_HUMAN_SENSE = {
0: "AC.PROGRAM_DETAIL.TOUCH_OFF",
1: "AC.PROGRAM_DETAIL.AVOID_TOUCH",
2: "AC.PROGRAM_DETAIL.FOLLOW_TOUCH",
}
SENSOR = {
"washing_modes": MACH_MODE,
"mach_modes_ac": AC_MACH_MODE,
"program_phases_wm": WASHING_PR_PHASE,
"program_phases_td": TUMBLE_DRYER_PR_PHASE,
"program_phases_dw": DISHWASHER_PR_PHASE,
"dry_levels": TUMBLE_DRYER_DRY_LEVEL,
}
SELECT = {
"dry_levels": TUMBLE_DRYER_DRY_LEVEL,
"eco_pilot": AC_HUMAN_SENSE,
"fan_mode": AC_FAN_MODE,
}
PROGRAMS = {
"programs_ac": "PROGRAMS.AC",
"programs_dw": "PROGRAMS.DW",
"programs_ih": "PROGRAMS.IH",
"programs_ov": "PROGRAMS.OV",
"programs_td": "PROGRAMS.TD",
"programs_wm": "PROGRAMS.WM_WD",
}
NAMES = {
"switch": {
"anti_crease": "HDRY_CMD&CTRL.PROGRAM_CYCLE_DETAIL.ANTICREASE_TITLE",
"add_dish": "DW_CMD&CTRL.c.ADD_DISH",
"eco_express": "DW_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.ECO",
"extra_dry": "DW_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.EXTRA_DRY",
"half_load": "DW_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.HALF_LOAD",
"open_door": "DW_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.OPEN_DOOR",
"three_in_one": "DW_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.THREE_IN_ONE",
"preheat": "OV.PROGRAM_DETAIL.PREHEAT",
"dish_washer": "GLOBALS.APPLIANCES_NAME.DW",
"tumble_dryer": "GLOBALS.APPLIANCES_NAME.TD",
"washing_machine": "GLOBALS.APPLIANCES_NAME.WM",
"washer_dryer": "GLOBALS.APPLIANCES_NAME.WD",
"oven": "GLOBALS.APPLIANCES_NAME.OV",
"prewash": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.PREWASH",
"pause": "GENERAL.PAUSE_PROGRAM",
"keep_fresh": "GLOBALS.APPLIANCE_STATUS.TUMBLING",
"delay_time": "HINTS.TIPS_TIME_ENERGY_SAVING.TIPS_USE_AT_NIGHT_TITLE",
"rapid_mode": "AC.PROGRAM_CARD.RAPID",
"eco_mode": "AC.PROGRAM_CARD.ECO_MODE",
"10_degree_heating": "PROGRAMS.AC.IOT_10_HEATING",
"self_clean": "PROGRAMS.AC.IOT_SELF_CLEAN",
"self_clean_56": "PROGRAMS.AC.IOT_SELF_CLEAN_56",
"silent_mode": "AC.PROGRAM_DETAIL.SILENT_MODE",
"mute_mode": "AC.PROGRAM_DETAIL.MUTE_MODE",
},
"binary_sensor": {
"door_lock": "WASHING_CMD&CTRL.CHECK_UP_RESULTS.DOOR_LOCK",
"extra_rinse_1": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.EXTRARINSE1",
"extra_rinse_2": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.EXTRARINSE2",
"extra_rinse_3": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.EXTRARINSE3",
"good_night": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.GOODNIGHT",
"anti_crease": "HDRY_CMD&CTRL.PROGRAM_CYCLE_DETAIL.ANTICREASE_TITLE",
"aqua_plus": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.ACQUAPLUS",
"spin_speed": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_MAIN_OPTIONS.SPINSPEED",
"still_hot": "IH.COILS_STATUS.STILL_HOT",
"pan_status": "IH.COILS_STATUS.PAN",
"remote_control": "OV.SUPPORT.REMOTE_CONTROL",
"rinse_aid": "DW_CMD&CTRL.MAINTENANCE.CONSUMABLE_LEVELS_ICON_RINSE_AID",
"salt_level": "DW_CMD&CTRL.MAINTENANCE.CONSUMABLE_LEVELS_ICON_SALT",
"door_open": "GLOBALS.APPLIANCE_STATUS.DOOR_OPEN",
"connection": "ENROLLMENT_COMMON.HEADER_NAME.STEP_APPLIANCE_CONNECTION",
"child_lock": "AP.FOOTER_MENU_MORE.SECURITY_LOCK_TITLE",
"on": "GLOBALS.GENERAL.ON",
"prewash": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.PREWASH",
},
"button": {
"induction_hob": "GLOBALS.APPLIANCES_NAME.IH",
},
"select": {
"dry_levels": "WASHING_CMD&CTRL.DRAWER_CYCLE_DRYING.TAB_LEVEL",
"dry_time": "WASHING_CMD&CTRL.DRAWER_CYCLE_DRYING.TAB_TIME",
"spin_speed": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_MAIN_OPTIONS.SPINSPEED",
"temperature": "IH.COMMON.TEMPERATURE",
"programs_dw": "WC.SET_PROGRAM.PROGRAM",
"programs_ih": "WC.SET_PROGRAM.PROGRAM",
"programs_ov": "WC.SET_PROGRAM.PROGRAM",
"programs_td": "WC.SET_PROGRAM.PROGRAM",
"programs_wm": "WC.SET_PROGRAM.PROGRAM",
"eco_pilot": "AC.PROGRAM_DETAIL.ECO_PILOT",
},
"sensor": {
"dry_levels": "WASHING_CMD&CTRL.DRAWER_CYCLE_DRYING.TAB_LEVEL",
"dry_time": "WASHING_CMD&CTRL.DRAWER_CYCLE_DRYING.TAB_TIME",
"power": "OV.RECIPE_DETAIL.POWER_LEVEL",
"remaining_time": "ENROLLMENT_COMMON.GENERAL.REMAINING_TIME",
"temperature": "IH.COMMON.TEMPERATURE",
"water_efficiency": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_RESULT.WATER_EFFICIENCY",
"water_saving": "STATISTICS.SMART_AI_CYCLE.WATER_SAVING",
"duration": "WASHING_CMD&CTRL.DRAWER_PROGRAM_FILTERS.DURATION",
"target_temperature": "IH.COOKING_DETAIL.TEMPERATURE_TARGETING",
"spin_speed": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_MAIN_OPTIONS.SPINSPEED",
"steam_leve": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_MAIN_OPTIONS.STEAM_LEVEL",
"dirt_level": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_MAIN_OPTIONS.DIRTY_LEVEL",
"program_phases_wm": "WASHING_CMD&CTRL.STATISTICS_GRAPHIC_INSTANT_CONSUMPTION.PHASE",
"program_phases_td": "WASHING_CMD&CTRL.STATISTICS_GRAPHIC_INSTANT_CONSUMPTION.PHASE",
"program_phases_dw": "WASHING_CMD&CTRL.STATISTICS_GRAPHIC_INSTANT_CONSUMPTION.PHASE",
"delay_time": "HINTS.TIPS_TIME_ENERGY_SAVING.TIPS_USE_AT_NIGHT_TITLE",
"suggested_load": "WASHING_CMD&CTRL.DRAWER_PROGRAM_FILTERS.LOAD_CAPACITY",
"energy_label": "WASHING_CMD&CTRL.DRAWER_PROGRAM_FILTERS.ENERGY_EFFICIENCY",
"det_dust": "HUBS.WIDGET.STAINS_WIDGET.STAINS.SUGGESTED_DET_DUST",
"det_liquid": "HUBS.WIDGET.STAINS_WIDGET.STAINS.SUGGESTED_DET_LIQUID",
"errors": "ROBOT_CMD&CTRL.PHASE_ERROR.TITLE",
"programs": "OV.TABS.CURRENT_PROGRAM",
"cycles_total": [
"WASHING_CMD&CTRL.GENERAL.CYCLES",
"WC.VIRTUAL_WINE_STATS_COUNTRY.TOTAL",
],
"energy_total": [
"MISE.ENERGY_CONSUMPTION.TITLE",
"WC.VIRTUAL_WINE_STATS_COUNTRY.TOTAL",
],
"water_total": [
"WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_RESULT.WATER_EFFICIENCY",
"WC.VIRTUAL_WINE_STATS_COUNTRY.TOTAL",
],
"energy_current": [
"MISE.ENERGY_CONSUMPTION.TITLE",
"CUBE90_GLOBAL.GENERAL.CURRENT",
],
"water_current": [
"WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_RESULT.WATER_EFFICIENCY",
"CUBE90_GLOBAL.GENERAL.CURRENT",
],
},
"number": {
"power_management": "HINTS.COOKING_WITH_INDUCTION.POWER_MANAGEMENT",
"temperature": "IH.COMMON.TEMPERATURE",
"delay_time": "HINTS.TIPS_TIME_ENERGY_SAVING.TIPS_USE_AT_NIGHT_TITLE",
"water_hard": "WASHING_CMD&CTRL.DASHBOARD_MENU_MORE_SETTINGS_WATER.TITLE",
"program_duration": "OV.PROGRAM_DETAIL.PROGRAM_DURATION",
"target_temperature": "IH.COOKING_DETAIL.TEMPERATURE_TARGETING",
"rinse_iterations": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL.DRAWER_HEADER_RINSE",
"wash_time": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL.WASHING_TIME",
"dry_time": "WASHING_CMD&CTRL.DRAWER_CYCLE_DRYING.TAB_TIME",
},
}
async def check_translation_files(translations):
for language in LANGUAGES:
path = translations / f"{language}.json"
if not path.is_file():
async with HonAPI(anonymous=True) as hon:
keys = await hon.translation_keys(language)
save_json(path, keys)
def load_hon_translations():
translations = Path(__file__).parent / "translations"
translations.mkdir(exist_ok=True)
asyncio.run(check_translation_files(translations))
return {f.stem: f for f in translations.glob("*.json")}
def load_hass_translations():
translations = (
Path(__file__).parent.parent / "custom_components" / "hon" / "translations"
)
return {f.stem: f for f in translations.glob("*.json")}
def load_json(path):
if path:
with open(path, "r") as file:
return json.loads(file.read())
return {}
def save_json(path, keys):
with open(path, "w") as json_file:
json_file.write(json.dumps(keys, indent=4, ensure_ascii=False))
def load_key(full_key, json_data, fallback=None):
if isinstance(full_key, list):
return " ".join(
[load_key(item, json_data, fallback).strip() for item in full_key]
)
result = json_data.copy()
for key in full_key.split("."):
result = result.get(key, {})
if not result and fallback:
return load_key(full_key, fallback)
return result or ""
def load_keys(full_key, json_data):
blacklist = ["description", "desctiption", "_recipe_", "_guided_"]
first, last = full_key.split(".")
data = json_data.get(first, {}).get(last, {})
return {
key.lower(): value
for key, value in data.items()
if not any(b in key.lower() for b in blacklist)
and re.findall("^[a-z0-9-_]+$", key.lower())
}
def add_data(old, original, fallback, data, name, entity="sensor"):
sensor = old.setdefault("entity", {}).setdefault(entity, {})
for number, phase in data.items():
state = sensor.setdefault(name, {}).setdefault("state", {})
if key := load_key(phase, original, fallback):
state[str(number)] = key
def translate_login(old, *args):
login = old.setdefault("config", {}).setdefault("step", {}).setdefault("user", {})
login["description"] = load_key("CUBE90_ALEXA.HAIER_SMART_SKILLS.STEP_2", *args)
login.setdefault("data", {})["email"] = load_key(
"PET.EDIT_PET_PROFESSIONALS.EMAIL", *args
)
login["data"]["password"] = load_key("CUBE90_GLOBAL.GENERAL.PASSWORD", *args)
def main():
hass = load_hass_translations()
hon = load_hon_translations()
base_path = Path(__file__).parent.parent / "custom_components/hon/translations"
fallback = load_json(hon.get("en", ""))
for language in LANGUAGES:
original = load_json(hon.get(language, ""))
old = load_json(hass.get(language, ""))
for name, data in SENSOR.items():
add_data(old, original, fallback, data, name)
for name, data in SELECT.items():
add_data(old, original, fallback, data, name, "select")
for name, program in PROGRAMS.items():
select = old.setdefault("entity", {}).setdefault("select", {})
select.setdefault(name, {})["state"] = load_keys(program, original)
for entity, data in NAMES.items():
for name, key in data.items():
select = old.setdefault("entity", {}).setdefault(entity, {})
select.setdefault(name, {})["name"] = load_key(key, original, fallback)
translate_login(old, original, fallback)
save_json(base_path / f"{language}.json", old)
if __name__ == "__main__":
main()

83
scripts/sensor_docs.py Executable file
View File

@ -0,0 +1,83 @@
#!/usr/bin/env python
import re
import sys
from pathlib import Path
if __name__ == "__main__":
sys.path.insert(0, str(Path(__file__).parent.parent))
from custom_components.hon.binary_sensor import BINARY_SENSORS
from custom_components.hon.button import BUTTONS
from custom_components.hon.number import NUMBERS
from custom_components.hon.select import SELECTS
from custom_components.hon.sensor import SENSORS
from custom_components.hon.switch import SWITCHES, HonSwitchEntityDescription
APPLIANCES = {
"AC": "Air conditioner",
"AP": "Air purifier",
"AS": "Air scanner",
"DW": "Dish washer",
"HO": "Hood",
"IH": "Hob",
"MW": "Microwave",
"OV": "Oven",
"REF": "Fridge",
"RVC": "Robot vacuum cleaner",
"TD": "Tumble dryer",
"WC": "Wine Cellar",
"WD": "Washer dryer",
"WH": "Water Heater",
"WM": "Washing machine",
}
ENTITY_CATEGORY_SORT = ["control", "config", "sensor"]
entities = {
"binary_sensor": BINARY_SENSORS,
"button": BUTTONS,
"number": NUMBERS,
"select": SELECTS,
"sensor": SENSORS,
"switch": SWITCHES,
}
result = {}
for entity_type, appliances in entities.items():
for appliance, data in appliances.items():
for entity in data:
if (
isinstance(entity, HonSwitchEntityDescription)
and entity.entity_category != "config"
):
key = f"{entity.turn_on_key}` / `{entity.turn_off_key}"
else:
key = entity.key
attributes = (key, entity.name, entity.icon, entity_type)
category = "control" if entity_type in ["switch", "button"] else "sensor"
result.setdefault(appliance, {}).setdefault(
entity.entity_category or category, []
).append(attributes)
text = ""
for appliance, categories in sorted(result.items()):
text += f"\n### {APPLIANCES[appliance]}\n"
categories = {k: categories[k] for k in ENTITY_CATEGORY_SORT if k in categories}
for category, data in categories.items():
text += f"#### {str(category).capitalize()}s\n"
text += "| Name | Icon | Entity | Key |\n"
text += "| --- | --- | --- | --- |\n"
for key, name, icon, entity_type in sorted(data, key=lambda d: d[1]):
icon = f"`{icon.replace('mdi:', '')}`" if icon else ""
text += f"| {name} | {icon} | `{entity_type}` | `{key}` |\n"
with open(Path(__file__).parent.parent / "README.md", "r") as file:
readme = file.read()
readme = re.sub(
"(## Appliance Features\n)(?:.|\\s)+?([^#]## |\\Z)",
f"\\1{text}\\2",
readme,
re.DOTALL,
)
with open(Path(__file__).parent.parent / "README.md", "w") as file:
file.write(readme)