Compare commits
	
		
			92 Commits
		
	
	
		
			v0.6.0-bet
			...
			v0.8
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4b95accf02 | |||
| 998b691a8e | |||
| 6084e4a034 | |||
| 5bc3120000 | |||
| 0f9f0dee4c | |||
| 80b3741f2f | |||
| c433714a94 | |||
| 228cf3cf73 | |||
| 1a50e8112d | |||
| 57ecd7c3a5 | |||
| 2fe8ace9f5 | |||
| 6e9981c9ab | |||
| cb660fa9e0 | |||
| a8762367ed | |||
| 696dc136eb | |||
| e9d1bb2056 | |||
| 9518031f24 | |||
| bf1a6e8fe2 | |||
| 833c395c97 | |||
| 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 | |||
| 5dbf508519 | |||
| 7d3813b8fd | 
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,4 @@
 | 
				
			|||||||
__pycache__/
 | 
					__pycache__/
 | 
				
			||||||
test.py
 | 
					 | 
				
			||||||
.idea/
 | 
					.idea/
 | 
				
			||||||
 | 
					scripts/translations/
 | 
				
			||||||
 | 
					scripts/test*
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										477
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										477
									
								
								README.md
									
									
									
									
									
								
							@ -1,16 +1,21 @@
 | 
				
			|||||||
# Haier hOn
 | 
					# Haier hOn
 | 
				
			||||||
