Compare commits
	
		
			118 Commits
		
	
	
		
			v0.2.3
			...
			v0.8.0-bet
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d963086dbf | |||
| 29238d3d08 | |||
| a4ec3290ba | |||
| d39deba973 | |||
| fae4c4c879 | |||
| 617ea0f99a | |||
| 81676771c7 | |||
| 604cf1b3c6 | |||
| 9a65eaba77 | |||
| e777fe1ec9 | |||
| 845adc75c9 | |||
| 17d4d14ead | |||
| 593d3912af | |||
| aefe2cf88d | |||
| 146e710881 | |||
| 0afbfe997d | |||
| 6828f3e9a8 | |||
| a56d3e5f88 | |||
| 240dc85ff3 | |||
| 44794c35ca | |||
| a5c7b99569 | |||
| 6935f5f07f | |||
| 74f5887bb2 | |||
| 155b1ff91a | |||
| 7b80acb6b9 | |||
| 0e9bd97c7b | |||
| dae8b48075 | |||
| 7e40afae68 | |||
| c0fda4cd1b | |||
| 2802bcad25 | |||
| 8aa8563b9b | |||
| 8e4e491c33 | |||
| 28a8ad1672 | |||
| e56f2c99c0 | |||
| e35a6ce751 | |||
| 5bff5d2143 | |||
| f1e16312ff | |||
| 8c1bba2468 | |||
| 616f7babdb | |||
| 1143c47fd3 | |||
| c60d94a170 | |||
| c89521f169 | |||
| e49841608d | |||
| 90e02428e8 | |||
| 9370cf84b8 | |||
| e24b48d672 | |||
| 4c3f6604d3 | |||
| 13a23eb6e1 | |||
| 2c93b86dfe | |||
| 9c0b467d68 | |||
| d2cebfad67 | |||
| 7f439139d5 | |||
| aa7b40a454 | |||
| e0cba7379a | |||
| 873cc2d70f | |||
| 43b967cd41 | |||
| 2c6def8f57 | |||
| b723744948 | |||
| e0081bf75e | |||
| 554ce1d7ff | |||
| 256c691213 | |||
| 7fb68be033 | |||
| 72c83527d5 | |||
| 75622e18a2 | |||
| a2d0257410 | |||
| e2c7ca36db | |||
| b33b6a40b2 | |||
| 75859543aa | |||
| 891ae51832 | |||
| 102a05ffcd | |||
| 380cde5a71 | |||
| 5f9dbef4fc | |||
| 5dbf508519 | |||
| 7d3813b8fd | |||
| 2aa1d3df01 | |||
| e2f7f15a5f | |||
| d91b3edb40 | |||
| 83c5e3479e | |||
| b0cd020941 | |||
| 593842144a | |||
| 9a6e1155f9 | |||
| 365a3af171 | |||
| 6de6ff375c | |||
| 89d2fd4af1 | |||
| 92add01a59 | |||
| 4a685e67e0 | |||
| 6303843116 | |||
| 907bc44533 | |||
| 4901be4050 | |||
| c8189414b8 | |||
| 799ac67d94 | |||
| 7e9202ef38 | |||
| e1a2af70e9 | |||
| c78aeb1fbb | |||
| 67f280512d | |||
| 6093b57f76 | |||
| 287e895f4d | |||
| d3dc1b9f45 | |||
| 116f9d5470 | |||
| 05e9d835b1 | |||
| 135d6cafed | |||
| 077bded6dd | |||
| 0d575f65f9 | |||
| 34e888f6d6 | |||
| 26db07acdc | |||
| e698393841 | |||
| 28a0ae53e0 | |||
| 34e99230da | |||
| 5032811963 | |||
| 196309ef5f | |||
| ae6d28f520 | |||
| 1a53ee7e5e | |||
| fbee75108d | |||
| fb8306a4d9 | |||
| 7ec3ca4681 | |||
| 2a3bcfe033 | |||
| db49881b57 | |||
| 93b9989cf2 | 
							
								
								
									
										38
									
								
								.github/workflows/python_check.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.github/workflows/python_check.yml
									
									
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										25
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
										Normal 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
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,4 @@
 | 
				
			|||||||
__pycache__/
 | 
					__pycache__/
 | 
				
			||||||
test.py
 | 
					 | 
				
			||||||
.idea/
 | 
					.idea/
 | 
				
			||||||
 | 
					scripts/translations/
 | 
				
			||||||
 | 
					scripts/test*
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										441
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										441
									
								
								README.md
									
									
									
									
									
								
							@ -1,29 +1,109 @@
 | 
				
			|||||||
# Haier hOn
 | 
					# Haier hOn
 | 
				
			||||||
