plugwise 1.6.1__tar.gz → 1.6.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plugwise-1.6.1 → plugwise-1.6.3}/PKG-INFO +1 -1
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/__init__.py +1 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/constants.py +2 -1
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/data.py +29 -21
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/helper.py +25 -7
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/smile.py +4 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise.egg-info/PKG-INFO +1 -1
- {plugwise-1.6.1 → plugwise-1.6.3}/pyproject.toml +1 -1
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_adam.py +20 -4
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_anna.py +30 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_init.py +12 -4
- {plugwise-1.6.1 → plugwise-1.6.3}/LICENSE +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/README.md +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/common.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/exceptions.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/legacy/data.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/legacy/helper.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/legacy/smile.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/py.typed +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise/util.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise.egg-info/SOURCES.txt +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise.egg-info/dependency_links.txt +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise.egg-info/requires.txt +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/plugwise.egg-info/top_level.txt +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/setup.cfg +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/setup.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_generic.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_legacy_anna.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_legacy_generic.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_legacy_p1.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_legacy_stretch.py +0 -0
- {plugwise-1.6.1 → plugwise-1.6.3}/tests/test_p1.py +0 -0
@@ -196,6 +196,7 @@ ZONE_MEASUREMENTS: Final[dict[str, DATA | UOM]] = {
|
|
196
196
|
"electricity_produced": UOM(POWER_WATT),
|
197
197
|
"relay": UOM(NONE),
|
198
198
|
"temperature": UOM(TEMP_CELSIUS), # HA Core thermostat current_temperature
|
199
|
+
"thermostat": DATA("setpoint", TEMP_CELSIUS), # HA Core thermostat setpoint
|
199
200
|
}
|
200
201
|
|
201
202
|
# Literals
|
@@ -566,7 +567,7 @@ class GwEntityData(TypedDict, total=False):
|
|
566
567
|
|
567
568
|
climate_mode: str
|
568
569
|
# Extra for Adam Master Thermostats
|
569
|
-
control_state: str
|
570
|
+
control_state: str
|
570
571
|
|
571
572
|
# Dict-types
|
572
573
|
binary_sensors: SmileBinarySensors
|
@@ -160,9 +160,16 @@ class SmileData(SmileHelper):
|
|
160
160
|
"""
|
161
161
|
zone = self._zones[loc_id]
|
162
162
|
data = self._get_zone_data(loc_id)
|
163
|
-
if ctrl_state := self._control_state(loc_id):
|
164
|
-
|
165
|
-
|
163
|
+
if ctrl_state := self._control_state(data, loc_id):
|
164
|
+
if str(ctrl_state) in ("cooling", "heating", "preheating"):
|
165
|
+
data["control_state"] = str(ctrl_state)
|
166
|
+
self._count += 1
|
167
|
+
if str(ctrl_state) == "off":
|
168
|
+
data["control_state"] = "idle"
|
169
|
+
self._count += 1
|
170
|
+
|
171
|
+
data["sensors"].pop("setpoint") # remove, only used in _control_state()
|
172
|
+
self._count -= 1
|
166
173
|
|
167
174
|
# Thermostat data (presets, temperatures etc)
|
168
175
|
self._climate_data(loc_id, zone, data)
|
@@ -191,7 +198,8 @@ class SmileData(SmileHelper):
|
|
191
198
|
# Switching groups data
|
192
199
|
self._entity_switching_group(entity, data)
|
193
200
|
# Adam data
|
194
|
-
self.
|
201
|
+
if self.smile(ADAM):
|
202
|
+
self._get_adam_data(entity, data)
|
195
203
|
|
196
204
|
# Thermostat data for Anna (presets, temperatures etc)
|
197
205
|
if self.smile(ANNA) and entity["dev_class"] == "thermostat":
|
@@ -218,26 +226,26 @@ class SmileData(SmileHelper):
|
|
218
226
|
"""Helper-function for _get_entity_data().
|
219
227
|
|
220
228
|
Determine Adam heating-status for on-off heating via valves,
|
221
|
-
available regulations_modes and thermostat control_states
|
229
|
+
available regulations_modes and thermostat control_states,
|
230
|
+
and add missing cooling_enabled when required.
|
222
231
|
"""
|
223
|
-
if
|
232
|
+
if entity["dev_class"] == "heater_central":
|
224
233
|
# Indicate heating_state based on valves being open in case of city-provided heating
|
225
|
-
if (
|
226
|
-
entity["dev_class"] == "heater_central"
|
227
|
-
and self._on_off_device
|
228
|
-
and isinstance(self._heating_valves(), int)
|
229
|
-
):
|
234
|
+
if self._on_off_device and isinstance(self._heating_valves(), int):
|
230
235
|
data["binary_sensors"]["heating_state"] = self._heating_valves() != 0
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
236
|
+
# Add cooling_enabled binary_sensor
|
237
|
+
if "binary_sensors" in data:
|
238
|
+
if "cooling_enabled" not in data["binary_sensors"] and self._cooling_present:
|
239
|
+
data["binary_sensors"]["cooling_enabled"] = self._cooling_enabled
|
240
|
+
|
241
|
+
# Show the allowed regulation_modes and gateway_modes
|
242
|
+
if entity["dev_class"] == "gateway":
|
243
|
+
if self._reg_allowed_modes:
|
244
|
+
data["regulation_modes"] = self._reg_allowed_modes
|
245
|
+
self._count += 1
|
246
|
+
if self._gw_allowed_modes:
|
247
|
+
data["gateway_modes"] = self._gw_allowed_modes
|
248
|
+
self._count += 1
|
241
249
|
|
242
250
|
def _climate_data(
|
243
251
|
self,
|
@@ -64,7 +64,7 @@ from dateutil import tz
|
|
64
64
|
from dateutil.parser import parse
|
65
65
|
from defusedxml import ElementTree as etree
|
66
66
|
from munch import Munch
|
67
|
-
from packaging
|
67
|
+
from packaging import version
|
68
68
|
|
69
69
|
|
70
70
|
class SmileComm:
|
@@ -252,13 +252,14 @@ class SmileHelper(SmileCommon):
|
|
252
252
|
self.gateway_id: str
|
253
253
|
self.gw_data: GatewayData = {}
|
254
254
|
self.gw_entities: dict[str, GwEntityData] = {}
|
255
|
-
self.smile_fw_version: Version | None
|
255
|
+
self.smile_fw_version: version.Version | None
|
256
256
|
self.smile_hw_version: str | None
|
257
257
|
self.smile_mac_address: str | None
|
258
258
|
self.smile_model: str
|
259
259
|
self.smile_model_id: str | None
|
260
260
|
self.smile_name: str
|
261
261
|
self.smile_type: str
|
262
|
+
self.smile_version: version.Version | None
|
262
263
|
self.smile_zigbee_mac_address: str | None
|
263
264
|
self.therms_with_offset_func: list[str] = []
|
264
265
|
self._zones: dict[str, GwEntityData] = {}
|
@@ -797,7 +798,9 @@ class SmileHelper(SmileCommon):
|
|
797
798
|
# Techneco Elga has cooling-capability
|
798
799
|
self._cooling_present = True
|
799
800
|
data["model"] = "Generic heater/cooler"
|
800
|
-
|
801
|
+
# Cooling_enabled in xml does NOT show the correct status!
|
802
|
+
# Setting it specifically:
|
803
|
+
self._cooling_enabled = data["binary_sensors"]["cooling_enabled"] = data["elga_status_code"] in (8, 9)
|
801
804
|
data["binary_sensors"]["cooling_state"] = self._cooling_active = (
|
802
805
|
data["elga_status_code"] == 8
|
803
806
|
)
|
@@ -811,11 +814,13 @@ class SmileHelper(SmileCommon):
|
|
811
814
|
|
812
815
|
def _update_loria_cooling(self, data: GwEntityData) -> None:
|
813
816
|
"""Loria/Thermastage: base cooling-related on cooling_state and modulation_level."""
|
814
|
-
|
817
|
+
# For Loria/Thermastage it's not clear if cooling_enabled in xml shows the correct status,
|
818
|
+
# setting it specifically:
|
819
|
+
self._cooling_enabled = data["binary_sensors"]["cooling_enabled"] = data["binary_sensors"]["cooling_state"]
|
815
820
|
self._cooling_active = data["sensors"]["modulation_level"] == 100
|
816
821
|
# For Loria the above does not work (pw-beta issue #301)
|
817
822
|
if "cooling_ena_switch" in data["switches"]:
|
818
|
-
self._cooling_enabled = data["switches"]["cooling_ena_switch"]
|
823
|
+
self._cooling_enabled = data["binary_sensors"]["cooling_enabled"] = data["switches"]["cooling_ena_switch"]
|
819
824
|
self._cooling_active = data["binary_sensors"]["cooling_state"]
|
820
825
|
|
821
826
|
def _cleanup_data(self, data: GwEntityData) -> None:
|
@@ -917,7 +922,7 @@ class SmileHelper(SmileCommon):
|
|
917
922
|
else:
|
918
923
|
thermo_loc["secondary"].append(appliance_id)
|
919
924
|
|
920
|
-
def _control_state(self, loc_id: str) -> str | bool:
|
925
|
+
def _control_state(self, data: GwEntityData, loc_id: str) -> str | bool:
|
921
926
|
"""Helper-function for _get_adam_data().
|
922
927
|
|
923
928
|
Adam: find the thermostat control_state of a location, from DOMAIN_OBJECTS.
|
@@ -930,7 +935,20 @@ class SmileHelper(SmileCommon):
|
|
930
935
|
if (ctrl_state := location.find(locator)) is not None:
|
931
936
|
return str(ctrl_state.text)
|
932
937
|
|
933
|
-
|
938
|
+
# Handle missing control_state in regulation_mode off for firmware >= 3.2.0 (issue #776)
|
939
|
+
# In newer firmware versions, default to "off" when control_state is not present
|
940
|
+
if self.smile_version is not None:
|
941
|
+
if self.smile_version >= version.parse("3.2.0"):
|
942
|
+
return "off"
|
943
|
+
|
944
|
+
# Older Adam firmware does not have the control_state xml-key
|
945
|
+
# Work around this by comparing the reported temperature and setpoint for a location
|
946
|
+
setpoint = data["sensors"]["setpoint"]
|
947
|
+
temperature = data["sensors"]["temperature"]
|
948
|
+
# No cooling available in older firmware
|
949
|
+
return "heating" if temperature < setpoint else "off"
|
950
|
+
|
951
|
+
return False # pragma: no cover
|
934
952
|
|
935
953
|
def _heating_valves(self) -> int | bool:
|
936
954
|
"""Helper-function for smile.py: _get_adam_data().
|
@@ -66,6 +66,7 @@ class SmileAPI(SmileData):
|
|
66
66
|
smile_model_id: str | None,
|
67
67
|
smile_name: str,
|
68
68
|
smile_type: str,
|
69
|
+
smile_version: Version | None,
|
69
70
|
port: int = DEFAULT_PORT,
|
70
71
|
username: str = DEFAULT_USERNAME,
|
71
72
|
) -> None:
|
@@ -90,6 +91,7 @@ class SmileAPI(SmileData):
|
|
90
91
|
self.smile_model_id = smile_model_id
|
91
92
|
self.smile_name = smile_name
|
92
93
|
self.smile_type = smile_type
|
94
|
+
self.smile_version = smile_version
|
93
95
|
SmileData.__init__(self)
|
94
96
|
|
95
97
|
|
@@ -129,6 +131,8 @@ class SmileAPI(SmileData):
|
|
129
131
|
try:
|
130
132
|
await self.full_xml_update()
|
131
133
|
self.get_all_gateway_entities()
|
134
|
+
# Set self._cooling_enabled -required for set_temperature,
|
135
|
+
#also, check for a failed data-retrieval
|
132
136
|
if "heater_id" in self.gw_data:
|
133
137
|
heat_cooler = self.gw_entities[self.gw_data["heater_id"]]
|
134
138
|
if (
|
@@ -18,7 +18,7 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
18
18
|
|
19
19
|
@pytest.mark.asyncio
|
20
20
|
async def test_connect_adam_plus_anna_new(self):
|
21
|
-
"""Test extended Adam (firmware 3.
|
21
|
+
"""Test extended Adam (firmware 3.7) with Anna and a switch-group setup."""
|
22
22
|
self.smile_setup = "adam_plus_anna_new"
|
23
23
|
|
24
24
|
testdata = self.load_testdata(SMILE_TYPE, self.smile_setup)
|
@@ -167,6 +167,20 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
167
167
|
await smile.close_connection()
|
168
168
|
await self.disconnect(server, client)
|
169
169
|
|
170
|
+
@pytest.mark.asyncio
|
171
|
+
async def test_connect_adam_plus_anna_new_regulation_off(self):
|
172
|
+
"""Test regultaion_mode off with control_state key missing for Adam."""
|
173
|
+
self.smile_setup = "adam_plus_anna_new_regulation_off"
|
174
|
+
|
175
|
+
testdata = self.load_testdata(SMILE_TYPE, self.smile_setup)
|
176
|
+
server, smile, client = await self.connect_wrapper()
|
177
|
+
assert smile.smile_hostname == "smile000000"
|
178
|
+
|
179
|
+
await self.device_test(smile, "2023-12-17 00:00:01", testdata)
|
180
|
+
|
181
|
+
await smile.close_connection()
|
182
|
+
await self.disconnect(server, client)
|
183
|
+
|
170
184
|
@pytest.mark.asyncio
|
171
185
|
async def test_connect_adam_zone_per_device(self):
|
172
186
|
"""Test an extensive setup of Adam with a zone per device."""
|
@@ -189,7 +203,7 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
189
203
|
assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE
|
190
204
|
assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA
|
191
205
|
assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA
|
192
|
-
assert self.entity_items ==
|
206
|
+
assert self.entity_items == 369
|
193
207
|
|
194
208
|
assert "af82e4ccf9c548528166d38e560662a4" in self.notifications
|
195
209
|
await smile.delete_notification()
|
@@ -267,7 +281,7 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
267
281
|
assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE
|
268
282
|
assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA
|
269
283
|
assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA
|
270
|
-
assert self.entity_items ==
|
284
|
+
assert self.entity_items == 369
|
271
285
|
|
272
286
|
assert "af82e4ccf9c548528166d38e560662a4" in self.notifications
|
273
287
|
|
@@ -306,6 +320,8 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
306
320
|
assert smile._last_active["8cf650a4c10c44819e426bed406aec34"] == WERKDAG_SCHEMA
|
307
321
|
assert smile._last_active["5cc21042f87f4b4c94ccb5537c47a53f"] == WERKDAG_SCHEMA
|
308
322
|
assert self.entity_items == 497
|
323
|
+
assert self.cooling_present
|
324
|
+
assert self._cooling_enabled
|
309
325
|
|
310
326
|
await smile.close_connection()
|
311
327
|
await self.disconnect(server, client)
|
@@ -351,7 +367,7 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
351
367
|
await self.device_test(smile, "2020-03-22 00:00:01", testdata)
|
352
368
|
assert smile.gateway_id == "b128b4bbbd1f47e9bf4d756e8fb5ee94"
|
353
369
|
assert smile._last_active["009490cc2f674ce6b576863fbb64f867"] == "Weekschema"
|
354
|
-
assert self.entity_items ==
|
370
|
+
assert self.entity_items == 80
|
355
371
|
assert "6fb89e35caeb4b1cb275184895202d84" in self.notifications
|
356
372
|
|
357
373
|
result = await self.tinker_thermostat(
|
@@ -205,6 +205,7 @@ class TestPlugwiseAnna(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
205
205
|
good_schedules=[
|
206
206
|
"standaard",
|
207
207
|
],
|
208
|
+
fail_cooling=True,
|
208
209
|
)
|
209
210
|
_LOGGER.debug(
|
210
211
|
"ERROR raised setting good schedule standaard: %s", exc.value
|
@@ -261,6 +262,7 @@ class TestPlugwiseAnna(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
261
262
|
good_schedules=[
|
262
263
|
"standaard",
|
263
264
|
],
|
265
|
+
fail_cooling=True,
|
264
266
|
)
|
265
267
|
_LOGGER.debug(
|
266
268
|
"ERROR raised good schedule to standaard: %s", exc.value
|
@@ -407,6 +409,33 @@ class TestPlugwiseAnna(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
407
409
|
assert self._cooling_enabled
|
408
410
|
assert self._cooling_active
|
409
411
|
|
412
|
+
result = await self.tinker_thermostat(
|
413
|
+
smile,
|
414
|
+
"d3ce834534114348be628b61b26d9220",
|
415
|
+
good_schedules=["Thermostat schedule"],
|
416
|
+
)
|
417
|
+
assert result
|
418
|
+
|
419
|
+
# Simulate a change of season: from cooling to heating after an update_interval
|
420
|
+
testdata_updated = self.load_testdata(
|
421
|
+
SMILE_TYPE, f"{self.smile_setup}_UPDATED_DATA"
|
422
|
+
)
|
423
|
+
|
424
|
+
self.smile_setup = "updated/anna_elga_2_switch_heating"
|
425
|
+
await self.device_test(
|
426
|
+
smile, "2020-04-05 00:00:01", testdata_updated, initialize=False
|
427
|
+
)
|
428
|
+
assert self.cooling_present
|
429
|
+
assert not self._cooling_enabled
|
430
|
+
assert not self._cooling_active
|
431
|
+
|
432
|
+
result = await self.tinker_thermostat(
|
433
|
+
smile,
|
434
|
+
"d3ce834534114348be628b61b26d9220",
|
435
|
+
good_schedules=["Thermostat schedule"],
|
436
|
+
)
|
437
|
+
assert result
|
438
|
+
|
410
439
|
await smile.close_connection()
|
411
440
|
await self.disconnect(server, client)
|
412
441
|
|
@@ -445,6 +474,7 @@ class TestPlugwiseAnna(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
445
474
|
good_schedules=[
|
446
475
|
"Winter",
|
447
476
|
],
|
477
|
+
fail_cooling=True,
|
448
478
|
)
|
449
479
|
_LOGGER.debug(
|
450
480
|
"ERROR raised setting to schedule Winter: %s", exc.value
|
@@ -704,14 +704,20 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
|
|
704
704
|
|
705
705
|
@pytest.mark.asyncio
|
706
706
|
async def tinker_thermostat_temp(
|
707
|
-
self, smile, loc_id, block_cooling=False, unhappy=False
|
707
|
+
self, smile, loc_id, block_cooling=False, fail_cooling=False, unhappy=False
|
708
708
|
):
|
709
709
|
"""Toggle temperature to test functionality."""
|
710
710
|
_LOGGER.info("Asserting modifying settings in location (%s):", loc_id)
|
711
711
|
tinker_temp_passed = False
|
712
712
|
test_temp = {"setpoint": 22.9}
|
713
713
|
if self.cooling_present and not block_cooling:
|
714
|
-
|
714
|
+
if smile.smile_name == "Smile Anna":
|
715
|
+
if self._cooling_enabled:
|
716
|
+
test_temp = {"setpoint_low": 4.0, "setpoint_high": 23.0}
|
717
|
+
else:
|
718
|
+
test_temp = {"setpoint_low": 19.0, "setpoint_high": 30.0}
|
719
|
+
if fail_cooling:
|
720
|
+
test_temp = {"setpoint_low": 19.0, "setpoint_high": 23.0}
|
715
721
|
_LOGGER.info("- Adjusting temperature to %s", test_temp)
|
716
722
|
try:
|
717
723
|
await smile.set_temperature(loc_id, test_temp)
|
@@ -826,6 +832,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
|
|
826
832
|
good_schedules=None,
|
827
833
|
single=False,
|
828
834
|
block_cooling=False,
|
835
|
+
fail_cooling=False,
|
829
836
|
unhappy=False,
|
830
837
|
):
|
831
838
|
"""Toggle various climate settings to test functionality."""
|
@@ -833,7 +840,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
|
|
833
840
|
good_schedules = ["Weekschema"]
|
834
841
|
|
835
842
|
result_1 = await self.tinker_thermostat_temp(
|
836
|
-
smile, loc_id, block_cooling, unhappy
|
843
|
+
smile, loc_id, block_cooling, fail_cooling, unhappy
|
837
844
|
)
|
838
845
|
result_2 = await self.tinker_thermostat_preset(smile, loc_id, unhappy)
|
839
846
|
if smile._schedule_old_states != {}:
|
@@ -858,11 +865,12 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
|
|
858
865
|
smile,
|
859
866
|
schedule_on=True,
|
860
867
|
block_cooling=False,
|
868
|
+
fail_cooling=False,
|
861
869
|
unhappy=False,
|
862
870
|
):
|
863
871
|
"""Toggle various climate settings to test functionality."""
|
864
872
|
result_1 = await self.tinker_thermostat_temp(
|
865
|
-
smile, "dummy", block_cooling, unhappy
|
873
|
+
smile, "dummy", block_cooling, fail_cooling, unhappy
|
866
874
|
)
|
867
875
|
result_2 = await self.tinker_thermostat_preset(smile, None, unhappy)
|
868
876
|
result_3 = await self.tinker_legacy_thermostat_schedule(smile, unhappy)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|