Compare commits
	
		
			8 Commits
		
	
	
		
			v0.7.0
			...
			v0.7.3-bet
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a56d3e5f88 | |||
| 240dc85ff3 | |||
| 44794c35ca | |||
| a5c7b99569 | |||
| 6935f5f07f | |||
| 74f5887bb2 | |||
| 155b1ff91a | |||
| 7b80acb6b9 | 
							
								
								
									
										157
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								README.md
									
									
									
									
									
								
							| @ -30,6 +30,40 @@ _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 Models | ||||||
|  | Support was confirmed for these models. If a supported model is missing, please [add it with this form](https://forms.gle/bTSD8qFotdZFytbf8). | ||||||
|  | - Haier WD90-B14TEAM5 | ||||||
|  | - Haier HD80-A3959 | ||||||
|  | - Haier HWO60SM2F3XH | ||||||
|  | - Hoover H-WASH 500 | ||||||
|  | - Candy CIS633SCTTWIFI | ||||||
|  | - Haier XIB 3B2SFS-80 | ||||||
|  | - Haier XIB 6B2D3FB | ||||||
|  | - Hoover HSOT3161WG | ||||||
|  |  | ||||||
|  | ## 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 | ||||||
|  |  | ||||||
| ## Contribute | ## Contribute | ||||||
| Any kind of contribution is welcome! | Any kind of contribution is welcome! | ||||||
| ### Read out device data | ### Read out device data | ||||||
| @ -94,38 +128,6 @@ 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 |  | ||||||
| - Haier WD90-B14TEAM5 |  | ||||||
| - Haier HD80-A3959 |  | ||||||
| - Haier HWO60SM2F3XH |  | ||||||
| - Hoover H-WASH 500 |  | ||||||
| - Candy CIS633SCTTWIFI |  | ||||||
| - Haier XIB 3B2SFS-80 |  | ||||||
| - Haier XIB 6B2D3FB |  | ||||||
|  |  | ||||||
| ## Supported Languages |  | ||||||
| Translation of internal names like programs are available for all languages which are official supported by the hOn app: |  | ||||||
| * 🇨🇳 Chinese |  | ||||||
| * 🇭🇷 Croatian |  | ||||||
| * 🇨🇿 Czech |  | ||||||
| * 🇳🇱 Dutch |  | ||||||
| * 🇬🇧 English |  | ||||||
| * 🇫🇷 French |  | ||||||
| * 🇩🇪 German |  | ||||||
| * 🇬🇷 Greek |  | ||||||
| * 🇮🇱 Hebrew |  | ||||||
| * 🇮🇹 Italian |  | ||||||
| * 🇵🇱 Polish |  | ||||||
| * 🇵🇹 Portuguese |  | ||||||
| * 🇷🇴 Romanian |  | ||||||
| * 🇷🇺 Russian |  | ||||||
| * 🇷🇸 Serbian |  | ||||||
| * 🇸🇰 Slovak |  | ||||||
| * 🇸🇮 Slovenian |  | ||||||
| * 🇪🇸 Spanish |  | ||||||
| * 🇹🇷 Turkish |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## About this Repo | ## About this Repo | ||||||
| The existing integrations missed some features from the app I liked to have in HomeAssistant. | The existing integrations missed some features from the app I liked to have in HomeAssistant. | ||||||
| I tried to create a pull request, but in the structures of these existing repos, I find it hard to fit in my needs, so I basically rewrote everything.  | I 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.  | ||||||
| @ -137,19 +139,19 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| #### Configs | #### Configs | ||||||
| | Name | Icon | Entity | Key | | | Name | Icon | Entity | Key | | ||||||
| | --- | --- | --- | --- | | | --- | --- | --- | --- | | ||||||
| | 10° Heating |  | `switch` | `startProgram.10degreeHeatingStatus` | | | 10° Heating | `heat-wave` | `switch` | `settings.10degreeHeatingStatus` | | ||||||
| | Echo |  | `switch` | `startProgram.echoStatus` | | | Echo | `account-voice` | `switch` | `settings.echoStatus` | | ||||||
| | Eco Mode |  | `switch` | `startProgram.ecoMode` | | | Eco Mode |  | `switch` | `settings.ecoMode` | | ||||||
| | Eco Pilot |  | `select` | `startProgram.humanSensingStatus` | | | Eco Pilot | `run` | `select` | `settings.humanSensingStatus` | | ||||||
| | Health Mode |  | `switch` | `startProgram.healthMode` | | | Health Mode | `medication-outline` | `switch` | `settings.healthMode` | | ||||||
| | Mute |  | `switch` | `startProgram.muteStatus` | | | Mute | `volume-off` | `switch` | `settings.muteStatus` | | ||||||
| | Program |  | `select` | `startProgram.program` | | | Program |  | `select` | `startProgram.program` | | ||||||
| | Rapid Mode |  | `switch` | `startProgram.rapidMode` | | | Rapid Mode | `run-fast` | `switch` | `settings.rapidMode` | | ||||||
| | Screen Display |  | `switch` | `startProgram.screenDisplayStatus` | | | Screen Display | `monitor-small` | `switch` | `settings.screenDisplayStatus` | | ||||||
| | Self Cleaning |  | `switch` | `startProgram.selfCleaningStatus` | | | Self Cleaning | `air-filter` | `switch` | `settings.selfCleaningStatus` | | ||||||
| | Self Cleaning 56 |  | `switch` | `startProgram.selfCleaning56Status` | | | Self Cleaning 56 | `air-filter` | `switch` | `settings.selfCleaning56Status` | | ||||||
| | Silent Sleep |  | `switch` | `startProgram.silentSleepStatus` | | | Silent Sleep | `bed` | `switch` | `settings.silentSleepStatus` | | ||||||
| | Target Temperature | `thermometer` | `number` | `startProgram.tempSel` | | | Target Temperature | `thermometer` | `number` | `settings.tempSel` | | ||||||
|  |  | ||||||
| ### Dish washer | ### Dish washer | ||||||
| #### Controls | #### Controls | ||||||
| @ -208,7 +210,6 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Pan Status | `pot-mix` | `binary_sensor` | `panStatus` | | | Pan Status | `pot-mix` | `binary_sensor` | `panStatus` | | ||||||
| | Power | `lightning-bolt` | `sensor` | `power` | | | Power | `lightning-bolt` | `sensor` | `power` | | ||||||
| | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | ||||||
| | Remote Control | `remote` | `binary_sensor` | `attributes.parameters.remoteCtrValid` | |  | ||||||
| | Temperature | `thermometer` | `sensor` | `temp` | | | Temperature | `thermometer` | `sensor` | `temp` | | ||||||
|  |  | ||||||
| ### Oven | ### Oven | ||||||
| @ -230,7 +231,6 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Connection | `wifi` | `binary_sensor` | `attributes.lastConnEvent.category` | | | Connection | `wifi` | `binary_sensor` | `attributes.lastConnEvent.category` | | ||||||
| | On | `power-cycle` | `binary_sensor` | `attributes.parameters.onOffStatus` | | | On | `power-cycle` | `binary_sensor` | `attributes.parameters.onOffStatus` | | ||||||
| | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | ||||||
| | Remote Control | `remote` | `binary_sensor` | `attributes.parameters.remoteCtrValid` | |  | ||||||
| | Start Time | `clock-start` | `sensor` | `delayTime` | | | Start Time | `clock-start` | `sensor` | `delayTime` | | ||||||
| | Temperature | `thermometer` | `sensor` | `temp` | | | Temperature | `thermometer` | `sensor` | `temp` | | ||||||
| | Temperature Selected | `thermometer` | `sensor` | `tempSel` | | | Temperature Selected | `thermometer` | `sensor` | `tempSel` | | ||||||
| @ -253,58 +253,96 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` | | | Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` | | ||||||
| | Program |  | `select` | `startProgram.program` | | | Program |  | `select` | `startProgram.program` | | ||||||
| | Steam Type | `weather-dust` | `sensor` | `steamType` | | | Steam Type | `weather-dust` | `sensor` | `steamType` | | ||||||
| | Steam level | `smoke` | `sensor` | `steamLevel` | | | Steam level | `smoke` | `sensor` | `startProgram.steamLevel` | | ||||||
| | Sterilization | `clock-start` | `switch` | `startProgram.sterilizationStatus` | | | Sterilization | `clock-start` | `switch` | `startProgram.sterilizationStatus` | | ||||||
| | Suggested Load | `weight-kilogram` | `sensor` | `startProgram.suggestedLoadD` | | | Suggested Load | `weight-kilogram` | `sensor` | `startProgram.suggestedLoadD` | | ||||||
| | Temperature level | `thermometer` | `number` | `startProgram.tempLevel` | | | Temperature level | `thermometer` | `number` | `startProgram.tempLevel` | | ||||||
| #### Sensors | #### Sensors | ||||||
| | Name | Icon | Entity | Key | | | Name | Icon | Entity | Key | | ||||||
| | --- | --- | --- | --- | | | --- | --- | --- | --- | | ||||||
|  | | Anti-Crease |  | `binary_sensor` | `anticrease` | | ||||||
| | Connection |  | `binary_sensor` | `attributes.lastConnEvent.category` | | | Connection |  | `binary_sensor` | `attributes.lastConnEvent.category` | | ||||||
| | Door |  | `binary_sensor` | `doorStatus` | | | Door |  | `binary_sensor` | `doorStatus` | | ||||||
| | Dry level | `hair-dryer` | `sensor` | `dryLevel` | | | Dry level | `hair-dryer` | `sensor` | `dryLevel` | | ||||||
| | Error | `math-log` | `sensor` | `errors` | | | Error | `math-log` | `sensor` | `errors` | | ||||||
| | Machine Status | `information` | `sensor` | `machMode` | | | Machine Status | `information` | `sensor` | `machMode` | | ||||||
| | Program | `tumble-dryer` | `sensor` | `prCode` | | | Program | `tumble-dryer` | `sensor` | `programName` | | ||||||
| | Program Phase | `washing-machine` | `sensor` | `prPhase` | | | Program Phase | `washing-machine` | `sensor` | `prPhase` | | ||||||
| | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | ||||||
| | Start Time | `clock-start` | `sensor` | `delayTime` | | | Start Time | `clock-start` | `sensor` | `delayTime` | | ||||||
|  | | Steam level | `smoke` | `sensor` | `steamLevel` | | ||||||
| | Temperature level | `thermometer` | `sensor` | `tempLevel` | | | Temperature level | `thermometer` | `sensor` | `tempLevel` | | ||||||
|  |  | ||||||
| ### Washer dryer | ### Washer dryer | ||||||
| #### Controls | #### Controls | ||||||
| | Name | Icon | Entity | Key | | | Name | Icon | Entity | Key | | ||||||
| | --- | --- | --- | --- | | | --- | --- | --- | --- | | ||||||
| | Pause Washing Machine | `pause` | `switch` | `pauseProgram` / `resumeProgram` | | | Pause Washer Dryer | `pause` | `switch` | `pauseProgram` / `resumeProgram` | | ||||||
| | Washing Machine | `washing-machine` | `switch` | `startProgram` / `stopProgram` | | | Washer Dryer | `washing-machine` | `switch` | `startProgram` / `stopProgram` | | ||||||
| #### Configs | #### Configs | ||||||
| | Name | Icon | Entity | Key | | | 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 | `cup` | `switch` | `startProgram.autoDetergentStatus` | | ||||||
|  | | Delay Status | `timer-check` | `switch` | `startProgram.delayStatus` | | ||||||
| | Delay Time | `timer-plus` | `number` | `startProgram.delayTime` | | | 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.autoSoftenerStatus` | | ||||||
|  | | Liquid Detergent Dose | `cup-water` | `sensor` | `startProgram.liquidDetergentDose` | | ||||||
|  | | Main Wash Time | `clock-start` | `number` | `startProgram.mainWashTime` | | ||||||
|  | | Powder Detergent Dose | `cup` | `sensor` | `startProgram.powderDetergentDose` | | ||||||
| | Program |  | `select` | `startProgram.program` | | | 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` | | | 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 | #### Sensors | ||||||
| | Name | Icon | Entity | Key | | | Name | Icon | Entity | Key | | ||||||
| | --- | --- | --- | --- | | | --- | --- | --- | --- | | ||||||
| | Acqua Plus |  | `binary_sensor` | `acquaplus` | | | Acqua Plus |  | `binary_sensor` | `acquaplus` | | ||||||
| | Anti-Crease |  | `binary_sensor` | `anticrease` | | | Anti-Crease |  | `binary_sensor` | `anticrease` | | ||||||
| | Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` | | | Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` | | ||||||
| | Current Program | `tumble-dryer` | `sensor` | `prCode` | |  | ||||||
| | Current Temperature | `thermometer` | `sensor` | `temp` | | | Current Temperature | `thermometer` | `sensor` | `temp` | | ||||||
| | Current Water Used | `water` | `sensor` | `currentWaterUsed` | | | Current Water Used | `water` | `sensor` | `currentWaterUsed` | | ||||||
| | Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` | | | Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` | | ||||||
|  | | Door |  | `binary_sensor` | `doorStatus` | | ||||||
|  | | Door Lock |  | `binary_sensor` | `doorLockStatus` | | ||||||
| | Dry level | `hair-dryer` | `sensor` | `dryLevel` | | | Dry level | `hair-dryer` | `sensor` | `dryLevel` | | ||||||
|  | | Error | `math-log` | `sensor` | `errors` | | ||||||
| | Extra Rinse 1 |  | `binary_sensor` | `extraRinse1` | | | Extra Rinse 1 |  | `binary_sensor` | `extraRinse1` | | ||||||
| | Extra Rinse 2 |  | `binary_sensor` | `extraRinse2` | | | Extra Rinse 2 |  | `binary_sensor` | `extraRinse2` | | ||||||
| | Extra Rinse 3 |  | `binary_sensor` | `extraRinse3` | | | Extra Rinse 3 |  | `binary_sensor` | `extraRinse3` | | ||||||
| | Good Night Mode |  | `binary_sensor` | `goodNight` | | | Good Night Mode |  | `binary_sensor` | `goodNight` | | ||||||
| | Machine Status | `information` | `sensor` | `machMode` | | | Machine Status | `information` | `sensor` | `machMode` | | ||||||
| | Pre Wash |  | `binary_sensor` | `startProgram.prewash` | | | Pre Wash |  | `binary_sensor` | `startProgram.prewash` | | ||||||
|  | | Program | `tumble-dryer` | `sensor` | `programName` | | ||||||
| | Program Phase | `washing-machine` | `sensor` | `prPhase` | | | Program Phase | `washing-machine` | `sensor` | `prPhase` | | ||||||
| | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | ||||||
| | Remote Control | `remote` | `binary_sensor` | `attributes.lastConnEvent.category` | | | Remote Control | `remote` | `binary_sensor` | `attributes.lastConnEvent.category` | | ||||||
| | Spin Speed | `fast-forward-outline` | `sensor` | `spinSpeed` | | | Spin Speed | `speedometer` | `sensor` | `spinSpeed` | | ||||||
|  | | Start Time | `clock-start` | `sensor` | `delayTime` | | ||||||
| | Steam level | `smoke` | `sensor` | `steamLevel` | | | Steam level | `smoke` | `sensor` | `steamLevel` | | ||||||
|  | | Temperature level | `thermometer` | `sensor` | `tempLevel` | | ||||||
| | Total Power |  | `sensor` | `totalElectricityUsed` | | | Total Power |  | `sensor` | `totalElectricityUsed` | | ||||||
| | Total Wash Cycle | `counter` | `sensor` | `totalWashCycle` | | | Total Wash Cycle | `counter` | `sensor` | `totalWashCycle` | | ||||||
| | Total Water |  | `sensor` | `totalWaterUsed` | | | Total Water |  | `sensor` | `totalWaterUsed` | | ||||||
| @ -323,10 +361,10 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| | Delay Status | `timer-check` | `switch` | `startProgram.delayStatus` | | | Delay Status | `timer-check` | `switch` | `startProgram.delayStatus` | | ||||||
| | Delay Time | `timer-plus` | `number` | `startProgram.delayTime` | | | Delay Time | `timer-plus` | `number` | `startProgram.delayTime` | | ||||||
| | Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` | | | Energy Label | `lightning-bolt-circle` | `sensor` | `startProgram.energyLabel` | | ||||||
| | Extra Rinse 1 | `numeric-1-box-multiple-outline` | `switch` | `extraRinse1` | | | Extra Rinse 1 | `numeric-1-box-multiple-outline` | `switch` | `startProgram.extraRinse1` | | ||||||
| | Extra Rinse 2 | `numeric-2-box-multiple-outline` | `switch` | `extraRinse2` | | | Extra Rinse 2 | `numeric-2-box-multiple-outline` | `switch` | `startProgram.extraRinse2` | | ||||||
| | Extra Rinse 3 | `numeric-3-box-multiple-outline` | `switch` | `extraRinse3` | | | Extra Rinse 3 | `numeric-3-box-multiple-outline` | `switch` | `startProgram.extraRinse3` | | ||||||
| | Good Night | `weather-night` | `switch` | `goodNight` | | | Good Night | `weather-night` | `switch` | `startProgram.goodNight` | | ||||||
| | Keep Fresh | `refresh-circle` | `switch` | `startProgram.autoSoftenerStatus` | | | Keep Fresh | `refresh-circle` | `switch` | `startProgram.autoSoftenerStatus` | | ||||||
| | Liquid Detergent Dose | `cup-water` | `sensor` | `startProgram.liquidDetergentDose` | | | Liquid Detergent Dose | `cup-water` | `sensor` | `startProgram.liquidDetergentDose` | | ||||||
| | Main Wash Time | `clock-start` | `number` | `startProgram.mainWashTime` | | | Main Wash Time | `clock-start` | `number` | `startProgram.mainWashTime` | | ||||||
| @ -345,13 +383,20 @@ I moved the api related stuff into the package [pyhOn](https://github.com/Andre0 | |||||||
| #### Sensors | #### Sensors | ||||||
| | Name | Icon | Entity | Key | | | Name | Icon | Entity | Key | | ||||||
| | --- | --- | --- | --- | | | --- | --- | --- | --- | | ||||||
|  | | Acqua Plus |  | `binary_sensor` | `acquaplus` | | ||||||
| | Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` | | | Current Electricity Used | `lightning-bolt` | `sensor` | `currentElectricityUsed` | | ||||||
|  | | Current Temperature | `thermometer` | `sensor` | `temp` | | ||||||
| | Current Water Used | `water` | `sensor` | `currentWaterUsed` | | | Current Water Used | `water` | `sensor` | `currentWaterUsed` | | ||||||
| | Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` | | | Dirt level | `liquid-spot` | `sensor` | `dirtyLevel` | | ||||||
| | Door |  | `binary_sensor` | `doorStatus` | | | Door |  | `binary_sensor` | `doorStatus` | | ||||||
| | Door Lock |  | `binary_sensor` | `doorLockStatus` | | | Door Lock |  | `binary_sensor` | `doorLockStatus` | | ||||||
| | Error | `math-log` | `sensor` | `errors` | | | 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` | | | Machine Status | `information` | `sensor` | `machMode` | | ||||||
|  | | Pre Wash |  | `binary_sensor` | `startProgram.prewash` | | ||||||
| | Program Phase | `washing-machine` | `sensor` | `prPhase` | | | Program Phase | `washing-machine` | `sensor` | `prPhase` | | ||||||
| | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | | Remaining Time | `timer` | `sensor` | `remainingTimeMM` | | ||||||
| | Remote Control | `remote` | `binary_sensor` | `attributes.lastConnEvent.category` | | | Remote Control | `remote` | `binary_sensor` | `attributes.lastConnEvent.category` | | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ 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 HonCoordinator, HonEntity, unique_entities | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @ -52,32 +52,6 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { | |||||||
|             on_value="1", |             on_value="1", | ||||||
|             translation_key="door_open", |             translation_key="door_open", | ||||||
|         ), |         ), | ||||||
|     ), |  | ||||||
|     "TD": ( |  | ||||||
|         HonBinarySensorEntityDescription( |  | ||||||
|             key="attributes.lastConnEvent.category", |  | ||||||
|             name="Connection", |  | ||||||
|             device_class=BinarySensorDeviceClass.CONNECTIVITY, |  | ||||||
|             on_value="CONNECTED", |  | ||||||
|             translation_key="connection", |  | ||||||
|         ), |  | ||||||
|         HonBinarySensorEntityDescription( |  | ||||||
|             key="doorStatus", |  | ||||||
|             name="Door", |  | ||||||
|             device_class=BinarySensorDeviceClass.DOOR, |  | ||||||
|             on_value="1", |  | ||||||
|             translation_key="door_open", |  | ||||||
|         ), |  | ||||||
|     ), |  | ||||||
|     "WD": ( |  | ||||||
|         HonBinarySensorEntityDescription( |  | ||||||
|             key="attributes.lastConnEvent.category", |  | ||||||
|             name="Remote Control", |  | ||||||
|             device_class=BinarySensorDeviceClass.CONNECTIVITY, |  | ||||||
|             on_value="CONNECTED", |  | ||||||
|             icon="mdi:remote", |  | ||||||
|             translation_key="remote_control", |  | ||||||
|         ), |  | ||||||
|         HonBinarySensorEntityDescription( |         HonBinarySensorEntityDescription( | ||||||
|             key="startProgram.prewash", name="Pre Wash", translation_key="prewash" |             key="startProgram.prewash", name="Pre Wash", translation_key="prewash" | ||||||
|         ), |         ), | ||||||
| @ -96,6 +70,22 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { | |||||||
|         HonBinarySensorEntityDescription( |         HonBinarySensorEntityDescription( | ||||||
|             key="acquaplus", name="Acqua Plus", translation_key="acqua_plus" |             key="acquaplus", name="Acqua Plus", translation_key="acqua_plus" | ||||||
|         ), |         ), | ||||||
|  |     ), | ||||||
|  |     "TD": ( | ||||||
|  |         HonBinarySensorEntityDescription( | ||||||
|  |             key="attributes.lastConnEvent.category", | ||||||
|  |             name="Connection", | ||||||
|  |             device_class=BinarySensorDeviceClass.CONNECTIVITY, | ||||||
|  |             on_value="CONNECTED", | ||||||
|  |             translation_key="connection", | ||||||
|  |         ), | ||||||
|  |         HonBinarySensorEntityDescription( | ||||||
|  |             key="doorStatus", | ||||||
|  |             name="Door", | ||||||
|  |             device_class=BinarySensorDeviceClass.DOOR, | ||||||
|  |             on_value="1", | ||||||
|  |             translation_key="door_open", | ||||||
|  |         ), | ||||||
|         HonBinarySensorEntityDescription( |         HonBinarySensorEntityDescription( | ||||||
|             key="anticrease", name="Anti-Crease", translation_key="anti_crease" |             key="anticrease", name="Anti-Crease", translation_key="anti_crease" | ||||||
|         ), |         ), | ||||||
| @ -109,14 +99,6 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { | |||||||
|             icon="mdi:wifi", |             icon="mdi:wifi", | ||||||
|             translation_key="connection", |             translation_key="connection", | ||||||
|         ), |         ), | ||||||
|         HonBinarySensorEntityDescription( |  | ||||||
|             key="attributes.parameters.remoteCtrValid", |  | ||||||
|             name="Remote Control", |  | ||||||
|             device_class=BinarySensorDeviceClass.CONNECTIVITY, |  | ||||||
|             on_value="1", |  | ||||||
|             icon="mdi:remote", |  | ||||||
|             translation_key="remote_control", |  | ||||||
|         ), |  | ||||||
|         HonBinarySensorEntityDescription( |         HonBinarySensorEntityDescription( | ||||||
|             key="attributes.parameters.onOffStatus", |             key="attributes.parameters.onOffStatus", | ||||||
|             name="On", |             name="On", | ||||||
| @ -135,14 +117,6 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { | |||||||
|             icon="mdi:wifi", |             icon="mdi:wifi", | ||||||
|             translation_key="connection", |             translation_key="connection", | ||||||
|         ), |         ), | ||||||
|         HonBinarySensorEntityDescription( |  | ||||||
|             key="attributes.parameters.remoteCtrValid", |  | ||||||
|             name="Remote Control", |  | ||||||
|             device_class=BinarySensorDeviceClass.CONNECTIVITY, |  | ||||||
|             on_value="1", |  | ||||||
|             icon="mdi:remote", |  | ||||||
|             translation_key="remote_control", |  | ||||||
|         ), |  | ||||||
|         HonBinarySensorEntityDescription( |         HonBinarySensorEntityDescription( | ||||||
|             key="attributes.parameters.onOffStatus", |             key="attributes.parameters.onOffStatus", | ||||||
|             name="On", |             name="On", | ||||||
| @ -208,6 +182,9 @@ BINARY_SENSORS: dict[str, tuple[HonBinarySensorEntityDescription, ...]] = { | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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] |     hon: Hon = hass.data[DOMAIN][entry.unique_id] | ||||||
|     coordinators = hass.data[DOMAIN]["coordinators"] |     coordinators = hass.data[DOMAIN]["coordinators"] | ||||||
| @ -224,12 +201,8 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | |||||||
|             for description in descriptions: |             for description in descriptions: | ||||||
|                 if not device.get(description.key): |                 if not device.get(description.key): | ||||||
|                     continue |                     continue | ||||||
|                 appliances.extend( |                 appliances.append( | ||||||
|                     [ |                     HonBinarySensorEntity(hass, coordinator, entry, device, description) | ||||||
|                         HonBinarySensorEntity( |  | ||||||
|                             hass, coordinator, entry, device, description |  | ||||||
|                         ) |  | ||||||
|                     ] |  | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|     async_add_entities(appliances) |     async_add_entities(appliances) | ||||||
|  | |||||||
| @ -64,6 +64,11 @@ class HonButtonEntity(HonEntity, ButtonEntity): | |||||||
|     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" | ||||||
|  |  | ||||||
|  |  | ||||||
| class HonFeatureRequestButton(HonEntity, ButtonEntity): | class HonFeatureRequestButton(HonEntity, ButtonEntity): | ||||||
|     def __init__(self, hass, coordinator, entry, device: HonAppliance) -> None: |     def __init__(self, hass, coordinator, entry, device: HonAppliance) -> None: | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ from .hon import HonEntity, HonCoordinator | |||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| CLIMATES = { | CLIMATES = { | ||||||
|     "AC": (ClimateEntityDescription(key="startProgram"),), |     "AC": (ClimateEntityDescription(key="startProgram", icon="mdi:air-conditioner"),), | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -47,7 +47,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | |||||||
|  |  | ||||||
|         if descriptions := CLIMATES.get(device.appliance_type): |         if descriptions := CLIMATES.get(device.appliance_type): | ||||||
|             for description in descriptions: |             for description in descriptions: | ||||||
|                 if description.key not in device.available_settings: |                 if description.key not in list(device.commands): | ||||||
|                     continue |                     continue | ||||||
|                 appliances.extend( |                 appliances.extend( | ||||||
|                     [HonClimateEntity(hass, coordinator, entry, device, description)] |                     [HonClimateEntity(hass, coordinator, entry, device, description)] | ||||||
| @ -61,21 +61,21 @@ class HonClimateEntity(HonEntity, ClimateEntity): | |||||||
|     ) -> None: |     ) -> None: | ||||||
|         super().__init__(hass, entry, coordinator, device) |         super().__init__(hass, entry, coordinator, device) | ||||||
|         self._coordinator = coordinator |         self._coordinator = coordinator | ||||||
|         self._device = coordinator.device |         self._device = device | ||||||
|         self.entity_description = description |         self.entity_description = description | ||||||
|         self._hass = hass |         self._hass = hass | ||||||
|         self._attr_unique_id = f"{super().unique_id}climate" |         self._attr_unique_id = f"{super().unique_id}climate" | ||||||
|  |  | ||||||
|         self._attr_temperature_unit = TEMP_CELSIUS |         self._attr_temperature_unit = TEMP_CELSIUS | ||||||
|         self._attr_target_temperature_step = PRECISION_WHOLE |         self._attr_target_temperature_step = PRECISION_WHOLE | ||||||
|         self._attr_max_temp = device.settings["tempSel"].max |         self._attr_max_temp = device.settings["settings.tempSel"].max | ||||||
|         self._attr_min_temp = device.settings["tempSel"].min |         self._attr_min_temp = device.settings["settings.tempSel"].min | ||||||
|  |  | ||||||
|         self._attr_hvac_modes = [HVACMode.OFF] + [ |         self._attr_hvac_modes = [HVACMode.OFF] + [ | ||||||
|             HON_HVAC_MODE[mode] for mode in device.settings["machMode"].values |             HON_HVAC_MODE[mode] for mode in device.settings["settings.machMode"].values | ||||||
|         ] |         ] | ||||||
|         self._attr_fan_modes = [FAN_OFF] + [ |         self._attr_fan_modes = [FAN_OFF] + [ | ||||||
|             HON_FAN[mode] for mode in device.settings["windSpeed"].values |             HON_FAN[mode] for mode in device.settings["settings.windSpeed"].values | ||||||
|         ] |         ] | ||||||
|         self._attr_swing_modes = [ |         self._attr_swing_modes = [ | ||||||
|             SWING_OFF, |             SWING_OFF, | ||||||
| @ -89,22 +89,28 @@ class HonClimateEntity(HonEntity, ClimateEntity): | |||||||
|             | ClimateEntityFeature.SWING_MODE |             | ClimateEntityFeature.SWING_MODE | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |         self._handle_coordinator_update() | ||||||
|  |  | ||||||
|     async def async_set_hvac_mode(self, hvac_mode): |     async def async_set_hvac_mode(self, hvac_mode): | ||||||
|         if hvac_mode == HVACMode.OFF: |         if hvac_mode == HVACMode.OFF: | ||||||
|             self._device.commands["stopProgram"].send() |             await self._device.commands["stopProgram"].send() | ||||||
|         else: |         else: | ||||||
|             self._device.settings["program"].value = HON_HVAC_PROGRAM[hvac_mode] |             self._device.settings["startProgram.program"].value = HON_HVAC_PROGRAM[ | ||||||
|             self._device.commands["startProgram"].send() |                 hvac_mode | ||||||
|  |             ] | ||||||
|  |             await self._device.commands["startProgram"].send() | ||||||
|         self._attr_hvac_mode = hvac_mode |         self._attr_hvac_mode = hvac_mode | ||||||
|  |  | ||||||
|     async def async_set_fan_mode(self, fan_mode): |     async def async_set_fan_mode(self, fan_mode): | ||||||
|         mode_number = list(HON_FAN.values()).index(fan_mode) |         mode_number = list(HON_FAN.values()).index(fan_mode) | ||||||
|         self._device.settings["windSpeed"].value = list(HON_FAN.keys())[mode_number] |         self._device.settings["settings.windSpeed"].value = list(HON_FAN.keys())[ | ||||||
|         self._device.commands["startProgram"].send() |             mode_number | ||||||
|  |         ] | ||||||
|  |         await self._device.commands["settings"].send() | ||||||
|  |  | ||||||
|     async def async_set_swing_mode(self, swing_mode): |     async def async_set_swing_mode(self, swing_mode): | ||||||
|         horizontal = self._device.settings["windDirectionHorizontal"] |         horizontal = self._device.settings["settings.windDirectionHorizontal"] | ||||||
|         vertical = self._device.settings["windDirectionVertical"] |         vertical = self._device.settings["settings.windDirectionVertical"] | ||||||
|         if swing_mode in [SWING_BOTH, SWING_HORIZONTAL]: |         if swing_mode in [SWING_BOTH, SWING_HORIZONTAL]: | ||||||
|             horizontal.value = "7" |             horizontal.value = "7" | ||||||
|         if swing_mode in [SWING_BOTH, SWING_VERTICAL]: |         if swing_mode in [SWING_BOTH, SWING_VERTICAL]: | ||||||
| @ -114,30 +120,30 @@ class HonClimateEntity(HonEntity, ClimateEntity): | |||||||
|         if swing_mode in [SWING_OFF, SWING_VERTICAL] and horizontal.value == "7": |         if swing_mode in [SWING_OFF, SWING_VERTICAL] and horizontal.value == "7": | ||||||
|             horizontal.value = "0" |             horizontal.value = "0" | ||||||
|         self._attr_swing_mode = swing_mode |         self._attr_swing_mode = swing_mode | ||||||
|         self._device.commands["startProgram"].send() |         await self._device.commands["settings"].send() | ||||||
|  |  | ||||||
|     async def async_set_temperature(self, **kwargs): |     async def async_set_temperature(self, **kwargs): | ||||||
|         if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None: |         if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None: | ||||||
|             return False |             return False | ||||||
|         self._device.settings["selTemp"].value = temperature |         self._device.settings["settings.selTemp"].value = temperature | ||||||
|         self._device.commands["startProgram"].send() |         await self._device.commands["settings"].send() | ||||||
|  |  | ||||||
|     @callback |     @callback | ||||||
|     def _handle_coordinator_update(self, update=True) -> None: |     def _handle_coordinator_update(self, update=True) -> None: | ||||||
|         self._attr_target_temperature = int(float(self._device.get("tempSel"))) |         self._attr_target_temperature = int(float(self._device.get("tempSel"))) | ||||||
|         self._attr_current_temperature = float(self._device.get("tempIndoor")) |         self._attr_current_temperature = float(self._device.get("tempIndoor")) | ||||||
|         self._attr_max_temp = self._device.settings["tempSel"].max |         self._attr_max_temp = self._device.settings["settings.tempSel"].max | ||||||
|         self._attr_min_temp = self._device.settings["tempSel"].min |         self._attr_min_temp = self._device.settings["settings.tempSel"].min | ||||||
|  |  | ||||||
|         if self._device.get("onOffStatus") == "0": |         if self._device.get("onOffStatus") == "0": | ||||||
|             self._attr_hvac_mode = HVACMode.OFF |             self._attr_hvac_mode = HVACMode.OFF | ||||||
|         else: |         else: | ||||||
|             self._attr_hvac_mode = HON_HVAC_MODE[self._device.get("machMode")] |             self._attr_hvac_mode = HON_HVAC_MODE[self._device.get("machMode") or "0"] | ||||||
|  |  | ||||||
|         self._attr_fan_mode = HON_FAN[self._device.settings["windSpeed"].value] |         self._attr_fan_mode = HON_FAN[self._device.settings["settings.windSpeed"].value] | ||||||
|  |  | ||||||
|         horizontal = self._device.settings["windDirectionHorizontal"] |         horizontal = self._device.settings["settings.windDirectionHorizontal"] | ||||||
|         vertical = self._device.settings["windDirectionVertical"] |         vertical = self._device.settings["settings.windDirectionVertical"] | ||||||
|         if horizontal == "7" and vertical == "8": |         if horizontal == "7" and vertical == "8": | ||||||
|             self._attr_swing_mode = SWING_BOTH |             self._attr_swing_mode = SWING_BOTH | ||||||
|         elif horizontal == "7": |         elif horizontal == "7": | ||||||
|  | |||||||
| @ -120,6 +120,19 @@ TUMBLE_DRYER_PR_PHASE = { | |||||||
|     "19": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE", |     "19": "WASHING_CMD&CTRL.PHASE_DRYING.TITLE", | ||||||
|     "20": "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 = { | DISHWASHER_PR_PHASE = { | ||||||
|     "0": "WASHING_CMD&CTRL.PHASE_READY.TITLE", |     "0": "WASHING_CMD&CTRL.PHASE_READY.TITLE", | ||||||
|     "1": "WASHING_CMD&CTRL.PHASE_PREWASH.TITLE", |     "1": "WASHING_CMD&CTRL.PHASE_PREWASH.TITLE", | ||||||
|  | |||||||
| @ -50,3 +50,12 @@ class HonCoordinator(DataUpdateCoordinator): | |||||||
|  |  | ||||||
|     async def _async_update_data(self): |     async def _async_update_data(self): | ||||||
|         await self._device.update() |         await self._device.update() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def unique_entities(base_entities, new_entities): | ||||||
|  |     result = list(base_entities) | ||||||
|  |     existing_entities = [entity.key for entity in base_entities] | ||||||
|  |     for entity in new_entities: | ||||||
|  |         if entity.key not in existing_entities: | ||||||
|  |             result.append(entity) | ||||||
|  |     return tuple(result) | ||||||
|  | |||||||
| @ -6,6 +6,6 @@ | |||||||
|   "documentation": "https://github.com/Andre0512/hon/", |   "documentation": "https://github.com/Andre0512/hon/", | ||||||
|   "iot_class": "cloud_polling", |   "iot_class": "cloud_polling", | ||||||
|   "issue_tracker": "https://github.com/Andre0512/hon/issues", |   "issue_tracker": "https://github.com/Andre0512/hon/issues", | ||||||
|  "requirements": ["pyhOn==0.10.3"], |  "requirements": ["pyhOn==0.10.6"], | ||||||
|   "version": "0.7.0" |   "version": "0.7.3-beta.1" | ||||||
| } | } | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ from homeassistant.core import callback | |||||||
| from homeassistant.helpers.entity import EntityCategory | from homeassistant.helpers.entity import EntityCategory | ||||||
|  |  | ||||||
| from .const import DOMAIN | from .const import DOMAIN | ||||||
| from .hon import HonEntity, HonCoordinator | from .hon import HonEntity, HonCoordinator, unique_entities | ||||||
|  |  | ||||||
| NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | ||||||
|     "WM": ( |     "WM": ( | ||||||
| @ -85,16 +85,6 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | |||||||
|             translation_key="dry_time", |             translation_key="dry_time", | ||||||
|         ), |         ), | ||||||
|     ), |     ), | ||||||
|     "WD": ( |  | ||||||
|         NumberEntityDescription( |  | ||||||
|             key="startProgram.delayTime", |  | ||||||
|             name="Delay Time", |  | ||||||
|             icon="mdi:timer-plus", |  | ||||||
|             entity_category=EntityCategory.CONFIG, |  | ||||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, |  | ||||||
|             translation_key="delay_time", |  | ||||||
|         ), |  | ||||||
|     ), |  | ||||||
|     "OV": ( |     "OV": ( | ||||||
|         NumberEntityDescription( |         NumberEntityDescription( | ||||||
|             key="startProgram.delayTime", |             key="startProgram.delayTime", | ||||||
| @ -156,7 +146,7 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | |||||||
|     ), |     ), | ||||||
|     "AC": ( |     "AC": ( | ||||||
|         NumberEntityDescription( |         NumberEntityDescription( | ||||||
|             key="startProgram.tempSel", |             key="settings.tempSel", | ||||||
|             name="Target Temperature", |             name="Target Temperature", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             icon="mdi:thermometer", |             icon="mdi:thermometer", | ||||||
| @ -166,6 +156,8 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | |||||||
|     ), |     ), | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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] |     hon: Hon = hass.data[DOMAIN][entry.unique_id] | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ from homeassistant.core import callback | |||||||
| from homeassistant.helpers.entity import EntityCategory | from homeassistant.helpers.entity import EntityCategory | ||||||
|  |  | ||||||
| from .const import DOMAIN | from .const import DOMAIN | ||||||
| from .hon import HonEntity, HonCoordinator | from .hon import HonEntity, HonCoordinator, unique_entities | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @ -66,14 +66,6 @@ SELECTS = { | |||||||
|             translation_key="dry_levels", |             translation_key="dry_levels", | ||||||
|         ), |         ), | ||||||
|     ), |     ), | ||||||
|     "WD": ( |  | ||||||
|         SelectEntityDescription( |  | ||||||
|             key="startProgram.program", |  | ||||||
|             name="Program", |  | ||||||
|             entity_category=EntityCategory.CONFIG, |  | ||||||
|             translation_key="programs_wm", |  | ||||||
|         ), |  | ||||||
|     ), |  | ||||||
|     "OV": ( |     "OV": ( | ||||||
|         SelectEntityDescription( |         SelectEntityDescription( | ||||||
|             key="startProgram.program", |             key="startProgram.program", | ||||||
| @ -106,14 +98,17 @@ SELECTS = { | |||||||
|             translation_key="programs_ac", |             translation_key="programs_ac", | ||||||
|         ), |         ), | ||||||
|         SelectEntityDescription( |         SelectEntityDescription( | ||||||
|             key="startProgram.humanSensingStatus", |             key="settings.humanSensingStatus", | ||||||
|             name="Eco Pilot", |             name="Eco Pilot", | ||||||
|  |             icon="mdi:run", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="eco_pilot", |             translation_key="eco_pilot", | ||||||
|         ), |         ), | ||||||
|     ), |     ), | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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] |     hon: Hon = hass.data[DOMAIN][entry.unique_id] | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ from homeassistant.const import PERCENTAGE | |||||||
|  |  | ||||||
| from . import const | from . import const | ||||||
| from .const import DOMAIN | from .const import DOMAIN | ||||||
| from .hon import HonCoordinator, HonEntity | from .hon import HonCoordinator, HonEntity, unique_entities | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @ -112,7 +112,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | |||||||
|             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, |             native_unit_of_measurement=REVOLUTIONS_PER_MINUTE, | ||||||
|             translation_key="spin_speed", |             translation_key="spin_speed", | ||||||
|         ), |         ), | ||||||
|         SensorEntityDescription( |         SensorEntityDescription( | ||||||
| @ -161,6 +161,14 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | |||||||
|             native_unit_of_measurement=UnitOfMass.KILOGRAMS, |             native_unit_of_measurement=UnitOfMass.KILOGRAMS, | ||||||
|             translation_key="suggested_load", |             translation_key="suggested_load", | ||||||
|         ), |         ), | ||||||
|  |         SensorEntityDescription( | ||||||
|  |             key="temp", | ||||||
|  |             name="Current Temperature", | ||||||
|  |             icon="mdi:thermometer", | ||||||
|  |             state_class=SensorStateClass.MEASUREMENT, | ||||||
|  |             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||||
|  |             translation_key="temperature", | ||||||
|  |         ), | ||||||
|     ), |     ), | ||||||
|     "TD": ( |     "TD": ( | ||||||
|         SensorEntityDescription( |         SensorEntityDescription( | ||||||
| @ -238,12 +246,18 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | |||||||
|             translation_key="energy_label", |             translation_key="energy_label", | ||||||
|         ), |         ), | ||||||
|         SensorEntityDescription( |         SensorEntityDescription( | ||||||
|             key="steamLevel", |             key="startProgram.steamLevel", | ||||||
|             name="Steam level", |             name="Steam level", | ||||||
|             icon="mdi:smoke", |             icon="mdi:smoke", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="steam_level", |             translation_key="steam_level", | ||||||
|         ), |         ), | ||||||
|  |         SensorEntityDescription( | ||||||
|  |             key="steamLevel", | ||||||
|  |             name="Steam level", | ||||||
|  |             icon="mdi:smoke", | ||||||
|  |             translation_key="steam_level", | ||||||
|  |         ), | ||||||
|         SensorEntityDescription( |         SensorEntityDescription( | ||||||
|             key="steamType", |             key="steamType", | ||||||
|             name="Steam Type", |             name="Steam Type", | ||||||
| @ -251,120 +265,6 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | |||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|         ), |         ), | ||||||
|     ), |     ), | ||||||
|     "WD": ( |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="totalElectricityUsed", |  | ||||||
|             name="Total Power", |  | ||||||
|             device_class=SensorDeviceClass.ENERGY, |  | ||||||
|             state_class=SensorStateClass.TOTAL_INCREASING, |  | ||||||
|             native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, |  | ||||||
|             translation_key="energy_total", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="totalWaterUsed", |  | ||||||
|             name="Total Water", |  | ||||||
|             device_class=SensorDeviceClass.WATER, |  | ||||||
|             state_class=SensorStateClass.TOTAL_INCREASING, |  | ||||||
|             native_unit_of_measurement=UnitOfVolume.LITERS, |  | ||||||
|             translation_key="water_total", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="totalWashCycle", |  | ||||||
|             name="Total Wash Cycle", |  | ||||||
|             state_class=SensorStateClass.TOTAL_INCREASING, |  | ||||||
|             icon="mdi:counter", |  | ||||||
|             translation_key="cycles_total", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="currentElectricityUsed", |  | ||||||
|             name="Current Electricity Used", |  | ||||||
|             state_class=SensorStateClass.MEASUREMENT, |  | ||||||
|             device_class=SensorDeviceClass.POWER, |  | ||||||
|             native_unit_of_measurement=UnitOfPower.KILO_WATT, |  | ||||||
|             icon="mdi:lightning-bolt", |  | ||||||
|             translation_key="energy_current", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="currentWaterUsed", |  | ||||||
|             name="Current Water Used", |  | ||||||
|             state_class=SensorStateClass.MEASUREMENT, |  | ||||||
|             icon="mdi:water", |  | ||||||
|             translation_key="water_current", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="startProgram.weight", |  | ||||||
|             name="Suggested weight", |  | ||||||
|             state_class=SensorStateClass.MEASUREMENT, |  | ||||||
|             entity_category=EntityCategory.CONFIG, |  | ||||||
|             native_unit_of_measurement=UnitOfMass.KILOGRAMS, |  | ||||||
|             icon="mdi:weight-kilogram", |  | ||||||
|             translation_key="suggested_load", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="machMode", |  | ||||||
|             name="Machine Status", |  | ||||||
|             icon="mdi:information", |  | ||||||
|             device_class=SensorDeviceClass.ENUM, |  | ||||||
|             translation_key="washing_modes", |  | ||||||
|             options=list(const.MACH_MODE), |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="spinSpeed", |  | ||||||
|             name="Spin Speed", |  | ||||||
|             icon="mdi:fast-forward-outline", |  | ||||||
|             state_class=SensorStateClass.MEASUREMENT, |  | ||||||
|             native_unit_of_measurement=REVOLUTIONS_PER_MINUTE, |  | ||||||
|             translation_key="spin_speed", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="remainingTimeMM", |  | ||||||
|             name="Remaining Time", |  | ||||||
|             icon="mdi:timer", |  | ||||||
|             state_class=SensorStateClass.MEASUREMENT, |  | ||||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, |  | ||||||
|             translation_key="remaining_time", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="prCode", |  | ||||||
|             name="Current Program", |  | ||||||
|             icon="mdi:tumble-dryer", |  | ||||||
|             translation_key="programs", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="prPhase", |  | ||||||
|             name="Program Phase", |  | ||||||
|             icon="mdi:washing-machine", |  | ||||||
|             device_class=SensorDeviceClass.ENUM, |  | ||||||
|             translation_key="program_phases_wm", |  | ||||||
|             options=list(const.WASHING_PR_PHASE), |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="dryLevel", |  | ||||||
|             name="Dry level", |  | ||||||
|             icon="mdi:hair-dryer", |  | ||||||
|             translation_key="dry_levels", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="dirtyLevel", |  | ||||||
|             name="Dirt level", |  | ||||||
|             icon="mdi:liquid-spot", |  | ||||||
|             translation_key="dirt_level", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="steamLevel", |  | ||||||
|             name="Steam level", |  | ||||||
|             icon="mdi:smoke", |  | ||||||
|             translation_key="steam_level", |  | ||||||
|         ), |  | ||||||
|         SensorEntityDescription( |  | ||||||
|             key="temp", |  | ||||||
|             name="Current Temperature", |  | ||||||
|             icon="mdi:thermometer", |  | ||||||
|             state_class=SensorStateClass.MEASUREMENT, |  | ||||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, |  | ||||||
|             translation_key="temperature", |  | ||||||
|         ), |  | ||||||
|     ), |  | ||||||
|     "OV": ( |     "OV": ( | ||||||
|         SensorEntityDescription( |         SensorEntityDescription( | ||||||
|             key="remainingTimeMM", |             key="remainingTimeMM", | ||||||
| @ -501,6 +401,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | |||||||
|         ), |         ), | ||||||
|     ), |     ), | ||||||
| } | } | ||||||
|  | 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: | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ from pyhon.appliance import HonAppliance | |||||||
| 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 HonCoordinator, HonEntity, unique_entities | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @ -82,28 +82,28 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | |||||||
|             translation_key="acqua_plus", |             translation_key="acqua_plus", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="extraRinse1", |             key="startProgram.extraRinse1", | ||||||
|             name="Extra Rinse 1", |             name="Extra Rinse 1", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             icon="mdi:numeric-1-box-multiple-outline", |             icon="mdi:numeric-1-box-multiple-outline", | ||||||
|             translation_key="extra_rinse_1", |             translation_key="extra_rinse_1", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="extraRinse2", |             key="startProgram.extraRinse2", | ||||||
|             name="Extra Rinse 2", |             name="Extra Rinse 2", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             icon="mdi:numeric-2-box-multiple-outline", |             icon="mdi:numeric-2-box-multiple-outline", | ||||||
|             translation_key="extra_rinse_2", |             translation_key="extra_rinse_2", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="extraRinse3", |             key="startProgram.extraRinse3", | ||||||
|             name="Extra Rinse 3", |             name="Extra Rinse 3", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             icon="mdi:numeric-3-box-multiple-outline", |             icon="mdi:numeric-3-box-multiple-outline", | ||||||
|             translation_key="extra_rinse_3", |             translation_key="extra_rinse_3", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="goodNight", |             key="startProgram.goodNight", | ||||||
|             name="Good Night", |             name="Good Night", | ||||||
|             icon="mdi:weather-night", |             icon="mdi:weather-night", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
| @ -168,7 +168,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | |||||||
|     "WD": ( |     "WD": ( | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             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", | ||||||
| @ -176,7 +176,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | |||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             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", | ||||||
| @ -237,65 +237,77 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | |||||||
|     ), |     ), | ||||||
|     "AC": ( |     "AC": ( | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.10degreeHeatingStatus", |             key="settings.10degreeHeatingStatus", | ||||||
|             name="10° Heating", |             name="10° Heating", | ||||||
|  |             icon="mdi:heat-wave", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="10_degree_heating", |             translation_key="10_degree_heating", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.echoStatus", |             key="settings.echoStatus", | ||||||
|             name="Echo", |             name="Echo", | ||||||
|  |             icon="mdi:account-voice", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.ecoMode", |             key="settings.ecoMode", | ||||||
|             name="Eco Mode", |             name="Eco Mode", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="eco_mode", |             translation_key="eco_mode", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.healthMode", |             key="settings.healthMode", | ||||||
|             name="Health Mode", |             name="Health Mode", | ||||||
|  |             icon="mdi:medication-outline", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.muteStatus", |             key="settings.muteStatus", | ||||||
|             name="Mute", |             name="Mute", | ||||||
|  |             icon="mdi:volume-off", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="mute_mode", |             translation_key="mute_mode", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.rapidMode", |             key="settings.rapidMode", | ||||||
|             name="Rapid Mode", |             name="Rapid Mode", | ||||||
|  |             icon="mdi:run-fast", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="rapid_mode", |             translation_key="rapid_mode", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.screenDisplayStatus", |             key="settings.screenDisplayStatus", | ||||||
|             name="Screen Display", |             name="Screen Display", | ||||||
|  |             icon="mdi:monitor-small", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.selfCleaning56Status", |             key="settings.selfCleaning56Status", | ||||||
|             name="Self Cleaning 56", |             name="Self Cleaning 56", | ||||||
|  |             icon="mdi:air-filter", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="self_clean_56", |             translation_key="self_clean_56", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.selfCleaningStatus", |             key="settings.selfCleaningStatus", | ||||||
|             name="Self Cleaning", |             name="Self Cleaning", | ||||||
|  |             icon="mdi:air-filter", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="self_clean", |             translation_key="self_clean", | ||||||
|         ), |         ), | ||||||
|         HonSwitchEntityDescription( |         HonSwitchEntityDescription( | ||||||
|             key="startProgram.silentSleepStatus", |             key="settings.silentSleepStatus", | ||||||
|             name="Silent Sleep", |             name="Silent Sleep", | ||||||
|  |             icon="mdi:bed", | ||||||
|             entity_category=EntityCategory.CONFIG, |             entity_category=EntityCategory.CONFIG, | ||||||
|             translation_key="silent_mode", |             translation_key="silent_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] |     hon: Hon = hass.data[DOMAIN][entry.unique_id] | ||||||
| @ -312,9 +324,15 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | |||||||
|         if descriptions := SWITCHES.get(device.appliance_type): |         if descriptions := SWITCHES.get(device.appliance_type): | ||||||
|             for description in descriptions: |             for description in descriptions: | ||||||
|                 if ( |                 if ( | ||||||
|  |                     description.entity_category == EntityCategory.CONFIG | ||||||
|  |                     and description.key not in device.available_settings | ||||||
|  |                     or not any( | ||||||
|                         device.get(description.key) is not None |                         device.get(description.key) is not None | ||||||
|                     or description.key in device.available_settings |                         or description.turn_on_key in list(device.commands) | ||||||
|  |                         or description.turn_off_key in list(device.commands) | ||||||
|  |                     ) | ||||||
|                 ): |                 ): | ||||||
|  |                     continue | ||||||
|                 appliances.extend( |                 appliances.extend( | ||||||
|                     [HonSwitchEntity(hass, coordinator, entry, device, description)] |                     [HonSwitchEntity(hass, coordinator, entry, device, description)] | ||||||
|                 ) |                 ) | ||||||
| @ -376,3 +394,11 @@ class HonSwitchEntity(HonEntity, SwitchEntity): | |||||||
|             await self.coordinator.async_refresh() |             await self.coordinator.async_refresh() | ||||||
|         else: |         else: | ||||||
|             await self._device.commands[self.entity_description.turn_off_key].send() |             await self._device.commands[self.entity_description.turn_off_key].send() | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def available(self) -> bool: | ||||||
|  |         """Return True if entity is available.""" | ||||||
|  |         if self.entity_category == EntityCategory.CONFIG: | ||||||
|  |             return super().available | ||||||
|  |         else: | ||||||
|  |             return super().available and self._device.get("remoteCtrValid") == "1" | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								info.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								info.md
									
									
									
									
									
								
							| @ -13,12 +13,6 @@ Support for home appliances of Haier's mobile app hOn. | |||||||
| - [Dish Washer](https://github.com/Andre0512/hon#dish-washer) | - [Dish Washer](https://github.com/Andre0512/hon#dish-washer) | ||||||
| - [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA] | - [Air conditioner](https://github.com/Andre0512/hon#air-conditioner) [BETA] | ||||||
|  |  | ||||||
| ## Tested Appliances |  | ||||||
| - Haier WD90-B14TEAM5 |  | ||||||
| - Haier HD80-A3959 |  | ||||||
| - Haier HWO60SM2F3XH |  | ||||||
| - Hoover H-WASH 500 |  | ||||||
|  |  | ||||||
| ## Configuration | ## Configuration | ||||||
|  |  | ||||||
| **Method 1**: [](https://my.home-assistant.io/redirect/config_flow_start/?domain=hon) | **Method 1**: [](https://my.home-assistant.io/redirect/config_flow_start/?domain=hon) | ||||||
| @ -26,9 +20,16 @@ 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._ | ||||||
|  |  | ||||||
| ## Contribute | ## Supported Models | ||||||
| Want to help us to support more appliances? Or add more sensors? Or help with translating? Or beautify some icons or captions?  | Support was confirmed for these models. If a supported model is missing, please [add it with this form](https://forms.gle/bTSD8qFotdZFytbf8). | ||||||
| Check out the [project on GitHub](https://github.com/Andre0512/hon), every contribution is welcome! | - Haier WD90-B14TEAM5 | ||||||
|  | - Haier HD80-A3959 | ||||||
|  | - Haier HWO60SM2F3XH | ||||||
|  | - Hoover H-WASH 500 | ||||||
|  | - Candy CIS633SCTTWIFI | ||||||
|  | - Haier XIB 3B2SFS-80 | ||||||
|  | - Haier XIB 6B2D3FB | ||||||
|  | - Hoover HSOT3161WG | ||||||
|  |  | ||||||
| ## Supported Languages | ## Supported Languages | ||||||
| Translation of internal names like programs are available for all languages which are official supported by the hOn app: | Translation of internal names like programs are available for all languages which are official supported by the hOn app: | ||||||
| @ -52,10 +53,13 @@ Translation of internal names like programs are available for all languages whic | |||||||
| * 🇪🇸 Spanish | * 🇪🇸 Spanish | ||||||
| * 🇹🇷 Turkish | * 🇹🇷 Turkish | ||||||
|  |  | ||||||
|  | ## Contribute | ||||||
|  | Want to help us to support more appliances? Or add more sensors? Or help with translating? Or beautify some icons or captions?  | ||||||
|  | Check out the [project on GitHub](https://github.com/Andre0512/hon), every contribution is welcome! | ||||||
|  |  | ||||||
| ## Useful Links | ## 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,10 +3,14 @@ | |||||||
| import asyncio | import asyncio | ||||||
| import json | import json | ||||||
| import re | import re | ||||||
|  | import sys | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
|  |  | ||||||
| from pyhon import HonAPI | from pyhon import HonAPI | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     sys.path.insert(0, str(Path(__file__).parent.parent)) | ||||||
|  |  | ||||||
| from custom_components.hon import const | from custom_components.hon import const | ||||||
|  |  | ||||||
| SENSOR = { | SENSOR = { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	