[](https://github.com/hacs/integration)
 | 
					[](https://hacs.xyz)
 | 
				
			||||||
 | 
					[](https://github.com/Andre0512/hon/releases/latest)
 | 
				
			||||||
 | 
					[](https://github.com/Andre0512/pyhOn)
 | 
				
			||||||
 | 
					[](https://github.com/Andre0512/hon/blob/main/LICENSE)
 | 
				
			||||||
 | 
					[](https://tooomm.github.io/github-release-stats/?username=Andre0512&repository=hon)  
 | 
				
			||||||
 | 
					Home Assistant integration for [Haier's mobile app hOn](https://hon-smarthome.com/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Home Assistant component supporting devices 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)
 | 
				
			||||||
 | 
					- [Dish Washer](https://github.com/Andre0512/hon#dish-washer)
 | 
				
			||||||
 | 
					- [Hob](https://github.com/Andre0512/hon#hob) [BETA]
 | 
				
			||||||
 | 
					- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA]
 | 
				
			||||||
 | 
					- [Fridge](https://github.com/Andre0512/hon#fridge) [BETA]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Installation
 | 
					## Installation
 | 
				
			||||||
#### Installing via HACS
 | 
					**Method 1:** [](https://my.home-assistant.io/redirect/hacs_repository/?owner=Andre0512&repository=hon&category=integration)
 | 
				
			||||||
1. You need to have installed [HACS](https://hacs.xyz/)
 | 
					
 | 
				
			||||||
2. Go to HACS->Integrations
 | 
					**Method 2:** [HACS](https://hacs.xyz/) > Integrations > Add Integration > **Haier hOn** > Install  
 | 
				
			||||||
3. Add this repo (`https://github.com/Andre0512/hon.git`) into your HACS custom repositories
 | 
					
 | 
				
			||||||
4. Search for Haier hOn and Download it
 | 
					**Method 3:** Manually copy `hon` folder from [latest release](https://github.com/Andre0512/hon/releases/latest) to `config/custom_components` folder.
 | 
				
			||||||
5. Restart your HomeAssistant
 | 
					
 | 
				
			||||||
6. Go to Settings->Devices & Services
 | 
					_Restart Home Assistant_
 | 
				
			||||||
7. Shift reload your browser
 | 
					
 | 
				
			||||||
8. Click Add Integration
 | 
					## Configuration
 | 
				
			||||||
9. Search for Haier hOn 
 | 
					
 | 
				
			||||||
10. Type your username used in the hOn App and hit submit
 | 
					**Method 1**: [](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._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Examples
 | 
				
			||||||
 | 
					### Washing Machine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Supported Models
 | 
				
			||||||
 | 
					Support has been confirmed for these models, but many more will work. Please add already supported devices [with this form to complete the list](https://forms.gle/bTSD8qFotdZFytbf8).
 | 
				
			||||||
 | 
					- Haier AD105S2SM3FA
 | 
				
			||||||
 | 
					- Haier AS25PBAHRA
 | 
				
			||||||
 | 
					- Haier AS25TADHRA-2
 | 
				
			||||||
 | 
					- Haier AS35TADHRA-2
 | 
				
			||||||
 | 
					- Haier EG9012B19SU1JD
 | 
				
			||||||
 | 
					- Haier HD80-A3959
 | 
				
			||||||
 | 
					- Haier HW90-B14TEAM5
 | 
				
			||||||
 | 
					- Haier HW100-B14959U1
 | 
				
			||||||
 | 
					- Haier HWD100-B14979
 | 
				
			||||||
 | 
					- Haier HWO60SM2F3XH
 | 
				
			||||||
 | 
					- Haier XIB 3B2SFS-80
 | 
				
			||||||
 | 
					- Haier XIB 6B2D3FB
 | 
				
			||||||
 | 
					- Candy CIS633SCTTWIFI
 | 
				
			||||||
 | 
					- Candy CSOE C10DE-80
 | 
				
			||||||
 | 
					- Candy ROE H9A3TCEX-S
 | 
				
			||||||
 | 
					- Candy RPW41066BWMR/1-S
 | 
				
			||||||
 | 
					- Hoover H-WASH 500
 | 
				
			||||||
 | 
					- Hoover H-DRY 500
 | 
				
			||||||
 | 
					- Hoover H7W4 48MBC-S
 | 
				
			||||||
 | 
					- Hoover H9A3TCBEXS-S
 | 
				
			||||||
 | 
					- Hoover HFB 6B2S3FX
 | 
				
			||||||
 | 
					- Hoover HLE C10DCE-80
 | 
				
			||||||
 | 
					- Hoover HSOT3161WG
 | 
				
			||||||
 | 
					- Hoover HWPD 69AMBC/1-S
 | 
				
			||||||
 | 
					- Hoover HWPS4954DAMR-11
 | 
				
			||||||
 | 
					- Hoover NDE H10A2TCE-80
 | 
				
			||||||
 | 
					- Hoover NDE H9A2TSBEXS-S
 | 
				
			||||||
 | 
					- Hoover NDPHY10A2TCBEXSS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Contribute
 | 
					## Contribute
 | 
				
			||||||
Any kind of contribution is welcome!
 | 
					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 infos of your appliance.
 | 
				
			||||||
 | 
					1. Enable the "Show 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 to create a notification
 | 
				
			||||||
 | 
					3. Open home assistant notifications and copy the message (Crtl+A, Ctrl+C)
 | 
				
			||||||
 | 
					### Add appliances or additional attributes
 | 
				
			||||||
1. Install [pyhOn](https://github.com/Andre0512/pyhOn)
 | 
					1. Install [pyhOn](https://github.com/Andre0512/pyhOn)
 | 
				
			||||||
   ```commandline
 | 
					   ```commandline
 | 
				
			||||||
    $ pip install pyhOn
 | 
					    $ 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
 | 
					    ```commandline
 | 
				
			||||||
    $ pyhOn
 | 
					    $ pyhOn
 | 
				
			||||||
    User for hOn account: user.name@example.com
 | 
					    User for hOn account: user.name@example.com
 | 
				
			||||||
@ -58,17 +138,330 @@ Any kind of contribution is welcome!
 | 
				
			|||||||
5. Create a [pull request](https://github.com/Andre0512/hon/pulls)
 | 
					5. Create a [pull request](https://github.com/Andre0512/hon/pulls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### Tips and Tricks
 | 
					#### 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.
 | 
					- 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Supported Appliances
 | 
					## Special Thanks
 | 
				
			||||||
- Washing Machine
 | 
					- to [@alexandre-leites](https://github.com/alexandre-leites), [@MiguelAngelLV](https://github.com/MiguelAngelLV) and [@drudgebg](https://github.com/drudgebg) for contributing early to this project and adding new integrations.
 | 
				
			||||||
 | 
					- to [gvigroux/hon](https://github.com/gvigroux/hon), [signalize/hon-app-research](https://github.com/signalize/hon-app-research) and [slegars56/hon](https://github.com/slegars56/hon) for inspiring me to do this integration and for doing pioneer work on the hOn api.
 | 
				
			||||||
 | 
					- to everyone who contributed, created an issue, gave this repo a star, and used this integration.
 | 
				
			||||||
 | 
					- to the patience of my girlfriend as I work on this integration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Tested Devices
 | 
					## Appliance Features
 | 
				
			||||||
- Haier WD90
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## About this Repo
 | 
					### Air conditioner
 | 
				
			||||||
The existing integrations missed some features from the app I liked to have in HomeAssistant.
 | 
					#### Controls
 | 
				
			||||||
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. 
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
I moved the api related stuff into the package [pyhOn](https://github.com/Andre0512/pyhOn).
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| 10° Heating | `heat-wave` | `switch` | `settings.10degreeHeatingStatus` |
 | 
				
			||||||
 | 
					| Air Conditioner | `air-conditioner` | `climate` | `settings` |
 | 
				
			||||||
 | 
					| Echo | `account-voice` | `switch` | `settings.echoStatus` |
 | 
				
			||||||
 | 
					| Eco Mode |  | `switch` | `settings.ecoMode` |
 | 
				
			||||||
 | 
					| Eco Pilot | `run` | `select` | `settings.humanSensingStatus` |
 | 
				
			||||||
 | 
					| Health Mode | `medication-outline` | `switch` | `settings.healthMode` |
 | 
				
			||||||
 | 
					| Mute | `volume-off` | `switch` | `settings.muteStatus` |
 | 
				
			||||||
 | 
					| Rapid Mode | `run-fast` | `switch` | `settings.rapidMode` |
 | 
				
			||||||
 | 
					| Screen Display | `monitor-small` | `switch` | `settings.screenDisplayStatus` |
 | 
				
			||||||
 | 
					| Self Cleaning | `air-filter` | `switch` | `settings.selfCleaningStatus` |
 | 
				
			||||||
 | 
					| Self Cleaning 56 | `air-filter` | `switch` | `settings.selfCleaning56Status` |
 | 
				
			||||||
 | 
					| Silent Sleep | `bed` | `switch` | `settings.silentSleepStatus` |
 | 
				
			||||||
 | 
					| Target Temperature | `thermometer` | `number` | `settings.tempSel` |
 | 
				
			||||||
 | 
					#### Sensors
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Air Temperature Outdoor | `thermometer` | `sensor` | `tempAirOutdoor` |
 | 
				
			||||||
 | 
					| Ch2O Cleaning |  | `binary_sensor` | `ch2oCleaningStatus` |
 | 
				
			||||||
 | 
					| Coiler Temperature Indoor | `thermometer` | `sensor` | `tempCoilerIndoor` |
 | 
				
			||||||
 | 
					| Coiler Temperature Outside | `thermometer` | `sensor` | `tempCoilerOutdoor` |
 | 
				
			||||||
 | 
					| Defrost Temperature Outdoor | `thermometer` | `sensor` | `tempDefrostOutdoor` |
 | 
				
			||||||
 | 
					| Filter Replacement |  | `binary_sensor` | `filterChangeStatusLocal` |
 | 
				
			||||||
 | 
					| In Air Temperature Outdoor | `thermometer` | `sensor` | `tempInAirOutdoor` |
 | 
				
			||||||
 | 
					| Indoor Temperature | `thermometer` | `sensor` | `tempIndoor` |
 | 
				
			||||||
 | 
					| Outdoor Temperature | `thermometer` | `sensor` | `tempOutdoor` |
 | 
				
			||||||
 | 
					| Program |  | `select` | `startProgram.program` |
 | 
				
			||||||
 | 
					| Selected Temperature | `thermometer` | `sensor` | `tempSel` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Dish washer
 | 
				
			||||||
 | 
					#### Controls
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Buzzer Disabled | `volume-off` | `switch` | `settings.buzzerDisabled` |
 | 
				
			||||||
 | 
					| 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` |
 | 
				
			||||||
 | 
					| Remaining Time | `timer` | `select` | `startProgram.remainingTime` |
 | 
				
			||||||
 | 
					| Temperature | `thermometer` | `select` | `startProgram.temp` |
 | 
				
			||||||
 | 
					| 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` |
 | 
				
			||||||
 | 
					| 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` |
 | 
				
			||||||
 | 
					| Start Time | `clock-start` | `sensor` | `delayTime` |
 | 
				
			||||||
 | 
					| Temperature | `thermometer` | `sensor` | `temp` |
 | 
				
			||||||
 | 
					| Temperature Selected | `thermometer` | `sensor` | `tempSel` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fridge
 | 
				
			||||||
 | 
					#### Controls
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Auto-Set Mode | `thermometer-auto` | `switch` | `settings.intelligenceMode` |
 | 
				
			||||||
 | 
					| Freezer Temperature | `thermometer` | `number` | `settings.tempSelZ2` |
 | 
				
			||||||
 | 
					| Fridge Temperature | `thermometer` | `number` | `settings.tempSelZ1` |
 | 
				
			||||||
 | 
					| Super Cool | `snowflake` | `switch` | `settings.quickModeZ2` |
 | 
				
			||||||
 | 
					| Super Freeze | `snowflake-variant` | `switch` | `settings.quickModeZ1` |
 | 
				
			||||||
 | 
					#### Configs
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Program |  | `select` | `startProgram.program` |
 | 
				
			||||||
 | 
					#### Sensors
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Auto-Set Mode | `thermometer-auto` | `binary_sensor` | `intelligenceMode` |
 | 
				
			||||||
 | 
					| Door Status Freezer | `fridge-top` | `binary_sensor` | `doorStatusZ1` |
 | 
				
			||||||
 | 
					| Door Status Fridge | `fridge-bottom` | `binary_sensor` | `door2StatusZ1` |
 | 
				
			||||||
 | 
					| Holiday Mode | `palm-tree` | `binary_sensor` | `holidayMode` |
 | 
				
			||||||
 | 
					| Room Humidity | `water-percent` | `sensor` | `humidityEnv` |
 | 
				
			||||||
 | 
					| Room Temperature | `home-thermometer-outline` | `sensor` | `tempEnv` |
 | 
				
			||||||
 | 
					| Super Cool | `snowflake` | `binary_sensor` | `quickModeZ2` |
 | 
				
			||||||
 | 
					| Super Freeze | `snowflake-variant` | `binary_sensor` | `quickModeZ1` |
 | 
				
			||||||
 | 
					| Temperature Freezer | `snowflake-thermometer` | `sensor` | `tempZ2` |
 | 
				
			||||||
 | 
					| Temperature Fridge | `thermometer` | `sensor` | `tempZ1` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 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` |
 | 
				
			||||||
 | 
					| Steam Type | `weather-dust` | `sensor` | `steamType` |
 | 
				
			||||||
 | 
					| Steam level | `smoke` | `sensor` | `startProgram.steamLevel` |
 | 
				
			||||||
 | 
					| Sterilization | `clock-start` | `switch` | `startProgram.sterilizationStatus` |
 | 
				
			||||||
 | 
					| Suggested Load | `weight-kilogram` | `sensor` | `startProgram.suggestedLoadD` |
 | 
				
			||||||
 | 
					| Temperature level | `thermometer` | `number` | `startProgram.tempLevel` |
 | 
				
			||||||
 | 
					#### Sensors
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Anti-Crease |  | `binary_sensor` | `anticrease` |
 | 
				
			||||||
 | 
					| 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` | `programName` |
 | 
				
			||||||
 | 
					| Program Phase | `washing-machine` | `sensor` | `prPhase` |
 | 
				
			||||||
 | 
					| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
 | 
				
			||||||
 | 
					| Start Time | `clock-start` | `sensor` | `delayTime` |
 | 
				
			||||||
 | 
					| Steam level | `smoke` | `sensor` | `steamLevel` |
 | 
				
			||||||
 | 
					| Temperature level | `thermometer` | `sensor` | `tempLevel` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Washer dryer
 | 
				
			||||||
 | 
					#### Controls
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Pause Washer Dryer | `pause` | `switch` | `pauseProgram` / `resumeProgram` |
 | 
				
			||||||
 | 
					| Washer Dryer | `washing-machine` | `switch` | `startProgram` / `stopProgram` |
 | 
				
			||||||
 | 
					#### Configs
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Acqua Plus | `water-plus` | `switch` | `startProgram.acquaplus` |
 | 
				
			||||||
 | 
					| Anti-Crease | `timer` | `switch` | `startProgram.antiCreaseTime` |
 | 
				
			||||||
 | 
					| Anti-Crease | `timer` | `switch` | `startProgram.anticrease` |
 | 
				
			||||||
 | 
					| Auto Dose Detergent | `cup` | `switch` | `startProgram.autoDetergentStatus` |
 | 
				
			||||||
 | 
					| Auto Dose Softener | `teddy-bear` | `switch` | `startProgram.autoSoftenerStatus` |
 | 
				
			||||||
 | 
					| Delay Status | `timer-check` | `switch` | `startProgram.delayStatus` |
 | 
				
			||||||
 | 
					| 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` |
 | 
				
			||||||
 | 
					| Extra Rinse 1 | `numeric-1-box-multiple-outline` | `switch` | `startProgram.extraRinse1` |
 | 
				
			||||||
 | 
					| Extra Rinse 2 | `numeric-2-box-multiple-outline` | `switch` | `startProgram.extraRinse2` |
 | 
				
			||||||
 | 
					| Extra Rinse 3 | `numeric-3-box-multiple-outline` | `switch` | `startProgram.extraRinse3` |
 | 
				
			||||||
 | 
					| Good Night | `weather-night` | `switch` | `startProgram.goodNight` |
 | 
				
			||||||
 | 
					| Keep Fresh | `refresh-circle` | `switch` | `startProgram.permanentPressStatus` |
 | 
				
			||||||
 | 
					| 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` |
 | 
				
			||||||
 | 
					| Steam Level | `weather-dust` | `number` | `startProgram.steamLevel` |
 | 
				
			||||||
 | 
					| Steam Type | `weather-dust` | `sensor` | `steamType` |
 | 
				
			||||||
 | 
					| Steam level | `smoke` | `sensor` | `startProgram.steamLevel` |
 | 
				
			||||||
 | 
					| Sterilization | `clock-start` | `switch` | `startProgram.sterilizationStatus` |
 | 
				
			||||||
 | 
					| Suggested Load | `weight-kilogram` | `sensor` | `startProgram.suggestedLoadW` |
 | 
				
			||||||
 | 
					| Suggested Load | `weight-kilogram` | `sensor` | `startProgram.suggestedLoadD` |
 | 
				
			||||||
 | 
					| Suggested weight | `weight-kilogram` | `sensor` | `startProgram.weight` |
 | 
				
			||||||
 | 
					| Temperature | `thermometer` | `select` | `startProgram.temp` |
 | 
				
			||||||
 | 
					| Temperature level | `thermometer` | `number` | `startProgram.tempLevel` |
 | 
				
			||||||
 | 
					| Water hard | `water` | `number` | `startProgram.waterHard` |
 | 
				
			||||||
 | 
					| lang |  | `number` | `startProgram.lang` |
 | 
				
			||||||
 | 
					#### Sensors
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Acqua Plus |  | `binary_sensor` | `acquaplus` |
 | 
				
			||||||
 | 
					| Anti-Crease |  | `binary_sensor` | `anticrease` |
 | 
				
			||||||
 | 
					| Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` |
 | 
				
			||||||
 | 
					| Current Temperature | `thermometer` | `sensor` | `temp` |
 | 
				
			||||||
 | 
					| Current Water Used | `water` | `sensor` | `currentWaterUsed` |
 | 
				
			||||||
 | 
					| Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` |
 | 
				
			||||||
 | 
					| Door |  | `binary_sensor` | `doorStatus` |
 | 
				
			||||||
 | 
					| Door Lock |  | `binary_sensor` | `doorLockStatus` |
 | 
				
			||||||
 | 
					| Dry level | `hair-dryer` | `sensor` | `dryLevel` |
 | 
				
			||||||
 | 
					| Error | `math-log` | `sensor` | `errors` |
 | 
				
			||||||
 | 
					| 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 | `tumble-dryer` | `sensor` | `programName` |
 | 
				
			||||||
 | 
					| Program Phase | `washing-machine` | `sensor` | `prPhase` |
 | 
				
			||||||
 | 
					| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
 | 
				
			||||||
 | 
					| Remote Control | `remote` | `binary_sensor` | `attributes.lastConnEvent.category` |
 | 
				
			||||||
 | 
					| Spin Speed | `speedometer` | `sensor` | `spinSpeed` |
 | 
				
			||||||
 | 
					| Start Time | `clock-start` | `sensor` | `delayTime` |
 | 
				
			||||||
 | 
					| Steam level | `smoke` | `sensor` | `steamLevel` |
 | 
				
			||||||
 | 
					| Temperature level | `thermometer` | `sensor` | `tempLevel` |
 | 
				
			||||||
 | 
					| 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 |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Acqua Plus | `water-plus` | `switch` | `startProgram.acquaplus` |
 | 
				
			||||||
 | 
					| Auto Dose Detergent | `cup` | `switch` | `startProgram.autoDetergentStatus` |
 | 
				
			||||||
 | 
					| Auto Dose Softener | `teddy-bear` | `switch` | `startProgram.autoSoftenerStatus` |
 | 
				
			||||||
 | 
					| Delay Status | `timer-check` | `switch` | `startProgram.delayStatus` |
 | 
				
			||||||
 | 
					| Delay Time | `timer-plus` | `number` | `startProgram.delayTime` |
 | 
				
			||||||
 | 
					| Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` |
 | 
				
			||||||
 | 
					| Extra Rinse 1 | `numeric-1-box-multiple-outline` | `switch` | `startProgram.extraRinse1` |
 | 
				
			||||||
 | 
					| Extra Rinse 2 | `numeric-2-box-multiple-outline` | `switch` | `startProgram.extraRinse2` |
 | 
				
			||||||
 | 
					| Extra Rinse 3 | `numeric-3-box-multiple-outline` | `switch` | `startProgram.extraRinse3` |
 | 
				
			||||||
 | 
					| Good Night | `weather-night` | `switch` | `startProgram.goodNight` |
 | 
				
			||||||
 | 
					| Keep Fresh | `refresh-circle` | `switch` | `startProgram.permanentPressStatus` |
 | 
				
			||||||
 | 
					| 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` |
 | 
				
			||||||
 | 
					| Steam Level | `weather-dust` | `number` | `startProgram.steamLevel` |
 | 
				
			||||||
 | 
					| Suggested Load | `weight-kilogram` | `sensor` | `startProgram.suggestedLoadW` |
 | 
				
			||||||
 | 
					| Suggested weight | `weight-kilogram` | `sensor` | `startProgram.weight` |
 | 
				
			||||||
 | 
					| Temperature | `thermometer` | `select` | `startProgram.temp` |
 | 
				
			||||||
 | 
					| Water hard | `water` | `number` | `startProgram.waterHard` |
 | 
				
			||||||
 | 
					| lang |  | `number` | `startProgram.lang` |
 | 
				
			||||||
 | 
					#### Sensors
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Acqua Plus |  | `binary_sensor` | `acquaplus` |
 | 
				
			||||||
 | 
					| Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` |
 | 
				
			||||||
 | 
					| Current Temperature | `thermometer` | `sensor` | `temp` |
 | 
				
			||||||
 | 
					| Current Water Used | `water` | `sensor` | `currentWaterUsed` |
 | 
				
			||||||
 | 
					| Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` |
 | 
				
			||||||
 | 
					| Door |  | `binary_sensor` | `doorStatus` |
 | 
				
			||||||
 | 
					| Door Lock |  | `binary_sensor` | `doorLockStatus` |
 | 
				
			||||||
 | 
					| Error | `math-log` | `sensor` | `errors` |
 | 
				
			||||||
 | 
					| 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 | `speedometer` | `sensor` | `spinSpeed` |
 | 
				
			||||||
 | 
					| Total Power |  | `sensor` | `totalElectricityUsed` |
 | 
				
			||||||
 | 
					| Total Wash Cycle | `counter` | `sensor` | `totalWashCycle` |
 | 
				
			||||||
 | 
					| Total Water |  | `sensor` | `totalWaterUsed` |
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								assets/washing_machine.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/washing_machine.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 202 KiB  | 
@ -1,7 +1,7 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import voluptuous as vol
 | 
					import voluptuous as vol
 | 
				
			||||||
from pyhon import HonConnection
 | 
					from pyhon import Hon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from homeassistant.config_entries import ConfigEntry
 | 
					from homeassistant.config_entries import ConfigEntry
 | 
				
			||||||
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
 | 
					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):
 | 
					async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
 | 
				
			||||||
    session = aiohttp_client.async_get_clientsession(hass)
 | 
					    session = aiohttp_client.async_get_clientsession(hass)
 | 
				
			||||||
    hon = HonConnection(entry.data["email"], entry.data["password"], session)
 | 
					    hon = await Hon(
 | 
				
			||||||
    await hon.setup()
 | 
					        entry.data["email"], entry.data["password"], session=session
 | 
				
			||||||
 | 
					    ).create()
 | 
				
			||||||
    hass.data.setdefault(DOMAIN, {})
 | 
					    hass.data.setdefault(DOMAIN, {})
 | 
				
			||||||
    hass.data[DOMAIN][entry.unique_id] = hon
 | 
					    hass.data[DOMAIN][entry.unique_id] = hon
 | 
				
			||||||
    hass.data[DOMAIN]["coordinators"] = {}
 | 
					    hass.data[DOMAIN]["coordinators"] = {}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,17 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
from dataclasses import dataclass
 | 
					from dataclasses import dataclass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import HonConnection
 | 
					from pyhon import Hon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from homeassistant.components.binary_sensor import BinarySensorEntityDescription, BinarySensorDeviceClass, \
 | 
					from homeassistant.components.binary_sensor import (
 | 
				
			||||||
    BinarySensorEntity
 | 
					    BinarySensorEntityDescription,
 | 
				
			||||||
 | 
					    BinarySensorDeviceClass,
 | 
				
			||||||
 | 
					    BinarySensorEntity,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from homeassistant.config_entries import ConfigEntry
 | 
					from homeassistant.config_entries import ConfigEntry
 | 
				
			||||||
from homeassistant.core import callback
 | 
					from homeassistant.core import callback
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonCoordinator, HonEntity
 | 
					from .hon import HonCoordinator, HonEntity, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -19,7 +22,9 @@ class HonBinarySensorEntityDescriptionMixin:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@dataclass
 | 
					@dataclass
 | 
				
			||||||
class HonBinarySensorEntityDescription(HonBinarySensorEntityDescriptionMixin, BinarySensorEntityDescription):
 | 
					class HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					    HonBinarySensorEntityDescriptionMixin, BinarySensorEntityDescription
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,39 +32,241 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
    "WM": (
 | 
					    "WM": (
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="attributes.lastConnEvent.category",
 | 
					            key="attributes.lastConnEvent.category",
 | 
				
			||||||
            name="Connection",
 | 
					            name="Remote Control",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
				
			||||||
            on_value="CONNECTED",
 | 
					            on_value="CONNECTED",
 | 
				
			||||||
 | 
					            icon="mdi:remote",
 | 
				
			||||||
 | 
					            translation_key="remote_control",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="doorLockStatus",
 | 
					            key="doorLockStatus",
 | 
				
			||||||
 | 
					            name="Door Lock",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.LOCK,
 | 
				
			||||||
 | 
					            on_value="0",
 | 
				
			||||||
 | 
					            translation_key="door_lock",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="doorStatus",
 | 
				
			||||||
            name="Door",
 | 
					            name="Door",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
					            device_class=BinarySensorDeviceClass.DOOR,
 | 
				
			||||||
            on_value="0",
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            translation_key="door_open",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.prewash", name="Pre Wash", translation_key="prewash"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="extraRinse1", name="Extra Rinse 1", translation_key="extra_rinse_1"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="extraRinse2", name="Extra Rinse 2", translation_key="extra_rinse_2"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="extraRinse3", name="Extra Rinse 3", translation_key="extra_rinse_3"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="goodNight", name="Good Night Mode", translation_key="good_night"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="acquaplus", name="Acqua Plus", translation_key="acqua_plus"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "TD": (
 | 
				
			||||||
 | 
					        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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="anticrease", name="Anti-Crease", translation_key="anti_crease"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "OV": (
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="attributes.lastConnEvent.category",
 | 
				
			||||||
 | 
					            name="Connection",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
				
			||||||
 | 
					            on_value="CONNECTED",
 | 
				
			||||||
 | 
					            icon="mdi:wifi",
 | 
				
			||||||
 | 
					            translation_key="connection",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="attributes.parameters.onOffStatus",
 | 
				
			||||||
 | 
					            name="On",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.RUNNING,
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            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.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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="filterChangeStatusLocal",
 | 
				
			||||||
 | 
					            name="Filter Replacement",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.PROBLEM,
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            translation_key="filter_replacement",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="ch2oCleaningStatus",
 | 
				
			||||||
 | 
					            name="Ch2O Cleaning",
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="quickModeZ2",
 | 
				
			||||||
 | 
					            name="Super Cool",
 | 
				
			||||||
 | 
					            icon="mdi:snowflake",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.RUNNING,
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            translation_key="super_cool",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="quickModeZ1",
 | 
				
			||||||
 | 
					            name="Super Freeze",
 | 
				
			||||||
 | 
					            icon="mdi:snowflake-variant",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.RUNNING,
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            translation_key="super_freeze",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="doorStatusZ1",
 | 
				
			||||||
 | 
					            name="Door Status Freezer",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.DOOR,
 | 
				
			||||||
 | 
					            icon="mdi:fridge-top",
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            translation_key="freezer_door",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="door2StatusZ1",
 | 
				
			||||||
 | 
					            name="Door Status Fridge",
 | 
				
			||||||
 | 
					            icon="mdi:fridge-bottom",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.DOOR,
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            translation_key="fridge_door",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="intelligenceMode",
 | 
				
			||||||
 | 
					            name="Auto-Set Mode",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer-auto",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.RUNNING,
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            translation_key="auto_set",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
 | 
					            key="holidayMode",
 | 
				
			||||||
 | 
					            name="Holiday Mode",
 | 
				
			||||||
 | 
					            icon="mdi:palm-tree",
 | 
				
			||||||
 | 
					            device_class=BinarySensorDeviceClass.RUNNING,
 | 
				
			||||||
 | 
					            on_value="1",
 | 
				
			||||||
 | 
					            translation_key="holiday_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BINARY_SENSORS["WD"] = unique_entities(BINARY_SENSORS["WM"], BINARY_SENSORS["TD"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
 | 
					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"]
 | 
					    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
				
			||||||
    appliances = []
 | 
					    appliances = []
 | 
				
			||||||
    for device in hon.devices:
 | 
					    for device in hon.appliances:
 | 
				
			||||||
        if device.mac_address in coordinators:
 | 
					        if device.unique_id in coordinators:
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
 | 
					            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            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()
 | 
					        await coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if descriptions := BINARY_SENSORS.get(device.appliance_type):
 | 
					        if descriptions := BINARY_SENSORS.get(device.appliance_type):
 | 
				
			||||||
            for description in descriptions:
 | 
					            for description in descriptions:
 | 
				
			||||||
                if not device.get(description.key):
 | 
					                if not device.get(description.key):
 | 
				
			||||||
                    _LOGGER.info("Can't setup %s", description.key)
 | 
					 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
                appliances.extend([
 | 
					                appliances.append(
 | 
				
			||||||
                    HonBinarySensorEntity(hass, coordinator, entry, device, description)]
 | 
					                    HonBinarySensorEntity(hass, coordinator, entry, device, description)
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async_add_entities(appliances)
 | 
					    async_add_entities(appliances)
 | 
				
			||||||
@ -71,16 +278,20 @@ class HonBinarySensorEntity(HonEntity, BinarySensorEntity):
 | 
				
			|||||||
    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
					    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					        super().__init__(hass, entry, coordinator, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.entity_description = description
 | 
					        self.entity_description = description
 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_on(self) -> bool:
 | 
					    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
 | 
					    @callback
 | 
				
			||||||
    def _handle_coordinator_update(self):
 | 
					    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()
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,59 +1,92 @@
 | 
				
			|||||||
from pyhon import HonConnection
 | 
					import logging
 | 
				
			||||||
from pyhon.device import HonDevice
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import pkg_resources
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from homeassistant.components import persistent_notification
 | 
				
			||||||
from homeassistant.components.button import ButtonEntityDescription, ButtonEntity
 | 
					from homeassistant.components.button import ButtonEntityDescription, ButtonEntity
 | 
				
			||||||
from homeassistant.config_entries import ConfigEntry
 | 
					from homeassistant.config_entries import ConfigEntry
 | 
				
			||||||
 | 
					from homeassistant.const import EntityCategory
 | 
				
			||||||
 | 
					from pyhon import Hon
 | 
				
			||||||
 | 
					from pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonCoordinator, HonEntity
 | 
					from .hon import HonCoordinator, HonEntity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = {
 | 
					BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = {
 | 
				
			||||||
    "WM": (
 | 
					    "IH": (
 | 
				
			||||||
        # ButtonEntityDescription(
 | 
					        ButtonEntityDescription(
 | 
				
			||||||
        #     key="pauseProgram",
 | 
					            key="startProgram",
 | 
				
			||||||
        #     name="Pause Program",
 | 
					            name="Start Program",
 | 
				
			||||||
        #     icon="mdi:pause",
 | 
					            icon="mdi:pot-steam",
 | 
				
			||||||
        # ),
 | 
					            translation_key="induction_hob",
 | 
				
			||||||
        # ButtonEntityDescription(
 | 
					        ),
 | 
				
			||||||
        #     key="resumeProgram",
 | 
					 | 
				
			||||||
        #     name="Resume Program",
 | 
					 | 
				
			||||||
        #     icon="mdi:play-pause",
 | 
					 | 
				
			||||||
        # ),
 | 
					 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
 | 
					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"]
 | 
					    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
				
			||||||
    appliances = []
 | 
					    appliances = []
 | 
				
			||||||
    for device in hon.devices:
 | 
					    for device in hon.appliances:
 | 
				
			||||||
        if device.mac_address in coordinators:
 | 
					        if device.unique_id in coordinators:
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
 | 
					            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            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()
 | 
					        await coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if descriptions := BUTTONS.get(device.appliance_type):
 | 
					        if descriptions := BUTTONS.get(device.appliance_type):
 | 
				
			||||||
            for description in descriptions:
 | 
					            for description in descriptions:
 | 
				
			||||||
                if not device.commands.get(description.key):
 | 
					                if not device.commands.get(description.key):
 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
                appliances.extend([
 | 
					                appliances.extend(
 | 
				
			||||||
                    HonButtonEntity(hass, coordinator, entry, device, description)]
 | 
					                    [HonButtonEntity(hass, coordinator, entry, device, description)]
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					        appliances.extend([HonFeatureRequestButton(hass, coordinator, entry, device)])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async_add_entities(appliances)
 | 
					    async_add_entities(appliances)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonButtonEntity(HonEntity, ButtonEntity):
 | 
					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)
 | 
					        super().__init__(hass, entry, coordinator, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					 | 
				
			||||||
        self._device = device
 | 
					 | 
				
			||||||
        self.entity_description = description
 | 
					        self.entity_description = description
 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def async_press(self) -> None:
 | 
					    async def async_press(self) -> None:
 | 
				
			||||||
        await self._device.commands[self.entity_description.key].send()
 | 
					        await self._device.commands[self.entity_description.key].send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def available(self) -> bool:
 | 
				
			||||||
 | 
					        """Return True if entity is available."""
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            super().available
 | 
				
			||||||
 | 
					            and self._device.get("remoteCtrValid", "1") == "1"
 | 
				
			||||||
 | 
					            and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HonFeatureRequestButton(HonEntity, ButtonEntity):
 | 
				
			||||||
 | 
					    def __init__(self, hass, coordinator, entry, device: HonAppliance) -> None:
 | 
				
			||||||
 | 
					        super().__init__(hass, entry, coordinator, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._attr_unique_id = f"{super().unique_id}_log_device_info"
 | 
				
			||||||
 | 
					        self._attr_icon = "mdi:information"
 | 
				
			||||||
 | 
					        self._attr_name = "Show 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"{self._device.diagnose()}pyhOnVersion: {pyhon_version}"
 | 
				
			||||||
 | 
					        title = f"{self._device.nick_name} Device Info"
 | 
				
			||||||
 | 
					        persistent_notification.create(
 | 
				
			||||||
 | 
					            self._hass, f"````\n```\n{info}\n```\n````", title
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        _LOGGER.info(info.replace(" ", "\u200B "))
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										162
									
								
								custom_components/hon/climate.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								custom_components/hon/climate.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,162 @@
 | 
				
			|||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from pyhon import Hon
 | 
				
			||||||
 | 
					from pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 .const import HON_HVAC_MODE, HON_FAN, HON_HVAC_PROGRAM, DOMAIN
 | 
				
			||||||
 | 
					from .hon import HonEntity, HonCoordinator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLIMATES = {
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        ClimateEntityDescription(
 | 
				
			||||||
 | 
					            key="settings",
 | 
				
			||||||
 | 
					            name="Air Conditioner",
 | 
				
			||||||
 | 
					            icon="mdi:air-conditioner",
 | 
				
			||||||
 | 
					            translation_key="air_conditioner",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 list(device.commands):
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                appliances.append(
 | 
				
			||||||
 | 
					                    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.entity_description = description
 | 
				
			||||||
 | 
					        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["settings.tempSel"].max
 | 
				
			||||||
 | 
					        self._attr_min_temp = device.settings["settings.tempSel"].min
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._attr_hvac_modes = [HVACMode.OFF] + [
 | 
				
			||||||
 | 
					            HON_HVAC_MODE[mode] for mode in device.settings["settings.machMode"].values
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        self._attr_fan_modes = [FAN_OFF] + [
 | 
				
			||||||
 | 
					            HON_FAN[mode] for mode in device.settings["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
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._handle_coordinator_update(update=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_hvac_mode(self, hvac_mode):
 | 
				
			||||||
 | 
					        if hvac_mode == HVACMode.OFF:
 | 
				
			||||||
 | 
					            await self._device.commands["stopProgram"].send()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self._device.settings["startProgram.program"].value = HON_HVAC_PROGRAM[
 | 
				
			||||||
 | 
					                hvac_mode
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					            await self._device.commands["startProgram"].send()
 | 
				
			||||||
 | 
					        self._attr_hvac_mode = hvac_mode
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_fan_mode(self, fan_mode):
 | 
				
			||||||
 | 
					        mode_number = list(HON_FAN.values()).index(fan_mode)
 | 
				
			||||||
 | 
					        self._device.settings["settings.windSpeed"].value = list(HON_FAN.keys())[
 | 
				
			||||||
 | 
					            mode_number
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_swing_mode(self, swing_mode):
 | 
				
			||||||
 | 
					        horizontal = self._device.settings["settings.windDirectionHorizontal"]
 | 
				
			||||||
 | 
					        vertical = self._device.settings["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
 | 
				
			||||||
 | 
					        await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_temperature(self, **kwargs):
 | 
				
			||||||
 | 
					        if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					        self._device.settings["settings.tempSel"].value = str(int(temperature))
 | 
				
			||||||
 | 
					        await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @callback
 | 
				
			||||||
 | 
					    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"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self._device.get("onOffStatus") == "0":
 | 
				
			||||||
 | 
					            self._attr_hvac_mode = HVACMode.OFF
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self._attr_hvac_mode = HON_HVAC_MODE[self._device.get("machMode") or "0"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._attr_fan_mode = HON_FAN[self._device.get("windSpeed")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        horizontal = self._device.get("windDirectionHorizontal")
 | 
				
			||||||
 | 
					        vertical = self._device.get("windDirectionVertical")
 | 
				
			||||||
 | 
					        if horizontal == "7" and vertical == "8":
 | 
				
			||||||
 | 
					            self._attr_swing_mode = SWING_BOTH
 | 
				
			||||||
 | 
					        elif horizontal == "7":
 | 
				
			||||||
 | 
					            self._attr_swing_mode = SWING_HORIZONTAL
 | 
				
			||||||
 | 
					        elif vertical == "8":
 | 
				
			||||||
 | 
					            self._attr_swing_mode = SWING_VERTICAL
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self._attr_swing_mode = SWING_OFF
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
@ -4,7 +4,6 @@ import voluptuous as vol
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from homeassistant import config_entries
 | 
					from homeassistant import config_entries
 | 
				
			||||||
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
 | 
					from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
 | 
				
			||||||
 | 
					 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
@ -20,8 +19,12 @@ class HonFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async def async_step_user(self, user_input=None):
 | 
					    async def async_step_user(self, user_input=None):
 | 
				
			||||||
        if user_input is None:
 | 
					        if user_input is None:
 | 
				
			||||||
            return self.async_show_form(step_id="user", data_schema=vol.Schema(
 | 
					            return self.async_show_form(
 | 
				
			||||||
                {vol.Required(CONF_EMAIL): str, vol.Required(CONF_PASSWORD): str}))
 | 
					                step_id="user",
 | 
				
			||||||
 | 
					                data_schema=vol.Schema(
 | 
				
			||||||
 | 
					                    {vol.Required(CONF_EMAIL): str, vol.Required(CONF_PASSWORD): str}
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._email = user_input[CONF_EMAIL]
 | 
					        self._email = user_input[CONF_EMAIL]
 | 
				
			||||||
        self._password = user_input[CONF_PASSWORD]
 | 
					        self._password = user_input[CONF_PASSWORD]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,11 @@
 | 
				
			|||||||
 | 
					from homeassistant.components.climate import (
 | 
				
			||||||
 | 
					    HVACMode,
 | 
				
			||||||
 | 
					    FAN_LOW,
 | 
				
			||||||
 | 
					    FAN_MEDIUM,
 | 
				
			||||||
 | 
					    FAN_HIGH,
 | 
				
			||||||
 | 
					    FAN_AUTO,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DOMAIN = "hon"
 | 
					DOMAIN = "hon"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PLATFORMS = [
 | 
					PLATFORMS = [
 | 
				
			||||||
@ -7,4 +15,302 @@ PLATFORMS = [
 | 
				
			|||||||
    "switch",
 | 
					    "switch",
 | 
				
			||||||
    "button",
 | 
					    "button",
 | 
				
			||||||
    "binary_sensor",
 | 
					    "binary_sensor",
 | 
				
			||||||
 | 
					    "climate",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HON_HVAC_MODE = {
 | 
				
			||||||
 | 
					    "0": HVACMode.AUTO,
 | 
				
			||||||
 | 
					    "1": HVACMode.COOL,
 | 
				
			||||||
 | 
					    "2": HVACMode.DRY,
 | 
				
			||||||
 | 
					    "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,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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",  # NO_STATE
 | 
				
			||||||
 | 
					    "1": "WASHING_CMD&CTRL.PHASE_READY.TITLE",  # SELECTION_MODE
 | 
				
			||||||
 | 
					    "2": "WASHING_CMD&CTRL.PHASE_RUNNING.TITLE",  # EXECUTION_MODE
 | 
				
			||||||
 | 
					    "3": "WASHING_CMD&CTRL.PHASE_PAUSE.TITLE",  # PAUSE_MODE
 | 
				
			||||||
 | 
					    "4": "WASHING_CMD&CTRL.PHASE_SCHEDULED.TITLE",  # DELAY_START_SELECTION_MODE
 | 
				
			||||||
 | 
					    "5": "WASHING_CMD&CTRL.PHASE_SCHEDULED.TITLE",  # DELAY_START_EXECUTION_MODE
 | 
				
			||||||
 | 
					    "6": "WASHING_CMD&CTRL.PHASE_ERROR.TITLE",  # ERROR_MODE
 | 
				
			||||||
 | 
					    "7": "WASHING_CMD&CTRL.PHASE_READY.TITLE",  # END_MODE
 | 
				
			||||||
 | 
					    "8": "Test",  # TEST_MODE
 | 
				
			||||||
 | 
					    "9": "GLOBALS.APPLIANCE_STATUS.ENDING_PROGRAM",  # STOP_MODE
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					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",
 | 
				
			||||||
 | 
					    "11": "WASHING_CMD&CTRL.PHASE_READY.TITLE",
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					    "17": "unknown",
 | 
				
			||||||
 | 
					    "18": "WASHING_CMD&CTRL.PHASE_TUMBLING.DASHBOARD_TITLE",
 | 
				
			||||||
 | 
					    "19": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE",
 | 
				
			||||||
 | 
					    "20": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					DIRTY_LEVEL = {
 | 
				
			||||||
 | 
					    "1": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.LITTLE",
 | 
				
			||||||
 | 
					    "2": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.NORMAL",
 | 
				
			||||||
 | 
					    "3": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.VERY",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					STEAM_LEVEL = {
 | 
				
			||||||
 | 
					    "0": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.NO_STEAM",
 | 
				
			||||||
 | 
					    "1": "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_FABRICS.COTTON_TITLE",
 | 
				
			||||||
 | 
					    "2": "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_FABRICS.DELICATE_TITLE",
 | 
				
			||||||
 | 
					    "3": "WASHING_CMD&CTRL.GUIDED_WASHING_SYMBOLS_FABRICS.SYNTHETIC_TITLE",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DISHWASHER_PR_PHASE = {
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					    "11": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_MAIN_OPTIONS.NO_DRY",
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROGRAMS_TD = [
 | 
				
			||||||
 | 
					    "active_dry",
 | 
				
			||||||
 | 
					    "allergy_care",
 | 
				
			||||||
 | 
					    "all_in_one",
 | 
				
			||||||
 | 
					    "antiallergy",
 | 
				
			||||||
 | 
					    "anti_odours",
 | 
				
			||||||
 | 
					    "auto_care",
 | 
				
			||||||
 | 
					    "baby",
 | 
				
			||||||
 | 
					    "bed_quilt",
 | 
				
			||||||
 | 
					    "care_30",
 | 
				
			||||||
 | 
					    "care_45",
 | 
				
			||||||
 | 
					    "care_59",
 | 
				
			||||||
 | 
					    "coloured",
 | 
				
			||||||
 | 
					    "daily_45_min",
 | 
				
			||||||
 | 
					    "daily_perfect_59_min",
 | 
				
			||||||
 | 
					    "darks_and_coloured",
 | 
				
			||||||
 | 
					    "delicates",
 | 
				
			||||||
 | 
					    "duvet",
 | 
				
			||||||
 | 
					    "eco",
 | 
				
			||||||
 | 
					    "ecospeed_cottons",
 | 
				
			||||||
 | 
					    "ecospeed_delicates",
 | 
				
			||||||
 | 
					    "ecospeed_mixed",
 | 
				
			||||||
 | 
					    "extra_hygiene",
 | 
				
			||||||
 | 
					    "fitness",
 | 
				
			||||||
 | 
					    "fresh_care",
 | 
				
			||||||
 | 
					    "genius",
 | 
				
			||||||
 | 
					    "hqd_baby_care",
 | 
				
			||||||
 | 
					    "hqd_bath_towel",
 | 
				
			||||||
 | 
					    "hqd_bed_sheets",
 | 
				
			||||||
 | 
					    "hqd_bulky",
 | 
				
			||||||
 | 
					    "hqd_casual",
 | 
				
			||||||
 | 
					    "hqd_cold_wind_30",
 | 
				
			||||||
 | 
					    "hqd_cold_wind_timing",
 | 
				
			||||||
 | 
					    "hqd_cotton",
 | 
				
			||||||
 | 
					    "hqd_curtain",
 | 
				
			||||||
 | 
					    "hqd_delicate",
 | 
				
			||||||
 | 
					    "hqd_diaper",
 | 
				
			||||||
 | 
					    "hqd_duvet",
 | 
				
			||||||
 | 
					    "hqd_feather",
 | 
				
			||||||
 | 
					    "hqd_hot_wind_timing",
 | 
				
			||||||
 | 
					    "hqd_hygienic",
 | 
				
			||||||
 | 
					    "hqd_i_refresh",
 | 
				
			||||||
 | 
					    "hqd_i_refresh_pro",
 | 
				
			||||||
 | 
					    "hqd_jacket",
 | 
				
			||||||
 | 
					    "hqd_jeans",
 | 
				
			||||||
 | 
					    "hqd_luxury",
 | 
				
			||||||
 | 
					    "hqd_mix",
 | 
				
			||||||
 | 
					    "hqd_night_dry",
 | 
				
			||||||
 | 
					    "hqd_outdoor",
 | 
				
			||||||
 | 
					    "hqd_precious_cure",
 | 
				
			||||||
 | 
					    "hqd_quick_20",
 | 
				
			||||||
 | 
					    "hqd_quick_30",
 | 
				
			||||||
 | 
					    "hqd_quick_dry",
 | 
				
			||||||
 | 
					    "hqd_quilt",
 | 
				
			||||||
 | 
					    "hqd_refresh",
 | 
				
			||||||
 | 
					    "hqd_school_uniform",
 | 
				
			||||||
 | 
					    "hqd_shirt",
 | 
				
			||||||
 | 
					    "hqd_shoes",
 | 
				
			||||||
 | 
					    "hqd_silk",
 | 
				
			||||||
 | 
					    "hqd_sports",
 | 
				
			||||||
 | 
					    "hqd_synthetics",
 | 
				
			||||||
 | 
					    "hqd_timer",
 | 
				
			||||||
 | 
					    "hqd_towel",
 | 
				
			||||||
 | 
					    "hqd_underwear",
 | 
				
			||||||
 | 
					    "hqd_warm_up",
 | 
				
			||||||
 | 
					    "hqd_wool",
 | 
				
			||||||
 | 
					    "hqd_working_suit",
 | 
				
			||||||
 | 
					    "hygiene",
 | 
				
			||||||
 | 
					    "iot_checkup",
 | 
				
			||||||
 | 
					    "iot_dry_anti_mites",
 | 
				
			||||||
 | 
					    "iot_dry_baby",
 | 
				
			||||||
 | 
					    "iot_dry_backpacks",
 | 
				
			||||||
 | 
					    "iot_dry_bathrobe",
 | 
				
			||||||
 | 
					    "iot_dry_bed_linen",
 | 
				
			||||||
 | 
					    "iot_dry_bed_quilt",
 | 
				
			||||||
 | 
					    "iot_dry_cotton",
 | 
				
			||||||
 | 
					    "iot_dry_cuddly_toys",
 | 
				
			||||||
 | 
					    "iot_dry_curtains",
 | 
				
			||||||
 | 
					    "iot_dry_dehumidifier",
 | 
				
			||||||
 | 
					    "iot_dry_delicates",
 | 
				
			||||||
 | 
					    "iot_dry_delicate_tablecloths",
 | 
				
			||||||
 | 
					    "iot_dry_denim_jeans",
 | 
				
			||||||
 | 
					    "iot_dry_down_jacket",
 | 
				
			||||||
 | 
					    "iot_dry_duvet",
 | 
				
			||||||
 | 
					    "iot_dry_easy_iron_cotton",
 | 
				
			||||||
 | 
					    "iot_dry_easy_iron_synthetics",
 | 
				
			||||||
 | 
					    "iot_dry_gym_fit",
 | 
				
			||||||
 | 
					    "iot_dry_lingerie",
 | 
				
			||||||
 | 
					    "iot_dry_mixed",
 | 
				
			||||||
 | 
					    "iot_dry_playsuits",
 | 
				
			||||||
 | 
					    "iot_dry_rapid_30",
 | 
				
			||||||
 | 
					    "iot_dry_rapid_59",
 | 
				
			||||||
 | 
					    "iot_dry_refresh",
 | 
				
			||||||
 | 
					    "iot_dry_regenerates_waterproof",
 | 
				
			||||||
 | 
					    "iot_dry_relax_creases",
 | 
				
			||||||
 | 
					    "iot_dry_shirts",
 | 
				
			||||||
 | 
					    "iot_dry_small_load",
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					    "jeans",
 | 
				
			||||||
 | 
					    "mix_and_dry",
 | 
				
			||||||
 | 
					    "pets",
 | 
				
			||||||
 | 
					    "pre_iron",
 | 
				
			||||||
 | 
					    "rapid_30",
 | 
				
			||||||
 | 
					    "rapid_45",
 | 
				
			||||||
 | 
					    "rapid_59",
 | 
				
			||||||
 | 
					    "refresh",
 | 
				
			||||||
 | 
					    "relax_creases",
 | 
				
			||||||
 | 
					    "saving_30_min",
 | 
				
			||||||
 | 
					    "shirts",
 | 
				
			||||||
 | 
					    "shoes",
 | 
				
			||||||
 | 
					    "small_load",
 | 
				
			||||||
 | 
					    "soft_care",
 | 
				
			||||||
 | 
					    "sport_plus",
 | 
				
			||||||
 | 
					    "super_easy_iron_misti",
 | 
				
			||||||
 | 
					    "super_easy_iron_xxl",
 | 
				
			||||||
 | 
					    "super_fast_cottons",
 | 
				
			||||||
 | 
					    "super_fast_delicates",
 | 
				
			||||||
 | 
					    "synthetics",
 | 
				
			||||||
 | 
					    "total_care",
 | 
				
			||||||
 | 
					    "trainers",
 | 
				
			||||||
 | 
					    "ultra_care",
 | 
				
			||||||
 | 
					    "waterproof_revitalize",
 | 
				
			||||||
 | 
					    "whites",
 | 
				
			||||||
 | 
					    "wool",
 | 
				
			||||||
 | 
					    "woolmark",
 | 
				
			||||||
 | 
					    "xxl_load",
 | 
				
			||||||
 | 
					    "zoom_59",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,11 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
from datetime import timedelta
 | 
					from datetime import timedelta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon.device import HonDevice
 | 
					from pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from homeassistant.helpers.entity import DeviceInfo
 | 
					from homeassistant.helpers.entity import DeviceInfo
 | 
				
			||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
 | 
					from homeassistant.helpers.update_coordinator import CoordinatorEntity
 | 
				
			||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
 | 
					from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
 | 
				
			||||||
 | 
					 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
@ -15,31 +14,48 @@ _LOGGER = logging.getLogger(__name__)
 | 
				
			|||||||
class HonEntity(CoordinatorEntity):
 | 
					class HonEntity(CoordinatorEntity):
 | 
				
			||||||
    _attr_has_entity_name = True
 | 
					    _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)
 | 
					        super().__init__(coordinator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._hon = hass.data[DOMAIN][entry.unique_id]
 | 
					        self._hon = hass.data[DOMAIN][entry.unique_id]
 | 
				
			||||||
        self._hass = hass
 | 
					        self._hass = hass
 | 
				
			||||||
 | 
					        self._coordinator = coordinator
 | 
				
			||||||
        self._device = device
 | 
					        self._device = device
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._attr_unique_id = self._device.mac_address
 | 
					        self._attr_unique_id = self._device.unique_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def device_info(self):
 | 
					    def device_info(self):
 | 
				
			||||||
        return DeviceInfo(
 | 
					        return DeviceInfo(
 | 
				
			||||||
            identifiers={(DOMAIN, self._device.mac_address)},
 | 
					            identifiers={(DOMAIN, self._device.unique_id)},
 | 
				
			||||||
            manufacturer=self._device.get("brand", ""),
 | 
					            manufacturer=self._device.get("brand", ""),
 | 
				
			||||||
            name=self._device.nick_name if self._device.nick_name else self._device.model_name,
 | 
					            name=self._device.nick_name
 | 
				
			||||||
 | 
					            if self._device.nick_name
 | 
				
			||||||
 | 
					            else self._device.model_name,
 | 
				
			||||||
            model=self._device.model_name,
 | 
					            model=self._device.model_name,
 | 
				
			||||||
            sw_version=self._device.get("fwVersion", ""),
 | 
					            sw_version=self._device.get("fwVersion", ""),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonCoordinator(DataUpdateCoordinator):
 | 
					class HonCoordinator(DataUpdateCoordinator):
 | 
				
			||||||
    def __init__(self, hass, device: HonDevice):
 | 
					    def __init__(self, hass, device: HonAppliance):
 | 
				
			||||||
        """Initialize my coordinator."""
 | 
					        """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
 | 
					        self._device = device
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _async_update_data(self):
 | 
					    async def _async_update_data(self):
 | 
				
			||||||
        await self._device.update()
 | 
					        await self._device.update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def unique_entities(base_entities, new_entities):
 | 
				
			||||||
 | 
					    result = list(base_entities)
 | 
				
			||||||
 | 
					    existing_entities = [entity.key for entity in base_entities]
 | 
				
			||||||
 | 
					    for entity in new_entities:
 | 
				
			||||||
 | 
					        if entity.key not in existing_entities:
 | 
				
			||||||
 | 
					            result.append(entity)
 | 
				
			||||||
 | 
					    return tuple(result)
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,6 @@
 | 
				
			|||||||
  "documentation": "https://github.com/Andre0512/hon/",
 | 
					  "documentation": "https://github.com/Andre0512/hon/",
 | 
				
			||||||
  "iot_class": "cloud_polling",
 | 
					  "iot_class": "cloud_polling",
 | 
				
			||||||
  "issue_tracker": "https://github.com/Andre0512/hon/issues",
 | 
					  "issue_tracker": "https://github.com/Andre0512/hon/issues",
 | 
				
			||||||
  "requirements": ["pyhOn==0.3.6"],
 | 
					 "requirements": ["pyhOn==0.10.9"],
 | 
				
			||||||
  "version": "0.2.3"
 | 
					  "version": "0.8.0-beta.4"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,20 @@
 | 
				
			|||||||
from __future__ import annotations
 | 
					from __future__ import annotations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import HonConnection
 | 
					 | 
				
			||||||
from pyhon.parameter import HonParameterRange
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from homeassistant.components.number import (
 | 
					from homeassistant.components.number import (
 | 
				
			||||||
    NumberEntity,
 | 
					    NumberEntity,
 | 
				
			||||||
    NumberEntityDescription,
 | 
					    NumberEntityDescription,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from homeassistant.config_entries import ConfigEntry
 | 
					from homeassistant.config_entries import ConfigEntry
 | 
				
			||||||
from homeassistant.const import UnitOfTime
 | 
					from homeassistant.const import UnitOfTime, UnitOfTemperature
 | 
				
			||||||
from homeassistant.core import callback
 | 
					from homeassistant.core import callback
 | 
				
			||||||
from homeassistant.helpers.entity import EntityCategory
 | 
					from homeassistant.helpers.entity import EntityCategory
 | 
				
			||||||
 | 
					from pyhon import Hon
 | 
				
			||||||
 | 
					from pyhon.parameter.base import HonParameter
 | 
				
			||||||
 | 
					from pyhon.parameter.fixed import HonParameterFixed
 | 
				
			||||||
 | 
					from pyhon.parameter.range import HonParameterRange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonEntity, HonCoordinator
 | 
					from .hon import HonEntity, HonCoordinator, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
 | 
					NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
 | 
				
			||||||
    "WM": (
 | 
					    "WM": (
 | 
				
			||||||
@ -22,41 +23,174 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
 | 
				
			|||||||
            name="Delay Time",
 | 
					            name="Delay Time",
 | 
				
			||||||
            icon="mdi:timer-plus",
 | 
					            icon="mdi:timer-plus",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        NumberEntityDescription(
 | 
					        NumberEntityDescription(
 | 
				
			||||||
            key="startProgram.rinseIterations",
 | 
					            key="startProgram.rinseIterations",
 | 
				
			||||||
            name="Rinse Iterations",
 | 
					            name="Rinse Iterations",
 | 
				
			||||||
            icon="mdi:rotate-right",
 | 
					            icon="mdi:rotate-right",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="rinse_iterations",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        NumberEntityDescription(
 | 
					        NumberEntityDescription(
 | 
				
			||||||
            key="startProgram.mainWashTime",
 | 
					            key="startProgram.mainWashTime",
 | 
				
			||||||
            name="Main Wash Time",
 | 
					            name="Main Wash Time",
 | 
				
			||||||
            icon="mdi:clock-start",
 | 
					            icon="mdi:clock-start",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="wash_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        NumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.steamLevel",
 | 
				
			||||||
 | 
					            name="Steam Level",
 | 
				
			||||||
 | 
					            icon="mdi:weather-dust",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="steam_level",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        NumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.waterHard",
 | 
				
			||||||
 | 
					            name="Water hard",
 | 
				
			||||||
 | 
					            icon="mdi:water",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="water_hard",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        NumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.lang",
 | 
				
			||||||
 | 
					            name="lang",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "TD": (
 | 
				
			||||||
 | 
					        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.tempLevel",
 | 
				
			||||||
 | 
					            name="Temperature level",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            translation_key="tumbledryertemplevel",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        NumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.dryTime",
 | 
				
			||||||
 | 
					            name="Dry Time",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="dry_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "OV": (
 | 
				
			||||||
 | 
					        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.tempSel",
 | 
				
			||||||
 | 
					            name="Target Temperature",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            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,
 | 
				
			||||||
 | 
					            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="settings.tempSel",
 | 
				
			||||||
 | 
					            name="Target Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="target_temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        NumberEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.tempSelZ1",
 | 
				
			||||||
 | 
					            name="Fridge Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="fridge_temp_sel",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        NumberEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.tempSelZ2",
 | 
				
			||||||
 | 
					            name="Freezer Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="freezer_temp_sel",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NUMBERS["WD"] = unique_entities(NUMBERS["WM"], NUMBERS["TD"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
 | 
					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"]
 | 
					    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
				
			||||||
    appliances = []
 | 
					    appliances = []
 | 
				
			||||||
    for device in hon.devices:
 | 
					    for device in hon.appliances:
 | 
				
			||||||
        if device.mac_address in coordinators:
 | 
					        if device.unique_id in coordinators:
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
 | 
					            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            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()
 | 
					        await coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if descriptions := NUMBERS.get(device.appliance_type):
 | 
					        if descriptions := NUMBERS.get(device.appliance_type):
 | 
				
			||||||
            for description in descriptions:
 | 
					            for description in descriptions:
 | 
				
			||||||
                appliances.extend([
 | 
					                if description.key not in device.available_settings:
 | 
				
			||||||
                    HonNumberEntity(hass, coordinator, entry, device, description)]
 | 
					                    continue
 | 
				
			||||||
 | 
					                appliances.extend(
 | 
				
			||||||
 | 
					                    [HonNumberEntity(hass, coordinator, entry, device, description)]
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async_add_entities(appliances)
 | 
					    async_add_entities(appliances)
 | 
				
			||||||
@ -66,8 +200,6 @@ class HonNumberEntity(HonEntity, NumberEntity):
 | 
				
			|||||||
    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
					    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					        super().__init__(hass, entry, coordinator, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					 | 
				
			||||||
        self._device = device
 | 
					 | 
				
			||||||
        self._data = device.settings[description.key]
 | 
					        self._data = device.settings[description.key]
 | 
				
			||||||
        self.entity_description = description
 | 
					        self.entity_description = description
 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
				
			||||||
@ -82,8 +214,14 @@ class HonNumberEntity(HonEntity, NumberEntity):
 | 
				
			|||||||
        return self._device.get(self.entity_description.key)
 | 
					        return self._device.get(self.entity_description.key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def async_set_native_value(self, value: float) -> None:
 | 
					    async def async_set_native_value(self, value: float) -> None:
 | 
				
			||||||
        self._device.settings[self.entity_description.key].value = value
 | 
					        setting = self._device.settings[self.entity_description.key]
 | 
				
			||||||
        await self.coordinator.async_request_refresh()
 | 
					        if not (
 | 
				
			||||||
 | 
					            isinstance(setting, HonParameter) or isinstance(setting, HonParameterFixed)
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
 | 
					            setting.value = value
 | 
				
			||||||
 | 
					        if "settings." in self.entity_description.key:
 | 
				
			||||||
 | 
					            await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @callback
 | 
					    @callback
 | 
				
			||||||
    def _handle_coordinator_update(self):
 | 
					    def _handle_coordinator_update(self):
 | 
				
			||||||
@ -94,3 +232,16 @@ class HonNumberEntity(HonEntity, NumberEntity):
 | 
				
			|||||||
            self._attr_native_step = setting.step
 | 
					            self._attr_native_step = setting.step
 | 
				
			||||||
        self._attr_native_value = setting.value
 | 
					        self._attr_native_value = setting.value
 | 
				
			||||||
        self.async_write_ha_state()
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def available(self) -> bool:
 | 
				
			||||||
 | 
					        """Return True if entity is available."""
 | 
				
			||||||
 | 
					        if self.entity_category == EntityCategory.CONFIG:
 | 
				
			||||||
 | 
					            return super().available
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return (
 | 
				
			||||||
 | 
					                super().available
 | 
				
			||||||
 | 
					                and self._device.get("remoteCtrValid", "1") == "1"
 | 
				
			||||||
 | 
					                and self._device.get("attributes.lastConnEvent.category")
 | 
				
			||||||
 | 
					                != "DISCONNECTED"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
				
			|||||||
@ -1,17 +1,20 @@
 | 
				
			|||||||
from __future__ import annotations
 | 
					from __future__ import annotations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import HonConnection
 | 
					import logging
 | 
				
			||||||
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.components.select import SelectEntity, SelectEntityDescription
 | 
				
			||||||
from homeassistant.config_entries import ConfigEntry
 | 
					from homeassistant.config_entries import ConfigEntry
 | 
				
			||||||
from homeassistant.const import UnitOfTemperature, REVOLUTIONS_PER_MINUTE
 | 
					from homeassistant.const import UnitOfTemperature, UnitOfTime, REVOLUTIONS_PER_MINUTE
 | 
				
			||||||
from homeassistant.core import callback
 | 
					from homeassistant.core import callback
 | 
				
			||||||
from homeassistant.helpers.entity import EntityCategory
 | 
					from homeassistant.helpers.entity import EntityCategory
 | 
				
			||||||
 | 
					 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonEntity, HonCoordinator
 | 
					from .hon import HonEntity, HonCoordinator, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SELECTS = {
 | 
					SELECTS = {
 | 
				
			||||||
    "WM": (
 | 
					    "WM": (
 | 
				
			||||||
@ -20,78 +23,188 @@ SELECTS = {
 | 
				
			|||||||
            name="Spin speed",
 | 
					            name="Spin speed",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
            icon="mdi:numeric",
 | 
					            icon="mdi:numeric",
 | 
				
			||||||
            unit_of_measurement=REVOLUTIONS_PER_MINUTE
 | 
					            unit_of_measurement=REVOLUTIONS_PER_MINUTE,
 | 
				
			||||||
 | 
					            translation_key="spin_speed",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        SelectEntityDescription(
 | 
				
			||||||
            key="startProgram.temp",
 | 
					            key="startProgram.temp",
 | 
				
			||||||
            name="Temperature",
 | 
					            name="Temperature",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
            unit_of_measurement=UnitOfTemperature.CELSIUS
 | 
					            unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        SelectEntityDescription(
 | 
				
			||||||
            key="startProgram.program",
 | 
					            key="startProgram.program",
 | 
				
			||||||
            name="Program",
 | 
					            name="Program",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
            translation_key="programs"
 | 
					            translation_key="programs_wm",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "TD": (
 | 
				
			||||||
 | 
					        SelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.program",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="programs_td",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.dryTimeMM",
 | 
				
			||||||
 | 
					            name="Dry Time",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:timer",
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "OV": (
 | 
				
			||||||
 | 
					        SelectEntityDescription(
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.temp",
 | 
				
			||||||
 | 
					            name="Temperature",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.remainingTime",
 | 
				
			||||||
 | 
					            name="Remaining Time",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:timer",
 | 
				
			||||||
 | 
					            unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        SelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.program",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            translation_key="programs_ac",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SelectEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.humanSensingStatus",
 | 
				
			||||||
 | 
					            name="Eco Pilot",
 | 
				
			||||||
 | 
					            icon="mdi:run",
 | 
				
			||||||
 | 
					            translation_key="eco_pilot",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        SelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.program",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="programs_ref",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECTS["WD"] = unique_entities(SELECTS["WM"], SELECTS["TD"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
 | 
					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"]
 | 
					    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
				
			||||||
    appliances = []
 | 
					    appliances = []
 | 
				
			||||||
    for device in hon.devices:
 | 
					    for device in hon.appliances:
 | 
				
			||||||
        if device.mac_address in coordinators:
 | 
					        if device.unique_id in coordinators:
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
 | 
					            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            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()
 | 
					        await coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if descriptions := SELECTS.get(device.appliance_type):
 | 
					        if descriptions := SELECTS.get(device.appliance_type):
 | 
				
			||||||
            for description in descriptions:
 | 
					            for description in descriptions:
 | 
				
			||||||
                if not device.get(description.key):
 | 
					                if description.key not in device.available_settings:
 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
                appliances.extend([
 | 
					                appliances.extend(
 | 
				
			||||||
                    HonSelectEntity(hass, coordinator, entry, device, description)]
 | 
					                    [HonSelectEntity(hass, coordinator, entry, device, description)]
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
    async_add_entities(appliances)
 | 
					    async_add_entities(appliances)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonSelectEntity(HonEntity, SelectEntity):
 | 
					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)
 | 
					        super().__init__(hass, entry, coordinator, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					 | 
				
			||||||
        self._device = device
 | 
					 | 
				
			||||||
        self.entity_description = description
 | 
					        self.entity_description = description
 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not isinstance(self._device.settings[description.key], HonParameterFixed):
 | 
					        if not (setting := self._device.settings.get(description.key)):
 | 
				
			||||||
            self._attr_options: list[str] = device.settings[description.key].values
 | 
					            self._attr_options: list[str] = []
 | 
				
			||||||
 | 
					        elif not isinstance(setting, HonParameterFixed):
 | 
				
			||||||
 | 
					            self._attr_options: list[str] = setting.values
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self._attr_options: list[str] = [device.settings[description.key].value]
 | 
					            self._attr_options: list[str] = [setting.value]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def current_option(self) -> str | None:
 | 
					    def current_option(self) -> str | None:
 | 
				
			||||||
        value = self._device.settings[self.entity_description.key].value
 | 
					        value = self._device.settings.get(self.entity_description.key)
 | 
				
			||||||
        if value is None or value not in self._attr_options:
 | 
					        if value is None or value.value not in self._attr_options:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
        return value
 | 
					        return value.value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def async_select_option(self, option: str) -> None:
 | 
					    async def async_select_option(self, option: str) -> None:
 | 
				
			||||||
        self._device.settings[self.entity_description.key].value = option
 | 
					        self._device.settings[self.entity_description.key].value = option
 | 
				
			||||||
        await self.coordinator.async_request_refresh()
 | 
					        if "settings." in self.entity_description.key:
 | 
				
			||||||
 | 
					            await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					        elif self._device.appliance_type in ["AC"]:
 | 
				
			||||||
 | 
					            await self._device.commands["startProgram"].send()
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @callback
 | 
					    @callback
 | 
				
			||||||
    def _handle_coordinator_update(self):
 | 
					    def _handle_coordinator_update(self):
 | 
				
			||||||
        setting = self._device.settings[self.entity_description.key]
 | 
					        setting = self._device.settings.get(self.entity_description.key)
 | 
				
			||||||
        if not isinstance(self._device.settings[self.entity_description.key], HonParameterFixed):
 | 
					        if setting is None:
 | 
				
			||||||
            self._attr_options: list[str] = setting.values
 | 
					            self._attr_available = False
 | 
				
			||||||
 | 
					            self._attr_options: list[str] = []
 | 
				
			||||||
 | 
					            self._attr_native_value = None
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self._attr_options = [setting.value]
 | 
					            self._attr_available = True
 | 
				
			||||||
 | 
					            self._attr_options: list[str] = setting.values
 | 
				
			||||||
            self._attr_native_value = setting.value
 | 
					            self._attr_native_value = setting.value
 | 
				
			||||||
        self.async_write_ha_state()
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def available(self) -> bool:
 | 
				
			||||||
 | 
					        """Return True if entity is available."""
 | 
				
			||||||
 | 
					        if self.entity_category == EntityCategory.CONFIG:
 | 
				
			||||||
 | 
					            return super().available
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return (
 | 
				
			||||||
 | 
					                super().available
 | 
				
			||||||
 | 
					                and self._device.get("remoteCtrValid", "1") == "1"
 | 
				
			||||||
 | 
					                and self._device.get("attributes.lastConnEvent.category")
 | 
				
			||||||
 | 
					                != "DISCONNECTED"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import HonConnection
 | 
					from pyhon import Hon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from homeassistant.components.sensor import (
 | 
					from homeassistant.components.sensor import (
 | 
				
			||||||
    SensorEntity,
 | 
					    SensorEntity,
 | 
				
			||||||
@ -9,37 +9,58 @@ from homeassistant.components.sensor import (
 | 
				
			|||||||
    SensorEntityDescription,
 | 
					    SensorEntityDescription,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from homeassistant.config_entries import ConfigEntry
 | 
					from homeassistant.config_entries import ConfigEntry
 | 
				
			||||||
from homeassistant.const import UnitOfEnergy, UnitOfVolume, UnitOfMass, UnitOfPower, UnitOfTime
 | 
					from homeassistant.const import PERCENTAGE
 | 
				
			||||||
 | 
					from homeassistant.const import (
 | 
				
			||||||
 | 
					    REVOLUTIONS_PER_MINUTE,
 | 
				
			||||||
 | 
					    UnitOfEnergy,
 | 
				
			||||||
 | 
					    UnitOfVolume,
 | 
				
			||||||
 | 
					    UnitOfMass,
 | 
				
			||||||
 | 
					    UnitOfPower,
 | 
				
			||||||
 | 
					    UnitOfTime,
 | 
				
			||||||
 | 
					    UnitOfTemperature,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from homeassistant.core import callback
 | 
					from homeassistant.core import callback
 | 
				
			||||||
from homeassistant.helpers.entity import EntityCategory
 | 
					from homeassistant.helpers.entity import EntityCategory
 | 
				
			||||||
from homeassistant.helpers.typing import StateType
 | 
					from homeassistant.helpers.typing import StateType
 | 
				
			||||||
 | 
					from . import const
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonCoordinator, HonEntity
 | 
					from .hon import HonCoordinator, HonEntity, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
 | 
					SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
 | 
				
			||||||
    "WM": (
 | 
					    "WM": (
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="prPhase",
 | 
				
			||||||
 | 
					            name="Program Phase",
 | 
				
			||||||
 | 
					            icon="mdi:washing-machine",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="program_phases_wm",
 | 
				
			||||||
 | 
					            options=list(const.WASHING_PR_PHASE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="totalElectricityUsed",
 | 
					            key="totalElectricityUsed",
 | 
				
			||||||
            name="Total Power",
 | 
					            name="Total Power",
 | 
				
			||||||
            device_class=SensorDeviceClass.ENERGY,
 | 
					            device_class=SensorDeviceClass.ENERGY,
 | 
				
			||||||
            state_class=SensorStateClass.TOTAL_INCREASING,
 | 
					            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(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="totalWaterUsed",
 | 
					            key="totalWaterUsed",
 | 
				
			||||||
            name="Total Water",
 | 
					            name="Total Water",
 | 
				
			||||||
            device_class=SensorDeviceClass.WATER,
 | 
					            device_class=SensorDeviceClass.WATER,
 | 
				
			||||||
            state_class=SensorStateClass.TOTAL_INCREASING,
 | 
					            state_class=SensorStateClass.TOTAL_INCREASING,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfVolume.LITERS
 | 
					            native_unit_of_measurement=UnitOfVolume.LITERS,
 | 
				
			||||||
 | 
					            translation_key="water_total",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="totalWashCycle",
 | 
					            key="totalWashCycle",
 | 
				
			||||||
            name="Total Wash Cycle",
 | 
					            name="Total Wash Cycle",
 | 
				
			||||||
            state_class=SensorStateClass.TOTAL_INCREASING,
 | 
					            state_class=SensorStateClass.TOTAL_INCREASING,
 | 
				
			||||||
            icon="mdi:counter"
 | 
					            icon="mdi:counter",
 | 
				
			||||||
 | 
					            translation_key="cycles_total",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="currentElectricityUsed",
 | 
					            key="currentElectricityUsed",
 | 
				
			||||||
@ -47,13 +68,15 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
 | 
				
			|||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            device_class=SensorDeviceClass.POWER,
 | 
					            device_class=SensorDeviceClass.POWER,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfPower.KILO_WATT,
 | 
					            native_unit_of_measurement=UnitOfPower.KILO_WATT,
 | 
				
			||||||
            icon="mdi:lightning-bolt"
 | 
					            icon="mdi:lightning-bolt",
 | 
				
			||||||
 | 
					            translation_key="energy_current",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="currentWaterUsed",
 | 
					            key="currentWaterUsed",
 | 
				
			||||||
            name="Current Water Used",
 | 
					            name="Current Water Used",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            icon="mdi:water"
 | 
					            icon="mdi:water",
 | 
				
			||||||
 | 
					            translation_key="water_current",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="startProgram.weight",
 | 
					            key="startProgram.weight",
 | 
				
			||||||
@ -61,19 +84,19 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
 | 
				
			|||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfMass.KILOGRAMS,
 | 
					            native_unit_of_measurement=UnitOfMass.KILOGRAMS,
 | 
				
			||||||
            icon="mdi:weight-kilogram"
 | 
					            icon="mdi:weight-kilogram",
 | 
				
			||||||
 | 
					            translation_key="suggested_load",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="machMode",
 | 
					            key="machMode",
 | 
				
			||||||
            name="Machine Status",
 | 
					            name="Machine Status",
 | 
				
			||||||
            icon="mdi:information",
 | 
					            icon="mdi:information",
 | 
				
			||||||
            translation_key="mode"
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="washing_modes",
 | 
				
			||||||
 | 
					            options=list(const.MACH_MODE),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="errors",
 | 
					            key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
 | 
				
			||||||
            name="Error",
 | 
					 | 
				
			||||||
            icon="mdi:math-log",
 | 
					 | 
				
			||||||
            translation_key="errors"
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="remainingTimeMM",
 | 
					            key="remainingTimeMM",
 | 
				
			||||||
@ -81,36 +104,429 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
 | 
				
			|||||||
            icon="mdi:timer",
 | 
					            icon="mdi:timer",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        SensorEntityDescription(
 | 
				
			||||||
            key="spinSpeed",
 | 
					            key="spinSpeed",
 | 
				
			||||||
            name="Spin Speed",
 | 
					            name="Spin Speed",
 | 
				
			||||||
 | 
					            icon="mdi:speedometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
 | 
				
			||||||
 | 
					            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",
 | 
					            icon="mdi:timer",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="dirtyLevel",
 | 
				
			||||||
 | 
					            name="Dirt level",
 | 
				
			||||||
 | 
					            icon="mdi:liquid-spot",
 | 
				
			||||||
 | 
					            translation_key="dirt_level",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.suggestedLoadW",
 | 
				
			||||||
 | 
					            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="temp",
 | 
				
			||||||
 | 
					            name="Current Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "TD": (
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="machMode",
 | 
				
			||||||
 | 
					            name="Machine Status",
 | 
				
			||||||
 | 
					            icon="mdi:information",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="washing_modes",
 | 
				
			||||||
 | 
					            options=list(const.MACH_MODE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        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="delayTime",
 | 
				
			||||||
 | 
					            name="Start Time",
 | 
				
			||||||
 | 
					            icon="mdi:clock-start",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="programName",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            icon="mdi:tumble-dryer",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="programs_td",
 | 
				
			||||||
 | 
					            options=const.PROGRAMS_TD,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="prPhase",
 | 
				
			||||||
 | 
					            name="Program Phase",
 | 
				
			||||||
 | 
					            icon="mdi:washing-machine",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="program_phases_td",
 | 
				
			||||||
 | 
					            options=list(const.TUMBLE_DRYER_PR_PHASE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="dryLevel",
 | 
				
			||||||
 | 
					            name="Dry level",
 | 
				
			||||||
 | 
					            icon="mdi:hair-dryer",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="dry_levels",
 | 
				
			||||||
 | 
					            options=list(const.TUMBLE_DRYER_DRY_LEVEL),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempLevel",
 | 
				
			||||||
 | 
					            name="Temperature level",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.steamLevel",
 | 
				
			||||||
 | 
					            name="Steam level",
 | 
				
			||||||
 | 
					            icon="mdi:smoke",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="steam_level",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="steamLevel",
 | 
				
			||||||
 | 
					            name="Steam level",
 | 
				
			||||||
 | 
					            icon="mdi:smoke",
 | 
				
			||||||
 | 
					            translation_key="steam_level",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="steamType",
 | 
				
			||||||
 | 
					            name="Steam Type",
 | 
				
			||||||
 | 
					            icon="mdi:weather-dust",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "OV": (
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="remainingTimeMM",
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="washing_modes",
 | 
				
			||||||
 | 
					            options=list(const.MACH_MODE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        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",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="program_phases_dw",
 | 
				
			||||||
 | 
					            options=list(const.DISHWASHER_PR_PHASE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempAirOutdoor",
 | 
				
			||||||
 | 
					            name="Air Temperature Outdoor",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempCoilerIndoor",
 | 
				
			||||||
 | 
					            name="Coiler Temperature Indoor",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempCoilerOutdoor",
 | 
				
			||||||
 | 
					            name="Coiler Temperature Outside",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempDefrostOutdoor",
 | 
				
			||||||
 | 
					            name="Defrost Temperature Outdoor",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempInAirOutdoor",
 | 
				
			||||||
 | 
					            name="In Air Temperature Outdoor",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempIndoor",
 | 
				
			||||||
 | 
					            name="Indoor Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempOutdoor",
 | 
				
			||||||
 | 
					            name="Outdoor Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempSel",
 | 
				
			||||||
 | 
					            name="Selected Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="humidityEnv",
 | 
				
			||||||
 | 
					            name="Room Humidity",
 | 
				
			||||||
 | 
					            icon="mdi:water-percent",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.HUMIDITY,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=PERCENTAGE,
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            translation_key="humidity",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempEnv",
 | 
				
			||||||
 | 
					            name="Room Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:home-thermometer-outline",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="room_temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempZ1",
 | 
				
			||||||
 | 
					            name="Temperature Fridge",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="fridge_temp",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        SensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempZ2",
 | 
				
			||||||
 | 
					            name="Temperature Freezer",
 | 
				
			||||||
 | 
					            icon="mdi:snowflake-thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="freezer_temp",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					SENSORS["WD"] = unique_entities(SENSORS["WM"], SENSORS["TD"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
 | 
					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"]
 | 
					    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
				
			||||||
    appliances = []
 | 
					    appliances = []
 | 
				
			||||||
    for device in hon.devices:
 | 
					    for device in hon.appliances:
 | 
				
			||||||
        if device.mac_address in coordinators:
 | 
					        if device.unique_id in coordinators:
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
 | 
					            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            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()
 | 
					        await coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if descriptions := SENSORS.get(device.appliance_type):
 | 
					        if descriptions := SENSORS.get(device.appliance_type):
 | 
				
			||||||
            for description in descriptions:
 | 
					            for description in descriptions:
 | 
				
			||||||
                if not device.get(description.key):
 | 
					                if not device.get(description.key) and not device.settings.get(
 | 
				
			||||||
 | 
					                    description.key
 | 
				
			||||||
 | 
					                ):
 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
                appliances.extend([
 | 
					                appliances.extend(
 | 
				
			||||||
                    HonSensorEntity(hass, coordinator, entry, device, description)]
 | 
					                    [HonSensorEntity(hass, coordinator, entry, device, description)]
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async_add_entities(appliances)
 | 
					    async_add_entities(appliances)
 | 
				
			||||||
@ -120,16 +536,20 @@ class HonSensorEntity(HonEntity, SensorEntity):
 | 
				
			|||||||
    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
					    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					        super().__init__(hass, entry, coordinator, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.entity_description = description
 | 
					        self.entity_description = description
 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def native_value(self) -> StateType:
 | 
					    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
 | 
					    @callback
 | 
				
			||||||
    def _handle_coordinator_update(self):
 | 
					    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()
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,25 +1,31 @@
 | 
				
			|||||||
 | 
					import logging
 | 
				
			||||||
from dataclasses import dataclass
 | 
					from dataclasses import dataclass
 | 
				
			||||||
from typing import Any
 | 
					from typing import Any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from pyhon import Hon
 | 
				
			||||||
 | 
					from pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					from pyhon.parameter.range import HonParameterRange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from homeassistant.components.switch import SwitchEntityDescription, SwitchEntity
 | 
					from homeassistant.components.switch import SwitchEntityDescription, SwitchEntity
 | 
				
			||||||
from homeassistant.config_entries import ConfigEntry
 | 
					from homeassistant.config_entries import ConfigEntry
 | 
				
			||||||
from homeassistant.const import EntityCategory
 | 
					from homeassistant.const import EntityCategory
 | 
				
			||||||
from pyhon import HonConnection
 | 
					from homeassistant.core import callback
 | 
				
			||||||
from pyhon.device import HonDevice
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonCoordinator, HonEntity
 | 
					from .hon import HonCoordinator, HonEntity, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@dataclass
 | 
					@dataclass
 | 
				
			||||||
class HonSwitchEntityDescriptionMixin:
 | 
					class HonSwitchEntityDescriptionMixin:
 | 
				
			||||||
    turn_on_key: str = ""
 | 
					    turn_on_key: str = ""
 | 
				
			||||||
    turn_off_key: str = ""
 | 
					    turn_off_key: str = ""
 | 
				
			||||||
 | 
					    status_key: str = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@dataclass
 | 
					@dataclass
 | 
				
			||||||
class HonSwitchEntityDescription(HonSwitchEntityDescriptionMixin,
 | 
					class HonSwitchEntityDescription(
 | 
				
			||||||
    SwitchEntityDescription
 | 
					    HonSwitchEntityDescriptionMixin, SwitchEntityDescription
 | 
				
			||||||
):
 | 
					):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,6 +38,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
 | 
				
			|||||||
            icon="mdi:washing-machine",
 | 
					            icon="mdi:washing-machine",
 | 
				
			||||||
            turn_on_key="startProgram",
 | 
					            turn_on_key="startProgram",
 | 
				
			||||||
            turn_off_key="stopProgram",
 | 
					            turn_off_key="stopProgram",
 | 
				
			||||||
 | 
					            translation_key="washing_machine",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
            key="pause",
 | 
					            key="pause",
 | 
				
			||||||
@ -39,40 +46,330 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
 | 
				
			|||||||
            icon="mdi:pause",
 | 
					            icon="mdi:pause",
 | 
				
			||||||
            turn_on_key="pauseProgram",
 | 
					            turn_on_key="pauseProgram",
 | 
				
			||||||
            turn_off_key="resumeProgram",
 | 
					            turn_off_key="resumeProgram",
 | 
				
			||||||
 | 
					            translation_key="pause",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.delayStatus",
 | 
					            key="startProgram.delayStatus",
 | 
				
			||||||
            name="Delay Status",
 | 
					            name="Delay Status",
 | 
				
			||||||
            icon="mdi:timer-check",
 | 
					            icon="mdi:timer-check",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.haier_SoakPrewashSelection",
 | 
					            key="startProgram.haier_SoakPrewashSelection",
 | 
				
			||||||
            name="Soak Prewash Selection",
 | 
					            name="Soak Prewash Selection",
 | 
				
			||||||
            icon="mdi:tshirt-crew",
 | 
					            icon="mdi:tshirt-crew",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="prewash",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.permanentPressStatus",
 | 
				
			||||||
 | 
					            name="Keep Fresh",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:refresh-circle",
 | 
				
			||||||
 | 
					            translation_key="keep_fresh",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.autoSoftenerStatus",
 | 
				
			||||||
 | 
					            name="Auto Dose Softener",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:teddy-bear",
 | 
				
			||||||
 | 
					            translation_key="auto_dose_softener",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.autoDetergentStatus",
 | 
				
			||||||
 | 
					            name="Auto Dose Detergent",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:cup",
 | 
				
			||||||
 | 
					            translation_key="auto_dose_detergent",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.acquaplus",
 | 
				
			||||||
 | 
					            name="Acqua Plus",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:water-plus",
 | 
				
			||||||
 | 
					            translation_key="acqua_plus",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.extraRinse1",
 | 
				
			||||||
 | 
					            name="Extra Rinse 1",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:numeric-1-box-multiple-outline",
 | 
				
			||||||
 | 
					            translation_key="extra_rinse_1",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.extraRinse2",
 | 
				
			||||||
 | 
					            name="Extra Rinse 2",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:numeric-2-box-multiple-outline",
 | 
				
			||||||
 | 
					            translation_key="extra_rinse_2",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.extraRinse3",
 | 
				
			||||||
 | 
					            name="Extra Rinse 3",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            icon="mdi:numeric-3-box-multiple-outline",
 | 
				
			||||||
 | 
					            translation_key="extra_rinse_3",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.goodNight",
 | 
				
			||||||
 | 
					            name="Good Night",
 | 
				
			||||||
 | 
					            icon="mdi:weather-night",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					            translation_key="good_night",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "TD": (
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="active",
 | 
				
			||||||
 | 
					            name="Tumble Dryer",
 | 
				
			||||||
 | 
					            icon="mdi:tumble-dryer",
 | 
				
			||||||
 | 
					            turn_on_key="startProgram",
 | 
				
			||||||
 | 
					            turn_off_key="stopProgram",
 | 
				
			||||||
 | 
					            translation_key="tumble_dryer",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="pause",
 | 
				
			||||||
 | 
					            name="Pause Tumble Dryer",
 | 
				
			||||||
 | 
					            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": (
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="active",
 | 
				
			||||||
 | 
					            name="Washer Dryer",
 | 
				
			||||||
 | 
					            icon="mdi:washing-machine",
 | 
				
			||||||
 | 
					            turn_on_key="startProgram",
 | 
				
			||||||
 | 
					            turn_off_key="stopProgram",
 | 
				
			||||||
 | 
					            translation_key="washer_dryer",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="pause",
 | 
				
			||||||
 | 
					            name="Pause Washer Dryer",
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.buzzerDisabled",
 | 
				
			||||||
 | 
					            name="Buzzer Disabled",
 | 
				
			||||||
 | 
					            icon="mdi:volume-off",
 | 
				
			||||||
 | 
					            translation_key="buzzer",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.10degreeHeatingStatus",
 | 
				
			||||||
 | 
					            status_key="10degreeHeatingStatus",
 | 
				
			||||||
 | 
					            name="10° Heating",
 | 
				
			||||||
 | 
					            icon="mdi:heat-wave",
 | 
				
			||||||
 | 
					            translation_key="10_degree_heating",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.echoStatus",
 | 
				
			||||||
 | 
					            status_key="echoStatus",
 | 
				
			||||||
 | 
					            name="Echo",
 | 
				
			||||||
 | 
					            icon="mdi:account-voice",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.ecoMode",
 | 
				
			||||||
 | 
					            name="Eco Mode",
 | 
				
			||||||
 | 
					            translation_key="eco_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.healthMode",
 | 
				
			||||||
 | 
					            status_key="healthMode",
 | 
				
			||||||
 | 
					            name="Health Mode",
 | 
				
			||||||
 | 
					            icon="mdi:medication-outline",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.muteStatus",
 | 
				
			||||||
 | 
					            status_key="muteStatus",
 | 
				
			||||||
 | 
					            name="Mute",
 | 
				
			||||||
 | 
					            icon="mdi:volume-off",
 | 
				
			||||||
 | 
					            translation_key="mute_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.rapidMode",
 | 
				
			||||||
 | 
					            status_key="rapidMode",
 | 
				
			||||||
 | 
					            name="Rapid Mode",
 | 
				
			||||||
 | 
					            icon="mdi:run-fast",
 | 
				
			||||||
 | 
					            translation_key="rapid_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.screenDisplayStatus",
 | 
				
			||||||
 | 
					            status_key="screenDisplayStatus",
 | 
				
			||||||
 | 
					            name="Screen Display",
 | 
				
			||||||
 | 
					            icon="mdi:monitor-small",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.selfCleaning56Status",
 | 
				
			||||||
 | 
					            name="Self Cleaning 56",
 | 
				
			||||||
 | 
					            icon="mdi:air-filter",
 | 
				
			||||||
 | 
					            translation_key="self_clean_56",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.selfCleaningStatus",
 | 
				
			||||||
 | 
					            status_key="selfCleaningStatus",
 | 
				
			||||||
 | 
					            name="Self Cleaning",
 | 
				
			||||||
 | 
					            icon="mdi:air-filter",
 | 
				
			||||||
 | 
					            translation_key="self_clean",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.silentSleepStatus",
 | 
				
			||||||
 | 
					            status_key="silentSleepStatus",
 | 
				
			||||||
 | 
					            name="Silent Sleep",
 | 
				
			||||||
 | 
					            icon="mdi:bed",
 | 
				
			||||||
 | 
					            translation_key="silent_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.intelligenceMode",
 | 
				
			||||||
 | 
					            name="Auto-Set Mode",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer-auto",
 | 
				
			||||||
 | 
					            translation_key="auto_set",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.quickModeZ1",
 | 
				
			||||||
 | 
					            name="Super Freeze",
 | 
				
			||||||
 | 
					            icon="mdi:snowflake-variant",
 | 
				
			||||||
 | 
					            translation_key="super_freeze",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.quickModeZ2",
 | 
				
			||||||
 | 
					            name="Super Cool",
 | 
				
			||||||
 | 
					            icon="mdi:snowflake",
 | 
				
			||||||
 | 
					            translation_key="super_cool",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SWITCHES["WD"] = unique_entities(SWITCHES["WD"], SWITCHES["WM"])
 | 
				
			||||||
 | 
					SWITCHES["WD"] = unique_entities(SWITCHES["WD"], SWITCHES["TD"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
 | 
					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"]
 | 
					    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
				
			||||||
    appliances = []
 | 
					    appliances = []
 | 
				
			||||||
    for device in hon.devices:
 | 
					    for device in hon.appliances:
 | 
				
			||||||
        if device.mac_address in coordinators:
 | 
					        if device.unique_id in coordinators:
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.mac_address]
 | 
					            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            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()
 | 
					        await coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if descriptions := SWITCHES.get(device.appliance_type):
 | 
					        if descriptions := SWITCHES.get(device.appliance_type):
 | 
				
			||||||
            for description in descriptions:
 | 
					            for description in descriptions:
 | 
				
			||||||
                if device.get(description.key) is not None or device.commands.get(description.key) is not None:
 | 
					                if description.entity_category == EntityCategory.CONFIG:
 | 
				
			||||||
                    appliances.extend([
 | 
					                    if description.key not in device.available_settings:
 | 
				
			||||||
                        HonSwitchEntity(hass, coordinator, entry, device, description)]
 | 
					                        continue
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    if not any(
 | 
				
			||||||
 | 
					                        [
 | 
				
			||||||
 | 
					                            device.get(description.key) is not None,
 | 
				
			||||||
 | 
					                            description.turn_on_key in list(device.commands),
 | 
				
			||||||
 | 
					                            description.turn_off_key in list(device.commands),
 | 
				
			||||||
 | 
					                        ]
 | 
				
			||||||
 | 
					                    ):
 | 
				
			||||||
 | 
					                        continue
 | 
				
			||||||
 | 
					                appliances.extend(
 | 
				
			||||||
 | 
					                    [HonSwitchEntity(hass, coordinator, entry, device, description)]
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async_add_entities(appliances)
 | 
					    async_add_entities(appliances)
 | 
				
			||||||
@ -81,40 +378,82 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
 | 
				
			|||||||
class HonSwitchEntity(HonEntity, SwitchEntity):
 | 
					class HonSwitchEntity(HonEntity, SwitchEntity):
 | 
				
			||||||
    entity_description: HonSwitchEntityDescription
 | 
					    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)
 | 
					        super().__init__(hass, entry, coordinator, device)
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					
 | 
				
			||||||
        self._device = device
 | 
					 | 
				
			||||||
        self.entity_description = description
 | 
					        self.entity_description = description
 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def available(self) -> bool:
 | 
					 | 
				
			||||||
        if self.entity_category == EntityCategory.CONFIG:
 | 
					 | 
				
			||||||
            return self._device.settings[self.entity_description.key].typology != "fixed"
 | 
					 | 
				
			||||||
        return True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_on(self) -> bool | None:
 | 
					    def is_on(self) -> bool | None:
 | 
				
			||||||
        """Return True if entity is on."""
 | 
					        """Return True if entity is on."""
 | 
				
			||||||
        if self.entity_category == EntityCategory.CONFIG:
 | 
					        if self.entity_category == EntityCategory.CONFIG:
 | 
				
			||||||
            setting = self._device.settings[self.entity_description.key]
 | 
					            setting = self._device.settings[self.entity_description.key]
 | 
				
			||||||
            return setting.value == "1" or hasattr(setting, "min") and setting.value != setting.min
 | 
					            return (
 | 
				
			||||||
 | 
					                setting.value == "1"
 | 
				
			||||||
 | 
					                or hasattr(setting, "min")
 | 
				
			||||||
 | 
					                and setting.value != setting.min
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        elif self.entity_description.status_key:
 | 
				
			||||||
 | 
					            return self._device.get(self.entity_description.status_key, "0") == "1"
 | 
				
			||||||
        return self._device.get(self.entity_description.key, False)
 | 
					        return self._device.get(self.entity_description.key, False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def async_turn_on(self, **kwargs: Any) -> None:
 | 
					    async def async_turn_on(self, **kwargs: Any) -> None:
 | 
				
			||||||
        if self.entity_category == EntityCategory.CONFIG:
 | 
					        if (
 | 
				
			||||||
 | 
					            self.entity_category == EntityCategory.CONFIG
 | 
				
			||||||
 | 
					            or "settings." in self.entity_description.key
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
            setting = self._device.settings[self.entity_description.key]
 | 
					            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()
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
					            if "settings." in self.entity_description.key:
 | 
				
			||||||
 | 
					                await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					            await self.coordinator.async_refresh()
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            await self._device.commands[self.entity_description.turn_on_key].send()
 | 
					            await self._device.commands[self.entity_description.turn_on_key].send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def async_turn_off(self, **kwargs: Any) -> None:
 | 
					    async def async_turn_off(self, **kwargs: Any) -> None:
 | 
				
			||||||
        if self.entity_category == EntityCategory.CONFIG:
 | 
					        if (
 | 
				
			||||||
 | 
					            self.entity_category == EntityCategory.CONFIG
 | 
				
			||||||
 | 
					            or "settings." in self.entity_description.key
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
            setting = self._device.settings[self.entity_description.key]
 | 
					            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()
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
					            if "settings." in self.entity_description.key:
 | 
				
			||||||
 | 
					                await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					            await self.coordinator.async_refresh()
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            await self._device.commands[self.entity_description.turn_off_key].send()
 | 
					            await self._device.commands[self.entity_description.turn_off_key].send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def available(self) -> bool:
 | 
				
			||||||
 | 
					        """Return True if entity is available."""
 | 
				
			||||||
 | 
					        if self.entity_category == EntityCategory.CONFIG:
 | 
				
			||||||
 | 
					            return super().available
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return (
 | 
				
			||||||
 | 
					                super().available
 | 
				
			||||||
 | 
					                and self._device.get("remoteCtrValid", "1") == "1"
 | 
				
			||||||
 | 
					                and self._device.get("attributes.lastConnEvent.category")
 | 
				
			||||||
 | 
					                != "DISCONNECTED"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @callback
 | 
				
			||||||
 | 
					    def _handle_coordinator_update(self):
 | 
				
			||||||
 | 
					        if not self.entity_description.status_key:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        value = self._device.get(self.entity_description.status_key, "0")
 | 
				
			||||||
 | 
					        self._attr_state = value == "1"
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										88
									
								
								custom_components/hon/translations/bg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								custom_components/hon/translations/bg.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "config": {
 | 
				
			||||||
 | 
					    "step": {
 | 
				
			||||||
 | 
					      "user": {
 | 
				
			||||||
 | 
					        "description": "Моля, въведете вашите данни за достъп до hOn",
 | 
				
			||||||
 | 
					        "data": {
 | 
				
			||||||
 | 
					          "email": "Email Адрес",
 | 
				
			||||||
 | 
					          "password": "Парола"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "entity": {
 | 
				
			||||||
 | 
					    "sensor": {
 | 
				
			||||||
 | 
					      "mode": {
 | 
				
			||||||
 | 
					        "state": {
 | 
				
			||||||
 | 
					          "0": "Изключен",
 | 
				
			||||||
 | 
					          "1": "Готов",
 | 
				
			||||||
 | 
					          "2": "Работи",
 | 
				
			||||||
 | 
					          "3": "На пауза",
 | 
				
			||||||
 | 
					          "5": "Scheduled",
 | 
				
			||||||
 | 
					          "6": "Грешка",
 | 
				
			||||||
 | 
					          "7": "Завършен"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "errors": {
 | 
				
			||||||
 | 
					        "state": {
 | 
				
			||||||
 | 
					          "00": "Няма грешки",
 | 
				
			||||||
 | 
					          "100000000000": "E2: Провери дали вратата е затворена",
 | 
				
			||||||
 | 
					          "8000000000000": "E4: Провери подаването на вода"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "programs": {
 | 
				
			||||||
 | 
					        "state": {
 | 
				
			||||||
 | 
					          "0": "Стандартна",
 | 
				
			||||||
 | 
					          "62": "Памук",
 | 
				
			||||||
 | 
					          "63": "Синтетика",
 | 
				
			||||||
 | 
					          "64": "Смесен тип",
 | 
				
			||||||
 | 
					          "66": "Чаршафи",
 | 
				
			||||||
 | 
					          "71": "Пердета",
 | 
				
			||||||
 | 
					          "72": "Спорт",
 | 
				
			||||||
 | 
					          "74": "i-time",
 | 
				
			||||||
 | 
					          "75": "Олекотени завивки",
 | 
				
			||||||
 | 
					          "76": "Вълна",
 | 
				
			||||||
 | 
					          "78": "i-Refresh",
 | 
				
			||||||
 | 
					          "83": "Хавлиена кърпа",
 | 
				
			||||||
 | 
					          "85": "Бързо Сушене",
 | 
				
			||||||
 | 
					          "92": "Деликатно пране",
 | 
				
			||||||
 | 
					          "103": "Отдалечен"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "program_phases_td": {
 | 
				
			||||||
 | 
					        "state": {
 | 
				
			||||||
 | 
					          "0": "Изчаване",
 | 
				
			||||||
 | 
					          "2": "Сушене",
 | 
				
			||||||
 | 
					          "3": "Охлажане",
 | 
				
			||||||
 | 
					          "11": "11"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "tumbledryertemplevel": {
 | 
				
			||||||
 | 
					        "state": {
 | 
				
			||||||
 | 
					          "1": "Хладен въздух",
 | 
				
			||||||
 | 
					          "2": "Ниска температура L-1",
 | 
				
			||||||
 | 
					          "3": "Средна температура L-2",
 | 
				
			||||||
 | 
					          "4": "Висока температура L-3"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "dry_levels": {
 | 
				
			||||||
 | 
					        "state": {
 | 
				
			||||||
 | 
					          "3": "Готови за съхранение",
 | 
				
			||||||
 | 
					          "12": "Готови за гладене H-1",
 | 
				
			||||||
 | 
					          "13": "Готови за съхранение H-2",
 | 
				
			||||||
 | 
					          "14": "Екстра сухо H-3"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "select": {
 | 
				
			||||||
 | 
					      "dry_levels": {
 | 
				
			||||||
 | 
					        "state": {
 | 
				
			||||||
 | 
					          "3": "Готови за съхранение",
 | 
				
			||||||
 | 
					          "12": "Готови за гладене H-1",
 | 
				
			||||||
 | 
					          "13": "Готови за съхранение H-2",
 | 
				
			||||||
 | 
					          "14": "Екстра сухо H-3"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1323
									
								
								custom_components/hon/translations/cs.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/cs.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/de.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/de.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/el.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/el.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/es.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/es.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/fr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/fr.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										776
									
								
								custom_components/hon/translations/he.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										776
									
								
								custom_components/hon/translations/he.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,776 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "entity": {
 | 
				
			||||||
 | 
					        "sensor": {
 | 
				
			||||||
 | 
					            "washing_modes": {
 | 
				
			||||||
 | 
					                "state": {
 | 
				
			||||||
 | 
					                    "0": "מוּכָן",
 | 
				
			||||||
 | 
					                    "1": "מוּכָן",
 | 
				
			||||||
 | 
					                    "3": "הַפסָקָה",
 | 
				
			||||||
 | 
					                    "4": "מתוזמן",
 | 
				
			||||||
 | 
					                    "5": "מתוזמן",
 | 
				
			||||||
 | 
					                    "6": "שְׁגִיאָה",
 | 
				
			||||||
 | 
					                    "7": "מוּכָן",
 | 
				
			||||||
 | 
					                    "2": "התוכנית פועלת",
 | 
				
			||||||
 | 
					                    "8": "Test",
 | 
				
			||||||
 | 
					                    "9": "Stopping cycle…"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "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": "יִבּוּשׁ",
 | 
				
			||||||
 | 
					                    "11": "מוּכָן",
 | 
				
			||||||
 | 
					                    "17": "unknown"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "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": "יבש במיוחד",
 | 
				
			||||||
 | 
					                    "11": "ללא ייבוש"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "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"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "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": "סינתטי יבש"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "room_temperature": {
 | 
				
			||||||
 | 
					                "name": "Room temperature"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "humidity": {
 | 
				
			||||||
 | 
					                "name": "Humidity"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "freezer_temp": {
 | 
				
			||||||
 | 
					                "name": "Freezer temperature"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "fridge_temp": {
 | 
				
			||||||
 | 
					                "name": "Fridge temperature"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "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": "יבש במיוחד",
 | 
				
			||||||
 | 
					                    "11": "ללא ייבוש"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "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": "התחל עכשיו"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "programs_ref": {
 | 
				
			||||||
 | 
					                "state": {
 | 
				
			||||||
 | 
					                    "chiller": "Quick cool",
 | 
				
			||||||
 | 
					                    "cold_drinks": "Soft chill",
 | 
				
			||||||
 | 
					                    "fruit_and_veg": "Fruit & Veg",
 | 
				
			||||||
 | 
					                    "keep_fresh": "0° Fresh",
 | 
				
			||||||
 | 
					                    "sea_food": "Ready to cook meal",
 | 
				
			||||||
 | 
					                    "soft_frozen": "Soft freezing",
 | 
				
			||||||
 | 
					                    "tea": "Cold drinks or Beverages"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "remaining_time": {
 | 
				
			||||||
 | 
					                "name": "זמן שנותר"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "switch": {
 | 
				
			||||||
 | 
					            "anti_crease": {
 | 
				
			||||||
 | 
					                "name": "Anticrease"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "add_dish": {
 | 
				
			||||||
 | 
					                "name": "Add dishes"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "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"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "extra_rinse_1": {
 | 
				
			||||||
 | 
					                "name": "+1 שטיפה"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "extra_rinse_2": {
 | 
				
			||||||
 | 
					                "name": "+2 שטיפות"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "extra_rinse_3": {
 | 
				
			||||||
 | 
					                "name": "+3 שטיפות"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "acqua_plus": {
 | 
				
			||||||
 | 
					                "name": "Acquaplus"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "auto_dose": {
 | 
				
			||||||
 | 
					                "name": "מינון אוטומטי"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "good_night": {
 | 
				
			||||||
 | 
					                "name": "לילה טוב"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "auto_dose_softener": {
 | 
				
			||||||
 | 
					                "name": "מינון אוטומטי מרכך"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "auto_dose_detergent": {
 | 
				
			||||||
 | 
					                "name": "מינון אוטומטי חומר ניקוי"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "auto_set": {
 | 
				
			||||||
 | 
					                "name": "Auto-Set"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "super_cool": {
 | 
				
			||||||
 | 
					                "name": "Super Cool"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "super_freeze": {
 | 
				
			||||||
 | 
					                "name": "Super Freeze"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "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": "שטיפה מראש"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "acqua_plus": {
 | 
				
			||||||
 | 
					                "name": "Acquaplus"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "auto_dose": {
 | 
				
			||||||
 | 
					                "name": "מינון אוטומטי"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "buzzer": {
 | 
				
			||||||
 | 
					                "name": "Cycle end chime"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "holiday_mode": {
 | 
				
			||||||
 | 
					                "name": "Holiday Mode"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "auto_set": {
 | 
				
			||||||
 | 
					                "name": "Auto-Set"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "super_cool": {
 | 
				
			||||||
 | 
					                "name": "Super Cool"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "super_freeze": {
 | 
				
			||||||
 | 
					                "name": "Super Freeze"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "freezer_door": {
 | 
				
			||||||
 | 
					                "name": "Door open Freezer"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "fridge_door": {
 | 
				
			||||||
 | 
					                "name": "Door open Fridge"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "filter_replacement": {
 | 
				
			||||||
 | 
					                "name": "Filter replacement"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "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": "זמן ייבוש"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "steam_level": {
 | 
				
			||||||
 | 
					                "name": "מפלס קיטור"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "freezer_temp_sel": {
 | 
				
			||||||
 | 
					                "name": "Target temperature Freezer"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "fridge_temp_sel": {
 | 
				
			||||||
 | 
					                "name": "Target temperature Fridge"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "button": {
 | 
				
			||||||
 | 
					            "induction_hob": {
 | 
				
			||||||
 | 
					                "name": "Induction Hob"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "climate": {
 | 
				
			||||||
 | 
					            "air_conditioner": {
 | 
				
			||||||
 | 
					                "name": "Air conditioner"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "config": {
 | 
				
			||||||
 | 
					        "step": {
 | 
				
			||||||
 | 
					            "user": {
 | 
				
			||||||
 | 
					                "description": "Do the login",
 | 
				
			||||||
 | 
					                "data": {
 | 
				
			||||||
 | 
					                    "email": "Email",
 | 
				
			||||||
 | 
					                    "password": "Password"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1323
									
								
								custom_components/hon/translations/hr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/hr.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1364
									
								
								custom_components/hon/translations/it.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1364
									
								
								custom_components/hon/translations/it.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/nl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/nl.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/pl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/pl.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/pt.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/pt.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/ro.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/ro.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/ru.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/ru.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/sk.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/sk.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/sl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/sl.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/sr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/sr.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/tr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/tr.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1323
									
								
								custom_components/hon/translations/zh.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1323
									
								
								custom_components/hon/translations/zh.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,5 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "Haier hOn",
 | 
					    "name": "Haier hOn",
 | 
				
			||||||
    "render_readme": true,
 | 
					    "homeassistant": "2023.2.0",
 | 
				
			||||||
    "homeassistant": "2023.2.0"
 | 
					    "zip_release": true,
 | 
				
			||||||
 | 
					    "filename": "haier_hon.zip"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										90
									
								
								info.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								info.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					# Haier hOn
 | 
				
			||||||
 | 
					[](https://github.com/Andre0512/hon/releases/latest)
 | 
				
			||||||
 | 
					[](https://github.com/Andre0512/hon/blob/main/LICENSE)
 | 
				
			||||||
 | 
					[](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)
 | 
				
			||||||
 | 
					- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA]
 | 
				
			||||||
 | 
					- [Fridge](https://github.com/Andre0512/hon#fridge) [BETA]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Method 1**: [](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._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Examples
 | 
				
			||||||
 | 
					### Washing Machine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Supported Models
 | 
				
			||||||
 | 
					Support has been confirmed for these models, but many more will work. Please add already supported devices [with this form to complete the list](https://forms.gle/bTSD8qFotdZFytbf8).
 | 
				
			||||||
 | 
					- Haier AD105S2SM3FA
 | 
				
			||||||
 | 
					- Haier AS25PBAHRA
 | 
				
			||||||
 | 
					- Haier AS25TADHRA-2
 | 
				
			||||||
 | 
					- Haier AS35TADHRA-2
 | 
				
			||||||
 | 
					- Haier EG9012B19SU1JD
 | 
				
			||||||
 | 
					- Haier HD80-A3959
 | 
				
			||||||
 | 
					- Haier HW90-B14TEAM5
 | 
				
			||||||
 | 
					- Haier HW100-B14959U1
 | 
				
			||||||
 | 
					- Haier HWD100-B14979
 | 
				
			||||||
 | 
					- Haier HWO60SM2F3XH
 | 
				
			||||||
 | 
					- Haier XIB 3B2SFS-80
 | 
				
			||||||
 | 
					- Haier XIB 6B2D3FB
 | 
				
			||||||
 | 
					- Candy CIS633SCTTWIFI
 | 
				
			||||||
 | 
					- Candy CSOE C10DE-80
 | 
				
			||||||
 | 
					- Candy ROE H9A3TCEX-S
 | 
				
			||||||
 | 
					- Candy RPW41066BWMR/1-S
 | 
				
			||||||
 | 
					- Hoover H-WASH 500
 | 
				
			||||||
 | 
					- Hoover H-DRY 500
 | 
				
			||||||
 | 
					- Hoover H7W4 48MBC-S
 | 
				
			||||||
 | 
					- Hoover H9A3TCBEXS-S
 | 
				
			||||||
 | 
					- Hoover HFB 6B2S3FX
 | 
				
			||||||
 | 
					- Hoover HLE C10DCE-80
 | 
				
			||||||
 | 
					- Hoover HSOT3161WG
 | 
				
			||||||
 | 
					- Hoover HWPD 69AMBC/1-S
 | 
				
			||||||
 | 
					- Hoover HWPS4954DAMR-11
 | 
				
			||||||
 | 
					- Hoover NDE H10A2TCE-80
 | 
				
			||||||
 | 
					- Hoover NDE H9A2TSBEXS-S
 | 
				
			||||||
 | 
					- Hoover NDPHY10A2TCBEXSS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 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!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 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
									
								
							
							
						
						
									
										3
									
								
								requirements_dev.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					pyhOn
 | 
				
			||||||
 | 
					black
 | 
				
			||||||
 | 
					homeassistant
 | 
				
			||||||
							
								
								
									
										301
									
								
								scripts/generate_translation.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										301
									
								
								scripts/generate_translation.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,301 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import asyncio
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from pyhon import HonAPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    sys.path.insert(0, str(Path(__file__).parent.parent))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from custom_components.hon import const
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SENSOR = {
 | 
				
			||||||
 | 
					    "washing_modes": const.MACH_MODE,
 | 
				
			||||||
 | 
					    "mach_modes_ac": const.AC_MACH_MODE,
 | 
				
			||||||
 | 
					    "program_phases_wm": const.WASHING_PR_PHASE,
 | 
				
			||||||
 | 
					    "program_phases_td": const.TUMBLE_DRYER_PR_PHASE,
 | 
				
			||||||
 | 
					    "program_phases_dw": const.DISHWASHER_PR_PHASE,
 | 
				
			||||||
 | 
					    "dry_levels": const.TUMBLE_DRYER_DRY_LEVEL,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT = {
 | 
				
			||||||
 | 
					    "dry_levels": const.TUMBLE_DRYER_DRY_LEVEL,
 | 
				
			||||||
 | 
					    "eco_pilot": const.AC_HUMAN_SENSE,
 | 
				
			||||||
 | 
					    "fan_mode": const.AC_FAN_MODE,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROGRAMS = {
 | 
				
			||||||
 | 
					    "select": {
 | 
				
			||||||
 | 
					        "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",
 | 
				
			||||||
 | 
					        "programs_ref": "PROGRAMS.REF",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "sensor": {
 | 
				
			||||||
 | 
					        "programs_td": "PROGRAMS.TD",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NAMES = {
 | 
				
			||||||
 | 
					    "switch": {
 | 
				
			||||||
 | 
					        "anti_crease": "HDRY_CMD&CTRL.PROGRAM_CYCLE_DETAIL.ANTICREASE_TITLE",
 | 
				
			||||||
 | 
					        "add_dish": "DW.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",
 | 
				
			||||||
 | 
					        "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",
 | 
				
			||||||
 | 
					        "acqua_plus": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.ACQUAPLUS",
 | 
				
			||||||
 | 
					        "auto_dose_softener": [
 | 
				
			||||||
 | 
					            "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.AUTODOSE",
 | 
				
			||||||
 | 
					            "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.SOFTENER",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "auto_dose_detergent": [
 | 
				
			||||||
 | 
					            "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.AUTODOSE",
 | 
				
			||||||
 | 
					            "WASHING_CMD&CTRL.DASHBOARD_MENU_MORE_SETTINGS_WATER.DETERGENT",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "good_night": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OTHER_OPTIONS.GOODNIGHT",
 | 
				
			||||||
 | 
					        "auto_set": "REF_CMD&CTRL.MODALITIES.ECO",
 | 
				
			||||||
 | 
					        "super_cool": "REF_CMD&CTRL.MODALITIES.SUPER_COOL",
 | 
				
			||||||
 | 
					        "super_freeze": "REF_CMD&CTRL.MODALITIES.SUPER_FREEZE",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					        "acqua_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",
 | 
				
			||||||
 | 
					        "buzzer": "DW_CMD&CTRL.SETTINGS.END_CYCLE_BUZZER",
 | 
				
			||||||
 | 
					        "holiday_mode": "REF.DASHBOARD_MENU_MORE_NOTIFICATIONS.HOLIDAY_MODE",
 | 
				
			||||||
 | 
					        "auto_set": "REF_CMD&CTRL.MODALITIES.ECO",
 | 
				
			||||||
 | 
					        "super_cool": "REF_CMD&CTRL.MODALITIES.SUPER_COOL",
 | 
				
			||||||
 | 
					        "super_freeze": "REF_CMD&CTRL.MODALITIES.SUPER_FREEZE",
 | 
				
			||||||
 | 
					        "freezer_door": ["GLOBALS.APPLIANCE_STATUS.DOOR_OPEN", "REF.ZONES.FREEZER"],
 | 
				
			||||||
 | 
					        "fridge_door": ["GLOBALS.APPLIANCE_STATUS.DOOR_OPEN", "REF.ZONES.FRIDGE"],
 | 
				
			||||||
 | 
					        "filter_replacement": "AP.MAINTENANCE.FILTER_REPLACEMENT",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					        "remaining_time": "ENROLLMENT_COMMON.GENERAL.REMAINING_TIME",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					        "room_temperature": "REF.SMART_DRINK_ASSISTANT.AMBIENT",
 | 
				
			||||||
 | 
					        "humidity": "AP.TITLES.HUMIDITY",
 | 
				
			||||||
 | 
					        "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",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "freezer_temp": "REF_CMD&CTRL.TEMPERATURE_DRAWER_FREEZER.FREEZER_TEMPERATURE_TITLE",
 | 
				
			||||||
 | 
					        "fridge_temp": "REF_CMD&CTRL.TEMPERATURE_DRAWER_FRIDGE.FRIDGE_TEMPERATURE_TITLE",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					        "steam_level": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_MAIN_OPTIONS.STEAM_LEVEL",
 | 
				
			||||||
 | 
					        "freezer_temp_sel": ["OV.COMMON.GOAL_TEMPERATURE", "REF.ZONES.FREEZER"],
 | 
				
			||||||
 | 
					        "fridge_temp_sel": ["OV.COMMON.GOAL_TEMPERATURE", "REF.ZONES.FRIDGE"],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "climate": {"air_conditioner": "GLOBALS.APPLIANCES_NAME.AC"},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async def check_translation_files(translations):
 | 
				
			||||||
 | 
					    for language in const.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 full_key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 const.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 entity, data in PROGRAMS.items():
 | 
				
			||||||
 | 
					            for name, program in data.items():
 | 
				
			||||||
 | 
					                select = old.setdefault("entity", {}).setdefault(entity, {})
 | 
				
			||||||
 | 
					                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()
 | 
				
			||||||
							
								
								
									
										93
									
								
								scripts/sensor_docs.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										93
									
								
								scripts/sensor_docs.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					#!/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.climate import CLIMATES
 | 
				
			||||||
 | 
					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,
 | 
				
			||||||
 | 
					    "climate": CLIMATES,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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"
 | 
				
			||||||
 | 
					                and "settings." not in entity.key
 | 
				
			||||||
 | 
					            ):
 | 
				
			||||||
 | 
					                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.key.startswith("settings")
 | 
				
			||||||
 | 
					                or hasattr(entity, "turn_on_key")
 | 
				
			||||||
 | 
					                or entity_type in ["button", "climate"]
 | 
				
			||||||
 | 
					                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)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user