@@ -145,6 +145,93 @@ async def async_update(self) -> PlugwiseData:
145145### API Set and HA Service-related Functions ###
146146########################################################################################################
147147
148+ async def delete_notification (self ) -> None :
149+ """Delete the active Plugwise Notification."""
150+ await self ._request (NOTIFICATIONS , method = "delete" )
151+
152+ async def set_dhw_mode (self , mode : str ) -> None :
153+ """Set the domestic hot water heating regulation mode."""
154+ if mode not in self ._dhw_allowed_modes :
155+ raise PlugwiseError ("Plugwise: invalid dhw mode." )
156+
157+ uri = f"{ APPLIANCES } ;type=heater_central/domestic_hot_water_mode_control"
158+ data = f"<domestic_hot_water_mode_control_functionality><mode>{ mode } </mode></domestic_hot_water_mode_control_functionality>"
159+
160+ await self ._request (uri , method = "put" , data = data )
161+
162+ async def set_gateway_mode (self , mode : str ) -> None :
163+ """Set the gateway mode."""
164+ if mode not in self ._gw_allowed_modes :
165+ raise PlugwiseError ("Plugwise: invalid gateway mode." )
166+
167+ end_time = "2037-04-21T08:00:53.000Z"
168+ valid = ""
169+ if mode == "away" :
170+ time_1 = self ._domain_objects .find ("./gateway/time" ).text
171+ away_time = dt .datetime .fromisoformat (time_1 ).astimezone (dt .UTC ).isoformat (timespec = "milliseconds" ).replace ("+00:00" , "Z" )
172+ valid = (
173+ f"<valid_from>{ away_time } </valid_from><valid_to>{ end_time } </valid_to>"
174+ )
175+ if mode == "vacation" :
176+ time_2 = str (dt .date .today () - dt .timedelta (1 ))
177+ vacation_time = time_2 + "T23:00:00.000Z"
178+ valid = f"<valid_from>{ vacation_time } </valid_from><valid_to>{ end_time } </valid_to>"
179+
180+ uri = f"{ APPLIANCES } ;id={ self .gateway_id } /gateway_mode_control"
181+ data = f"<gateway_mode_control_functionality><mode>{ mode } </mode>{ valid } </gateway_mode_control_functionality>"
182+
183+ await self ._request (uri , method = "put" , data = data )
184+
185+ async def set_number_setpoint (self , key : str , temperature : float ) -> None :
186+ """Set the max. Boiler or DHW setpoint on the Central Heating boiler."""
187+ temp = str (temperature )
188+ thermostat_id : str | None = None
189+ locator = f'appliance[@id="{ self ._heater_id } "]/actuator_functionalities/thermostat_functionality'
190+ if th_func_list := self ._domain_objects .findall (locator ):
191+ for th_func in th_func_list :
192+ if th_func .find ("type" ).text == key :
193+ thermostat_id = th_func .attrib ["id" ]
194+
195+ if thermostat_id is None :
196+ raise PlugwiseError (f"Plugwise: cannot change setpoint, { key } not found." )
197+
198+ uri = f"{ APPLIANCES } ;id={ self ._heater_id } /thermostat;id={ thermostat_id } "
199+ data = f"<thermostat_functionality><setpoint>{ temp } </setpoint></thermostat_functionality>"
200+ await self ._request (uri , method = "put" , data = data )
201+
202+ async def set_preset (self , loc_id : str , preset : str ) -> None :
203+ """Set the given Preset on the relevant Thermostat - from LOCATIONS."""
204+ if (presets := self ._presets (loc_id )) is None :
205+ raise PlugwiseError ("Plugwise: no presets available." ) # pragma: no cover
206+ if preset not in list (presets ):
207+ raise PlugwiseError ("Plugwise: invalid preset." )
208+
209+ current_location = self ._domain_objects .find (f'location[@id="{ loc_id } "]' )
210+ location_name = current_location .find ("name" ).text
211+ location_type = current_location .find ("type" ).text
212+
213+ uri = f"{ LOCATIONS } ;id={ loc_id } "
214+ data = (
215+ "<locations><location"
216+ f' id="{ loc_id } "><name>{ location_name } </name><type>{ location_type } '
217+ f"</type><preset>{ preset } </preset></location></locations>"
218+ )
219+
220+ await self ._request (uri , method = "put" , data = data )
221+
222+ async def set_regulation_mode (self , mode : str ) -> None :
223+ """Set the heating regulation mode."""
224+ if mode not in self ._reg_allowed_modes :
225+ raise PlugwiseError ("Plugwise: invalid regulation mode." )
226+
227+ uri = f"{ APPLIANCES } ;type=gateway/regulation_mode_control"
228+ duration = ""
229+ if "bleeding" in mode :
230+ duration = "<duration>300</duration>"
231+ data = f"<regulation_mode_control_functionality>{ duration } <mode>{ mode } </mode></regulation_mode_control_functionality>"
232+
233+ await self ._request (uri , method = "put" , data = data )
234+
148235 async def set_schedule_state (
149236 self ,
150237 loc_id : str ,
@@ -219,97 +306,6 @@ def determine_contexts(
219306
220307 return etree .tostring (contexts , encoding = "unicode" ).rstrip ()
221308
222- async def set_preset (self , loc_id : str , preset : str ) -> None :
223- """Set the given Preset on the relevant Thermostat - from LOCATIONS."""
224- if (presets := self ._presets (loc_id )) is None :
225- raise PlugwiseError ("Plugwise: no presets available." ) # pragma: no cover
226- if preset not in list (presets ):
227- raise PlugwiseError ("Plugwise: invalid preset." )
228-
229- current_location = self ._domain_objects .find (f'location[@id="{ loc_id } "]' )
230- location_name = current_location .find ("name" ).text
231- location_type = current_location .find ("type" ).text
232-
233- uri = f"{ LOCATIONS } ;id={ loc_id } "
234- data = (
235- "<locations><location"
236- f' id="{ loc_id } "><name>{ location_name } </name><type>{ location_type } '
237- f"</type><preset>{ preset } </preset></location></locations>"
238- )
239-
240- await self ._request (uri , method = "put" , data = data )
241-
242- async def set_temperature (self , loc_id : str , items : dict [str , float ]) -> None :
243- """Set the given Temperature on the relevant Thermostat."""
244- setpoint : float | None = None
245-
246- if "setpoint" in items :
247- setpoint = items ["setpoint" ]
248-
249- if self .smile (ANNA ) and self ._cooling_present :
250- if "setpoint_high" not in items :
251- raise PlugwiseError (
252- "Plugwise: failed setting temperature: no valid input provided"
253- )
254- tmp_setpoint_high = items ["setpoint_high" ]
255- tmp_setpoint_low = items ["setpoint_low" ]
256- if self ._cooling_enabled : # in cooling mode
257- setpoint = tmp_setpoint_high
258- if tmp_setpoint_low != MIN_SETPOINT :
259- raise PlugwiseError (
260- "Plugwise: heating setpoint cannot be changed when in cooling mode"
261- )
262- else : # in heating mode
263- setpoint = tmp_setpoint_low
264- if tmp_setpoint_high != MAX_SETPOINT :
265- raise PlugwiseError (
266- "Plugwise: cooling setpoint cannot be changed when in heating mode"
267- )
268-
269- if setpoint is None :
270- raise PlugwiseError (
271- "Plugwise: failed setting temperature: no valid input provided"
272- ) # pragma: no cover"
273-
274- temperature = str (setpoint )
275- uri = self ._thermostat_uri (loc_id )
276- data = (
277- "<thermostat_functionality><setpoint>"
278- f"{ temperature } </setpoint></thermostat_functionality>"
279- )
280-
281- await self ._request (uri , method = "put" , data = data )
282-
283- async def set_number_setpoint (self , key : str , temperature : float ) -> None :
284- """Set the max. Boiler or DHW setpoint on the Central Heating boiler."""
285- temp = str (temperature )
286- thermostat_id : str | None = None
287- locator = f'appliance[@id="{ self ._heater_id } "]/actuator_functionalities/thermostat_functionality'
288- if th_func_list := self ._domain_objects .findall (locator ):
289- for th_func in th_func_list :
290- if th_func .find ("type" ).text == key :
291- thermostat_id = th_func .attrib ["id" ]
292-
293- if thermostat_id is None :
294- raise PlugwiseError (f"Plugwise: cannot change setpoint, { key } not found." )
295-
296- uri = f"{ APPLIANCES } ;id={ self ._heater_id } /thermostat;id={ thermostat_id } "
297- data = f"<thermostat_functionality><setpoint>{ temp } </setpoint></thermostat_functionality>"
298- await self ._request (uri , method = "put" , data = data )
299-
300- async def set_temperature_offset (self , dev_id : str , offset : float ) -> None :
301- """Set the Temperature offset for thermostats that support this feature."""
302- if dev_id not in self .therms_with_offset_func :
303- raise PlugwiseError (
304- "Plugwise: this device does not have temperature-offset capability."
305- )
306-
307- value = str (offset )
308- uri = f"{ APPLIANCES } ;id={ dev_id } /offset;type=temperature_offset"
309- data = f"<offset_functionality><offset>{ value } </offset></offset_functionality>"
310-
311- await self ._request (uri , method = "put" , data = data )
312-
313309 async def set_switch_state (
314310 self , appl_id : str , members : list [str ] | None , model : str , state : str
315311 ) -> None :
@@ -374,52 +370,56 @@ async def _set_groupswitch_member_state(
374370
375371 await self ._request (uri , method = "put" , data = data )
376372
377- async def set_gateway_mode (self , mode : str ) -> None :
378- """Set the gateway mode."""
379- if mode not in self ._gw_allowed_modes :
380- raise PlugwiseError ("Plugwise: invalid gateway mode." )
381-
382- end_time = "2037-04-21T08:00:53.000Z"
383- valid = ""
384- if mode == "away" :
385- time_1 = self ._domain_objects .find ("./gateway/time" ).text
386- away_time = dt .datetime .fromisoformat (time_1 ).astimezone (dt .UTC ).isoformat (timespec = "milliseconds" ).replace ("+00:00" , "Z" )
387- valid = (
388- f"<valid_from>{ away_time } </valid_from><valid_to>{ end_time } </valid_to>"
389- )
390- if mode == "vacation" :
391- time_2 = str (dt .date .today () - dt .timedelta (1 ))
392- vacation_time = time_2 + "T23:00:00.000Z"
393- valid = f"<valid_from>{ vacation_time } </valid_from><valid_to>{ end_time } </valid_to>"
373+ async def set_temperature (self , loc_id : str , items : dict [str , float ]) -> None :
374+ """Set the given Temperature on the relevant Thermostat."""
375+ setpoint : float | None = None
394376
395- uri = f" { APPLIANCES } ;id= { self . gateway_id } /gateway_mode_control"
396- data = f"<gateway_mode_control_functionality><mode> { mode } </mode> { valid } </gateway_mode_control_functionality>"
377+ if "setpoint" in items :
378+ setpoint = items [ "setpoint" ]
397379
398- await self ._request (uri , method = "put" , data = data )
380+ if self .smile (ANNA ) and self ._cooling_present :
381+ if "setpoint_high" not in items :
382+ raise PlugwiseError (
383+ "Plugwise: failed setting temperature: no valid input provided"
384+ )
385+ tmp_setpoint_high = items ["setpoint_high" ]
386+ tmp_setpoint_low = items ["setpoint_low" ]
387+ if self ._cooling_enabled : # in cooling mode
388+ setpoint = tmp_setpoint_high
389+ if tmp_setpoint_low != MIN_SETPOINT :
390+ raise PlugwiseError (
391+ "Plugwise: heating setpoint cannot be changed when in cooling mode"
392+ )
393+ else : # in heating mode
394+ setpoint = tmp_setpoint_low
395+ if tmp_setpoint_high != MAX_SETPOINT :
396+ raise PlugwiseError (
397+ "Plugwise: cooling setpoint cannot be changed when in heating mode"
398+ )
399399
400- async def set_regulation_mode ( self , mode : str ) -> None :
401- """Set the heating regulation mode."""
402- if mode not in self . _reg_allowed_modes :
403- raise PlugwiseError ( "Plugwise: invalid regulation mode." )
400+ if setpoint is None :
401+ raise PlugwiseError (
402+ "Plugwise: failed setting temperature: no valid input provided"
403+ ) # pragma: no cover"
404404
405- uri = f"{ APPLIANCES } ;type=gateway/regulation_mode_control"
406- duration = ""
407- if "bleeding" in mode :
408- duration = "<duration>300</duration>"
409- data = f"<regulation_mode_control_functionality>{ duration } <mode>{ mode } </mode></regulation_mode_control_functionality>"
405+ temperature = str (setpoint )
406+ uri = self ._thermostat_uri (loc_id )
407+ data = (
408+ "<thermostat_functionality><setpoint>"
409+ f"{ temperature } </setpoint></thermostat_functionality>"
410+ )
410411
411412 await self ._request (uri , method = "put" , data = data )
412413
413- async def set_dhw_mode (self , mode : str ) -> None :
414- """Set the domestic hot water heating regulation mode."""
415- if mode not in self ._dhw_allowed_modes :
416- raise PlugwiseError ("Plugwise: invalid dhw mode." )
414+ async def set_temperature_offset (self , dev_id : str , offset : float ) -> None :
415+ """Set the Temperature offset for thermostats that support this feature."""
416+ if dev_id not in self .therms_with_offset_func :
417+ raise PlugwiseError (
418+ "Plugwise: this device does not have temperature-offset capability."
419+ )
417420
418- uri = f"{ APPLIANCES } ;type=heater_central/domestic_hot_water_mode_control"
419- data = f"<domestic_hot_water_mode_control_functionality><mode>{ mode } </mode></domestic_hot_water_mode_control_functionality>"
421+ value = str (offset )
422+ uri = f"{ APPLIANCES } ;id={ dev_id } /offset;type=temperature_offset"
423+ data = f"<offset_functionality><offset>{ value } </offset></offset_functionality>"
420424
421425 await self ._request (uri , method = "put" , data = data )
422-
423- async def delete_notification (self ) -> None :
424- """Delete the active Plugwise Notification."""
425- await self ._request (NOTIFICATIONS , method = "delete" )
0 commit comments