1313 PRESET_NONE ,
1414 ClimateEntity ,
1515 ClimateEntityFeature ,
16+ HVACAction ,
1617 HVACMode ,
1718)
1819from homeassistant .config_entries import ConfigEntry
2526
2627LOGGER = logging .getLogger (__name__ )
2728
28- MIN_TEMP = 8
29- MAX_TEMP = 28
29+ MIN_TEMP = 7.5
30+ MAX_TEMP = 28.5
3031
3132
3233async def async_setup_entry (
@@ -43,28 +44,27 @@ class CometBlueClimateEntity(CometBlueBluetoothEntity, ClimateEntity):
4344
4445 _attr_min_temp = MIN_TEMP
4546 _attr_max_temp = MAX_TEMP
46- _attr_target_temperature_step = PRECISION_HALVES
4747 _attr_name = None
48+ _attr_hvac_modes = [HVACMode .AUTO , HVACMode .HEAT , HVACMode .OFF ]
49+ _attr_preset_modes = [
50+ PRESET_NONE ,
51+ PRESET_ECO ,
52+ PRESET_AWAY ,
53+ PRESET_COMFORT ,
54+ ]
55+ _attr_supported_features : ClimateEntityFeature = (
56+ ClimateEntityFeature .TARGET_TEMPERATURE
57+ | ClimateEntityFeature .TARGET_TEMPERATURE_RANGE
58+ | ClimateEntityFeature .PRESET_MODE
59+ )
60+ _attr_target_temperature_step = PRECISION_HALVES
61+ _attr_temperature_unit = UnitOfTemperature .CELSIUS
4862
4963 def __init__ (self , coordinator : CometBlueDataUpdateCoordinator ) -> None :
5064 """Initialize CometBlueClimateEntity."""
5165
5266 super ().__init__ (coordinator )
5367 self ._attr_unique_id = f"{ coordinator .address } -climate"
54- self ._attr_temperature_unit = UnitOfTemperature .CELSIUS
55- self ._attr_hvac_modes = [HVACMode .AUTO ]
56- self ._attr_hvac_mode = HVACMode .AUTO
57- self ._attr_supported_features : ClimateEntityFeature = (
58- ClimateEntityFeature .TARGET_TEMPERATURE
59- | ClimateEntityFeature .TARGET_TEMPERATURE_RANGE
60- | ClimateEntityFeature .PRESET_MODE
61- )
62- self ._attr_preset_modes = [
63- PRESET_NONE ,
64- PRESET_ECO ,
65- PRESET_AWAY ,
66- PRESET_COMFORT ,
67- ]
6868
6969 @property
7070 def current_temperature (self ) -> float | None :
@@ -74,7 +74,11 @@ def current_temperature(self) -> float | None:
7474 @property
7575 def target_temperature (self ) -> float | None :
7676 """Return the temperature currently set to be reached."""
77- return self .coordinator .data ["manualTemp" ]
77+ # if holiday mode is active (i.e. temperature is available), return holiday temperature
78+ return (
79+ self .coordinator .data ["holiday" ].get ("temperature" )
80+ or self .coordinator .data ["manualTemp" ]
81+ )
7882
7983 @property
8084 def target_temperature_high (self ) -> float | None :
@@ -87,21 +91,53 @@ def target_temperature_low(self) -> float | None:
8791 return self .coordinator .data ["targetTempLow" ]
8892
8993 @property
90- def preset_mode (self ) -> str | None :
91- """Return the current preset mode, e.g., home, away, temp.
94+ def hvac_mode (self ) -> HVACMode | None :
95+ """Return hvac operation mode."""
96+ if self .coordinator .data ["manualTemp" ] == 7.5 :
97+ return HVACMode .OFF
98+ if self .coordinator .data ["manualTemp" ] == 28.5 :
99+ return HVACMode .HEAT
100+ return HVACMode .AUTO
92101
93- Requires ClimateEntityFeature.PRESET_MODE.
94- """
95- if self .target_temperature == self .target_temperature_low :
96- return PRESET_ECO
102+ @property
103+ def hvac_action (self ) -> HVACAction | None :
104+ """Return the current running hvac action if supported."""
105+
106+ if self .coordinator .data ["manualTemp" ] == 7.5 :
107+ return HVACAction .OFF
108+ if (
109+ self .coordinator .data ["currentTemp" ] + 0.5
110+ < self .coordinator .data ["manualTemp" ]
111+ ):
112+ return HVACAction .HEATING
113+ return HVACAction .IDLE
114+
115+ @property
116+ def preset_mode (self ) -> str | None :
117+ """Return the current preset mode, e.g., home, away, temp."""
118+ # presets have an order in which they are displayed on TRV:
119+ # away, comfort, eco, none (or manual)
120+ if (
121+ self .coordinator .data ["holiday" ].get ("start" ) is None
122+ and self .coordinator .data ["holiday" ].get ("end" ) is not None
123+ ):
124+ return PRESET_AWAY
97125 if self .target_temperature == self .target_temperature_high :
98126 return PRESET_COMFORT
99- # AWAY MODE NOT SUPPORTED YET
127+ if self .target_temperature == self .target_temperature_low :
128+ return PRESET_ECO
100129 return PRESET_NONE
101130
102131 async def async_set_temperature (self , ** kwargs : Any ) -> None :
103132 """Set new target temperatures."""
104133
134+ # Not sure if actually the case. Maybe set vacation mode to really hot and check
135+ # what happens when changing it manually
136+ if self .preset_mode == PRESET_AWAY :
137+ raise ValueError (
138+ "Cannot adjust TRV remotely, manually disable 'away' mode on TRV first"
139+ )
140+
105141 await self .coordinator .send_command (
106142 "set_temperature_async" ,
107143 {
@@ -125,6 +161,22 @@ async def async_set_preset_mode(self, preset_mode: str) -> None:
125161 if preset_mode in [PRESET_NONE , PRESET_AWAY ]:
126162 raise ValueError (f"Setting preset '{ preset_mode } ' is not supported." )
127163 if preset_mode == PRESET_ECO :
128- await self .async_set_temperature (temperature = self .target_temperature_low )
129- elif preset_mode == PRESET_COMFORT :
130- await self .async_set_temperature (temperature = self .target_temperature_high )
164+ return await self .async_set_temperature (
165+ temperature = self .target_temperature_low
166+ )
167+ if preset_mode == PRESET_COMFORT :
168+ return await self .async_set_temperature (
169+ temperature = self .target_temperature_high
170+ )
171+
172+ async def async_set_hvac_mode (self , hvac_mode : HVACMode ) -> None :
173+ """Set new target hvac mode."""
174+
175+ if hvac_mode == HVACMode .OFF :
176+ return await self .async_set_temperature (temperature = 7.5 )
177+ if hvac_mode == HVACMode .HEAT :
178+ return await self .async_set_temperature (temperature = 28.5 )
179+ if hvac_mode == HVACMode .AUTO :
180+ return await self .async_set_temperature (
181+ temperature = self .target_temperature_low
182+ )
0 commit comments