Skip to content

Commit cc2f5f5

Browse files
authored
Merge pull request #940 from MartvanMale/cooling-allowed-per-zone
Gate the preset cooling setpoints on the zone's own cooling_allowed
2 parents 25d3d8b + 36890af commit cc2f5f5

7 files changed

Lines changed: 117 additions & 136 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## Ongoing
4+
5+
- A zone shows the cooling setpoint of each preset only when the gateway has cooling and cooling is allowed for that zone. A zone that may not cool shows the heating setpoint alone, and, when no schedule is selected, reports heating as its climate mode.
6+
- Setting the heating setpoint of a preset no longer fails in a zone that may not cool when the value is above the cooling setpoint stored for that zone.
7+
38
## v1.15.0
49

510
- Contribution PR's [#936](https://github.com/plugwise/python-plugwise/pull/936) and [#938](https://github.com/plugwise/python-plugwise/pull/938) by @MartvanMale:

‎fixtures/adam_heatpump_cooling/data.json‎

Lines changed: 34 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@
178178
"asleep_preset_temperature": {
179179
"lower_bound": 4.0,
180180
"resolution": 0.5,
181-
"setpoint_high": 22.0,
182-
"setpoint_low": 18.0,
181+
"setpoint": 18.0,
183182
"upper_bound": 30.0
184183
},
185184
"available_schedules": [
@@ -191,27 +190,24 @@
191190
"away_preset_temperature": {
192191
"lower_bound": 4.0,
193192
"resolution": 0.5,
194-
"setpoint_high": 25.0,
195-
"setpoint_low": 18.5,
193+
"setpoint": 18.5,
196194
"upper_bound": 30.0
197195
},
198-
"climate_mode": "cool",
196+
"climate_mode": "heat",
199197
"control_state": "idle",
200198
"dev_class": "climate",
201199
"home_preset_temperature": {
202200
"lower_bound": 4.0,
203201
"resolution": 0.5,
204-
"setpoint_high": 22.0,
205-
"setpoint_low": 18.0,
202+
"setpoint": 18.0,
206203
"upper_bound": 30.0
207204
},
208205
"model": "ThermoZone",
209206
"name": "Slaapkamer DB",
210207
"no_frost_preset_temperature": {
211208
"lower_bound": 4.0,
212209
"resolution": 0.5,
213-
"setpoint_high": 30.0,
214-
"setpoint_low": 10.0,
210+
"setpoint": 10.0,
215211
"upper_bound": 30.0
216212
},
217213
"preset_modes": [
@@ -243,8 +239,7 @@
243239
"vacation_preset_temperature": {
244240
"lower_bound": 4.0,
245241
"resolution": 0.5,
246-
"setpoint_high": 28.0,
247-
"setpoint_low": 16.0,
242+
"setpoint": 16.0,
248243
"upper_bound": 30.0
249244
},
250245
"vendor": "Plugwise",
@@ -341,8 +336,7 @@
341336
"asleep_preset_temperature": {
342337
"lower_bound": 4.0,
343338
"resolution": 0.5,
344-
"setpoint_high": 23.0,
345-
"setpoint_low": 20.5,
339+
"setpoint": 20.5,
346340
"upper_bound": 30.0
347341
},
348342
"available_schedules": [
@@ -354,8 +348,7 @@
354348
"away_preset_temperature": {
355349
"lower_bound": 4.0,
356350
"resolution": 0.5,
357-
"setpoint_high": 25.0,
358-
"setpoint_low": 20.5,
351+
"setpoint": 20.5,
359352
"upper_bound": 30.0
360353
},
361354
"climate_mode": "auto",
@@ -364,17 +357,15 @@
364357
"home_preset_temperature": {
365358
"lower_bound": 4.0,
366359
"resolution": 0.5,
367-
"setpoint_high": 22.0,
368-
"setpoint_low": 20.5,
360+
"setpoint": 20.5,
369361
"upper_bound": 30.0
370362
},
371363
"model": "ThermoZone",
372364
"name": "Badkamer 2",
373365
"no_frost_preset_temperature": {
374366
"lower_bound": 4.0,
375367
"resolution": 0.5,
376-
"setpoint_high": 30.0,
377-
"setpoint_low": 10.0,
368+
"setpoint": 10.0,
378369
"upper_bound": 30.0
379370
},
380371
"preset_modes": [
@@ -405,8 +396,7 @@
405396
"vacation_preset_temperature": {
406397
"lower_bound": 4.0,
407398
"resolution": 0.5,
408-
"setpoint_high": 28.0,
409-
"setpoint_low": 16.0,
399+
"setpoint": 16.0,
410400
"upper_bound": 30.0
411401
},
412402
"vendor": "Plugwise",
@@ -536,8 +526,7 @@
536526
"asleep_preset_temperature": {
537527
"lower_bound": 4.0,
538528
"resolution": 0.5,
539-
"setpoint_high": 23.0,
540-
"setpoint_low": 20.5,
529+
"setpoint": 20.5,
541530
"upper_bound": 30.0
542531
},
543532
"available_schedules": [
@@ -549,8 +538,7 @@
549538
"away_preset_temperature": {
550539
"lower_bound": 4.0,
551540
"resolution": 0.5,
552-
"setpoint_high": 25.0,
553-
"setpoint_low": 20.5,
541+
"setpoint": 20.5,
554542
"upper_bound": 30.0
555543
},
556544
"climate_mode": "auto",
@@ -559,17 +547,15 @@
559547
"home_preset_temperature": {
560548
"lower_bound": 4.0,
561549
"resolution": 0.5,
562-
"setpoint_high": 22.0,
563-
"setpoint_low": 20.5,
550+
"setpoint": 20.5,
564551
"upper_bound": 30.0
565552
},
566553
"model": "ThermoZone",
567554
"name": "Badkamer 1",
568555
"no_frost_preset_temperature": {
569556
"lower_bound": 4.0,
570557
"resolution": 0.5,
571-
"setpoint_high": 30.0,
572-
"setpoint_low": 10.0,
558+
"setpoint": 10.0,
573559
"upper_bound": 30.0
574560
},
575561
"preset_modes": [
@@ -601,8 +587,7 @@
601587
"vacation_preset_temperature": {
602588
"lower_bound": 4.0,
603589
"resolution": 0.5,
604-
"setpoint_high": 28.0,
605-
"setpoint_low": 16.0,
590+
"setpoint": 16.0,
606591
"upper_bound": 30.0
607592
},
608593
"vendor": "Plugwise",
@@ -617,8 +602,7 @@
617602
"asleep_preset_temperature": {
618603
"lower_bound": 4.0,
619604
"resolution": 0.5,
620-
"setpoint_high": 22.0,
621-
"setpoint_low": 18.0,
605+
"setpoint": 18.0,
622606
"upper_bound": 30.0
623607
},
624608
"available_schedules": [
@@ -630,27 +614,24 @@
630614
"away_preset_temperature": {
631615
"lower_bound": 4.0,
632616
"resolution": 0.5,
633-
"setpoint_high": 25.0,
634-
"setpoint_low": 18.5,
617+
"setpoint": 18.5,
635618
"upper_bound": 30.0
636619
},
637-
"climate_mode": "cool",
620+
"climate_mode": "heat",
638621
"control_state": "idle",
639622
"dev_class": "climate",
640623
"home_preset_temperature": {
641624
"lower_bound": 4.0,
642625
"resolution": 0.5,
643-
"setpoint_high": 22.0,
644-
"setpoint_low": 20.0,
626+
"setpoint": 20.0,
645627
"upper_bound": 30.0
646628
},
647629
"model": "ThermoZone",
648630
"name": "Slaapkamer RB",
649631
"no_frost_preset_temperature": {
650632
"lower_bound": 4.0,
651633
"resolution": 0.5,
652-
"setpoint_high": 30.0,
653-
"setpoint_low": 10.0,
634+
"setpoint": 10.0,
654635
"upper_bound": 30.0
655636
},
656637
"preset_modes": [
@@ -681,8 +662,7 @@
681662
"vacation_preset_temperature": {
682663
"lower_bound": 4.0,
683664
"resolution": 0.5,
684-
"setpoint_high": 28.0,
685-
"setpoint_low": 16.0,
665+
"setpoint": 16.0,
686666
"upper_bound": 30.0
687667
},
688668
"vendor": "Plugwise",
@@ -899,8 +879,7 @@
899879
"asleep_preset_temperature": {
900880
"lower_bound": 4.0,
901881
"resolution": 0.5,
902-
"setpoint_high": 22.0,
903-
"setpoint_low": 17.5,
882+
"setpoint": 17.5,
904883
"upper_bound": 30.0
905884
},
906885
"available_schedules": [
@@ -912,27 +891,24 @@
912891
"away_preset_temperature": {
913892
"lower_bound": 4.0,
914893
"resolution": 0.5,
915-
"setpoint_high": 25.0,
916-
"setpoint_low": 18.0,
894+
"setpoint": 18.0,
917895
"upper_bound": 30.0
918896
},
919-
"climate_mode": "cool",
897+
"climate_mode": "heat",
920898
"control_state": "idle",
921899
"dev_class": "climate",
922900
"home_preset_temperature": {
923901
"lower_bound": 4.0,
924902
"resolution": 0.5,
925-
"setpoint_high": 22.0,
926-
"setpoint_low": 18.0,
903+
"setpoint": 18.0,
927904
"upper_bound": 30.0
928905
},
929906
"model": "ThermoZone",
930907
"name": "Bijkeuken",
931908
"no_frost_preset_temperature": {
932909
"lower_bound": 4.0,
933910
"resolution": 0.5,
934-
"setpoint_high": 30.0,
935-
"setpoint_low": 10.0,
911+
"setpoint": 10.0,
936912
"upper_bound": 30.0
937913
},
938914
"preset_modes": [
@@ -964,8 +940,7 @@
964940
"vacation_preset_temperature": {
965941
"lower_bound": 4.0,
966942
"resolution": 0.5,
967-
"setpoint_high": 28.0,
968-
"setpoint_low": 16.0,
943+
"setpoint": 16.0,
969944
"upper_bound": 30.0
970945
},
971946
"vendor": "Plugwise",
@@ -1078,8 +1053,7 @@
10781053
"asleep_preset_temperature": {
10791054
"lower_bound": 4.0,
10801055
"resolution": 0.5,
1081-
"setpoint_high": 21.5,
1082-
"setpoint_low": 17.5,
1056+
"setpoint": 17.5,
10831057
"upper_bound": 30.0
10841058
},
10851059
"available_schedules": [
@@ -1091,27 +1065,24 @@
10911065
"away_preset_temperature": {
10921066
"lower_bound": 4.0,
10931067
"resolution": 0.5,
1094-
"setpoint_high": 25.0,
1095-
"setpoint_low": 17.5,
1068+
"setpoint": 17.5,
10961069
"upper_bound": 30.0
10971070
},
1098-
"climate_mode": "cool",
1071+
"climate_mode": "heat",
10991072
"control_state": "idle",
11001073
"dev_class": "climate",
11011074
"home_preset_temperature": {
11021075
"lower_bound": 4.0,
11031076
"resolution": 0.5,
1104-
"setpoint_high": 22.0,
1105-
"setpoint_low": 17.5,
1077+
"setpoint": 17.5,
11061078
"upper_bound": 30.0
11071079
},
11081080
"model": "ThermoZone",
11091081
"name": "Slaapkamer JM",
11101082
"no_frost_preset_temperature": {
11111083
"lower_bound": 4.0,
11121084
"resolution": 0.5,
1113-
"setpoint_high": 30.0,
1114-
"setpoint_low": 10.0,
1085+
"setpoint": 10.0,
11151086
"upper_bound": 30.0
11161087
},
11171088
"preset_modes": [
@@ -1143,8 +1114,7 @@
11431114
"vacation_preset_temperature": {
11441115
"lower_bound": 4.0,
11451116
"resolution": 0.5,
1146-
"setpoint_high": 28.0,
1147-
"setpoint_low": 16.0,
1117+
"setpoint": 16.0,
11481118
"upper_bound": 30.0
11491119
},
11501120
"vendor": "Plugwise",

‎plugwise/data.py‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ def _climate_data(self, location_id: str, entity: GwEntityData) -> None:
268268
if entity.get("location") is not None:
269269
loc_id = entity["location"]
270270

271+
zone_cools = self._cooling_present and self._cooling_allowed(loc_id)
272+
271273
# Presets
272274
entity["preset_modes"] = None
273275
entity["active_preset"] = None
@@ -277,7 +279,7 @@ def _climate_data(self, location_id: str, entity: GwEntityData) -> None:
277279
entity["active_preset"] = self._preset(loc_id)
278280
# Only a zone's own rule can be edited without touching other zones
279281
if self._preset_rule_id(loc_id) is not None:
280-
self._preset_temperatures(presets, entity)
282+
self._preset_temperatures(zone_cools, presets, entity)
281283

282284
# Schedule
283285
entity["available_schedules"] = [OFF]
@@ -293,7 +295,7 @@ def _climate_data(self, location_id: str, entity: GwEntityData) -> None:
293295
self._count += 1
294296
if sel_schedule == OFF:
295297
entity["climate_mode"] = "heat"
296-
if self._cooling_present:
298+
if zone_cools:
297299
entity["climate_mode"] = (
298300
"cool" if self.check_reg_mode("cooling") else "heat_cool"
299301
)
@@ -306,17 +308,17 @@ def _climate_data(self, location_id: str, entity: GwEntityData) -> None:
306308
)
307309

308310
def _preset_temperatures(
309-
self, presets: dict[str, list[float]], entity: GwEntityData
311+
self, zone_cools: bool, presets: dict[str, list[float]], entity: GwEntityData
310312
) -> None:
311313
"""Helper-function for _climate_data().
312314
313315
Add the setpoints of each preset as an adjustable value: the heating setpoint,
314-
or with cooling present the heating (low) and cooling (high) setpoints.
316+
or where the zone may cool the heating (low) and cooling (high) setpoints.
315317
"""
316318
for key, preset in PRESET_TEMPERATURES.items():
317319
if preset in presets:
318320
heating, cooling = presets[preset]
319-
if self._cooling_present:
321+
if zone_cools:
320322
entity[key] = ActuatorData(
321323
lower_bound=MIN_SETPOINT,
322324
resolution=PRESET_TEMPERATURE_RESOLUTION,

‎plugwise/helper.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,22 @@ def _preset(self, loc_id: str) -> str | None:
920920

921921
return None # pragma: no cover
922922

923+
def _cooling_allowed(self, loc_id: str) -> bool:
924+
"""Helper-function for data.py: _climate_data() and smile.py: set_preset_temperature().
925+
926+
Collect whether cooling is allowed in a zone, based on Location ID.
927+
Assume it is where the zone says nothing, leaving the gateway-wide
928+
capability to decide.
929+
"""
930+
locator = (
931+
f'./location[@id="{loc_id}"]/actuator_functionalities'
932+
"/thermostat_functionality/cooling_allowed"
933+
)
934+
if (allowed := self._domain_objects.find(locator)) is not None:
935+
return str(allowed.text) == "true"
936+
937+
return True
938+
923939
def _presets(self, loc_id: str) -> dict[str, list[float]]:
924940
"""Collect Presets for a Thermostat based on location_id."""
925941
presets: dict[str, list[float]] = {}

0 commit comments

Comments
 (0)