python-hilo 2026.11.1__tar.gz → 2026.11.2__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.
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/PKG-INFO +1 -1
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/const.py +1 -1
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/device/climate.py +13 -6
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyproject.toml +1 -1
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/tests/test_climate.py +27 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/uv.lock +7 -17
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.bandit.yaml +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.devcontainer/devcontainer-lock.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.devcontainer/devcontainer.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.editorconfig +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.gitattributes +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.github/ISSUE_TEMPLATE/issue.md +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.github/dependabot.yml +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.github/labels.yml +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.github/release-drafter.yml +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.github/workflows/labeler.yml +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.github/workflows/release-drafter.yml +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.github/workflows/tests.yaml +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.gitignore +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/.pre-commit-config.yaml +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/AGENTS.md +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/LICENSE +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/README.md +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/README.md +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/graphql/onAnyDeviceUpdated-cee.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/graphql/onAnyDeviceUpdated-meter.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/graphql/onAnyDeviceUpdated-tstat.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/postman/hilo-prod.postman_environment.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/postman/hilo.postman_collection.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/rest/location_weather.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/rest/season_events_ch_2025.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/rest/season_events_ch_2026_empty.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/rest/season_events_hilo_2024.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/rest/seasons_summary.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/ChallengeAdded.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/EventAdded.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/EventCHConsumptionUpdatedValuesReceived-during-event.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/EventCHConsumptionUpdatedValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/EventCHDetailsInitialValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/EventCHDetailsUpdatedValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/EventFlexConsumptionUpdatedValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/EventFlexDetailsInitialValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/EventFlexDetailsUpdatedValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/legacy-pre-2025/ChallengeAdded.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/legacy-pre-2025/ChallengeConsumptionUpdatedValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/legacy-pre-2025/ChallengeDetailsInitialValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/legacy-pre-2025/ChallengeListInitialValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/legacy-pre-2025/ChallengeListUpdatedValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/devicehub/DeviceListInitialValuesReceived.json +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/__init__.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/api.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/auth.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/device/__init__.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/device/graphql_value_mapper.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/device/light.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/device/sensor.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/device/switch.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/devices.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/event.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/exceptions.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/graphql.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/oauth2helper.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/signalr.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/util/__init__.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/pyhilo/util/state.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/tests/__init__.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/tests/test_api_auth.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/tests/test_device.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/tests/test_graphql_value_mapper.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/tests/test_signalr.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/tests/test_util.py +0 -0
- {python_hilo-2026.11.1 → python_hilo-2026.11.2}/tests/test_util_state.py +0 -0
|
@@ -11,7 +11,7 @@ INSTANCE_ID: Final = str(uuid.uuid4())[24:]
|
|
|
11
11
|
LOG: Final = logging.getLogger(__package__)
|
|
12
12
|
DEFAULT_STATE_FILE: Final = "hilo_state.yaml"
|
|
13
13
|
REQUEST_RETRY: Final = 9
|
|
14
|
-
PYHILO_VERSION: Final = "2026.11.
|
|
14
|
+
PYHILO_VERSION: Final = "2026.11.02"
|
|
15
15
|
# TODO: Find a way to keep previous line in sync with pyproject.toml automatically
|
|
16
16
|
|
|
17
17
|
CONTENT_TYPE_FORM: Final = "application/x-www-form-urlencoded"
|
|
@@ -102,9 +102,20 @@ class Climate(HiloDevice):
|
|
|
102
102
|
"""
|
|
103
103
|
Gets the current HVAC action of the device.
|
|
104
104
|
|
|
105
|
+
For 24 V thermostats the action comes from currentState ("HEATING",
|
|
106
|
+
"COOLING", "OFF"). For baseboard thermostats it is derived from the
|
|
107
|
+
reported heating power.
|
|
108
|
+
|
|
105
109
|
Returns:
|
|
106
|
-
str: 'heating'
|
|
110
|
+
str: one of 'heating', 'cooling', or 'idle'.
|
|
107
111
|
"""
|
|
112
|
+
if self.is_low_voltage:
|
|
113
|
+
state = self.current_state
|
|
114
|
+
if state == "HEATING":
|
|
115
|
+
return "heating"
|
|
116
|
+
if state == "COOLING":
|
|
117
|
+
return "cooling"
|
|
118
|
+
return "idle"
|
|
108
119
|
attr = self.get_value("heating", 0)
|
|
109
120
|
return "heating" if attr > 0 else "idle"
|
|
110
121
|
|
|
@@ -170,11 +181,7 @@ class Climate(HiloDevice):
|
|
|
170
181
|
|
|
171
182
|
@property
|
|
172
183
|
def current_state(self) -> str | None:
|
|
173
|
-
"""Raw running state reported by a 24 V thermostat.
|
|
174
|
-
|
|
175
|
-
Exposed for consumers, but deliberately not mapped to hvac_action yet:
|
|
176
|
-
its vocabulary has not been observed in enough operating conditions.
|
|
177
|
-
"""
|
|
184
|
+
"""Raw running state reported by a 24 V thermostat ("HEATING", "COOLING", "OFF")."""
|
|
178
185
|
return self._optional_str("current_state")
|
|
179
186
|
|
|
180
187
|
@property
|
|
@@ -41,6 +41,33 @@ def _climate(**readings):
|
|
|
41
41
|
return device
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
class TestHvacAction:
|
|
45
|
+
@pytest.mark.parametrize(
|
|
46
|
+
"current_state, expected",
|
|
47
|
+
[
|
|
48
|
+
pytest.param("HEATING", "heating", id="heating"),
|
|
49
|
+
pytest.param("COOLING", "cooling", id="cooling"),
|
|
50
|
+
pytest.param("OFF", "idle", id="off-is-idle"),
|
|
51
|
+
pytest.param(None, "idle", id="unreported-is-idle"),
|
|
52
|
+
],
|
|
53
|
+
)
|
|
54
|
+
def test_low_voltage_maps_current_state(self, current_state, expected):
|
|
55
|
+
kwargs = {"Thermostat24VMode": "AUTO"}
|
|
56
|
+
if current_state is not None:
|
|
57
|
+
kwargs["CurrentState"] = current_state
|
|
58
|
+
assert _climate(**kwargs).hvac_action == expected
|
|
59
|
+
|
|
60
|
+
@pytest.mark.parametrize(
|
|
61
|
+
"heating, expected",
|
|
62
|
+
[
|
|
63
|
+
pytest.param(1, "heating", id="power-on-is-heating"),
|
|
64
|
+
pytest.param(0, "idle", id="power-off-is-idle"),
|
|
65
|
+
],
|
|
66
|
+
)
|
|
67
|
+
def test_baseboard_uses_heating_power(self, heating, expected):
|
|
68
|
+
assert _climate(Heating=heating).hvac_action == expected
|
|
69
|
+
|
|
70
|
+
|
|
44
71
|
class TestAsList:
|
|
45
72
|
def test_none_is_empty(self):
|
|
46
73
|
assert as_list(None) == []
|
|
@@ -907,14 +907,14 @@ wheels = [
|
|
|
907
907
|
|
|
908
908
|
[[package]]
|
|
909
909
|
name = "pytest-asyncio"
|
|
910
|
-
version = "1.4.1"
|
|
910
|
+
version = "1.4.1.post1"
|
|
911
911
|
source = { registry = "https://pypi.org/simple" }
|
|
912
912
|
dependencies = [
|
|
913
913
|
{ name = "pytest" },
|
|
914
914
|
]
|
|
915
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
915
|
+
sdist = { url = "https://files.pythonhosted.org/packages/73/7f/c60a4338420b33453d4f814ac0c930abd399f162b9bdd21af4b9e363037f/pytest_asyncio-1.4.1.post1.tar.gz", hash = "sha256:f582d9ea4a1c082195abe8bd29a1fe106aeb1cd435e3dad2d3bc2749935c36a2", size = 145360, upload-time = "2026-11-01T18:26:03.732Z" }
|
|
916
916
|
wheels = [
|
|
917
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
917
|
+
{ url = "https://files.pythonhosted.org/packages/e3/de/adbc7578959cfab07e5e7c05cf6d54224a51e7667ea2c07458b6bc571e75/pytest_asyncio-1.4.1.post1-py3-none-any.whl", hash = "sha256:0755e488cc0a2b9bd2eab7292cc6390d4cbb8390f1020745647bae5a708e0165", size = 17140, upload-time = "2026-11-01T18:26:02.168Z" },
|
|
918
918
|
]
|
|
919
919
|
|
|
920
920
|
[[package]]
|
|
@@ -933,15 +933,14 @@ wheels = [
|
|
|
933
933
|
|
|
934
934
|
[[package]]
|
|
935
935
|
name = "python-dateutil"
|
|
936
|
-
version = "
|
|
936
|
+
version = "4.0.0"
|
|
937
937
|
source = { registry = "https://pypi.org/simple" }
|
|
938
938
|
dependencies = [
|
|
939
|
-
{ name = "six" },
|
|
940
939
|
{ name = "tzdata" },
|
|
941
940
|
]
|
|
942
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
941
|
+
sdist = { url = "https://files.pythonhosted.org/packages/18/39/b3927f3616f6223832f9b760e4208e8a7c7e1dea2b4d9ad7d32a5d214c3a/python_dateutil-4.0.0.tar.gz", hash = "sha256:d7295ff14fdc0f92f662100bfb6c551d160ca090f2939f1ec5b9794265c03f06", size = 250419, upload-time = "2026-11-01T07:02:42.426Z" }
|
|
943
942
|
wheels = [
|
|
944
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
943
|
+
{ url = "https://files.pythonhosted.org/packages/2f/a9/52b89563d154433d79b51ed1eb4842bf7334cb2696891a7fe135618853d7/python_dateutil-4.0.0-py3-none-any.whl", hash = "sha256:a5e246f79eb80475e691bf93862cead98decd8a498cf53ba0516fcdc0f50dc1c", size = 92853, upload-time = "2026-11-01T07:02:40.797Z" },
|
|
945
944
|
]
|
|
946
945
|
|
|
947
946
|
[[package]]
|
|
@@ -958,7 +957,7 @@ wheels = [
|
|
|
958
957
|
|
|
959
958
|
[[package]]
|
|
960
959
|
name = "python-hilo"
|
|
961
|
-
version = "2026.11.
|
|
960
|
+
version = "2026.11.2"
|
|
962
961
|
source = { editable = "." }
|
|
963
962
|
dependencies = [
|
|
964
963
|
{ name = "aiofiles" },
|
|
@@ -1064,15 +1063,6 @@ wheels = [
|
|
|
1064
1063
|
{ url = "https://files.pythonhosted.org/packages/99/d5/4ad4ed31413c301430918e70d3d38ae6f097af0766cb9ab8c9d502b2a4d6/ruff-0.17.3-py3-none-win_arm64.whl", hash = "sha256:81fce74bcd6be0e9da7c67c7553fd0f1f12964a2052cd728ef917b937a5ca1d9", size = 9854332, upload-time = "2026-10-27T00:34:03.847Z" },
|
|
1065
1064
|
]
|
|
1066
1065
|
|
|
1067
|
-
[[package]]
|
|
1068
|
-
name = "six"
|
|
1069
|
-
version = "1.17.0"
|
|
1070
|
-
source = { registry = "https://pypi.org/simple" }
|
|
1071
|
-
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
|
|
1072
|
-
wheels = [
|
|
1073
|
-
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
|
|
1074
|
-
]
|
|
1075
|
-
|
|
1076
1066
|
[[package]]
|
|
1077
1067
|
name = "typing-extensions"
|
|
1078
1068
|
version = "4.16.0"
|
|
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
|
|
File without changes
|
{python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/postman/hilo-prod.postman_environment.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_hilo-2026.11.1 → python_hilo-2026.11.2}/doc/signalr/challengehub/ChallengeAdded.json
RENAMED
|
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
|
|
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
|