[](https://hacs.xyz)
 | 
					[](https://hacs.xyz)
 | 
				
			||||||
[](https://github.com/Andre0512/hon/releases/latest)
 | 
					[](https://github.com/Andre0512/hon/releases/latest)
 | 
				
			||||||

 | 
					[](https://github.com/Andre0512/pyhOn)
 | 
				
			||||||
[](https://analytics.home-assistant.io/)  
 | 
					[](https://github.com/Andre0512/hon/blob/main/LICENSE)
 | 
				
			||||||
Home Assistant integration for Haier hOn: support for Haier/Candy/Hoover home appliances like washing machines.
 | 
					[](https://tooomm.github.io/github-release-stats/?username=Andre0512&repository=hon)  
 | 
				
			||||||
 | 
					Home Assistant integration for [Haier's mobile app hOn](https://hon-smarthome.com/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Supported Appliances
 | 
					## Supported Appliances
 | 
				
			||||||
- Washing Machine
 | 
					- [Washing Machine](https://github.com/Andre0512/hon#washing-machine)
 | 
				
			||||||
- Tumble Dryer
 | 
					- [Tumble Dryer](https://github.com/Andre0512/hon#tumble-dryer)
 | 
				
			||||||
- Washer Dryer
 | 
					- [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer)
 | 
				
			||||||
- Oven
 | 
					- [Oven](https://github.com/Andre0512/hon#oven)
 | 
				
			||||||
- Hob
 | 
					- [Dish Washer](https://github.com/Andre0512/hon#dish-washer)
 | 
				
			||||||
- Dish Washer
 | 
					- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner)
 | 
				
			||||||
 | 
					- [Fridge](https://github.com/Andre0512/hon#fridge)
 | 
				
			||||||
 | 
					- [Hob](https://github.com/Andre0512/hon#hob) [BETA]
 | 
				
			||||||
 | 
					- [Hood](https://github.com/Andre0512/hon#hood) [BETA]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Installation
 | 
					## Installation
 | 
				
			||||||
**Method 1:** [](https://my.home-assistant.io/redirect/hacs_repository/?owner=Andre0512&repository=hon&category=integration)
 | 
					**Method 1:** [](https://my.home-assistant.io/redirect/hacs_repository/?owner=Andre0512&repository=hon&category=integration)
 | 
				
			||||||
@ -28,28 +33,80 @@ _Restart Home Assistant_
 | 
				
			|||||||
**Method 2**: Settings > Devices & Services > Add Integration > **Haier 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._
 | 
					_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 AS20HPL1HRA
 | 
				
			||||||
 | 
					- Haier AS25PBAHRA
 | 
				
			||||||
 | 
					- Haier AS25S2SF1FA-WH
 | 
				
			||||||
 | 
					- Haier AS25TADHRA-2
 | 
				
			||||||
 | 
					- Haier AS35TADHRA-2
 | 
				
			||||||
 | 
					- Haier EG9012B19SU1JD
 | 
				
			||||||
 | 
					- Haier HA2MTSJ68MC
 | 
				
			||||||
 | 
					- Haier HADG6DS46BWIFI
 | 
				
			||||||
 | 
					- Haier HD80-A3959
 | 
				
			||||||
 | 
					- Haier HW90-B14TEAM5
 | 
				
			||||||
 | 
					- Haier HW100-B14959U1
 | 
				
			||||||
 | 
					- Haier HWD100-B14979
 | 
				
			||||||
 | 
					- Haier HWO60SM2F3XH
 | 
				
			||||||
 | 
					- Haier XIB 3B2SFS-80
 | 
				
			||||||
 | 
					- Haier XIB 6B2D3FB
 | 
				
			||||||
 | 
					- Candy BCTDH7A1TE
 | 
				
			||||||
 | 
					- Candy CCE4T620EWU
 | 
				
			||||||
 | 
					- Candy CIS633SCTTWIFI
 | 
				
			||||||
 | 
					- Candy CSOE C10DE-80
 | 
				
			||||||
 | 
					- Candy RO44 1286DWMC4-07
 | 
				
			||||||
 | 
					- 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 HW 68AMC/1-80
 | 
				
			||||||
 | 
					- 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!
 | 
				
			||||||
### Read out device data
 | 
					### 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.
 | 
					If you want to make a request for adding new appliances or additional attributes and don't want to use the command line, here is how you can read out your device data.
 | 
				
			||||||
For every device exists a hidden button which can be used to log all info of your appliance.
 | 
					For every device exists a hidden button which can be used to log all infos of your appliance.
 | 
				
			||||||
1. Enable the "Log Device Info" button  
 | 
					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._
 | 
					   _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
 | 
					2. Press the button to create a notification
 | 
				
			||||||
3. Go to Settings > System > Logs, click _load full logs_ and scroll down  
 | 
					3. Open home assistant notifications and copy the message (Crtl+A, Ctrl+C)
 | 
				
			||||||
   _The formatting is messy if you not load full logs_
 | 
					 | 
				
			||||||
4. Here you can find all data which can be read out via the api
 | 
					 | 
				
			||||||
   ```yaml
 | 
					 | 
				
			||||||
   data:
 | 
					 | 
				
			||||||
     appliance:
 | 
					 | 
				
			||||||
       applianceId: 12-34-56-78-90-ab#2022-10-25T19:47:11Z
 | 
					 | 
				
			||||||
       applianceModelId: 1569 
 | 
					 | 
				
			||||||
       ...
 | 
					 | 
				
			||||||
   ```
 | 
					 | 
				
			||||||
5. Copy this data and create a [new issue](https://github.com/Andre0512/hon/issues/new) with your request
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Add appliances or additional attributes
 | 
					### Add appliances or additional attributes
 | 
				
			||||||
1. Install [pyhOn](https://github.com/Andre0512/pyhOn)
 | 
					1. Install [pyhOn](https://github.com/Andre0512/pyhOn)
 | 
				
			||||||
   ```commandline
 | 
					   ```commandline
 | 
				
			||||||
@ -94,13 +151,367 @@ For every device exists a hidden button which can be used to log all info of you
 | 
				
			|||||||
- 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
 | 
					- Use [pyhOn's translate command](https://github.com/Andre0512/pyhOn#translation) to read out the official translations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Tested Devices
 | 
					## Special Thanks
 | 
				
			||||||
- Haier WD90-B14TEAM5
 | 
					- 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.
 | 
				
			||||||
- Haier HD80-A3959
 | 
					- 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.
 | 
				
			||||||
- Haier HWO60SM2F3XH
 | 
					- to everyone who contributed, created an issue, gave this repo a star, and used this integration.
 | 
				
			||||||
- Hoover H-WASH 500
 | 
					- to the patience of my girlfriend as I work on this integration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## About this Repo
 | 
					## Appliance Features
 | 
				
			||||||
The existing integrations missed some features from the app I liked to have in HomeAssistant.
 | 
					
 | 
				
			||||||
I tried to create a pull request, but in the structures of these existing repos, I find it hard to fit in my needs, so I basically rewrote everything. 
 | 
					### Air conditioner
 | 
				
			||||||
I moved the api related stuff into the package [pyhOn](https://github.com/Andre0512/pyhOn).
 | 
					#### Controls
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| 10° Heating | `heat-wave` | `switch` | `10degreeHeatingStatus` |
 | 
				
			||||||
 | 
					| Air Conditioner | `air-conditioner` | `climate` | `settings` |
 | 
				
			||||||
 | 
					| Echo | `account-voice` | `switch` | `echoStatus` |
 | 
				
			||||||
 | 
					| Eco Mode |  | `switch` | `ecoMode` |
 | 
				
			||||||
 | 
					| Eco Pilot | `run` | `select` | `settings.humanSensingStatus` |
 | 
				
			||||||
 | 
					| Health Mode | `medication-outline` | `switch` | `healthMode` |
 | 
				
			||||||
 | 
					| Mute | `volume-off` | `switch` | `muteStatus` |
 | 
				
			||||||
 | 
					| Rapid Mode | `run-fast` | `switch` | `rapidMode` |
 | 
				
			||||||
 | 
					| Screen Display | `monitor-small` | `switch` | `screenDisplayStatus` |
 | 
				
			||||||
 | 
					| Self Cleaning | `air-filter` | `switch` | `selfCleaningStatus` |
 | 
				
			||||||
 | 
					| Self Cleaning 56 | `air-filter` | `switch` | `selfCleaning56Status` |
 | 
				
			||||||
 | 
					| Silent Sleep | `bed` | `switch` | `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` |
 | 
				
			||||||
 | 
					| Program | `play` | `sensor` | `programName` |
 | 
				
			||||||
 | 
					| Selected Temperature | `thermometer` | `sensor` | `tempSel` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Dish washer
 | 
				
			||||||
 | 
					#### Controls
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Buzzer Disabled | `volume-off` | `switch` | `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 | `play` | `sensor` | `programName` |
 | 
				
			||||||
 | 
					| Program Phase | `washing-machine` | `sensor` | `prPhase` |
 | 
				
			||||||
 | 
					| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
 | 
				
			||||||
 | 
					| Rinse Aid | `spray-bottle` | `binary_sensor` | `rinseAidStatus` |
 | 
				
			||||||
 | 
					| Salt | `shaker-outline` | `binary_sensor` | `saltStatus` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Hood
 | 
				
			||||||
 | 
					#### Controls
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Start Program | `hvac` | `button` | `startProgram` |
 | 
				
			||||||
 | 
					| Stop Program | `hvac-off` | `button` | `stopProgram` |
 | 
				
			||||||
 | 
					#### Configs
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Light status | `lightbulb` | `number` | `startProgram.lightStatus` |
 | 
				
			||||||
 | 
					| Wind speed | `fan` | `number` | `startProgram.windSpeed` |
 | 
				
			||||||
 | 
					#### Sensors
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Delay time | `clock-start` | `sensor` | `delayTime` |
 | 
				
			||||||
 | 
					| Delay time status | `clock-start` | `sensor` | `delayTimeStatus` |
 | 
				
			||||||
 | 
					| Errors | `alert-circle` | `sensor` | `errors` |
 | 
				
			||||||
 | 
					| Filter Cleaning Alarm Status |  | `sensor` | `filterCleaningAlarmStatus` |
 | 
				
			||||||
 | 
					| Filter Cleaning Status |  | `sensor` | `filterCleaningStatus` |
 | 
				
			||||||
 | 
					| Last Work Time | `clock-start` | `sensor` | `lastWorkTime` |
 | 
				
			||||||
 | 
					| Light Status | `lightbulb` | `sensor` | `lightStatus` |
 | 
				
			||||||
 | 
					| Mach Mode |  | `sensor` | `machMode` |
 | 
				
			||||||
 | 
					| On / Off Status | `lightbulb` | `sensor` | `onOffStatus` |
 | 
				
			||||||
 | 
					| Quick Delay Time Status |  | `sensor` | `quickDelayTimeStatus` |
 | 
				
			||||||
 | 
					| RGB Light Color | `lightbulb` | `sensor` | `rgbLightColors` |
 | 
				
			||||||
 | 
					| RGB Light Status | `lightbulb` | `sensor` | `rgbLightStatus` |
 | 
				
			||||||
 | 
					| Wind Speed | `fan` | `sensor` | `windSpeed` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 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` |
 | 
				
			||||||
 | 
					| Program | `play` | `sensor` | `programName` |
 | 
				
			||||||
 | 
					| Remaining Time | `timer` | `sensor` | `remainingTimeMM` |
 | 
				
			||||||
 | 
					| Temperature | `thermometer` | `sensor` | `temp` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Oven
 | 
				
			||||||
 | 
					#### Controls
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Oven | `toaster-oven` | `switch` | `startProgram` / `stopProgram` |
 | 
				
			||||||
 | 
					| Oven | `thermometer` | `climate` | `settings.tempSel` |
 | 
				
			||||||
 | 
					#### 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` |
 | 
				
			||||||
 | 
					| Program | `play` | `sensor` | `programName` |
 | 
				
			||||||
 | 
					| 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` | `intelligenceMode` |
 | 
				
			||||||
 | 
					| Freezer | `snowflake-thermometer` | `climate` | `settings.tempSelZ2` |
 | 
				
			||||||
 | 
					| Freezer Temperature | `thermometer` | `number` | `settings.tempSelZ2` |
 | 
				
			||||||
 | 
					| Fridge | `thermometer` | `climate` | `settings.tempSelZ1` |
 | 
				
			||||||
 | 
					| Fridge Temperature | `thermometer` | `number` | `settings.tempSelZ1` |
 | 
				
			||||||
 | 
					| Holiday Mode | `palm-tree` | `switch` | `holidayMode` |
 | 
				
			||||||
 | 
					| Program Start | `play` | `button` | `startProgram` |
 | 
				
			||||||
 | 
					| Program Stop | `stop` | `button` | `stopProgram` |
 | 
				
			||||||
 | 
					| Super Cool | `snowflake` | `switch` | `quickModeZ2` |
 | 
				
			||||||
 | 
					| Super Freeze | `snowflake-variant` | `switch` | `quickModeZ1` |
 | 
				
			||||||
 | 
					#### Configs
 | 
				
			||||||
 | 
					| Name | Icon | Entity | Key |
 | 
				
			||||||
 | 
					| --- | --- | --- | --- |
 | 
				
			||||||
 | 
					| Program |  | `select` | `startProgram.program` |
 | 
				
			||||||
 | 
					| Zone | `radiobox-marked` | `select` | `startProgram.zone` |
 | 
				
			||||||
 | 
					#### 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` |
 | 
				
			||||||
 | 
					| Error | `math-log` | `sensor` | `errors` |
 | 
				
			||||||
 | 
					| 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 | `play` | `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 | `play` | `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 | `play` | `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` |
 | 
				
			||||||
 | 
					| 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,8 +1,6 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
from dataclasses import dataclass
 | 
					from dataclasses import dataclass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import Hon
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from homeassistant.components.binary_sensor import (
 | 
					from homeassistant.components.binary_sensor import (
 | 
				
			||||||
    BinarySensorEntityDescription,
 | 
					    BinarySensorEntityDescription,
 | 
				
			||||||
    BinarySensorDeviceClass,
 | 
					    BinarySensorDeviceClass,
 | 
				
			||||||
@ -10,8 +8,9 @@ from homeassistant.components.binary_sensor import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
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 HonEntity, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,18 +35,39 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
				
			||||||
            on_value="CONNECTED",
 | 
					            on_value="CONNECTED",
 | 
				
			||||||
            icon="mdi:remote",
 | 
					            icon="mdi:remote",
 | 
				
			||||||
 | 
					            translation_key="remote_control",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="doorLockStatus",
 | 
					            key="doorLockStatus",
 | 
				
			||||||
            name="Door Lock",
 | 
					            name="Door Lock",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.LOCK,
 | 
					            device_class=BinarySensorDeviceClass.LOCK,
 | 
				
			||||||
            on_value="0",
 | 
					            on_value="0",
 | 
				
			||||||
 | 
					            translation_key="door_lock",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="doorStatus",
 | 
					            key="doorStatus",
 | 
				
			||||||
            name="Door",
 | 
					            name="Door",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
					            device_class=BinarySensorDeviceClass.DOOR,
 | 
				
			||||||
            on_value="1",
 | 
					            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": (
 | 
					    "TD": (
 | 
				
			||||||
@ -56,49 +76,17 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
            name="Connection",
 | 
					            name="Connection",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
				
			||||||
            on_value="CONNECTED",
 | 
					            on_value="CONNECTED",
 | 
				
			||||||
 | 
					            translation_key="connection",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="doorStatus",
 | 
					            key="doorStatus",
 | 
				
			||||||
            name="Door",
 | 
					            name="Door",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
					            device_class=BinarySensorDeviceClass.DOOR,
 | 
				
			||||||
            on_value="1",
 | 
					            on_value="1",
 | 
				
			||||||
        ),
 | 
					            translation_key="door_open",
 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    "WD": (
 | 
					 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="attributes.lastConnEvent.category",
 | 
					 | 
				
			||||||
            name="Remote Control",
 | 
					 | 
				
			||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					 | 
				
			||||||
            on_value="CONNECTED",
 | 
					 | 
				
			||||||
            icon="mdi:remote",
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="startProgram.prewash",
 | 
					            key="anticrease", name="Anti-Crease", translation_key="anti_crease"
 | 
				
			||||||
            name="Pre Wash",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="extraRinse1",
 | 
					 | 
				
			||||||
            name="Extra Rinse 1",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="extraRinse2",
 | 
					 | 
				
			||||||
            name="Extra Rinse 2",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="extraRinse3",
 | 
					 | 
				
			||||||
            name="Extra Rinse 3",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="goodNight",
 | 
					 | 
				
			||||||
            name="Good Night Mode",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="acquaplus",
 | 
					 | 
				
			||||||
            name="Acqua Plus",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="anticrease",
 | 
					 | 
				
			||||||
            name="Anti-Crease",
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "OV": (
 | 
					    "OV": (
 | 
				
			||||||
@ -108,13 +96,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
				
			||||||
            on_value="CONNECTED",
 | 
					            on_value="CONNECTED",
 | 
				
			||||||
            icon="mdi:wifi",
 | 
					            icon="mdi:wifi",
 | 
				
			||||||
        ),
 | 
					            translation_key="connection",
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="attributes.parameters.remoteCtrValid",
 | 
					 | 
				
			||||||
            name="Remote Control",
 | 
					 | 
				
			||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					 | 
				
			||||||
            on_value="1",
 | 
					 | 
				
			||||||
            icon="mdi:remote",
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="attributes.parameters.onOffStatus",
 | 
					            key="attributes.parameters.onOffStatus",
 | 
				
			||||||
@ -122,6 +104,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
            device_class=BinarySensorDeviceClass.RUNNING,
 | 
					            device_class=BinarySensorDeviceClass.RUNNING,
 | 
				
			||||||
            on_value="1",
 | 
					            on_value="1",
 | 
				
			||||||
            icon="mdi:power-cycle",
 | 
					            icon="mdi:power-cycle",
 | 
				
			||||||
 | 
					            translation_key="on",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "IH": (
 | 
					    "IH": (
 | 
				
			||||||
@ -131,13 +114,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
				
			||||||
            on_value="CONNECTED",
 | 
					            on_value="CONNECTED",
 | 
				
			||||||
            icon="mdi:wifi",
 | 
					            icon="mdi:wifi",
 | 
				
			||||||
        ),
 | 
					            translation_key="connection",
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					 | 
				
			||||||
            key="attributes.parameters.remoteCtrValid",
 | 
					 | 
				
			||||||
            name="Remote Control",
 | 
					 | 
				
			||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					 | 
				
			||||||
            on_value="1",
 | 
					 | 
				
			||||||
            icon="mdi:remote",
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="attributes.parameters.onOffStatus",
 | 
					            key="attributes.parameters.onOffStatus",
 | 
				
			||||||
@ -145,18 +122,28 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
            device_class=BinarySensorDeviceClass.RUNNING,
 | 
					            device_class=BinarySensorDeviceClass.RUNNING,
 | 
				
			||||||
            on_value="1",
 | 
					            on_value="1",
 | 
				
			||||||
            icon="mdi:power-cycle",
 | 
					            icon="mdi:power-cycle",
 | 
				
			||||||
 | 
					            translation_key="on",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="hotStatus",
 | 
					            key="hotStatus",
 | 
				
			||||||
            name="Hot Status",
 | 
					            name="Hot Status",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.HEAT,
 | 
					            device_class=BinarySensorDeviceClass.HEAT,
 | 
				
			||||||
            on_value="1",
 | 
					            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(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="hobLockStatus",
 | 
					            key="hobLockStatus",
 | 
				
			||||||
            name="Hob Lock",
 | 
					            name="Hob Lock",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.LOCK,
 | 
					            device_class=BinarySensorDeviceClass.LOCK,
 | 
				
			||||||
            on_value="0",
 | 
					            on_value="0",
 | 
				
			||||||
 | 
					            translation_key="child_lock",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "DW": (
 | 
					    "DW": (
 | 
				
			||||||
@ -166,6 +153,7 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
            device_class=BinarySensorDeviceClass.PROBLEM,
 | 
					            device_class=BinarySensorDeviceClass.PROBLEM,
 | 
				
			||||||
            on_value="1",
 | 
					            on_value="1",
 | 
				
			||||||
            icon="mdi:shaker-outline",
 | 
					            icon="mdi:shaker-outline",
 | 
				
			||||||
 | 
					            translation_key="salt_level",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="rinseAidStatus",
 | 
					            key="rinseAidStatus",
 | 
				
			||||||
@ -173,64 +161,108 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = {
 | 
				
			|||||||
            device_class=BinarySensorDeviceClass.PROBLEM,
 | 
					            device_class=BinarySensorDeviceClass.PROBLEM,
 | 
				
			||||||
            on_value="1",
 | 
					            on_value="1",
 | 
				
			||||||
            icon="mdi:spray-bottle",
 | 
					            icon="mdi:spray-bottle",
 | 
				
			||||||
 | 
					            translation_key="rinse_aid",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="attributes.lastConnEvent.category",
 | 
					            key="attributes.lastConnEvent.category",
 | 
				
			||||||
            name="Connection",
 | 
					            name="Connection",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
					            device_class=BinarySensorDeviceClass.CONNECTIVITY,
 | 
				
			||||||
            on_value="CONNECTED",
 | 
					            on_value="CONNECTED",
 | 
				
			||||||
 | 
					            translation_key="connection",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonBinarySensorEntityDescription(
 | 
					        HonBinarySensorEntityDescription(
 | 
				
			||||||
            key="doorStatus",
 | 
					            key="doorStatus",
 | 
				
			||||||
            name="Door",
 | 
					            name="Door",
 | 
				
			||||||
            device_class=BinarySensorDeviceClass.DOOR,
 | 
					            device_class=BinarySensorDeviceClass.DOOR,
 | 
				
			||||||
            on_value="1",
 | 
					            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: Hon = hass.data[DOMAIN][entry.unique_id]
 | 
					    entities = []
 | 
				
			||||||
    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
					    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
				
			||||||
    appliances = []
 | 
					        for description in BINARY_SENSORS.get(device.appliance_type, []):
 | 
				
			||||||
    for device in hon.appliances:
 | 
					            if not device.get(description.key):
 | 
				
			||||||
        if device.unique_id in coordinators:
 | 
					                continue
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
					            entity = HonBinarySensorEntity(hass, entry, device, description)
 | 
				
			||||||
        else:
 | 
					            await entity.coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            entities.append(entity)
 | 
				
			||||||
            hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
 | 
					    async_add_entities(entities)
 | 
				
			||||||
        await coordinator.async_config_entry_first_refresh()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if descriptions := BINARY_SENSORS.get(device.appliance_type):
 | 
					 | 
				
			||||||
            for description in descriptions:
 | 
					 | 
				
			||||||
                if not device.get(description.key):
 | 
					 | 
				
			||||||
                    _LOGGER.warning(
 | 
					 | 
				
			||||||
                        "[%s] Can't setup %s", device.appliance_type, description.key
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                    continue
 | 
					 | 
				
			||||||
                appliances.extend(
 | 
					 | 
				
			||||||
                    [
 | 
					 | 
				
			||||||
                        HonBinarySensorEntity(
 | 
					 | 
				
			||||||
                            hass, coordinator, entry, device, description
 | 
					 | 
				
			||||||
                        )
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async_add_entities(appliances)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonBinarySensorEntity(HonEntity, BinarySensorEntity):
 | 
					class HonBinarySensorEntity(HonEntity, BinarySensorEntity):
 | 
				
			||||||
    entity_description: HonBinarySensorEntityDescription
 | 
					    entity_description: HonBinarySensorEntityDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
					 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self._coordinator = coordinator
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.entity_description = description
 | 
					 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_on(self) -> bool:
 | 
					    def is_on(self) -> bool:
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
@ -239,9 +271,10 @@ class HonBinarySensorEntity(HonEntity, BinarySensorEntity):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @callback
 | 
					    @callback
 | 
				
			||||||
    def _handle_coordinator_update(self):
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
        self._attr_native_value = (
 | 
					        self._attr_native_value = (
 | 
				
			||||||
            self._device.get(self.entity_description.key, "")
 | 
					            self._device.get(self.entity_description.key, "")
 | 
				
			||||||
            == self.entity_description.on_value
 | 
					            == self.entity_description.on_value
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.async_write_ha_state()
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,90 +1,102 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
import urllib
 | 
					 | 
				
			||||||
from urllib.parse import quote
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 pyhon import Hon
 | 
					from homeassistant.const import EntityCategory
 | 
				
			||||||
from pyhon.appliance import HonAppliance
 | 
					from pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from homeassistant.const import EntityCategory
 | 
					 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonCoordinator, HonEntity
 | 
					from .hon import HonEntity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = {
 | 
					BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = {
 | 
				
			||||||
    "OV": (
 | 
					 | 
				
			||||||
        ButtonEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram",
 | 
					 | 
				
			||||||
            name="Start Program",
 | 
					 | 
				
			||||||
            icon="mdi:power-cycle",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        ButtonEntityDescription(
 | 
					 | 
				
			||||||
            key="stopProgram",
 | 
					 | 
				
			||||||
            name="Stop Program",
 | 
					 | 
				
			||||||
            icon="mdi:power-off",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    "IH": (
 | 
					    "IH": (
 | 
				
			||||||
        ButtonEntityDescription(
 | 
					        ButtonEntityDescription(
 | 
				
			||||||
            key="startProgram",
 | 
					            key="startProgram",
 | 
				
			||||||
            name="Start Program",
 | 
					            name="Start Program",
 | 
				
			||||||
            icon="mdi:pot-steam",
 | 
					            icon="mdi:pot-steam",
 | 
				
			||||||
 | 
					            translation_key="induction_hob",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        ButtonEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram",
 | 
				
			||||||
 | 
					            name="Program Start",
 | 
				
			||||||
 | 
					            icon="mdi:play",
 | 
				
			||||||
 | 
					            translation_key="start_program",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        ButtonEntityDescription(
 | 
				
			||||||
 | 
					            key="stopProgram",
 | 
				
			||||||
 | 
					            name="Program Stop",
 | 
				
			||||||
 | 
					            icon="mdi:stop",
 | 
				
			||||||
 | 
					            translation_key="stop_program",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "HO": (
 | 
				
			||||||
 | 
					        ButtonEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram",
 | 
				
			||||||
 | 
					            name="Start Program",
 | 
				
			||||||
 | 
					            icon="mdi:hvac",
 | 
				
			||||||
 | 
					            translation_key="start_program",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        ButtonEntityDescription(
 | 
				
			||||||
 | 
					            key="stopProgram",
 | 
				
			||||||
 | 
					            name="Stop Program",
 | 
				
			||||||
 | 
					            icon="mdi:hvac-off",
 | 
				
			||||||
 | 
					            translation_key="stop_program",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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: Hon = hass.data[DOMAIN][entry.unique_id]
 | 
					    entities = []
 | 
				
			||||||
    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
					    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
				
			||||||
    appliances = []
 | 
					        for description in BUTTONS.get(device.appliance_type, []):
 | 
				
			||||||
    for device in hon.appliances:
 | 
					            if not device.commands.get(description.key):
 | 
				
			||||||
        if device.unique_id in coordinators:
 | 
					                continue
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
					            entity = HonButtonEntity(hass, entry, device, description)
 | 
				
			||||||
        else:
 | 
					            await entity.coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            entities.append(entity)
 | 
				
			||||||
            hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
 | 
					        entities.append(HonFeatureRequestButton(hass, entry, device))
 | 
				
			||||||
        await coordinator.async_config_entry_first_refresh()
 | 
					        await entities[-1].coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					    async_add_entities(entities)
 | 
				
			||||||
        if descriptions := BUTTONS.get(device.appliance_type):
 | 
					 | 
				
			||||||
            for description in descriptions:
 | 
					 | 
				
			||||||
                if not device.commands.get(description.key):
 | 
					 | 
				
			||||||
                    continue
 | 
					 | 
				
			||||||
                appliances.extend(
 | 
					 | 
				
			||||||
                    [HonButtonEntity(hass, coordinator, entry, device, description)]
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
        appliances.extend([HonFeatureRequestButton(hass, coordinator, entry, device)])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async_add_entities(appliances)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonButtonEntity(HonEntity, ButtonEntity):
 | 
					class HonButtonEntity(HonEntity, ButtonEntity):
 | 
				
			||||||
    def __init__(
 | 
					    entity_description: ButtonEntityDescription
 | 
				
			||||||
        self, hass, coordinator, entry, device: HonAppliance, description
 | 
					 | 
				
			||||||
    ) -> None:
 | 
					 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self._coordinator = coordinator
 | 
					 | 
				
			||||||
        self._device = device
 | 
					 | 
				
			||||||
        self.entity_description = description
 | 
					 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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):
 | 
					class HonFeatureRequestButton(HonEntity, ButtonEntity):
 | 
				
			||||||
    def __init__(self, hass, coordinator, entry, device: HonAppliance) -> None:
 | 
					    def __init__(self, hass, entry, device: HonAppliance) -> None:
 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					        super().__init__(hass, entry, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._device = device
 | 
					 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}_log_device_info"
 | 
					        self._attr_unique_id = f"{super().unique_id}_log_device_info"
 | 
				
			||||||
        self._attr_icon = "mdi:information"
 | 
					        self._attr_icon = "mdi:information"
 | 
				
			||||||
        self._attr_name = "Log Device Info"
 | 
					        self._attr_name = "Show Device Info"
 | 
				
			||||||
        self._attr_entity_category = EntityCategory.DIAGNOSTIC
 | 
					        self._attr_entity_category = EntityCategory.DIAGNOSTIC
 | 
				
			||||||
        self._attr_entity_registry_enabled_default = False
 | 
					        self._attr_entity_registry_enabled_default = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def async_press(self) -> None:
 | 
					    async def async_press(self) -> None:
 | 
				
			||||||
        _LOGGER.error("Device Info:\n" + self._device.diagnose)
 | 
					        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 "))
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										320
									
								
								custom_components/hon/climate.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								custom_components/hon/climate.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,320 @@
 | 
				
			|||||||
 | 
					import logging
 | 
				
			||||||
 | 
					from dataclasses import dataclass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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,
 | 
				
			||||||
 | 
					    TEMP_CELSIUS,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from homeassistant.core import callback
 | 
				
			||||||
 | 
					from pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .const import HON_HVAC_MODE, HON_FAN, HON_HVAC_PROGRAM, DOMAIN
 | 
				
			||||||
 | 
					from .hon import HonEntity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonACClimateEntityDescription(ClimateEntityDescription):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonClimateEntityDescription(ClimateEntityDescription):
 | 
				
			||||||
 | 
					    mode: HVACMode = "auto"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLIMATES = {
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        HonACClimateEntityDescription(
 | 
				
			||||||
 | 
					            key="settings",
 | 
				
			||||||
 | 
					            name="Air Conditioner",
 | 
				
			||||||
 | 
					            icon="mdi:air-conditioner",
 | 
				
			||||||
 | 
					            translation_key="air_conditioner",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        HonClimateEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.tempSelZ1",
 | 
				
			||||||
 | 
					            mode=HVACMode.COOL,
 | 
				
			||||||
 | 
					            name="Fridge",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            translation_key="fridge",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonClimateEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.tempSelZ2",
 | 
				
			||||||
 | 
					            mode=HVACMode.COOL,
 | 
				
			||||||
 | 
					            name="Freezer",
 | 
				
			||||||
 | 
					            icon="mdi:snowflake-thermometer",
 | 
				
			||||||
 | 
					            translation_key="freezer",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "OV": (
 | 
				
			||||||
 | 
					        HonClimateEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.tempSel",
 | 
				
			||||||
 | 
					            mode=HVACMode.HEAT,
 | 
				
			||||||
 | 
					            name="Oven",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            translation_key="oven",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None:
 | 
				
			||||||
 | 
					    entities = []
 | 
				
			||||||
 | 
					    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
				
			||||||
 | 
					        for description in CLIMATES.get(device.appliance_type, []):
 | 
				
			||||||
 | 
					            if isinstance(description, HonACClimateEntityDescription):
 | 
				
			||||||
 | 
					                if description.key not in list(device.commands):
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                entity = HonACClimateEntity(hass, entry, device, description)
 | 
				
			||||||
 | 
					            elif isinstance(description, HonClimateEntityDescription):
 | 
				
			||||||
 | 
					                if description.key not in device.available_settings:
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                entity = HonClimateEntity(hass, entry, device, description)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            await entity.coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					            entities.append(entity)
 | 
				
			||||||
 | 
					    async_add_entities(entities)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HonACClimateEntity(HonEntity, ClimateEntity):
 | 
				
			||||||
 | 
					    def __init__(self, hass, entry, device: HonAppliance, description) -> None:
 | 
				
			||||||
 | 
					        super().__init__(hass, entry, device, description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._attr_temperature_unit = TEMP_CELSIUS
 | 
				
			||||||
 | 
					        self._attr_target_temperature_step = device.settings["settings.tempSel"].step
 | 
				
			||||||
 | 
					        self._attr_max_temp = device.settings["settings.tempSel"].max
 | 
				
			||||||
 | 
					        self._attr_min_temp = device.settings["settings.tempSel"].min
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._attr_hvac_modes = [HVACMode.OFF]
 | 
				
			||||||
 | 
					        for mode in device.settings["settings.machMode"].values:
 | 
				
			||||||
 | 
					            self._attr_hvac_modes.append(HON_HVAC_MODE[mode])
 | 
				
			||||||
 | 
					        self._attr_fan_modes = [FAN_OFF]
 | 
				
			||||||
 | 
					        for mode in device.settings["settings.windSpeed"].values:
 | 
				
			||||||
 | 
					            self._attr_fan_modes.append(HON_FAN[mode])
 | 
				
			||||||
 | 
					        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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def target_temperature(self) -> int | None:
 | 
				
			||||||
 | 
					        """Return the temperature we try to reach."""
 | 
				
			||||||
 | 
					        return int(float(self._device.get("tempSel")))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def current_temperature(self) -> float | None:
 | 
				
			||||||
 | 
					        """Return the current temperature."""
 | 
				
			||||||
 | 
					        return float(self._device.get("tempIndoor"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def hvac_mode(self) -> HVACMode | str | None:
 | 
				
			||||||
 | 
					        if self._device.get("onOffStatus") == "0":
 | 
				
			||||||
 | 
					            return HVACMode.OFF
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return HON_HVAC_MODE[self._device.get("machMode")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_hvac_mode(self, hvac_mode):
 | 
				
			||||||
 | 
					        self._attr_hvac_mode = hvac_mode
 | 
				
			||||||
 | 
					        if hvac_mode == HVACMode.OFF:
 | 
				
			||||||
 | 
					            command = "stopProgram"
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            mode = HON_HVAC_PROGRAM[hvac_mode]
 | 
				
			||||||
 | 
					            self._device.settings["startProgram.program"].value = mode
 | 
				
			||||||
 | 
					            command = "startProgram"
 | 
				
			||||||
 | 
					        await self._device.commands[command].send()
 | 
				
			||||||
 | 
					        self._device.sync_command(command, "settings")
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def fan_mode(self) -> str | None:
 | 
				
			||||||
 | 
					        """Return the fan setting."""
 | 
				
			||||||
 | 
					        return HON_FAN[self._device.get("windSpeed")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_fan_mode(self, fan_mode):
 | 
				
			||||||
 | 
					        mode_number = list(HON_FAN.values()).index(fan_mode)
 | 
				
			||||||
 | 
					        mode = list(HON_FAN.keys())[mode_number]
 | 
				
			||||||
 | 
					        self._device.settings["settings.windSpeed"].value = mode
 | 
				
			||||||
 | 
					        self._attr_fan_mode = fan_mode
 | 
				
			||||||
 | 
					        await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def swing_mode(self) -> str | None:
 | 
				
			||||||
 | 
					        """Return the swing setting."""
 | 
				
			||||||
 | 
					        horizontal = self._device.get("windDirectionHorizontal")
 | 
				
			||||||
 | 
					        vertical = self._device.get("windDirectionVertical")
 | 
				
			||||||
 | 
					        if horizontal == "7" and vertical == "8":
 | 
				
			||||||
 | 
					            return SWING_BOTH
 | 
				
			||||||
 | 
					        elif horizontal == "7":
 | 
				
			||||||
 | 
					            return SWING_HORIZONTAL
 | 
				
			||||||
 | 
					        elif vertical == "8":
 | 
				
			||||||
 | 
					            return SWING_VERTICAL
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return SWING_OFF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @callback
 | 
				
			||||||
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
 | 
					        self._attr_target_temperature = self.target_temperature
 | 
				
			||||||
 | 
					        self._attr_current_temperature = self.current_temperature
 | 
				
			||||||
 | 
					        self._attr_hvac_mode = self.hvac_mode
 | 
				
			||||||
 | 
					        self._attr_fan_mode = self.fan_mode
 | 
				
			||||||
 | 
					        self._attr_swing_mode = self.swing_mode
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HonClimateEntity(HonEntity, ClimateEntity):
 | 
				
			||||||
 | 
					    entity_description = HonClimateEntityDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, hass, entry, device: HonAppliance, description) -> None:
 | 
				
			||||||
 | 
					        super().__init__(hass, entry, device, description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._attr_temperature_unit = TEMP_CELSIUS
 | 
				
			||||||
 | 
					        self._set_temperature_bound()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._attr_supported_features = (
 | 
				
			||||||
 | 
					            ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._attr_hvac_modes = [description.mode]
 | 
				
			||||||
 | 
					        if device.get("onOffStatus"):
 | 
				
			||||||
 | 
					            self._attr_hvac_modes += [HVACMode.OFF]
 | 
				
			||||||
 | 
					            modes = []
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            modes = ["no_mode"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for mode, data in device.commands["startProgram"].categories.items():
 | 
				
			||||||
 | 
					            if mode not in data.parameters["program"].values:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            if zone := data.parameters.get("zone"):
 | 
				
			||||||
 | 
					                if self.entity_description.name.lower() in zone.values:
 | 
				
			||||||
 | 
					                    modes.append(mode)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                modes.append(mode)
 | 
				
			||||||
 | 
					        self._attr_preset_modes = modes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._handle_coordinator_update(update=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def target_temperature(self) -> int | None:
 | 
				
			||||||
 | 
					        """Return the temperature we try to reach."""
 | 
				
			||||||
 | 
					        return int(self._device.get(self.entity_description.key))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def current_temperature(self) -> int | None:
 | 
				
			||||||
 | 
					        """Return the current temperature."""
 | 
				
			||||||
 | 
					        temp_key = self.entity_description.key.split(".")[-1].replace("Sel", "")
 | 
				
			||||||
 | 
					        return int(self._device.get(temp_key))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_temperature(self, **kwargs):
 | 
				
			||||||
 | 
					        if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					        self._device.settings[self.entity_description.key].value = str(int(temperature))
 | 
				
			||||||
 | 
					        await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def hvac_mode(self) -> HVACMode | str | None:
 | 
				
			||||||
 | 
					        if self._device.get("onOffStatus") == "0":
 | 
				
			||||||
 | 
					            return HVACMode.OFF
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return self.entity_description.mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_hvac_mode(self, hvac_mode):
 | 
				
			||||||
 | 
					        if len(self.hvac_modes) <= 1:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        if hvac_mode == HVACMode.OFF:
 | 
				
			||||||
 | 
					            await self._device.commands["stopProgram"].send()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            await self._device.commands["startProgram"].send()
 | 
				
			||||||
 | 
					        self._attr_hvac_mode = hvac_mode
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def preset_mode(self) -> str | None:
 | 
				
			||||||
 | 
					        """Return the current Preset for this channel."""
 | 
				
			||||||
 | 
					        if self._device.get("onOffStatus") is not None:
 | 
				
			||||||
 | 
					            return self._device.get("programName", "")
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return self._device.get(
 | 
				
			||||||
 | 
					                f"mode{self.entity_description.key[-2:]}", "no_mode"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_preset_mode(self, preset_mode: str) -> None:
 | 
				
			||||||
 | 
					        """Set the new preset mode."""
 | 
				
			||||||
 | 
					        command = "stopProgram" if preset_mode == "no_mode" else "startProgram"
 | 
				
			||||||
 | 
					        if program := self._device.settings.get(f"{command}.program"):
 | 
				
			||||||
 | 
					            program.value = preset_mode
 | 
				
			||||||
 | 
					        if zone := self._device.settings.get(f"{command}.zone"):
 | 
				
			||||||
 | 
					            zone.value = self.entity_description.name.lower()
 | 
				
			||||||
 | 
					        self._device.sync_command(command, "settings")
 | 
				
			||||||
 | 
					        self._set_temperature_bound()
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					        await self._device.commands[command].send()
 | 
				
			||||||
 | 
					        self._attr_preset_mode = preset_mode
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _set_temperature_bound(self):
 | 
				
			||||||
 | 
					        self._attr_target_temperature_step = self._device.settings[
 | 
				
			||||||
 | 
					            self.entity_description.key
 | 
				
			||||||
 | 
					        ].step
 | 
				
			||||||
 | 
					        self._attr_max_temp = self._device.settings[self.entity_description.key].max
 | 
				
			||||||
 | 
					        self._attr_min_temp = self._device.settings[self.entity_description.key].min
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @callback
 | 
				
			||||||
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
 | 
					        self._attr_target_temperature = self.target_temperature
 | 
				
			||||||
 | 
					        self._attr_current_temperature = self.current_temperature
 | 
				
			||||||
 | 
					        self._attr_hvac_mode = self.hvac_mode
 | 
				
			||||||
 | 
					        self._attr_preset_mode = self.preset_mode
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
@ -1,7 +1,6 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import voluptuous as vol
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,13 @@
 | 
				
			|||||||
 | 
					from homeassistant.components.climate import (
 | 
				
			||||||
 | 
					    HVACMode,
 | 
				
			||||||
 | 
					    FAN_LOW,
 | 
				
			||||||
 | 
					    FAN_MEDIUM,
 | 
				
			||||||
 | 
					    FAN_HIGH,
 | 
				
			||||||
 | 
					    FAN_AUTO,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DOMAIN = "hon"
 | 
					DOMAIN = "hon"
 | 
				
			||||||
 | 
					UPDATE_INTERVAL = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PLATFORMS = [
 | 
					PLATFORMS = [
 | 
				
			||||||
    "sensor",
 | 
					    "sensor",
 | 
				
			||||||
@ -7,4 +16,176 @@ 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",
 | 
				
			||||||
 | 
					    "8": "unknown",
 | 
				
			||||||
 | 
					    "11": "WASHING_CMD&CTRL.PHASE_READY.TITLE",
 | 
				
			||||||
 | 
					    "12": "unknown",
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REF_ZONES = {
 | 
				
			||||||
 | 
					    "fridge": "REF.ZONES.FRIDGE",
 | 
				
			||||||
 | 
					    "freezer": "REF.ZONES.FREEZER",
 | 
				
			||||||
 | 
					    "vtroom1": "REF.ZONES.MY_ZONE_1",
 | 
				
			||||||
 | 
					    "fridge_freezer": ["REF.ZONES.FRIDGE", " & ", "REF.ZONES.FREEZER"],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,13 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
from datetime import timedelta
 | 
					from datetime import timedelta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon.appliance import HonAppliance
 | 
					from homeassistant.core import callback
 | 
				
			||||||
 | 
					 | 
				
			||||||
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 pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN, UPDATE_INTERVAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -15,14 +15,21 @@ _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: HonAppliance) -> None:
 | 
					    def __init__(self, hass, entry, device: HonAppliance, description=None) -> None:
 | 
				
			||||||
 | 
					        coordinator = get_coordinator(hass, device)
 | 
				
			||||||
        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._device = device
 | 
					        self._coordinator = coordinator
 | 
				
			||||||
 | 
					        self._device: HonAppliance = device
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._attr_unique_id = self._device.unique_id
 | 
					        if description is not None:
 | 
				
			||||||
 | 
					            self.entity_description = description
 | 
				
			||||||
 | 
					            self._attr_unique_id = f"{self._device.unique_id}{description.key}"
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self._attr_unique_id = self._device.unique_id
 | 
				
			||||||
 | 
					        self._handle_coordinator_update(update=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def device_info(self):
 | 
					    def device_info(self):
 | 
				
			||||||
@ -36,6 +43,11 @@ class HonEntity(CoordinatorEntity):
 | 
				
			|||||||
            sw_version=self._device.get("fwVersion", ""),
 | 
					            sw_version=self._device.get("fwVersion", ""),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @callback
 | 
				
			||||||
 | 
					    def _handle_coordinator_update(self, update: bool = True) -> None:
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonCoordinator(DataUpdateCoordinator):
 | 
					class HonCoordinator(DataUpdateCoordinator):
 | 
				
			||||||
    def __init__(self, hass, device: HonAppliance):
 | 
					    def __init__(self, hass, device: HonAppliance):
 | 
				
			||||||
@ -44,9 +56,28 @@ class HonCoordinator(DataUpdateCoordinator):
 | 
				
			|||||||
            hass,
 | 
					            hass,
 | 
				
			||||||
            _LOGGER,
 | 
					            _LOGGER,
 | 
				
			||||||
            name=device.unique_id,
 | 
					            name=device.unique_id,
 | 
				
			||||||
            update_interval=timedelta(seconds=30),
 | 
					            update_interval=timedelta(seconds=UPDATE_INTERVAL),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_coordinator(hass, appliance):
 | 
				
			||||||
 | 
					    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
				
			||||||
 | 
					    if appliance.unique_id in coordinators:
 | 
				
			||||||
 | 
					        coordinator = hass.data[DOMAIN]["coordinators"][appliance.unique_id]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        coordinator = HonCoordinator(hass, appliance)
 | 
				
			||||||
 | 
					        hass.data[DOMAIN]["coordinators"][appliance.unique_id] = coordinator
 | 
				
			||||||
 | 
					    return coordinator
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,15 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "domain": "hon",
 | 
					  "domain": "hon",
 | 
				
			||||||
  "name": "Haier hOn",
 | 
					  "name": "Haier hOn",
 | 
				
			||||||
  "codeowners": ["@Andre0512"],
 | 
					  "codeowners": [
 | 
				
			||||||
 | 
					    "@Andre0512"
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
  "config_flow": true,
 | 
					  "config_flow": true,
 | 
				
			||||||
  "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.8.0b5"],
 | 
					  "requirements": [
 | 
				
			||||||
  "version": "0.6.0-beta.5"
 | 
					    "pyhOn==0.12.4"
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  "version": "0.8.1"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,6 @@
 | 
				
			|||||||
from __future__ import annotations
 | 
					from __future__ import annotations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import Hon
 | 
					from dataclasses import dataclass
 | 
				
			||||||
from pyhon.parameter.range import HonParameterRange
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from homeassistant.components.number import (
 | 
					from homeassistant.components.number import (
 | 
				
			||||||
    NumberEntity,
 | 
					    NumberEntity,
 | 
				
			||||||
@ -11,166 +10,201 @@ from homeassistant.config_entries import ConfigEntry
 | 
				
			|||||||
from homeassistant.const import UnitOfTime, UnitOfTemperature
 | 
					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.parameter.range import HonParameterRange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonEntity, HonCoordinator
 | 
					from .hon import HonEntity, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonConfigNumberEntityDescription(NumberEntityDescription):
 | 
				
			||||||
 | 
					    entity_category: EntityCategory = EntityCategory.CONFIG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonNumberEntityDescription(NumberEntityDescription):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
 | 
					NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = {
 | 
				
			||||||
    "WM": (
 | 
					    "WM": (
 | 
				
			||||||
        NumberEntityDescription(
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
            key="startProgram.delayTime",
 | 
					            key="startProgram.delayTime",
 | 
				
			||||||
            name="Delay Time",
 | 
					            name="Delay Time",
 | 
				
			||||||
            icon="mdi:timer-plus",
 | 
					            icon="mdi:timer-plus",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        NumberEntityDescription(
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
            key="startProgram.rinseIterations",
 | 
					            key="startProgram.rinseIterations",
 | 
				
			||||||
            name="Rinse Iterations",
 | 
					            name="Rinse Iterations",
 | 
				
			||||||
            icon="mdi:rotate-right",
 | 
					            icon="mdi:rotate-right",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="rinse_iterations",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        NumberEntityDescription(
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
            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,
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="wash_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
    "TD": (
 | 
					            key="startProgram.steamLevel",
 | 
				
			||||||
        NumberEntityDescription(
 | 
					            name="Steam Level",
 | 
				
			||||||
            key="startProgram.delayTime",
 | 
					            icon="mdi:weather-dust",
 | 
				
			||||||
            name="Delay time",
 | 
					            translation_key="steam_level",
 | 
				
			||||||
            icon="mdi:timer-plus",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        NumberEntityDescription(
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
            key="startProgram.dryLevel",
 | 
					 | 
				
			||||||
            name="Dry level",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:hair-dryer",
 | 
					 | 
				
			||||||
            translation_key="tumbledryerdrylevel",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.tempLevel",
 | 
					 | 
				
			||||||
            name="Temperature level",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					 | 
				
			||||||
            translation_key="tumbledryertemplevel",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.antiCreaseTime",
 | 
					 | 
				
			||||||
            name="Anti-Crease time",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:timer",
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.sterilizationStatus",
 | 
					 | 
				
			||||||
            name="Sterilization status",
 | 
					 | 
				
			||||||
            icon="mdi:clock-start",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    "WD": (
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.delayTime",
 | 
					 | 
				
			||||||
            name="Delay Time",
 | 
					 | 
				
			||||||
            icon="mdi:timer-plus",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    "OV": (
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.delayTime",
 | 
					 | 
				
			||||||
            name="Delay time",
 | 
					 | 
				
			||||||
            icon="mdi:timer-plus",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.tempSel",
 | 
					 | 
				
			||||||
            name="Target Temperature",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.prTime",
 | 
					 | 
				
			||||||
            name="Program Duration",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:timelapse",
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    "IH": (
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.temp",
 | 
					 | 
				
			||||||
            name="Temperature",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.powerManagement",
 | 
					 | 
				
			||||||
            name="Power Management",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:timelapse",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    "DW": (
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.delayTime",
 | 
					 | 
				
			||||||
            name="Delay time",
 | 
					 | 
				
			||||||
            icon="mdi:timer-plus",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        NumberEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.waterHard",
 | 
					            key="startProgram.waterHard",
 | 
				
			||||||
            name="Water hard",
 | 
					            name="Water hard",
 | 
				
			||||||
            icon="mdi:water",
 | 
					            icon="mdi:water",
 | 
				
			||||||
 | 
					            translation_key="water_hard",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.lang",
 | 
				
			||||||
 | 
					            name="lang",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "TD": (
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.delayTime",
 | 
				
			||||||
 | 
					            name="Delay time",
 | 
				
			||||||
 | 
					            icon="mdi:timer-plus",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.tempLevel",
 | 
				
			||||||
 | 
					            name="Temperature level",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            translation_key="tumbledryertemplevel",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.dryTime",
 | 
				
			||||||
 | 
					            name="Dry Time",
 | 
				
			||||||
 | 
					            translation_key="dry_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "OV": (
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.delayTime",
 | 
				
			||||||
 | 
					            name="Delay time",
 | 
				
			||||||
 | 
					            icon="mdi:timer-plus",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.tempSel",
 | 
				
			||||||
 | 
					            name="Target Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="target_temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.prTime",
 | 
				
			||||||
 | 
					            name="Program Duration",
 | 
				
			||||||
 | 
					            icon="mdi:timelapse",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="program_duration",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "IH": (
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.temp",
 | 
				
			||||||
 | 
					            name="Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.powerManagement",
 | 
				
			||||||
 | 
					            name="Power Management",
 | 
				
			||||||
 | 
					            icon="mdi:timelapse",
 | 
				
			||||||
 | 
					            translation_key="power_management",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "DW": (
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.delayTime",
 | 
				
			||||||
 | 
					            name="Delay time",
 | 
				
			||||||
 | 
					            icon="mdi:timer-plus",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.waterHard",
 | 
				
			||||||
 | 
					            name="Water hard",
 | 
				
			||||||
 | 
					            icon="mdi:water",
 | 
				
			||||||
 | 
					            translation_key="water_hard",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        HonNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.tempSel",
 | 
				
			||||||
 | 
					            name="Target Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="target_temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        HonNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.tempSelZ1",
 | 
				
			||||||
 | 
					            name="Fridge Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="fridge_temp_sel",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.tempSelZ2",
 | 
				
			||||||
 | 
					            name="Freezer Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="freezer_temp_sel",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "HO": (
 | 
				
			||||||
 | 
					        HonNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.windSpeed",
 | 
				
			||||||
 | 
					            name="Wind speed",
 | 
				
			||||||
 | 
					            icon="mdi:fan",
 | 
				
			||||||
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonNumberEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.lightStatus",
 | 
				
			||||||
 | 
					            name="Light status",
 | 
				
			||||||
 | 
					            icon="mdi:lightbulb",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            entity_category=EntityCategory.CONFIG,
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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: Hon = hass.data[DOMAIN][entry.unique_id]
 | 
					    entities = []
 | 
				
			||||||
    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
					    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
				
			||||||
    appliances = []
 | 
					        for description in NUMBERS.get(device.appliance_type, []):
 | 
				
			||||||
    for device in hon.appliances:
 | 
					            if description.key not in device.available_settings:
 | 
				
			||||||
        if device.unique_id in coordinators:
 | 
					                continue
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
					            if isinstance(description, HonNumberEntityDescription):
 | 
				
			||||||
        else:
 | 
					                entity = HonNumberEntity(hass, entry, device, description)
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            elif isinstance(description, HonConfigNumberEntityDescription):
 | 
				
			||||||
            hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
 | 
					                entity = HonConfigNumberEntity(hass, entry, device, description)
 | 
				
			||||||
        await coordinator.async_config_entry_first_refresh()
 | 
					            else:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
        if descriptions := NUMBERS.get(device.appliance_type):
 | 
					            await entity.coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
            for description in descriptions:
 | 
					            entities.append(entity)
 | 
				
			||||||
                if not device.settings.get(description.key):
 | 
					    async_add_entities(entities)
 | 
				
			||||||
                    continue
 | 
					 | 
				
			||||||
                appliances.extend(
 | 
					 | 
				
			||||||
                    [HonNumberEntity(hass, coordinator, entry, device, description)]
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async_add_entities(appliances)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonNumberEntity(HonEntity, NumberEntity):
 | 
					class HonNumberEntity(HonEntity, NumberEntity):
 | 
				
			||||||
    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
					    entity_description: HonNumberEntityDescription
 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, hass, entry, device, description) -> None:
 | 
				
			||||||
 | 
					        super().__init__(hass, entry, device, description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					 | 
				
			||||||
        self._device = device
 | 
					 | 
				
			||||||
        self._data = device.settings[description.key]
 | 
					        self._data = device.settings[description.key]
 | 
				
			||||||
        self.entity_description = description
 | 
					 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(self._data, HonParameterRange):
 | 
					        if isinstance(self._data, HonParameterRange):
 | 
				
			||||||
            self._attr_native_max_value = self._data.max
 | 
					            self._attr_native_max_value = self._data.max
 | 
				
			||||||
            self._attr_native_min_value = self._data.min
 | 
					            self._attr_native_min_value = self._data.min
 | 
				
			||||||
@ -181,15 +215,44 @@ 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 isinstance(setting, HonParameterRange):
 | 
				
			||||||
 | 
					            setting.value = value
 | 
				
			||||||
 | 
					        command = self.entity_description.key.split(".")[0]
 | 
				
			||||||
 | 
					        await self._device.commands[command].send()
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @callback
 | 
					    @callback
 | 
				
			||||||
    def _handle_coordinator_update(self):
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
        setting = self._device.settings[self.entity_description.key]
 | 
					        setting = self._device.settings[self.entity_description.key]
 | 
				
			||||||
        if isinstance(setting, HonParameterRange):
 | 
					        if isinstance(setting, HonParameterRange):
 | 
				
			||||||
            self._attr_native_max_value = setting.max
 | 
					            self._attr_native_max_value = setting.max
 | 
				
			||||||
            self._attr_native_min_value = setting.min
 | 
					            self._attr_native_min_value = setting.min
 | 
				
			||||||
            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()
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @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 HonConfigNumberEntity(HonNumberEntity):
 | 
				
			||||||
 | 
					    entity_description: HonConfigNumberEntityDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_set_native_value(self, value: str) -> None:
 | 
				
			||||||
 | 
					        setting = self._device.settings[self.entity_description.key]
 | 
				
			||||||
 | 
					        if isinstance(setting, HonParameterRange):
 | 
				
			||||||
 | 
					            setting.value = value
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def available(self) -> bool:
 | 
				
			||||||
 | 
					        """Return True if entity is available."""
 | 
				
			||||||
 | 
					        return super(NumberEntity, self).available
 | 
				
			||||||
 | 
				
			|||||||
@ -1,157 +1,215 @@
 | 
				
			|||||||
from __future__ import annotations
 | 
					from __future__ import annotations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					from dataclasses import dataclass
 | 
				
			||||||
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, UnitOfTime, 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 pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					from pyhon.parameter.fixed import HonParameterFixed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonEntity, HonCoordinator
 | 
					from .hon import HonEntity, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonSelectEntityDescription(SelectEntityDescription):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonConfigSelectEntityDescription(SelectEntityDescription):
 | 
				
			||||||
 | 
					    entity_category: EntityCategory = EntityCategory.CONFIG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SELECTS = {
 | 
					SELECTS = {
 | 
				
			||||||
    "WM": (
 | 
					    "WM": (
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
            key="startProgram.spinSpeed",
 | 
					            key="startProgram.spinSpeed",
 | 
				
			||||||
            name="Spin speed",
 | 
					            name="Spin speed",
 | 
				
			||||||
            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(
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
            key="startProgram.temp",
 | 
					            key="startProgram.temp",
 | 
				
			||||||
            name="Temperature",
 | 
					            name="Temperature",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
            unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
					            unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
            key="startProgram.program",
 | 
					            key="startProgram.program",
 | 
				
			||||||
            name="Program",
 | 
					            name="Program",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="programs_wm",
 | 
				
			||||||
            translation_key="programs",
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "TD": (
 | 
					    "TD": (
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
            key="startProgram.program",
 | 
					            key="startProgram.program",
 | 
				
			||||||
            name="Program",
 | 
					            name="Program",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="programs_td",
 | 
				
			||||||
            translation_key="programs",
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
            key="startProgram.dryTimeMM",
 | 
					            key="startProgram.dryTimeMM",
 | 
				
			||||||
            name="Time",
 | 
					            name="Dry Time",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            icon="mdi:timer",
 | 
					            icon="mdi:timer",
 | 
				
			||||||
            unit_of_measurement=UnitOfTime.MINUTES,
 | 
					            unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="dry_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
    "WD": (
 | 
					            key="startProgram.dryLevel",
 | 
				
			||||||
        SelectEntityDescription(
 | 
					            name="Dry level",
 | 
				
			||||||
            key="startProgram.program",
 | 
					            icon="mdi:hair-dryer",
 | 
				
			||||||
            name="Program",
 | 
					            translation_key="dry_levels",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            translation_key="programs",
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "OV": (
 | 
					    "OV": (
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
            key="startProgram.program",
 | 
					            key="startProgram.program",
 | 
				
			||||||
            name="Program",
 | 
					            name="Program",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="programs_ov",
 | 
				
			||||||
            translation_key="programs",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SelectEntityDescription(
 | 
					 | 
				
			||||||
            key="startProgram.preheatStatus",
 | 
					 | 
				
			||||||
            name="Preheat",
 | 
					 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "IH": (
 | 
					    "IH": (
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
            key="startProgram.program",
 | 
					            key="startProgram.program",
 | 
				
			||||||
            name="Program",
 | 
					            name="Program",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="programs_ih",
 | 
				
			||||||
            translation_key="programs",
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "DW": (
 | 
					    "DW": (
 | 
				
			||||||
        SelectEntityDescription(
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
            key="startProgram.program",
 | 
					            key="startProgram.program",
 | 
				
			||||||
            name="Program",
 | 
					            name="Program",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
            translation_key="programs_dw",
 | 
					            translation_key="programs_dw",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.temp",
 | 
				
			||||||
 | 
					            name="Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.remainingTime",
 | 
				
			||||||
 | 
					            name="Remaining Time",
 | 
				
			||||||
 | 
					            icon="mdi:timer",
 | 
				
			||||||
 | 
					            unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        HonSelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.program",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            translation_key="programs_ac",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSelectEntityDescription(
 | 
				
			||||||
 | 
					            key="settings.humanSensingStatus",
 | 
				
			||||||
 | 
					            name="Eco Pilot",
 | 
				
			||||||
 | 
					            icon="mdi:run",
 | 
				
			||||||
 | 
					            translation_key="eco_pilot",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.program",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            translation_key="programs_ref",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSelectEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.zone",
 | 
				
			||||||
 | 
					            name="Zone",
 | 
				
			||||||
 | 
					            icon="mdi:radiobox-marked",
 | 
				
			||||||
 | 
					            translation_key="ref_zones",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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: Hon = hass.data[DOMAIN][entry.unique_id]
 | 
					    entities = []
 | 
				
			||||||
    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
					    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
				
			||||||
    appliances = []
 | 
					        for description in SELECTS.get(device.appliance_type, []):
 | 
				
			||||||
    for device in hon.appliances:
 | 
					            if description.key not in device.available_settings:
 | 
				
			||||||
        if device.unique_id in coordinators:
 | 
					                continue
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
					            if isinstance(description, HonSelectEntityDescription):
 | 
				
			||||||
        else:
 | 
					                entity = HonSelectEntity(hass, entry, device, description)
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            elif isinstance(description, HonConfigSelectEntityDescription):
 | 
				
			||||||
            hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
 | 
					                entity = HonConfigSelectEntity(hass, entry, device, description)
 | 
				
			||||||
        await coordinator.async_config_entry_first_refresh()
 | 
					            else:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
        if descriptions := SELECTS.get(device.appliance_type):
 | 
					            await entity.coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
            for description in descriptions:
 | 
					            entities.append(entity)
 | 
				
			||||||
                if not device.settings.get(description.key):
 | 
					    async_add_entities(entities)
 | 
				
			||||||
                    continue
 | 
					 | 
				
			||||||
                appliances.extend(
 | 
					 | 
				
			||||||
                    [HonSelectEntity(hass, coordinator, entry, device, description)]
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
    async_add_entities(appliances)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonSelectEntity(HonEntity, SelectEntity):
 | 
					class HonSelectEntity(HonEntity, SelectEntity):
 | 
				
			||||||
    def __init__(
 | 
					    entity_description: HonSelectEntityDescription
 | 
				
			||||||
        self, hass, coordinator, entry, device: HonAppliance, description
 | 
					 | 
				
			||||||
    ) -> None:
 | 
					 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					    def __init__(self, hass, entry, device: HonAppliance, description) -> None:
 | 
				
			||||||
        self._device = device
 | 
					        super().__init__(hass, entry, device, description)
 | 
				
			||||||
        self.entity_description = description
 | 
					 | 
				
			||||||
        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()
 | 
					        command = self.entity_description.key.split(".")[0]
 | 
				
			||||||
 | 
					        await self._device.commands[command].send()
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @callback
 | 
					    @callback
 | 
				
			||||||
    def _handle_coordinator_update(self):
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
        setting = self._device.settings[self.entity_description.key]
 | 
					        setting = self._device.settings.get(self.entity_description.key)
 | 
				
			||||||
        if not isinstance(
 | 
					        if setting is None:
 | 
				
			||||||
            self._device.settings[self.entity_description.key], HonParameterFixed
 | 
					            self._attr_available = False
 | 
				
			||||||
        ):
 | 
					            self._attr_options: list[str] = []
 | 
				
			||||||
            self._attr_options: list[str] = setting.values
 | 
					            self._attr_native_value = None
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self._attr_options = [setting.value]
 | 
					            self._attr_available = True
 | 
				
			||||||
        self._attr_native_value = setting.value
 | 
					            self._attr_options: list[str] = setting.values
 | 
				
			||||||
        self.async_write_ha_state()
 | 
					            self._attr_native_value = setting.value
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @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 HonConfigSelectEntity(HonSelectEntity):
 | 
				
			||||||
 | 
					    entity_description: HonConfigSelectEntityDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_select_option(self, option: str) -> None:
 | 
				
			||||||
 | 
					        self._device.settings[self.entity_description.key].value = option
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def available(self) -> bool:
 | 
				
			||||||
 | 
					        """Return True if entity is available."""
 | 
				
			||||||
 | 
					        return super(SelectEntity, self).available
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					from dataclasses import dataclass
 | 
				
			||||||
from pyhon import Hon
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from homeassistant.components.sensor import (
 | 
					from homeassistant.components.sensor import (
 | 
				
			||||||
    SensorEntity,
 | 
					    SensorEntity,
 | 
				
			||||||
@ -9,6 +8,7 @@ from homeassistant.components.sensor import (
 | 
				
			|||||||
    SensorEntityDescription,
 | 
					    SensorEntityDescription,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from homeassistant.config_entries import ConfigEntry
 | 
					from homeassistant.config_entries import ConfigEntry
 | 
				
			||||||
 | 
					from homeassistant.const import PERCENTAGE
 | 
				
			||||||
from homeassistant.const import (
 | 
					from homeassistant.const import (
 | 
				
			||||||
    REVOLUTIONS_PER_MINUTE,
 | 
					    REVOLUTIONS_PER_MINUTE,
 | 
				
			||||||
    UnitOfEnergy,
 | 
					    UnitOfEnergy,
 | 
				
			||||||
@ -20,330 +20,643 @@ from homeassistant.const import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
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 pyhon.appliance import HonAppliance
 | 
				
			||||||
from homeassistant.const import PERCENTAGE
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from . import const
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonCoordinator, HonEntity
 | 
					from .hon import HonEntity, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonConfigSensorEntityDescription(SensorEntityDescription):
 | 
				
			||||||
 | 
					    entity_category: EntityCategory = EntityCategory.CONFIG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonSensorEntityDescription(SensorEntityDescription):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
 | 
					SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
 | 
				
			||||||
    "WM": (
 | 
					    "WM": (
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="prPhase",
 | 
				
			||||||
 | 
					            name="Program Phase",
 | 
				
			||||||
 | 
					            icon="mdi:washing-machine",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="program_phases_wm",
 | 
				
			||||||
 | 
					            options=list(const.WASHING_PR_PHASE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            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(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            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(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            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(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="currentElectricityUsed",
 | 
					            key="currentElectricityUsed",
 | 
				
			||||||
            name="Current Electricity Used",
 | 
					            name="Current Electricity Used",
 | 
				
			||||||
            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(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            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(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="startProgram.weight",
 | 
					            key="startProgram.weight",
 | 
				
			||||||
            name="Suggested weight",
 | 
					            name="Suggested weight",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            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(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            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(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
 | 
					            key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="remainingTimeMM",
 | 
					            key="remainingTimeMM",
 | 
				
			||||||
            name="Remaining Time",
 | 
					            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,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="spinSpeed",
 | 
					            key="spinSpeed",
 | 
				
			||||||
            name="Spin Speed",
 | 
					            name="Spin Speed",
 | 
				
			||||||
            icon="mdi:speedometer",
 | 
					            icon="mdi:speedometer",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    "TD": (
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="machMode",
 | 
					 | 
				
			||||||
            name="Machine Status",
 | 
					 | 
				
			||||||
            icon="mdi:information",
 | 
					 | 
				
			||||||
            translation_key="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,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="delayTime",
 | 
					 | 
				
			||||||
            name="Start Time",
 | 
					 | 
				
			||||||
            icon="mdi:clock-start",
 | 
					 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="prCode",
 | 
					 | 
				
			||||||
            name="Program",
 | 
					 | 
				
			||||||
            icon="mdi:tumble-dryer",
 | 
					 | 
				
			||||||
            translation_key="tumbledryerprogram",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="prPhase",
 | 
					 | 
				
			||||||
            name="Program Phase",
 | 
					 | 
				
			||||||
            icon="mdi:tumble-dryer",
 | 
					 | 
				
			||||||
            translation_key="tumbledryerprogramphase",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="dryLevel",
 | 
					 | 
				
			||||||
            name="Dry level",
 | 
					 | 
				
			||||||
            icon="mdi:hair-dryer",
 | 
					 | 
				
			||||||
            translation_key="tumbledryerdrylevel",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="tempLevel",
 | 
					 | 
				
			||||||
            name="Temperature level",
 | 
					 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					 | 
				
			||||||
            translation_key="tumbledryertemplevel",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    "WD": (
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="machMode",
 | 
					 | 
				
			||||||
            name="Machine Status",
 | 
					 | 
				
			||||||
            icon="mdi:information",
 | 
					 | 
				
			||||||
            translation_key="mode",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="spinSpeed",
 | 
					 | 
				
			||||||
            name="Spin Speed",
 | 
					 | 
				
			||||||
            icon="mdi:fast-forward-outline",
 | 
					 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					 | 
				
			||||||
            native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
 | 
					            native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
 | 
				
			||||||
 | 
					            translation_key="spin_speed",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="remainingTimeMM",
 | 
					            key="startProgram.energyLabel",
 | 
				
			||||||
 | 
					            name="Energy Label",
 | 
				
			||||||
 | 
					            icon="mdi:lightning-bolt-circle",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            translation_key="energy_label",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.liquidDetergentDose",
 | 
				
			||||||
 | 
					            name="Liquid Detergent Dose",
 | 
				
			||||||
 | 
					            icon="mdi:cup-water",
 | 
				
			||||||
 | 
					            translation_key="det_liquid",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.powderDetergentDose",
 | 
				
			||||||
 | 
					            name="Powder Detergent Dose",
 | 
				
			||||||
 | 
					            icon="mdi:cup",
 | 
				
			||||||
 | 
					            translation_key="det_dust",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.remainingTime",
 | 
				
			||||||
            name="Remaining Time",
 | 
					            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,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="prCode",
 | 
					 | 
				
			||||||
            name="Current Program",
 | 
					 | 
				
			||||||
            icon="mdi:tumble-dryer",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="prPhase",
 | 
					 | 
				
			||||||
            name="Program Phase",
 | 
					 | 
				
			||||||
            icon="mdi:tumble-dryer",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="dryLevel",
 | 
					 | 
				
			||||||
            name="Dry level",
 | 
					 | 
				
			||||||
            icon="mdi:hair-dryer",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        SensorEntityDescription(
 | 
					 | 
				
			||||||
            key="dirtyLevel",
 | 
					            key="dirtyLevel",
 | 
				
			||||||
            name="Dirt level",
 | 
					            name="Dirt level",
 | 
				
			||||||
            icon="mdi:liquid-spot",
 | 
					            icon="mdi:liquid-spot",
 | 
				
			||||||
 | 
					            translation_key="dirt_level",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="steamLevel",
 | 
					            key="startProgram.suggestedLoadW",
 | 
				
			||||||
            name="Steam level",
 | 
					            name="Suggested Load",
 | 
				
			||||||
            icon="mdi:smoke",
 | 
					            icon="mdi:weight-kilogram",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfMass.KILOGRAMS,
 | 
				
			||||||
 | 
					            translation_key="suggested_load",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="temp",
 | 
					            key="temp",
 | 
				
			||||||
            name="Current Temperature",
 | 
					            name="Current Temperature",
 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="programName",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            icon="mdi:play",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="programs_wm",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "OV": (
 | 
					    "TD": (
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="machMode",
 | 
				
			||||||
 | 
					            name="Machine Status",
 | 
				
			||||||
 | 
					            icon="mdi:information",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="washing_modes",
 | 
				
			||||||
 | 
					            options=list(const.MACH_MODE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="remainingTimeMM",
 | 
					            key="remainingTimeMM",
 | 
				
			||||||
            name="Remaining Time",
 | 
					            name="Remaining Time",
 | 
				
			||||||
            icon="mdi:timer",
 | 
					            icon="mdi:timer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="delayTime",
 | 
					            key="delayTime",
 | 
				
			||||||
            name="Start Time",
 | 
					            name="Start Time",
 | 
				
			||||||
            icon="mdi:clock-start",
 | 
					            icon="mdi:clock-start",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="temp",
 | 
					            key="programName",
 | 
				
			||||||
            name="Temperature",
 | 
					            name="Program",
 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					            icon="mdi:play",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="programs_td",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="tempSel",
 | 
					            key="prPhase",
 | 
				
			||||||
            name="Temperature Selected",
 | 
					            name="Program Phase",
 | 
				
			||||||
 | 
					            icon="mdi:washing-machine",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="program_phases_td",
 | 
				
			||||||
 | 
					            options=list(const.TUMBLE_DRYER_PR_PHASE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="dryLevel",
 | 
				
			||||||
 | 
					            name="Dry level",
 | 
				
			||||||
 | 
					            icon="mdi:hair-dryer",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="dry_levels",
 | 
				
			||||||
 | 
					            options=list(const.TUMBLE_DRYER_DRY_LEVEL),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempLevel",
 | 
				
			||||||
 | 
					            name="Temperature level",
 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            translation_key="tumbledryertemplevel",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.suggestedLoadD",
 | 
				
			||||||
 | 
					            name="Suggested Load",
 | 
				
			||||||
 | 
					            icon="mdi:weight-kilogram",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfMass.KILOGRAMS,
 | 
				
			||||||
 | 
					            translation_key="suggested_load",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.energyLabel",
 | 
				
			||||||
 | 
					            name="Energy Label",
 | 
				
			||||||
 | 
					            icon="mdi:lightning-bolt-circle",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            translation_key="energy_label",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.steamLevel",
 | 
				
			||||||
 | 
					            name="Steam level",
 | 
				
			||||||
 | 
					            icon="mdi:smoke",
 | 
				
			||||||
 | 
					            translation_key="steam_level",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="steamLevel",
 | 
				
			||||||
 | 
					            name="Steam level",
 | 
				
			||||||
 | 
					            icon="mdi:smoke",
 | 
				
			||||||
 | 
					            translation_key="steam_level",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="steamType",
 | 
				
			||||||
 | 
					            name="Steam Type",
 | 
				
			||||||
 | 
					            icon="mdi:weather-dust",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "IH": (
 | 
					    "OV": (
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="remainingTimeMM",
 | 
					            key="remainingTimeMM",
 | 
				
			||||||
            name="Remaining Time",
 | 
					            name="Remaining Time",
 | 
				
			||||||
            icon="mdi:timer",
 | 
					            icon="mdi:timer",
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="delayTime",
 | 
				
			||||||
 | 
					            name="Start Time",
 | 
				
			||||||
 | 
					            icon="mdi:clock-start",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="delay_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="temp",
 | 
				
			||||||
 | 
					            name="Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempSel",
 | 
				
			||||||
 | 
					            name="Temperature Selected",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            translation_key="target_temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="programName",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            icon="mdi:play",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="programs_ov",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "IH": (
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="remainingTimeMM",
 | 
				
			||||||
 | 
					            name="Remaining Time",
 | 
				
			||||||
 | 
					            icon="mdi:timer",
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="temp",
 | 
					            key="temp",
 | 
				
			||||||
            name="Temperature",
 | 
					            name="Temperature",
 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					            translation_key="temperature",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="power",
 | 
				
			||||||
 | 
					            name="Power",
 | 
				
			||||||
 | 
					            icon="mdi:lightning-bolt",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            translation_key="power",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="programName",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            icon="mdi:play",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="programs_ih",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(key="errors", name="Error", icon="mdi:math-log"),
 | 
					 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "DW": (
 | 
					    "DW": (
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="startProgram.ecoIndex",
 | 
					            key="startProgram.ecoIndex",
 | 
				
			||||||
            name="Eco Index",
 | 
					            name="Eco Index",
 | 
				
			||||||
            icon="mdi:sprout",
 | 
					            icon="mdi:sprout",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="startProgram.waterEfficiency",
 | 
					            key="startProgram.waterEfficiency",
 | 
				
			||||||
            name="Water Efficiency",
 | 
					            name="Water Efficiency",
 | 
				
			||||||
            icon="mdi:water",
 | 
					            icon="mdi:water",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="water_efficiency",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="startProgram.waterSaving",
 | 
					            key="startProgram.waterSaving",
 | 
				
			||||||
            name="Water Saving",
 | 
					            name="Water Saving",
 | 
				
			||||||
            icon="mdi:water-percent",
 | 
					            icon="mdi:water-percent",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            native_unit_of_measurement=PERCENTAGE,
 | 
					            native_unit_of_measurement=PERCENTAGE,
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="water_saving",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="startProgram.temp",
 | 
					            key="startProgram.temp",
 | 
				
			||||||
            name="Temperature",
 | 
					            name="Temperature",
 | 
				
			||||||
            icon="mdi:thermometer",
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="temperature",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="startProgram.energyLabel",
 | 
					            key="startProgram.energyLabel",
 | 
				
			||||||
            name="Energy Label",
 | 
					            name="Energy Label",
 | 
				
			||||||
            icon="mdi:lightning-bolt-circle",
 | 
					            icon="mdi:lightning-bolt-circle",
 | 
				
			||||||
            state_class=SensorStateClass.MEASUREMENT,
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="energy_label",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonConfigSensorEntityDescription(
 | 
				
			||||||
            key="startProgram.remainingTime",
 | 
					            key="startProgram.remainingTime",
 | 
				
			||||||
            name="Time",
 | 
					            name="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="duration",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="machMode",
 | 
					            key="machMode",
 | 
				
			||||||
            name="Machine Status",
 | 
					            name="Machine Status",
 | 
				
			||||||
            icon="mdi:information",
 | 
					            icon="mdi:information",
 | 
				
			||||||
            translation_key="mode_dw",
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="washing_modes",
 | 
				
			||||||
 | 
					            options=list(const.MACH_MODE),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
 | 
					            key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        SensorEntityDescription(
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
            key="remainingTimeMM",
 | 
					            key="remainingTimeMM",
 | 
				
			||||||
            name="Remaining Time",
 | 
					            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,
 | 
				
			||||||
 | 
					            translation_key="remaining_time",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="prPhase",
 | 
				
			||||||
 | 
					            name="Program Phase",
 | 
				
			||||||
 | 
					            icon="mdi:washing-machine",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="program_phases_dw",
 | 
				
			||||||
 | 
					            options=list(const.DISHWASHER_PR_PHASE),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="programName",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            icon="mdi:play",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="programs_dw",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempAirOutdoor",
 | 
				
			||||||
 | 
					            name="Air Temperature Outdoor",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempCoilerIndoor",
 | 
				
			||||||
 | 
					            name="Coiler Temperature Indoor",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempCoilerOutdoor",
 | 
				
			||||||
 | 
					            name="Coiler Temperature Outside",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempDefrostOutdoor",
 | 
				
			||||||
 | 
					            name="Defrost Temperature Outdoor",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempInAirOutdoor",
 | 
				
			||||||
 | 
					            name="In Air Temperature Outdoor",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempIndoor",
 | 
				
			||||||
 | 
					            name="Indoor Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempOutdoor",
 | 
				
			||||||
 | 
					            name="Outdoor Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="tempSel",
 | 
				
			||||||
 | 
					            name="Selected Temperature",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.TEMPERATURE,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="programName",
 | 
				
			||||||
 | 
					            name="Program",
 | 
				
			||||||
 | 
					            icon="mdi:play",
 | 
				
			||||||
 | 
					            device_class=SensorDeviceClass.ENUM,
 | 
				
			||||||
 | 
					            translation_key="programs_ac",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="errors", name="Error", icon="mdi:math-log", translation_key="errors"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "HO": (
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="delayTime",
 | 
				
			||||||
 | 
					            name="Delay time",
 | 
				
			||||||
 | 
					            icon="mdi:clock-start",
 | 
				
			||||||
 | 
					            state_class=SensorStateClass.MEASUREMENT,
 | 
				
			||||||
 | 
					            native_unit_of_measurement=UnitOfTime.MINUTES,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="delayTimeStatus",
 | 
				
			||||||
 | 
					            name="Delay time status",
 | 
				
			||||||
 | 
					            icon="mdi:clock-start",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="errors",
 | 
				
			||||||
 | 
					            name="Errors",
 | 
				
			||||||
 | 
					            icon="mdi:alert-circle",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="filterCleaningAlarmStatus",
 | 
				
			||||||
 | 
					            name="Filter Cleaning Alarm Status",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="filterCleaningStatus",
 | 
				
			||||||
 | 
					            name="Filter Cleaning Status",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="lastWorkTime",
 | 
				
			||||||
 | 
					            name="Last Work Time",
 | 
				
			||||||
 | 
					            icon="mdi:clock-start",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="lightStatus",
 | 
				
			||||||
 | 
					            name="Light Status",
 | 
				
			||||||
 | 
					            icon="mdi:lightbulb",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="machMode",
 | 
				
			||||||
 | 
					            name="Mach Mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="onOffStatus",
 | 
				
			||||||
 | 
					            name="On / Off Status",
 | 
				
			||||||
 | 
					            icon="mdi:lightbulb",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="quickDelayTimeStatus",
 | 
				
			||||||
 | 
					            name="Quick Delay Time Status",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="rgbLightColors",
 | 
				
			||||||
 | 
					            name="RGB Light Color",
 | 
				
			||||||
 | 
					            icon="mdi:lightbulb",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="rgbLightStatus",
 | 
				
			||||||
 | 
					            name="RGB Light Status",
 | 
				
			||||||
 | 
					            icon="mdi:lightbulb",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSensorEntityDescription(
 | 
				
			||||||
 | 
					            key="windSpeed",
 | 
				
			||||||
 | 
					            name="Wind Speed",
 | 
				
			||||||
 | 
					            icon="mdi:fan",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					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: Hon = hass.data[DOMAIN][entry.unique_id]
 | 
					    entities = []
 | 
				
			||||||
    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
					    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
				
			||||||
    appliances = []
 | 
					        for description in SENSORS.get(device.appliance_type, []):
 | 
				
			||||||
    for device in hon.appliances:
 | 
					            if isinstance(description, HonSensorEntityDescription):
 | 
				
			||||||
        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 := SENSORS.get(device.appliance_type):
 | 
					 | 
				
			||||||
            for description in descriptions:
 | 
					 | 
				
			||||||
                if not device.get(description.key):
 | 
					                if not device.get(description.key):
 | 
				
			||||||
                    _LOGGER.warning(
 | 
					 | 
				
			||||||
                        "[%s] Can't setup %s", device.appliance_type, description.key
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
                appliances.extend(
 | 
					                entity = HonSensorEntity(hass, entry, device, description)
 | 
				
			||||||
                    [HonSensorEntity(hass, coordinator, entry, device, description)]
 | 
					            elif isinstance(description, HonConfigSensorEntityDescription):
 | 
				
			||||||
                )
 | 
					                if description.key not in device.available_settings:
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                entity = HonConfigSensorEntity(hass, entry, device, description)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            await entity.coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					            entities.append(entity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async_add_entities(appliances)
 | 
					    async_add_entities(entities)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonSensorEntity(HonEntity, SensorEntity):
 | 
					class HonSensorEntity(HonEntity, SensorEntity):
 | 
				
			||||||
    def __init__(self, hass, coordinator, entry, device, description) -> None:
 | 
					    entity_description: HonSensorEntityDescription
 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					    def __init__(self, hass, entry, device: HonAppliance, description):
 | 
				
			||||||
 | 
					        super().__init__(hass, entry, device, description)
 | 
				
			||||||
        self.entity_description = description
 | 
					        if self.entity_description.key == "programName":
 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					            self._attr_options = self._device.settings.get(
 | 
				
			||||||
 | 
					                "startProgram.program"
 | 
				
			||||||
    @property
 | 
					            ).values + ["No Program"]
 | 
				
			||||||
    def native_value(self) -> StateType:
 | 
					 | 
				
			||||||
        return self._device.get(self.entity_description.key, "")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @callback
 | 
					    @callback
 | 
				
			||||||
    def _handle_coordinator_update(self):
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
        self._attr_native_value = self._device.get(self.entity_description.key, "")
 | 
					        value = self._device.get(self.entity_description.key, "")
 | 
				
			||||||
        self.async_write_ha_state()
 | 
					        if not value and self.entity_description.state_class is not None:
 | 
				
			||||||
 | 
					            self._attr_native_value = 0
 | 
				
			||||||
 | 
					        self._attr_native_value = value
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HonConfigSensorEntity(HonEntity, SensorEntity):
 | 
				
			||||||
 | 
					    entity_description: HonConfigSensorEntityDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @callback
 | 
				
			||||||
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
 | 
					        value = self._device.settings.get(self.entity_description.key, None)
 | 
				
			||||||
 | 
					        if self.entity_description.state_class is not None:
 | 
				
			||||||
 | 
					            if value and value.value:
 | 
				
			||||||
 | 
					                self._attr_native_value = (
 | 
				
			||||||
 | 
					                    float(value.value) if "." in str(value.value) else int(value.value)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                self._attr_native_value = 0
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self._attr_native_value = value.value
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,17 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
from dataclasses import dataclass
 | 
					from dataclasses import dataclass
 | 
				
			||||||
 | 
					from datetime import datetime, timedelta
 | 
				
			||||||
from typing import Any
 | 
					from typing import Any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 Hon
 | 
					from homeassistant.core import callback
 | 
				
			||||||
from pyhon.appliance import HonAppliance
 | 
					from pyhon.parameter.base import HonParameter
 | 
				
			||||||
from pyhon.parameter.range import HonParameterRange
 | 
					from pyhon.parameter.range import HonParameterRange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .const import DOMAIN
 | 
					from .const import DOMAIN
 | 
				
			||||||
from .hon import HonCoordinator, HonEntity
 | 
					from .hon import HonEntity, unique_entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,195 +23,457 @@ class HonSwitchEntityDescriptionMixin:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@dataclass
 | 
					@dataclass
 | 
				
			||||||
class HonSwitchEntityDescription(
 | 
					class HonControlSwitchEntityDescription(
 | 
				
			||||||
    HonSwitchEntityDescriptionMixin, SwitchEntityDescription
 | 
					    HonSwitchEntityDescriptionMixin, SwitchEntityDescription
 | 
				
			||||||
):
 | 
					):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HonSwitchEntityDescription(SwitchEntityDescription):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dataclass
 | 
				
			||||||
 | 
					class HonConfigSwitchEntityDescription(SwitchEntityDescription):
 | 
				
			||||||
 | 
					    entity_category: EntityCategory = EntityCategory.CONFIG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
 | 
					SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = {
 | 
				
			||||||
    "WM": (
 | 
					    "WM": (
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonControlSwitchEntityDescription(
 | 
				
			||||||
            key="active",
 | 
					            key="active",
 | 
				
			||||||
            name="Washing Machine",
 | 
					            name="Washing Machine",
 | 
				
			||||||
            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(
 | 
					        HonControlSwitchEntityDescription(
 | 
				
			||||||
            key="pause",
 | 
					            key="pause",
 | 
				
			||||||
            name="Pause Washing Machine",
 | 
					            name="Pause Washing Machine",
 | 
				
			||||||
            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(
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.delayStatus",
 | 
					            key="startProgram.delayStatus",
 | 
				
			||||||
            name="Delay Status",
 | 
					            name="Delay Status",
 | 
				
			||||||
            icon="mdi:timer-check",
 | 
					            icon="mdi:timer-check",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="delay_time",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
            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,
 | 
					            translation_key="prewash",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.permanentPressStatus",
 | 
				
			||||||
 | 
					            name="Keep Fresh",
 | 
				
			||||||
 | 
					            icon="mdi:refresh-circle",
 | 
				
			||||||
 | 
					            translation_key="keep_fresh",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.autoSoftenerStatus",
 | 
				
			||||||
 | 
					            name="Auto Dose Softener",
 | 
				
			||||||
 | 
					            icon="mdi:teddy-bear",
 | 
				
			||||||
 | 
					            translation_key="auto_dose_softener",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.autoDetergentStatus",
 | 
				
			||||||
 | 
					            name="Auto Dose Detergent",
 | 
				
			||||||
 | 
					            icon="mdi:cup",
 | 
				
			||||||
 | 
					            translation_key="auto_dose_detergent",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.acquaplus",
 | 
				
			||||||
 | 
					            name="Acqua Plus",
 | 
				
			||||||
 | 
					            icon="mdi:water-plus",
 | 
				
			||||||
 | 
					            translation_key="acqua_plus",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.extraRinse1",
 | 
				
			||||||
 | 
					            name="Extra Rinse 1",
 | 
				
			||||||
 | 
					            icon="mdi:numeric-1-box-multiple-outline",
 | 
				
			||||||
 | 
					            translation_key="extra_rinse_1",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.extraRinse2",
 | 
				
			||||||
 | 
					            name="Extra Rinse 2",
 | 
				
			||||||
 | 
					            icon="mdi:numeric-2-box-multiple-outline",
 | 
				
			||||||
 | 
					            translation_key="extra_rinse_2",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.extraRinse3",
 | 
				
			||||||
 | 
					            name="Extra Rinse 3",
 | 
				
			||||||
 | 
					            icon="mdi:numeric-3-box-multiple-outline",
 | 
				
			||||||
 | 
					            translation_key="extra_rinse_3",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.goodNight",
 | 
				
			||||||
 | 
					            name="Good Night",
 | 
				
			||||||
 | 
					            icon="mdi:weather-night",
 | 
				
			||||||
 | 
					            translation_key="good_night",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "TD": (
 | 
					    "TD": (
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonControlSwitchEntityDescription(
 | 
				
			||||||
            key="active",
 | 
					            key="active",
 | 
				
			||||||
            name="Tumble Dryer",
 | 
					            name="Tumble Dryer",
 | 
				
			||||||
            icon="mdi:tumble-dryer",
 | 
					            icon="mdi:tumble-dryer",
 | 
				
			||||||
            turn_on_key="startProgram",
 | 
					            turn_on_key="startProgram",
 | 
				
			||||||
            turn_off_key="stopProgram",
 | 
					            turn_off_key="stopProgram",
 | 
				
			||||||
 | 
					            translation_key="tumble_dryer",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonControlSwitchEntityDescription(
 | 
				
			||||||
            key="pause",
 | 
					            key="pause",
 | 
				
			||||||
            name="Pause Tumble Dryer",
 | 
					            name="Pause Tumble Dryer",
 | 
				
			||||||
            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",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.sterilizationStatus",
 | 
				
			||||||
 | 
					            name="Sterilization",
 | 
				
			||||||
 | 
					            icon="mdi:clock-start",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.antiCreaseTime",
 | 
				
			||||||
 | 
					            name="Anti-Crease",
 | 
				
			||||||
 | 
					            icon="mdi:timer",
 | 
				
			||||||
 | 
					            translation_key="anti_crease",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.anticrease",
 | 
				
			||||||
 | 
					            name="Anti-Crease",
 | 
				
			||||||
 | 
					            icon="mdi:timer",
 | 
				
			||||||
 | 
					            translation_key="anti_crease",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "OV": (
 | 
				
			||||||
 | 
					        HonControlSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="active",
 | 
				
			||||||
 | 
					            name="Oven",
 | 
				
			||||||
 | 
					            icon="mdi:toaster-oven",
 | 
				
			||||||
 | 
					            turn_on_key="startProgram",
 | 
				
			||||||
 | 
					            turn_off_key="stopProgram",
 | 
				
			||||||
 | 
					            translation_key="oven",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="startProgram.preheatStatus",
 | 
				
			||||||
 | 
					            name="Preheat",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer-chevron-up",
 | 
				
			||||||
 | 
					            translation_key="preheat",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "WD": (
 | 
					    "WD": (
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonControlSwitchEntityDescription(
 | 
				
			||||||
            key="active",
 | 
					            key="active",
 | 
				
			||||||
            name="Washing Machine",
 | 
					            name="Washer Dryer",
 | 
				
			||||||
            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="washer_dryer",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonControlSwitchEntityDescription(
 | 
				
			||||||
            key="pause",
 | 
					            key="pause",
 | 
				
			||||||
            name="Pause Washing Machine",
 | 
					            name="Pause Washer Dryer",
 | 
				
			||||||
            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",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    "DW": (
 | 
					    "DW": (
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonControlSwitchEntityDescription(
 | 
				
			||||||
            key="active",
 | 
					            key="active",
 | 
				
			||||||
            name="Dish Washer",
 | 
					            name="Dish Washer",
 | 
				
			||||||
            icon="mdi:dishwasher",
 | 
					            icon="mdi:dishwasher",
 | 
				
			||||||
            turn_on_key="startProgram",
 | 
					            turn_on_key="startProgram",
 | 
				
			||||||
            turn_off_key="stopProgram",
 | 
					            turn_off_key="stopProgram",
 | 
				
			||||||
 | 
					            translation_key="dish_washer",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.extraDry",
 | 
					            key="startProgram.extraDry",
 | 
				
			||||||
            name="Extra Dry",
 | 
					            name="Extra Dry",
 | 
				
			||||||
            icon="mdi:hair-dryer",
 | 
					            icon="mdi:hair-dryer",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="extra_dry",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.halfLoad",
 | 
					            key="startProgram.halfLoad",
 | 
				
			||||||
            name="Half Load",
 | 
					            name="Half Load",
 | 
				
			||||||
            icon="mdi:fraction-one-half",
 | 
					            icon="mdi:fraction-one-half",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="half_load",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.openDoor",
 | 
					            key="startProgram.openDoor",
 | 
				
			||||||
            name="Open Door",
 | 
					            name="Open Door",
 | 
				
			||||||
            icon="mdi:door-open",
 | 
					            icon="mdi:door-open",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="open_door",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.threeInOne",
 | 
					            key="startProgram.threeInOne",
 | 
				
			||||||
            name="Three in One",
 | 
					            name="Three in One",
 | 
				
			||||||
            icon="mdi:numeric-3-box-outline",
 | 
					            icon="mdi:numeric-3-box-outline",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="three_in_one",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.ecoExpress",
 | 
					            key="startProgram.ecoExpress",
 | 
				
			||||||
            name="Eco Express",
 | 
					            name="Eco Express",
 | 
				
			||||||
            icon="mdi:sprout",
 | 
					            icon="mdi:sprout",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="eco",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        HonSwitchEntityDescription(
 | 
					        HonConfigSwitchEntityDescription(
 | 
				
			||||||
            key="startProgram.addDish",
 | 
					            key="startProgram.addDish",
 | 
				
			||||||
            name="Add Dish",
 | 
					            name="Add Dish",
 | 
				
			||||||
            icon="mdi:silverware-fork-knife",
 | 
					            icon="mdi:silverware-fork-knife",
 | 
				
			||||||
            entity_category=EntityCategory.CONFIG,
 | 
					            translation_key="add_dish",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="buzzerDisabled",
 | 
				
			||||||
 | 
					            name="Buzzer Disabled",
 | 
				
			||||||
 | 
					            icon="mdi:volume-off",
 | 
				
			||||||
 | 
					            translation_key="buzzer",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "AC": (
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="10degreeHeatingStatus",
 | 
				
			||||||
 | 
					            name="10° Heating",
 | 
				
			||||||
 | 
					            icon="mdi:heat-wave",
 | 
				
			||||||
 | 
					            translation_key="10_degree_heating",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="echoStatus",
 | 
				
			||||||
 | 
					            name="Echo",
 | 
				
			||||||
 | 
					            icon="mdi:account-voice",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="ecoMode",
 | 
				
			||||||
 | 
					            name="Eco Mode",
 | 
				
			||||||
 | 
					            translation_key="eco_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="healthMode",
 | 
				
			||||||
 | 
					            name="Health Mode",
 | 
				
			||||||
 | 
					            icon="mdi:medication-outline",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="muteStatus",
 | 
				
			||||||
 | 
					            name="Mute",
 | 
				
			||||||
 | 
					            icon="mdi:volume-off",
 | 
				
			||||||
 | 
					            translation_key="mute_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="rapidMode",
 | 
				
			||||||
 | 
					            name="Rapid Mode",
 | 
				
			||||||
 | 
					            icon="mdi:run-fast",
 | 
				
			||||||
 | 
					            translation_key="rapid_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="screenDisplayStatus",
 | 
				
			||||||
 | 
					            name="Screen Display",
 | 
				
			||||||
 | 
					            icon="mdi:monitor-small",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="selfCleaning56Status",
 | 
				
			||||||
 | 
					            name="Self Cleaning 56",
 | 
				
			||||||
 | 
					            icon="mdi:air-filter",
 | 
				
			||||||
 | 
					            translation_key="self_clean_56",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="selfCleaningStatus",
 | 
				
			||||||
 | 
					            name="Self Cleaning",
 | 
				
			||||||
 | 
					            icon="mdi:air-filter",
 | 
				
			||||||
 | 
					            translation_key="self_clean",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="silentSleepStatus",
 | 
				
			||||||
 | 
					            name="Silent Sleep",
 | 
				
			||||||
 | 
					            icon="mdi:bed",
 | 
				
			||||||
 | 
					            translation_key="silent_mode",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    "REF": (
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="intelligenceMode",
 | 
				
			||||||
 | 
					            name="Auto-Set Mode",
 | 
				
			||||||
 | 
					            icon="mdi:thermometer-auto",
 | 
				
			||||||
 | 
					            translation_key="auto_set",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="quickModeZ1",
 | 
				
			||||||
 | 
					            name="Super Freeze",
 | 
				
			||||||
 | 
					            icon="mdi:snowflake-variant",
 | 
				
			||||||
 | 
					            translation_key="super_freeze",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="quickModeZ2",
 | 
				
			||||||
 | 
					            name="Super Cool",
 | 
				
			||||||
 | 
					            icon="mdi:snowflake",
 | 
				
			||||||
 | 
					            translation_key="super_cool",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        HonSwitchEntityDescription(
 | 
				
			||||||
 | 
					            key="holidayMode",
 | 
				
			||||||
 | 
					            name="Holiday Mode",
 | 
				
			||||||
 | 
					            icon="mdi:palm-tree",
 | 
				
			||||||
 | 
					            translation_key="holiday_mode",
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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: Hon = hass.data[DOMAIN][entry.unique_id]
 | 
					    entities = []
 | 
				
			||||||
    coordinators = hass.data[DOMAIN]["coordinators"]
 | 
					    for device in hass.data[DOMAIN][entry.unique_id].appliances:
 | 
				
			||||||
    appliances = []
 | 
					        for description in SWITCHES.get(device.appliance_type, []):
 | 
				
			||||||
    for device in hon.appliances:
 | 
					            if isinstance(description, HonConfigSwitchEntityDescription):
 | 
				
			||||||
        if device.unique_id in coordinators:
 | 
					                if description.key not in device.available_settings:
 | 
				
			||||||
            coordinator = hass.data[DOMAIN]["coordinators"][device.unique_id]
 | 
					                    continue
 | 
				
			||||||
        else:
 | 
					                entity = HonConfigSwitchEntity(hass, entry, device, description)
 | 
				
			||||||
            coordinator = HonCoordinator(hass, device)
 | 
					            elif isinstance(description, HonControlSwitchEntityDescription):
 | 
				
			||||||
            hass.data[DOMAIN]["coordinators"][device.unique_id] = coordinator
 | 
					                if not (
 | 
				
			||||||
        await coordinator.async_config_entry_first_refresh()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if descriptions := SWITCHES.get(device.appliance_type):
 | 
					 | 
				
			||||||
            for description in descriptions:
 | 
					 | 
				
			||||||
                if (
 | 
					 | 
				
			||||||
                    device.get(description.key) is not None
 | 
					                    device.get(description.key) is not None
 | 
				
			||||||
                    or device.commands.get(description.key) is not None
 | 
					                    or description.turn_on_key in list(device.commands)
 | 
				
			||||||
 | 
					                    or description.turn_off_key in list(device.commands)
 | 
				
			||||||
                ):
 | 
					                ):
 | 
				
			||||||
                    appliances.extend(
 | 
					                    continue
 | 
				
			||||||
                        [HonSwitchEntity(hass, coordinator, entry, device, description)]
 | 
					                entity = HonControlSwitchEntity(hass, entry, device, description)
 | 
				
			||||||
                    )
 | 
					            elif isinstance(description, HonSwitchEntityDescription):
 | 
				
			||||||
                else:
 | 
					                if (
 | 
				
			||||||
                    _LOGGER.warning(
 | 
					                    f"settings.{description.key}" not in device.available_settings
 | 
				
			||||||
                        "[%s] Can't setup %s", device.appliance_type, description.key
 | 
					                    or not device.get(description.key)
 | 
				
			||||||
                    )
 | 
					                ):
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                entity = HonSwitchEntity(hass, entry, device, description)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            await entity.coordinator.async_config_entry_first_refresh()
 | 
				
			||||||
 | 
					            entities.append(entity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async_add_entities(appliances)
 | 
					    async_add_entities(entities)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonSwitchEntity(HonEntity, SwitchEntity):
 | 
					class HonSwitchEntity(HonEntity, SwitchEntity):
 | 
				
			||||||
    entity_description: HonSwitchEntityDescription
 | 
					    entity_description: HonSwitchEntityDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    @property
 | 
				
			||||||
        self,
 | 
					    def is_on(self) -> bool | None:
 | 
				
			||||||
        hass,
 | 
					        """Return True if entity is on."""
 | 
				
			||||||
        coordinator,
 | 
					        return self._device.get(self.entity_description.key, "0") == "1"
 | 
				
			||||||
        entry,
 | 
					
 | 
				
			||||||
        device: HonAppliance,
 | 
					    async def async_turn_on(self, **kwargs: Any) -> None:
 | 
				
			||||||
        description: HonSwitchEntityDescription,
 | 
					        setting = self._device.settings[f"settings.{self.entity_description.key}"]
 | 
				
			||||||
    ) -> None:
 | 
					        if type(setting) == HonParameter:
 | 
				
			||||||
        super().__init__(hass, entry, coordinator, device)
 | 
					            return
 | 
				
			||||||
        self._coordinator = coordinator
 | 
					        setting.value = setting.max if isinstance(setting, HonParameterRange) else "1"
 | 
				
			||||||
        self._device = device
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
        self.entity_description = description
 | 
					        await self._device.commands["settings"].send()
 | 
				
			||||||
        self._attr_unique_id = f"{super().unique_id}{description.key}"
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_turn_off(self, **kwargs: Any) -> None:
 | 
				
			||||||
 | 
					        setting = self._device.settings[f"settings.{self.entity_description.key}"]
 | 
				
			||||||
 | 
					        if type(setting) == HonParameter:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        setting.value = setting.min if isinstance(setting, HonParameterRange) else "0"
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					        await self._device.commands["settings"].send()
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @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"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @callback
 | 
				
			||||||
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
 | 
					        value = self._device.get(self.entity_description.key, "0")
 | 
				
			||||||
 | 
					        self._attr_state = value == "1"
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HonControlSwitchEntity(HonEntity, SwitchEntity):
 | 
				
			||||||
 | 
					    entity_description: HonControlSwitchEntityDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @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:
 | 
					 | 
				
			||||||
            setting = self._device.settings[self.entity_description.key]
 | 
					 | 
				
			||||||
            return (
 | 
					 | 
				
			||||||
                setting.value == "1"
 | 
					 | 
				
			||||||
                or hasattr(setting, "min")
 | 
					 | 
				
			||||||
                and setting.value != setting.min
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        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:
 | 
					        await self._device.commands[self.entity_description.turn_on_key].send()
 | 
				
			||||||
            setting = self._device.settings[self.entity_description.key]
 | 
					        self._device.attributes[self.entity_description.key] = True
 | 
				
			||||||
            setting.value = (
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
                setting.max if isinstance(setting, HonParameterRange) else "1"
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            self.async_write_ha_state()
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            await self._device.commands[self.entity_description.turn_on_key].send()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def async_turn_off(self, **kwargs: Any) -> None:
 | 
					    async def async_turn_off(self, **kwargs: Any) -> None:
 | 
				
			||||||
        if self.entity_category == EntityCategory.CONFIG:
 | 
					        await self._device.commands[self.entity_description.turn_off_key].send()
 | 
				
			||||||
            setting = self._device.settings[self.entity_description.key]
 | 
					        self._device.attributes[self.entity_description.key] = False
 | 
				
			||||||
            setting.value = (
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
                setting.min if isinstance(setting, HonParameterRange) else "0"
 | 
					
 | 
				
			||||||
 | 
					    @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"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def extra_state_attributes(self) -> dict[str, Any]:
 | 
				
			||||||
 | 
					        """Return the optional state attributes."""
 | 
				
			||||||
 | 
					        result = {}
 | 
				
			||||||
 | 
					        if remaining_time := int(self._device.get("remainingTimeMM", 0)):
 | 
				
			||||||
 | 
					            delay_time = int(self._device.get("delayTime", 0))
 | 
				
			||||||
 | 
					            result["start_time"] = datetime.now() + timedelta(minutes=delay_time)
 | 
				
			||||||
 | 
					            result["end_time"] = datetime.now() + timedelta(
 | 
				
			||||||
 | 
					                minutes=delay_time + remaining_time
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					        return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HonConfigSwitchEntity(HonEntity, SwitchEntity):
 | 
				
			||||||
 | 
					    entity_description: HonConfigSwitchEntityDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def is_on(self) -> bool | None:
 | 
				
			||||||
 | 
					        """Return True if entity is on."""
 | 
				
			||||||
 | 
					        setting = self._device.settings[self.entity_description.key]
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            setting.value != setting.min
 | 
				
			||||||
 | 
					            if hasattr(setting, "min")
 | 
				
			||||||
 | 
					            else setting.value == "1"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_turn_on(self, **kwargs: Any) -> None:
 | 
				
			||||||
 | 
					        setting = self._device.settings[self.entity_description.key]
 | 
				
			||||||
 | 
					        if type(setting) == HonParameter:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        setting.value = setting.max if isinstance(setting, HonParameterRange) else "1"
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def async_turn_off(self, **kwargs: Any) -> None:
 | 
				
			||||||
 | 
					        setting = self._device.settings[self.entity_description.key]
 | 
				
			||||||
 | 
					        if type(setting) == HonParameter:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        setting.value = setting.min if isinstance(setting, HonParameterRange) else "0"
 | 
				
			||||||
 | 
					        self.async_write_ha_state()
 | 
				
			||||||
 | 
					        await self.coordinator.async_refresh()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @callback
 | 
				
			||||||
 | 
					    def _handle_coordinator_update(self, update=True) -> None:
 | 
				
			||||||
 | 
					        value = self._device.settings.get(self.entity_description.key, "0")
 | 
				
			||||||
 | 
					        self._attr_state = value == "1"
 | 
				
			||||||
 | 
					        if update:
 | 
				
			||||||
            self.async_write_ha_state()
 | 
					            self.async_write_ha_state()
 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            await self._device.commands[self.entity_description.turn_off_key].send()
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -30,7 +30,7 @@
 | 
				
			|||||||
          "8000000000000": "E4: Провери подаването на вода"
 | 
					          "8000000000000": "E4: Провери подаването на вода"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "tumbledryerprogram": {
 | 
					      "programs": {
 | 
				
			||||||
        "state": {
 | 
					        "state": {
 | 
				
			||||||
          "0": "Стандартна",
 | 
					          "0": "Стандартна",
 | 
				
			||||||
          "62": "Памук",
 | 
					          "62": "Памук",
 | 
				
			||||||
@ -49,7 +49,7 @@
 | 
				
			|||||||
          "103": "Отдалечен"
 | 
					          "103": "Отдалечен"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "tumbledryerprogramphase": {
 | 
					      "program_phases_td": {
 | 
				
			||||||
        "state": {
 | 
					        "state": {
 | 
				
			||||||
          "0": "Изчаване",
 | 
					          "0": "Изчаване",
 | 
				
			||||||
          "2": "Сушене",
 | 
					          "2": "Сушене",
 | 
				
			||||||
@ -65,7 +65,7 @@
 | 
				
			|||||||
          "4": "Висока температура L-3"
 | 
					          "4": "Висока температура L-3"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "tumbledryerdrylevel": {
 | 
					      "dry_levels": {
 | 
				
			||||||
        "state": {
 | 
					        "state": {
 | 
				
			||||||
          "3": "Готови за съхранение",
 | 
					          "3": "Готови за съхранение",
 | 
				
			||||||
          "12": "Готови за гладене H-1",
 | 
					          "12": "Готови за гладене H-1",
 | 
				
			||||||
@ -75,334 +75,12 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "select": {
 | 
					    "select": {
 | 
				
			||||||
      "programs": {
 | 
					      "dry_levels": {
 | 
				
			||||||
        "state": {
 | 
					        "state": {
 | 
				
			||||||
          "20_degrees_coloured_cottons": "20° Colored and Cottons",
 | 
					          "3": "Готови за съхранение",
 | 
				
			||||||
          "20_degrees_new_energy_label": "20°C",
 | 
					          "12": "Готови за гладене H-1",
 | 
				
			||||||
          "active_steam": "Steam",
 | 
					          "13": "Готови за съхранение H-2",
 | 
				
			||||||
          "active_wash": "Active Wash",
 | 
					          "14": "Екстра сухо H-3"
 | 
				
			||||||
          "active_wash_steam": "Active Wash + Steam",
 | 
					 | 
				
			||||||
          "allergy_care": "Allergy Care",
 | 
					 | 
				
			||||||
          "allergy_care_pro": "Allergy Care Pro",
 | 
					 | 
				
			||||||
          "all_in_one_49": "All in One 49'",
 | 
					 | 
				
			||||||
          "all_in_one_59": "All in One 59'",
 | 
					 | 
				
			||||||
          "all_in_one_59_steam": "Active Wash + Steam",
 | 
					 | 
				
			||||||
          "autocare": "Autocare",
 | 
					 | 
				
			||||||
          "autoclean": "Drum Cleaning",
 | 
					 | 
				
			||||||
          "baby_60": "All Baby 60°C",
 | 
					 | 
				
			||||||
          "care_14": "Rapid Care 14'",
 | 
					 | 
				
			||||||
          "care_30": "Rapid Care 30'",
 | 
					 | 
				
			||||||
          "care_44": "Rapid Care 44'",
 | 
					 | 
				
			||||||
          "checkup": "Check-Up",
 | 
					 | 
				
			||||||
          "colour_59": "Colored 59'",
 | 
					 | 
				
			||||||
          "colour_59_steam": "Colored 59' + Steam",
 | 
					 | 
				
			||||||
          "cottons": "Cotton",
 | 
					 | 
				
			||||||
          "cottons_prewash": "Cottons + Prewash",
 | 
					 | 
				
			||||||
          "cottons_steam": "Cotton + Steam",
 | 
					 | 
				
			||||||
          "cotton_care_59": "Cotton Care 59'",
 | 
					 | 
				
			||||||
          "delicate_59": "Delicate 59'",
 | 
					 | 
				
			||||||
          "delicate_silk": "Delicate and Silk",
 | 
					 | 
				
			||||||
          "delicate_silk_steam": "Delicate and Silk + Steam",
 | 
					 | 
				
			||||||
          "delicati_59": "Delicate 59'",
 | 
					 | 
				
			||||||
          "delicati_59_steam": "Delicate 59' + Steam",
 | 
					 | 
				
			||||||
          "drain_spin": "Drain + Spin",
 | 
					 | 
				
			||||||
          "easy_iron": "Easy Iron",
 | 
					 | 
				
			||||||
          "eco_40_60_new_energy_label": "Eco 40-60",
 | 
					 | 
				
			||||||
          "extra_care": "Extra Care",
 | 
					 | 
				
			||||||
          "fitness": "Fitness Care",
 | 
					 | 
				
			||||||
          "fitness_care": "Fitness Care",
 | 
					 | 
				
			||||||
          "fresh_care": "Fresh Care",
 | 
					 | 
				
			||||||
          "fresh_care_steam": "Fresh Care + Steam",
 | 
					 | 
				
			||||||
          "handwash_wool": "Hand Wash + Wool",
 | 
					 | 
				
			||||||
          "high_dry": "High Heat Dry",
 | 
					 | 
				
			||||||
          "hqd_20_degrees": "Cotton 20℃",
 | 
					 | 
				
			||||||
          "hqd_allergy": "Allergy Care",
 | 
					 | 
				
			||||||
          "hqd_autoclean": "Автоматично почистване",
 | 
					 | 
				
			||||||
          "hqd_babycare": "Бебе",
 | 
					 | 
				
			||||||
          "hqd_baby_care": "Бебе",
 | 
					 | 
				
			||||||
          "hqd_bath_towel": "Хавлиени кърпи",
 | 
					 | 
				
			||||||
          "hqd_bed_sheets": "Чаршафи",
 | 
					 | 
				
			||||||
          "hqd_checkup": "Check-Up",
 | 
					 | 
				
			||||||
          "hqd_bulky": "Обемисти",
 | 
					 | 
				
			||||||
          "hqd_casual": "Ежедневни",
 | 
					 | 
				
			||||||
          "hqd_cold_wind_30": "Студен бриз 30 мин",
 | 
					 | 
				
			||||||
          "hqd_cold_wind_timing": "Студен бриз за време",
 | 
					 | 
				
			||||||
          "hqd_cotton": "Памук",
 | 
					 | 
				
			||||||
          "hqd_cottons": "Памук",
 | 
					 | 
				
			||||||
          "hqd_curtain": "Пердета",
 | 
					 | 
				
			||||||
          "hqd_delicate": "Деликатни",
 | 
					 | 
				
			||||||
          "hqd_delicate_cradle": "Деликатни",
 | 
					 | 
				
			||||||
          "hqd_diaper": "Бебешки пелени",
 | 
					 | 
				
			||||||
          "hqd_dry": "Cotton Dry",
 | 
					 | 
				
			||||||
          "hqd_dry_synthetics": "Low Heat Dry",
 | 
					 | 
				
			||||||
          "hqd_duvet": "Олекотени завивки",
 | 
					 | 
				
			||||||
          "hqd_eco_40_60_degrees": "Eco 40-60",
 | 
					 | 
				
			||||||
          "hqd_feather": "Пълнеж от пера(пух)",
 | 
					 | 
				
			||||||
          "hqd_handwash_wool": "Wool",
 | 
					 | 
				
			||||||
          "hqd_hot_wind_timing": "Горещ въздух за време",
 | 
					 | 
				
			||||||
          "hqd_hygienic": "Здравословна",
 | 
					 | 
				
			||||||
          "hqd_i_refresh": "i-Refresh",
 | 
					 | 
				
			||||||
          "hqd_i_refresh_pro": "i-Refresh Pro",
 | 
					 | 
				
			||||||
          "hqd_jacket": "Якета",
 | 
					 | 
				
			||||||
          "hqd_jeans": "Дънки",
 | 
					 | 
				
			||||||
          "hqd_luxury": "Луксозно",
 | 
					 | 
				
			||||||
          "hqd_mix": "Смесен тип",
 | 
					 | 
				
			||||||
          "hqd_night_dry": "Сушене през ноща",
 | 
					 | 
				
			||||||
          "hqd_outdoor": "Дрехи за открито",
 | 
					 | 
				
			||||||
          "hqd_precious_cure": "Precious cure",
 | 
					 | 
				
			||||||
          "hqd_quick_15": "Бързо 15 мин",
 | 
					 | 
				
			||||||
          "hqd_quick_20": "Бързо 20 мин",
 | 
					 | 
				
			||||||
          "hqd_quick_30": "Бързо 30 мин",
 | 
					 | 
				
			||||||
          "hqd_quick_dry": "Бързо",
 | 
					 | 
				
			||||||
          "hqd_quick_wash_57": "Quick Wash 57'",
 | 
					 | 
				
			||||||
          "hqd_quilt": "Юргани",
 | 
					 | 
				
			||||||
          "hqd_rapid_wash_and_dry": "Wash and dry",
 | 
					 | 
				
			||||||
          "hqd_refresh": "Освежаване",
 | 
					 | 
				
			||||||
          "hqd_rinse": "Rinses",
 | 
					 | 
				
			||||||
          "hqd_school_uniform": "Ученически униформи",
 | 
					 | 
				
			||||||
          "hqd_shirt": "Ризи",
 | 
					 | 
				
			||||||
          "hqd_shirts": "Ризи",
 | 
					 | 
				
			||||||
          "hqd_shoes": "Обувки",
 | 
					 | 
				
			||||||
          "hqd_silk": "Коприна",
 | 
					 | 
				
			||||||
          "hqd_smart": "Smart A.I.",
 | 
					 | 
				
			||||||
          "hqd_spin": "Spin",
 | 
					 | 
				
			||||||
          "hqd_sport": "Спорт",
 | 
					 | 
				
			||||||
          "hqd_sports": "Спорт",
 | 
					 | 
				
			||||||
          "hqd_synthetics": "Синтетика",
 | 
					 | 
				
			||||||
          "hqd_super_fast": "Супер бързо 39 мин",
 | 
					 | 
				
			||||||
          "hqd_synthetic_and_coloured": "Synthetics",
 | 
					 | 
				
			||||||
          "hqd_timer": "Таймер",
 | 
					 | 
				
			||||||
          "hqd_towel": "Хавлиени кърпи",
 | 
					 | 
				
			||||||
          "hqd_underwear": "Бельо",
 | 
					 | 
				
			||||||
          "hqd_warm_up": "Затопляне",
 | 
					 | 
				
			||||||
          "hqd_wool": "Вълна",
 | 
					 | 
				
			||||||
          "hqd_working_suit": "Работно облекло",
 | 
					 | 
				
			||||||
          "hygiene_59": "Hygiene Plus 59'",
 | 
					 | 
				
			||||||
          "hygiene_60": "Hygiene 60°C",
 | 
					 | 
				
			||||||
          "hygiene_plus_59": "Hygiene Plus 59'",
 | 
					 | 
				
			||||||
          "hygiene_plus_59_min": "Hygiene Plus 59'",
 | 
					 | 
				
			||||||
          "hygiene_pro_4_min": "Hygiene Pro 49'",
 | 
					 | 
				
			||||||
          "hygiene_pro_49_min": "Hygiene Pro 49'",
 | 
					 | 
				
			||||||
          "hygiene_pro_steam": "Hygiene Pro + Steam",
 | 
					 | 
				
			||||||
          "intensive_40": "Intensive 40°C",
 | 
					 | 
				
			||||||
          "intensive_40_steam": "Intensive 40°C + Steam",
 | 
					 | 
				
			||||||
          "iot_checkup": "Check-Up",
 | 
					 | 
				
			||||||
          "iot_dry_air_refresh": "Air Refresh",
 | 
					 | 
				
			||||||
          "iot_dry_anti_mites": "Anti-mite",
 | 
					 | 
				
			||||||
          "iot_dry_baby": "Бебе",
 | 
					 | 
				
			||||||
          "iot_dry_backpacks": "Раници",
 | 
					 | 
				
			||||||
          "iot_dry_bathrobe": "Халати за баня",
 | 
					 | 
				
			||||||
          "iot_dry_bed_linen": "Спално бельо",
 | 
					 | 
				
			||||||
          "iot_dry_cotton": "Памук",
 | 
					 | 
				
			||||||
          "iot_dry_cotton_dry": "Памук",
 | 
					 | 
				
			||||||
          "iot_dry_cuddly_toys": "Плюшени играчки",
 | 
					 | 
				
			||||||
          "iot_dry_curtains": "Пердета",
 | 
					 | 
				
			||||||
          "iot_dry_dehumidifier": "Humidity Remover",
 | 
					 | 
				
			||||||
          "iot_dry_delicates": "Деликатни",
 | 
					 | 
				
			||||||
          "iot_dry_delicates_antiallergy": "Delicates  Anti-allergy",
 | 
					 | 
				
			||||||
          "iot_dry_delicate_tablecloths": "Delicate Tablecloths",
 | 
					 | 
				
			||||||
          "iot_dry_denim_jeans": "Дънки",
 | 
					 | 
				
			||||||
          "iot_dry_down_jacket": "Пухени якета",
 | 
					 | 
				
			||||||
          "iot_dry_duvet": "Олекотени завивки",
 | 
					 | 
				
			||||||
          "iot_dry_easy_iron_cotton": "Easy Iron - Cotton",
 | 
					 | 
				
			||||||
          "iot_dry_easy_iron_synthetics": "Easy Iron - Synthetics",
 | 
					 | 
				
			||||||
          "iot_dry_gym_fit": "Фитнес",
 | 
					 | 
				
			||||||
          "iot_dry_lingerie": "Деликано бельо",
 | 
					 | 
				
			||||||
          "iot_dry_mixed": "Смесен тип",
 | 
					 | 
				
			||||||
          "iot_dry_mixed_dry": "Смесен тип",
 | 
					 | 
				
			||||||
          "iot_dry_rapid_30": "Бързо 30 мин",
 | 
					 | 
				
			||||||
          "iot_dry_rapid_59": "Бързо 59 мин",
 | 
					 | 
				
			||||||
          "iot_dry_rapid_60_min_delicates": "Rapid 60' - Delicates",
 | 
					 | 
				
			||||||
          "iot_dry_shirts": "Ризи",
 | 
					 | 
				
			||||||
          "iot_dry_swimsuits_and_bikinis": "Бански",
 | 
					 | 
				
			||||||
          "iot_dry_synthetics": "Синтетика",
 | 
					 | 
				
			||||||
          "iot_dry_synthetic_dry": "Synthetic Dry",
 | 
					 | 
				
			||||||
          "iot_dry_tablecloths": "Покривки",
 | 
					 | 
				
			||||||
          "iot_dry_technical_fabrics": "Технически тъкани",
 | 
					 | 
				
			||||||
          "iot_dry_warm_embrace": "Warm Embrace",
 | 
					 | 
				
			||||||
          "iot_dry_wool": "Вълна",
 | 
					 | 
				
			||||||
          "iot_dry_wool_dry": "Вълна",
 | 
					 | 
				
			||||||
          "iot_wash_and_dry": "Wash and dry",
 | 
					 | 
				
			||||||
          "iot_wash_anti_mites": "Anti-mites",
 | 
					 | 
				
			||||||
          "iot_wash_anti_odor": "Anti-odour",
 | 
					 | 
				
			||||||
          "iot_wash_ariel_clean_cycle": "Ariel Ultimate Clean",
 | 
					 | 
				
			||||||
          "iot_wash_ariel_cold_cycle": "Ariel Cold Clean",
 | 
					 | 
				
			||||||
          "iot_wash_ariel_fresh_cycle": "Ariel Fresh Clean",
 | 
					 | 
				
			||||||
          "iot_wash_baby_sanitizer": "Sanitizer",
 | 
					 | 
				
			||||||
          "iot_wash_baby_sanitizer_steam": "Sanitiser + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_backpacks": "Backpacks",
 | 
					 | 
				
			||||||
          "iot_wash_backpacks_zelig": "Backpacks",
 | 
					 | 
				
			||||||
          "iot_wash_bathrobe": "Bathrobes and Towels",
 | 
					 | 
				
			||||||
          "iot_wash_bathrobe_steam": "Bathrobe and Towels + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_bed_linen": "Bed Linen",
 | 
					 | 
				
			||||||
          "iot_wash_bed_linen_steam": "Bed Linen + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_bed_linen_zelig": "Bed Linens",
 | 
					 | 
				
			||||||
          "iot_wash_big_single_load": "Big single load",
 | 
					 | 
				
			||||||
          "iot_wash_bleaching": "Bleaching",
 | 
					 | 
				
			||||||
          "iot_wash_blood_stains": "Bloodstains",
 | 
					 | 
				
			||||||
          "iot_wash_cashmere": "Cashmere",
 | 
					 | 
				
			||||||
          "iot_wash_chocolate_stains": "Chocolate stains",
 | 
					 | 
				
			||||||
          "iot_wash_cold_wash": "Cold Wash",
 | 
					 | 
				
			||||||
          "iot_wash_colored": "Colored",
 | 
					 | 
				
			||||||
          "iot_wash_colored_anti_stain": "Colored Anti-stain",
 | 
					 | 
				
			||||||
          "iot_wash_colored_delicate": "Colored Delicate",
 | 
					 | 
				
			||||||
          "iot_wash_coloured": "Colored",
 | 
					 | 
				
			||||||
          "iot_wash_coloured_bed_linen": "Colored Bed Linen",
 | 
					 | 
				
			||||||
          "iot_wash_coloured_bed_linen_steam": "Coloured Bed Linen + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_coloured_curtains": "Colored Curtains",
 | 
					 | 
				
			||||||
          "iot_wash_coloured_shirts": "Colored Shirts",
 | 
					 | 
				
			||||||
          "iot_wash_coloured_shirts_steam": "Colored Shirts + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_coloured_steam": "Colored + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_coloured_tableclothes": "Colored Tableclothes",
 | 
					 | 
				
			||||||
          "iot_wash_coloured_tableclothes_steam": "Coloured Tablecloths + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_cotton": "Cotton",
 | 
					 | 
				
			||||||
          "iot_wash_cotton_steam": "Cotton + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_cuddly_toys": "Cuddly Toys",
 | 
					 | 
				
			||||||
          "iot_wash_curtains": "Curtains",
 | 
					 | 
				
			||||||
          "iot_wash_curtains_steam": "Curtains + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_curtains_zelig": "Curtains",
 | 
					 | 
				
			||||||
          "iot_wash_dark": "Darks",
 | 
					 | 
				
			||||||
          "iot_wash_darks_and_coloured_44": "Darks and Colored 44'",
 | 
					 | 
				
			||||||
          "iot_wash_darks_and_coloured_59": "Darks and Colored 59'",
 | 
					 | 
				
			||||||
          "iot_wash_darks_and_coloured_xl": "Darks and Colored XL",
 | 
					 | 
				
			||||||
          "iot_wash_dark_steam": "Darks + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_dash_clean_cycle": "Dash Ultimate Clean",
 | 
					 | 
				
			||||||
          "iot_wash_dash_cold_cycle": "Dash Cold Clean",
 | 
					 | 
				
			||||||
          "iot_wash_dash_fresh_cycle": "Dash Fresh Clean",
 | 
					 | 
				
			||||||
          "iot_wash_delicate": "Delicates",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_antiallergy": "Delicate Anti-Allergy",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_antiallergy_steam": "Delicate Anti-Allergy + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_antiallergy_zelig": "Delicate Anti-Allergy",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_colors": "Delicate Colors",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_colors_steam": "Delicate Colors + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_dark": "Delicate Darks",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_steam": "Delicates + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_tablecloths": "Delicate Tablecloths",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_tablecloths_steam": "Delicate Tablecloths + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_delicate_whites": "Delicate Whites",
 | 
					 | 
				
			||||||
          "iot_wash_denim_jeans": "Denim - Jeans",
 | 
					 | 
				
			||||||
          "iot_wash_diving_suits": "Diving Suits",
 | 
					 | 
				
			||||||
          "iot_wash_diving_suits_zelig": "Diving Suits",
 | 
					 | 
				
			||||||
          "iot_wash_down_jackets": "Down Jackets",
 | 
					 | 
				
			||||||
          "iot_wash_down_jackets_zelig": "Down Jackets",
 | 
					 | 
				
			||||||
          "iot_wash_duvet": "Duvet",
 | 
					 | 
				
			||||||
          "iot_wash_fruit_stains": "Fruit stains",
 | 
					 | 
				
			||||||
          "iot_wash_gym_fit": "Gym Fit - Fitness",
 | 
					 | 
				
			||||||
          "iot_wash_handwash": "Handwash",
 | 
					 | 
				
			||||||
          "iot_wash_handwash_colored": "Handwash Colored",
 | 
					 | 
				
			||||||
          "iot_wash_handwash_dark": "Handwash Darks",
 | 
					 | 
				
			||||||
          "iot_wash_lingerie": "Lingerie",
 | 
					 | 
				
			||||||
          "iot_wash_masks_refresh": "Masks Refresh",
 | 
					 | 
				
			||||||
          "iot_wash_masks_sanification": "Masks Sanitization",
 | 
					 | 
				
			||||||
          "iot_wash_masks_sanification_steam": "Mask Sanitisation + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_mats": "Mats",
 | 
					 | 
				
			||||||
          "iot_wash_men_s_trousers": "Trousers",
 | 
					 | 
				
			||||||
          "iot_wash_mixed": "Mixed",
 | 
					 | 
				
			||||||
          "iot_wash_mixed_steam": "Mixed + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_mix_and_coloured_44": "Mix and Colored 44'",
 | 
					 | 
				
			||||||
          "iot_wash_mix_and_coloured_59": "Mix and Colored 59'",
 | 
					 | 
				
			||||||
          "iot_wash_mix_and_coloured_xl": "Mix and colored XL",
 | 
					 | 
				
			||||||
          "iot_wash_new_clothes": "New Clothes",
 | 
					 | 
				
			||||||
          "iot_wash_perfect_white": "Perfect White",
 | 
					 | 
				
			||||||
          "iot_wash_perfect_white_steam": "Perfect White + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_pets": "Pet Accessories",
 | 
					 | 
				
			||||||
          "iot_wash_pets_hair_removal": "Pets Hair Removal",
 | 
					 | 
				
			||||||
          "iot_wash_pets_odours_stains_removal": "Pets Odours and Stains Removal",
 | 
					 | 
				
			||||||
          "iot_wash_pets_steam": "Pet Accessories + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_playsuits": "Playsuits",
 | 
					 | 
				
			||||||
          "iot_wash_playsuits_steam": "Playsuits + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_quick_drum_cleaner": "Quick drum cleaner",
 | 
					 | 
				
			||||||
          "iot_wash_rapid_14": "Rapid 14’",
 | 
					 | 
				
			||||||
          "iot_wash_rapid_30": "Rapid 30’",
 | 
					 | 
				
			||||||
          "iot_wash_rapid_44": "Rapid 44'",
 | 
					 | 
				
			||||||
          "iot_wash_rapid_59": "Rapid 59'",
 | 
					 | 
				
			||||||
          "iot_wash_rapid_59_steam": "Rapid 59' + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_refresh_14_min": "Refresh 14'",
 | 
					 | 
				
			||||||
          "iot_wash_resistant_colored": "Resistant Colored",
 | 
					 | 
				
			||||||
          "iot_wash_resistant_dark": "Resistant Darks",
 | 
					 | 
				
			||||||
          "iot_wash_resistant_whites": "Resistant Whites",
 | 
					 | 
				
			||||||
          "iot_wash_rinse": "Rinses",
 | 
					 | 
				
			||||||
          "iot_wash_shirts": "Shirts",
 | 
					 | 
				
			||||||
          "iot_wash_shirts_steam": "Shirts + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_silk": "Silk",
 | 
					 | 
				
			||||||
          "iot_wash_ski_suit": "Ski Suit",
 | 
					 | 
				
			||||||
          "iot_wash_ski_suit_zelig": "Ski Suit",
 | 
					 | 
				
			||||||
          "iot_wash_spin": "Spin",
 | 
					 | 
				
			||||||
          "iot_wash_sport": "Sport",
 | 
					 | 
				
			||||||
          "iot_wash_sport_anti_odor": "Anti-odour Sportswear",
 | 
					 | 
				
			||||||
          "iot_wash_sport_anti_odor_zelig": "Anti-odour Sportswear",
 | 
					 | 
				
			||||||
          "iot_wash_stains_remover": "Stain Remover",
 | 
					 | 
				
			||||||
          "iot_wash_swimsuits_and_bikinis": "Swimsuits and Bikinis",
 | 
					 | 
				
			||||||
          "iot_wash_synthetic": "Synthetics",
 | 
					 | 
				
			||||||
          "iot_wash_synthetic_steam": "Synthetics + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_tablecloths": "Tablecloths",
 | 
					 | 
				
			||||||
          "iot_wash_tablecloths_steam": "Tablecloths + Steam",
 | 
					 | 
				
			||||||
          "iot_wash_technical_fabrics": "Technical Fabrics",
 | 
					 | 
				
			||||||
          "iot_wash_technical_fabrics_zelig": "Technical Fabrics",
 | 
					 | 
				
			||||||
          "iot_wash_technical_jackets": "Technical Jackets",
 | 
					 | 
				
			||||||
          "iot_wash_technical_jackets_zelig": "Technical Jackets",
 | 
					 | 
				
			||||||
          "iot_wash_trainers": "Trainers",
 | 
					 | 
				
			||||||
          "iot_wash_whites": "Whites",
 | 
					 | 
				
			||||||
          "iot_wash_whites_44": "Whites 44'",
 | 
					 | 
				
			||||||
          "iot_wash_whites_59": "Whites 59'",
 | 
					 | 
				
			||||||
          "iot_wash_whites_xl": "Whites XL",
 | 
					 | 
				
			||||||
          "iot_wash_wine_stains": "Wine Stains",
 | 
					 | 
				
			||||||
          "iot_wash_wool": "Wool",
 | 
					 | 
				
			||||||
          "jeans": "Jeans",
 | 
					 | 
				
			||||||
          "jeans_60": "Jeans",
 | 
					 | 
				
			||||||
          "low_dry": "Low Heat Dry",
 | 
					 | 
				
			||||||
          "mixed": "Mixed",
 | 
					 | 
				
			||||||
          "mixed_and_colored_59": "Mixed and Colored 59'",
 | 
					 | 
				
			||||||
          "mixed_steam": "Mixed + Steam",
 | 
					 | 
				
			||||||
          "mix_and_colour_59": "Mixed and Colored 59'",
 | 
					 | 
				
			||||||
          "mix_and_colour_59_steam": "Mixed and Coloured 59' + Steam",
 | 
					 | 
				
			||||||
          "night_and_day": "Night and Day",
 | 
					 | 
				
			||||||
          "night_wash": "Night Wash",
 | 
					 | 
				
			||||||
          "perfect_59": "Perfect 59'",
 | 
					 | 
				
			||||||
          "perfect_cotton_59": "Perfect Cotton 59'",
 | 
					 | 
				
			||||||
          "perfect_cotton_59_steam": "Perfect Cotton 59' + Steam",
 | 
					 | 
				
			||||||
          "perfect_whites_59": "Perfect White 59'",
 | 
					 | 
				
			||||||
          "rapid_14_min": "Rapid 14'",
 | 
					 | 
				
			||||||
          "rapid_30_min": "Rapid 30'",
 | 
					 | 
				
			||||||
          "rapid_44_min": "Rapid 44'",
 | 
					 | 
				
			||||||
          "rapid_a_class_60": "Rapid 59' A Class",
 | 
					 | 
				
			||||||
          "rapid_a_class_60_steam": "Rapid 59' A Class + Steam",
 | 
					 | 
				
			||||||
          "rapid_wash_and_dry_59_min": "Wash and Dry 59'",
 | 
					 | 
				
			||||||
          "resistant_cotton": "Resistant Cotton",
 | 
					 | 
				
			||||||
          "resistant_cotton_steam": "Resistant Cotton + Steam",
 | 
					 | 
				
			||||||
          "rinse": "Rinse",
 | 
					 | 
				
			||||||
          "shirts_steam": "Shirts + Steam",
 | 
					 | 
				
			||||||
          "silent_night": "Silent Night",
 | 
					 | 
				
			||||||
          "single_item": "Single Item",
 | 
					 | 
				
			||||||
          "single_item_steam": "Single Item + Steam",
 | 
					 | 
				
			||||||
          "smart_wash": "Smart Wash",
 | 
					 | 
				
			||||||
          "soft_care": "Soft Care",
 | 
					 | 
				
			||||||
          "soft_care_steam": "Soft Care + Steam",
 | 
					 | 
				
			||||||
          "soft_care_steam_title": "Soft Care + Steam",
 | 
					 | 
				
			||||||
          "special_39": "Special 39'",
 | 
					 | 
				
			||||||
          "special_39_full_load": "Special 39'",
 | 
					 | 
				
			||||||
          "special_39_full_load_steam": "Special 39' + Steam",
 | 
					 | 
				
			||||||
          "special_49": "Special 49'",
 | 
					 | 
				
			||||||
          "sport_39": "Sport 39'",
 | 
					 | 
				
			||||||
          "sport_plus_29": "Sport Plus 29'",
 | 
					 | 
				
			||||||
          "sport_plus_39": "Sport Plus 39'",
 | 
					 | 
				
			||||||
          "steam_39": "Steam 39'",
 | 
					 | 
				
			||||||
          "steam_care_pro": "Steam Care Pro",
 | 
					 | 
				
			||||||
          "steam_care_pro_cotton": "Steam Care Pro - Cottons",
 | 
					 | 
				
			||||||
          "steam_care_pro_delicates": "Steam Care Pro - Delicates",
 | 
					 | 
				
			||||||
          "steam_care_pro_synthetic": "Steam Care Pro - Synthetics",
 | 
					 | 
				
			||||||
          "steam_hygiene_plus": "Hygiene Plus + Steam",
 | 
					 | 
				
			||||||
          "synthetics": "Synthetics",
 | 
					 | 
				
			||||||
          "synthetic_and_coloured": "Synthetic and Colored",
 | 
					 | 
				
			||||||
          "synthetic_and_coloured_steam": "Synthetic and Coloured + Steam",
 | 
					 | 
				
			||||||
          "tailored_resistant_cotton": "Tailored Resistant Cotton",
 | 
					 | 
				
			||||||
          "tailored_synthetic_and_coloured": "Tailored Synthetic Colored",
 | 
					 | 
				
			||||||
          "total_care": "Total Care",
 | 
					 | 
				
			||||||
          "tumbling": "Tumbling",
 | 
					 | 
				
			||||||
          "wool": "Wool",
 | 
					 | 
				
			||||||
          "wool_and_delicates_49": "Wool and Delicates 49'",
 | 
					 | 
				
			||||||
          "wool_dry": "Wool Dry",
 | 
					 | 
				
			||||||
          "wool_soft_care": "Wool and Soft Car"
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1995
									
								
								custom_components/hon/translations/cs.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/cs.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/de.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/de.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/el.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								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
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/es.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/es.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/fr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/fr.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1081
									
								
								custom_components/hon/translations/he.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1081
									
								
								custom_components/hon/translations/he.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/hr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/hr.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2036
									
								
								custom_components/hon/translations/it.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2036
									
								
								custom_components/hon/translations/it.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/nl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/nl.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/pl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/pl.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/pt.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/pt.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/ro.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/ro.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/ru.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/ru.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/sk.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/sk.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/sl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/sl.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/sr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/sr.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/tr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/tr.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1995
									
								
								custom_components/hon/translations/zh.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1995
									
								
								custom_components/hon/translations/zh.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										91
									
								
								info.md
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								info.md
									
									
									
									
									
								
							@ -1,22 +1,19 @@
 | 
				
			|||||||
# Haier hOn
 | 
					# Haier hOn
 | 
				
			||||||
[](https://github.com/Andre0512/hon/releases/latest)
 | 
					[](https://github.com/Andre0512/hon/releases/latest)
 | 
				
			||||||

 | 
					[](https://github.com/Andre0512/hon/blob/main/LICENSE)
 | 
				
			||||||
[](https://analytics.home-assistant.io/)  
 | 
					[](https://tooomm.github.io/github-release-stats/?username=Andre0512&repository=hon)  
 | 
				
			||||||
Support for home appliances of Haier's mobile app hOn. 
 | 
					Support for home appliances of Haier's mobile app hOn. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Supported Appliances
 | 
					## Supported Appliances
 | 
				
			||||||
- Tumble Dryer
 | 
					- [Washing Machine](https://github.com/Andre0512/hon#washing-machine)
 | 
				
			||||||
- Washer Dryer
 | 
					- [Tumble Dryer](https://github.com/Andre0512/hon#tumble-dryer)
 | 
				
			||||||
- Washing Machine
 | 
					- [Washer Dryer](https://github.com/Andre0512/hon#washer-dryer)
 | 
				
			||||||
- Oven
 | 
					- [Oven](https://github.com/Andre0512/hon#oven)
 | 
				
			||||||
- Hob
 | 
					- [Dish Washer](https://github.com/Andre0512/hon#dish-washer)
 | 
				
			||||||
 | 
					- [Air conditioner](https://github.com/Andre0512/hon#air-conditioner)
 | 
				
			||||||
## Tested Appliances
 | 
					- [Fridge](https://github.com/Andre0512/hon#fridge)
 | 
				
			||||||
- Haier WD90-B14TEAM5
 | 
					- [Hob](https://github.com/Andre0512/hon#hob) [BETA]
 | 
				
			||||||
- Haier HD80-A3959
 | 
					- [Hood](https://github.com/Andre0512/hon#hood) [BETA]
 | 
				
			||||||
- Haier HWO60SM2F3XH
 | 
					 | 
				
			||||||
- Hoover H-WASH 500
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Configuration
 | 
					## Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -25,16 +22,78 @@ Support for home appliances of Haier's mobile app hOn.
 | 
				
			|||||||
**Method 2**: Settings > Devices & Services > Add Integration > **Haier 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._
 | 
					_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 AS20HPL1HRA
 | 
				
			||||||
 | 
					- Haier AS25PBAHRA
 | 
				
			||||||
 | 
					- Haier AS25S2SF1FA-WH
 | 
				
			||||||
 | 
					- Haier AS25TADHRA-2
 | 
				
			||||||
 | 
					- Haier AS35TADHRA-2
 | 
				
			||||||
 | 
					- Haier EG9012B19SU1JD
 | 
				
			||||||
 | 
					- Haier HA2MTSJ68MC
 | 
				
			||||||
 | 
					- Haier HADG6DS46BWIFI
 | 
				
			||||||
 | 
					- Haier HD80-A3959
 | 
				
			||||||
 | 
					- Haier HW90-B14TEAM5
 | 
				
			||||||
 | 
					- Haier HW100-B14959U1
 | 
				
			||||||
 | 
					- Haier HWD100-B14979
 | 
				
			||||||
 | 
					- Haier HWO60SM2F3XH
 | 
				
			||||||
 | 
					- Haier XIB 3B2SFS-80
 | 
				
			||||||
 | 
					- Haier XIB 6B2D3FB
 | 
				
			||||||
 | 
					- Candy BCTDH7A1TE
 | 
				
			||||||
 | 
					- Candy CCE4T620EWU
 | 
				
			||||||
 | 
					- Candy CIS633SCTTWIFI
 | 
				
			||||||
 | 
					- Candy CSOE C10DE-80
 | 
				
			||||||
 | 
					- Candy RO44 1286DWMC4-07
 | 
				
			||||||
 | 
					- 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 HW 68AMC/1-80
 | 
				
			||||||
 | 
					- Hoover HWPD 69AMBC/1-S
 | 
				
			||||||
 | 
					- Hoover HWPS4954DAMR-11
 | 
				
			||||||
 | 
					- Hoover NDE H10A2TCE-80
 | 
				
			||||||
 | 
					- Hoover NDE H9A2TSBEXS-S
 | 
				
			||||||
 | 
					- Hoover NDPHY10A2TCBEXSS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Contribute
 | 
					## Contribute
 | 
				
			||||||
Want to help us to support more appliances? Or add more sensors? Or help with translating? Or beautify some icons or captions? 
 | 
					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!
 | 
					Check out the [project on GitHub](https://github.com/Andre0512/hon), every contribution is welcome!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Useful Links
 | 
					## Useful Links
 | 
				
			||||||
 | 
					 | 
				
			||||||
* [GitHub repository](https://github.com/Andre0512/hon) (please add a star if you like this integration!)
 | 
					* [GitHub repository](https://github.com/Andre0512/hon) (please add a star if you like this integration!)
 | 
				
			||||||
* [pyhOn library](https://github.com/Andre0512/pyhOn)
 | 
					* [pyhOn library](https://github.com/Andre0512/pyhOn)
 | 
				
			||||||
* [Release notes](https://github.com/Andre0512/hon/releases)
 | 
					* [Release notes](https://github.com/Andre0512/hon/releases)
 | 
				
			||||||
* [Discussion and help](https://github.com/Andre0512/hon/discussions)
 | 
					* [Discussion and help](https://github.com/Andre0512/hon/discussions)
 | 
				
			||||||
* [Issues](https://github.com/Andre0512/hon/issues)
 | 
					* [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
 | 
				
			||||||
							
								
								
									
										369
									
								
								scripts/generate_translation.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										369
									
								
								scripts/generate_translation.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,369 @@
 | 
				
			|||||||
 | 
					#!/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,
 | 
				
			||||||
 | 
					    "ref_zones": const.REF_ZONES,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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_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",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLIMATE = {
 | 
				
			||||||
 | 
					    "fridge": {
 | 
				
			||||||
 | 
					        "preset_mode": {
 | 
				
			||||||
 | 
					            "name": "REF_CMD&CTRL.MODE_SELECTION_DRAWER_FRIDGE.FRIDGE_MODE_TITLE",
 | 
				
			||||||
 | 
					            "state": {
 | 
				
			||||||
 | 
					                "auto_set": "REF_CMD&CTRL.MODALITIES.ECO",
 | 
				
			||||||
 | 
					                "super_cool": "REF_CMD&CTRL.MODALITIES.SUPER_COOL",
 | 
				
			||||||
 | 
					                "holiday": "REF_CMD&CTRL.MODALITIES.BACK_FROM_HOLIDAY",
 | 
				
			||||||
 | 
					                "no_mode": "REF_CMD&CTRL.MODALITIES.NO_MODE_SELECTED",
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "freezer": {
 | 
				
			||||||
 | 
					        "preset_mode": {
 | 
				
			||||||
 | 
					            "name": "REF_CMD&CTRL.MODE_SELECTION_DRAWER_FREEZER.FREEZER_MODE_TITLE",
 | 
				
			||||||
 | 
					            "state": {
 | 
				
			||||||
 | 
					                "auto_set": "REF_CMD&CTRL.MODALITIES.ECO",
 | 
				
			||||||
 | 
					                "super_freeze": "REF_CMD&CTRL.MODALITIES.SHOCK_FREEZE",
 | 
				
			||||||
 | 
					                "no_mode": "REF_CMD&CTRL.MODALITIES.NO_MODE_SELECTED",
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "oven": {
 | 
				
			||||||
 | 
					        "preset_mode": {
 | 
				
			||||||
 | 
					            "name": "OV.TABS.PROGRAMS_TITLE",
 | 
				
			||||||
 | 
					            "state": "PROGRAMS.OV",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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",
 | 
				
			||||||
 | 
					        "refrigerator": "REF.NAME",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					        "start_program": ["WC.SET_PROGRAM.PROGRAM", "GLOBALS.GENERAL.START_ON"],
 | 
				
			||||||
 | 
					        "stop_program": ["WC.SET_PROGRAM.PROGRAM", "GLOBALS.GENERAL.STOP"],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					        "programs_ac": "WC.SET_PROGRAM.PROGRAM",
 | 
				
			||||||
 | 
					        "programs_ref": "WC.SET_PROGRAM.PROGRAM",
 | 
				
			||||||
 | 
					        "eco_pilot": "AC.PROGRAM_DETAIL.ECO_PILOT",
 | 
				
			||||||
 | 
					        "remaining_time": "ENROLLMENT_COMMON.GENERAL.REMAINING_TIME",
 | 
				
			||||||
 | 
					        "ref_zones": "IH.COMMON.COIL",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					        "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",
 | 
				
			||||||
 | 
					        "programs_ac": "WC.SET_PROGRAM.PROGRAM",
 | 
				
			||||||
 | 
					        "programs_ref": "WC.SET_PROGRAM.PROGRAM",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
 | 
					        "fridge": "REF.ZONES.FRIDGE",
 | 
				
			||||||
 | 
					        "freezer": "REF.ZONES.FREEZER",
 | 
				
			||||||
 | 
					        "oven": "GLOBALS.APPLIANCES_NAME.OV",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
					        for name, modes in CLIMATE.items():
 | 
				
			||||||
 | 
					            climate = old.setdefault("entity", {}).setdefault("climate", {})
 | 
				
			||||||
 | 
					            attr = climate.setdefault(name, {}).setdefault("state_attributes", {})
 | 
				
			||||||
 | 
					            for mode, data in modes.items():
 | 
				
			||||||
 | 
					                mode_name = load_key(data["name"], original, fallback)
 | 
				
			||||||
 | 
					                attr.setdefault(mode, {})["name"] = mode_name
 | 
				
			||||||
 | 
					                if isinstance(data["state"], dict):
 | 
				
			||||||
 | 
					                    for state, key in data["state"].items():
 | 
				
			||||||
 | 
					                        mode_state = load_key(key, original, fallback)
 | 
				
			||||||
 | 
					                        attr[mode].setdefault("state", {})[state] = mode_state
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    attr[mode]["state"] = load_keys(data["state"], original)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        translate_login(old, original, fallback)
 | 
				
			||||||
 | 
					        save_json(base_path / f"{language}.json", old)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
							
								
								
									
										94
									
								
								scripts/sensor_docs.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										94
									
								
								scripts/sensor_docs.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					#!/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,
 | 
				
			||||||
 | 
					    HonControlSwitchEntityDescription,
 | 
				
			||||||
 | 
					    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, HonControlSwitchEntityDescription):
 | 
				
			||||||
 | 
					                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 isinstance(entity, HonSwitchEntityDescription)
 | 
				
			||||||
 | 
					                or isinstance(entity, HonControlSwitchEntityDescription)
 | 
				
			||||||
 | 
					                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