2727 MAX_SETPOINT ,
2828 MIN_SETPOINT ,
2929 MODULES ,
30+ NONE ,
3031 NOTIFICATIONS ,
32+ OFF ,
3133 REQUIRE_APPLIANCES ,
3234 RULES ,
3335 SMILES ,
@@ -201,13 +203,6 @@ def _device_data_adam(
201203
202204 return device_data
203205
204- def check_reg_mode (self , mode : str ) -> bool :
205- """Helper-function for device_data_climate()."""
206- gateway = self .gw_devices [self .gateway_id ]
207- return (
208- "regulation_modes" in gateway and gateway ["select_regulation_mode" ] == mode
209- )
210-
211206 def _device_data_climate (
212207 self , device : DeviceData , device_data : DeviceData
213208 ) -> DeviceData :
@@ -239,7 +234,7 @@ def _device_data_climate(
239234 # Operation modes: auto, heat, heat_cool, cool and off
240235 device_data ["mode" ] = "auto"
241236 self ._count += 1
242- if sel_schedule == "None" :
237+ if sel_schedule == NONE :
243238 device_data ["mode" ] = "heat"
244239 if self ._cooling_present :
245240 device_data ["mode" ] = (
@@ -249,17 +244,46 @@ def _device_data_climate(
249244 if self .check_reg_mode ("off" ):
250245 device_data ["mode" ] = "off"
251246
252- if "None" not in avail_schedules :
253- loc_schedule_states = {}
254- for schedule in avail_schedules :
255- loc_schedule_states [schedule ] = (
256- "off" if device_data ["mode" ] == "auto" else "on"
257- )
258-
259- self ._schedule_old_states [loc_id ] = loc_schedule_states
247+ if NONE in avail_schedules :
248+ return device_data
260249
250+ device_data = self ._get_schedule_states_with_off (
251+ loc_id , avail_schedules , sel_schedule , device_data
252+ )
261253 return device_data
262254
255+ def check_reg_mode (self , mode : str ) -> bool :
256+ """Helper-function for device_data_climate()."""
257+ gateway = self .gw_devices [self .gateway_id ]
258+ return (
259+ "regulation_modes" in gateway and gateway ["select_regulation_mode" ] == mode
260+ )
261+
262+ def _get_schedule_states_with_off (
263+ self , location : str , schedules : list [str ], selected : str , data : DeviceData
264+ ) -> DeviceData :
265+ """Collect schedules with states for each thermostat.
266+
267+ Also, replace NONE by OFF when none of the schedules are active,
268+ only for non-legacy thermostats.
269+ """
270+ loc_schedule_states : dict [str , str ] = {}
271+ for schedule in schedules :
272+ loc_schedule_states [schedule ] = "off"
273+ if schedule == selected and data ["mode" ] == "auto" :
274+ loc_schedule_states [schedule ] = "on"
275+ self ._schedule_old_states [location ] = loc_schedule_states
276+
277+ all_off = True
278+ if not self ._smile_legacy :
279+ for state in self ._schedule_old_states [location ].values ():
280+ if state == "on" :
281+ all_off = False
282+ if all_off :
283+ data ["select_schedule" ] = OFF
284+
285+ return data
286+
263287 def _check_availability (
264288 self , device : DeviceData , device_data : DeviceData
265289 ) -> DeviceData :
@@ -647,7 +671,13 @@ async def set_schedule_state(
647671 # Input checking
648672 if new_state not in ["on" , "off" ]:
649673 raise PlugwiseError ("Plugwise: invalid schedule state." )
650- if name is None :
674+
675+ # Translate selection of Off-schedule-option to disabling the active schedule
676+ if name == OFF :
677+ new_state = "off"
678+
679+ # Handle no schedule-name / Off-schedule provided
680+ if name is None or name == OFF :
651681 if schedule_name := self ._last_active [loc_id ]:
652682 name = schedule_name
653683 else :
@@ -668,7 +698,6 @@ async def set_schedule_state(
668698 return
669699
670700 schedule_rule_id : str = next (iter (schedule_rule ))
671-
672701 template = (
673702 '<template tag="zone_preset_based_on_time_and_presence_with_override" />'
674703 )
@@ -683,6 +712,7 @@ async def set_schedule_state(
683712 f'<rules><rule id="{ schedule_rule_id } "><name><![CDATA[{ name } ]]></name>'
684713 f"{ template } { contexts } </rule></rules>"
685714 )
715+
686716 await self ._request (uri , method = "put" , data = data )
687717 self ._schedule_old_states [loc_id ][name ] = new_state
688718
0 commit comments