aiocomfoconnect 0.2.1__tar.gz → 0.3.0__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.
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/PKG-INFO +5 -7
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/README.md +2 -2
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/bridge.py +7 -2
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/comfoconnect.py +9 -3
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/pyproject.toml +5 -5
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/LICENSE +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/__init__.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/__main__.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/const.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/discovery.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/exceptions.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/properties.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/protobuf/nanopb_pb2.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/protobuf/zehnder_pb2.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/sensors.py +0 -0
- {aiocomfoconnect-0.2.1 → aiocomfoconnect-0.3.0}/aiocomfoconnect/util.py +0 -0
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiocomfoconnect
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: aiocomfoconnect is an asyncio Python 3 library for communicating with a Zehnder ComfoAir Q350/450/600 ventilation system
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Author: Michaël Arnauts
|
|
7
7
|
Author-email: michael.arnauts@gmail.com
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.13,<4.0
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
13
10
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
11
|
Classifier: Programming Language :: Python :: 3.14
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
15
13
|
Requires-Dist: aiohttp (>=3.8.0,<4.0.0)
|
|
16
14
|
Requires-Dist: protobuf (>=6.31,<8)
|
|
17
15
|
Project-URL: Homepage, https://github.com/michaelarnauts/aiocomfoconnect
|
|
@@ -24,7 +22,7 @@ Description-Content-Type: text/markdown
|
|
|
24
22
|
|
|
25
23
|
The [home-assistant-comfoconnect](https://github.com/michaelarnauts/home-assistant-comfoconnect) is using this library.
|
|
26
24
|
|
|
27
|
-
It's compatible with Python 3.
|
|
25
|
+
It's compatible with Python 3.13 and higher.
|
|
28
26
|
|
|
29
27
|
## Installation
|
|
30
28
|
|
|
@@ -65,7 +63,7 @@ $ python -m aiocomfoconnect get-property --host 192.168.1.213 1 1 8 9 # Unit 0x
|
|
|
65
63
|
- `async register_sensor(sensor)`: Register a sensor.
|
|
66
64
|
- `async deregister_sensor(sensor)`: Deregister a sensor.
|
|
67
65
|
- `async get_mode()`: Get the ventilation mode.
|
|
68
|
-
- `async set_mode(mode)`: Set the ventilation mode. (auto / manual)
|
|
66
|
+
- `async set_mode(mode)`: Set the ventilation mode. (auto / manual) Selecting `auto` also cancels the temporary fan-speed override and returns control to the unit's schedule.
|
|
69
67
|
- `async get_comfocool_mode()`: Get Comfocool mode
|
|
70
68
|
- `async set_comfocool_mode()`: Set Comfocool mode. (auto / off)
|
|
71
69
|
- `async get_speed()`: Get the ventilation speed.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
The [home-assistant-comfoconnect](https://github.com/michaelarnauts/home-assistant-comfoconnect) is using this library.
|
|
7
7
|
|
|
8
|
-
It's compatible with Python 3.
|
|
8
|
+
It's compatible with Python 3.13 and higher.
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
@@ -46,7 +46,7 @@ $ python -m aiocomfoconnect get-property --host 192.168.1.213 1 1 8 9 # Unit 0x
|
|
|
46
46
|
- `async register_sensor(sensor)`: Register a sensor.
|
|
47
47
|
- `async deregister_sensor(sensor)`: Deregister a sensor.
|
|
48
48
|
- `async get_mode()`: Get the ventilation mode.
|
|
49
|
-
- `async set_mode(mode)`: Set the ventilation mode. (auto / manual)
|
|
49
|
+
- `async set_mode(mode)`: Set the ventilation mode. (auto / manual) Selecting `auto` also cancels the temporary fan-speed override and returns control to the unit's schedule.
|
|
50
50
|
- `async get_comfocool_mode()`: Get Comfocool mode
|
|
51
51
|
- `async set_comfocool_mode()`: Set Comfocool mode. (auto / off)
|
|
52
52
|
- `async get_speed()`: Get the ventilation speed.
|
|
@@ -13,7 +13,7 @@ from typing import Awaitable, Callable, Dict, Iterator, Optional, Set
|
|
|
13
13
|
from google.protobuf.message import DecodeError
|
|
14
14
|
from google.protobuf.message import Message as ProtobufMessage
|
|
15
15
|
|
|
16
|
-
from .const import VENTILATION_UNIT_PRODUCT_IDS
|
|
16
|
+
from .const import VENTILATION_UNIT_PRODUCT_IDS, PdoType
|
|
17
17
|
from .exceptions import (
|
|
18
18
|
AioComfoConnectNotConnected,
|
|
19
19
|
AioComfoConnectNotReachable,
|
|
@@ -134,6 +134,7 @@ class Bridge:
|
|
|
134
134
|
self._ventilation_node_found: Optional[asyncio.Event] = None
|
|
135
135
|
|
|
136
136
|
self.__sensor_callback_fn: Optional[Callable[[int, int], None]] = None
|
|
137
|
+
self._sensor_pdo_types: Dict[int, int] = {}
|
|
137
138
|
self.__alarm_callback_fn: Optional[Callable[[int, ProtobufMessage], None]] = None
|
|
138
139
|
|
|
139
140
|
self._loop: Optional[asyncio.AbstractEventLoop] = loop
|
|
@@ -424,7 +425,9 @@ class Bridge:
|
|
|
424
425
|
# pylint: disable=no-member
|
|
425
426
|
if message.cmd.type == zehnder_pb2.GatewayOperation.CnRpdoNotificationType:
|
|
426
427
|
if self.__sensor_callback_fn:
|
|
427
|
-
self.
|
|
428
|
+
pdo_type = self._sensor_pdo_types.get(message.msg.pdid)
|
|
429
|
+
signed = pdo_type not in (PdoType.TYPE_CN_UINT8, PdoType.TYPE_CN_UINT16, PdoType.TYPE_CN_UINT32)
|
|
430
|
+
self.__sensor_callback_fn(message.msg.pdid, int.from_bytes(message.msg.data, byteorder="little", signed=signed))
|
|
428
431
|
else:
|
|
429
432
|
_LOGGER.info("Unhandled CnRpdoNotificationType since no callback is registered.")
|
|
430
433
|
|
|
@@ -572,6 +575,8 @@ class Bridge:
|
|
|
572
575
|
def cmd_rpdo_request(self, pdid: int, pdo_type: int = 1, zone: int = 1, timeout=None) -> Awaitable[Message]:
|
|
573
576
|
"""Register a RPDO request."""
|
|
574
577
|
_LOGGER.debug("CnRpdoRequest")
|
|
578
|
+
# Notifications can arrive before the subscription acknowledgement.
|
|
579
|
+
self._sensor_pdo_types[pdid] = pdo_type
|
|
575
580
|
# pylint: disable=no-member
|
|
576
581
|
return self._send(
|
|
577
582
|
zehnder_pb2.CnRpdoRequest,
|
|
@@ -301,9 +301,14 @@ class ComfoConnect(Bridge):
|
|
|
301
301
|
|
|
302
302
|
self._sensors_values[sensor_id] = sensor_value
|
|
303
303
|
|
|
304
|
-
#
|
|
304
|
+
# The bridge sends invalid (zero) values right after we subscribe to a sensor, so we hold them back.
|
|
305
|
+
# A non-zero value is a real value, so we can release the hold and emit it right away.
|
|
305
306
|
if sensor_id in self._sensor_holds:
|
|
306
|
-
|
|
307
|
+
if not sensor_value:
|
|
308
|
+
return
|
|
309
|
+
|
|
310
|
+
_LOGGER.debug("Got a valid value for sensor %s, releasing the hold", sensor_id)
|
|
311
|
+
self._sensor_holds.pop(sensor_id).cancel()
|
|
307
312
|
|
|
308
313
|
if sensor.value_fn:
|
|
309
314
|
val = sensor.value_fn(sensor_value)
|
|
@@ -335,9 +340,10 @@ class ComfoConnect(Bridge):
|
|
|
335
340
|
return VentilationMode.MANUAL if mode == 1 else VentilationMode.AUTO
|
|
336
341
|
|
|
337
342
|
async def set_mode(self, mode: Literal["auto", "manual"]):
|
|
338
|
-
"""Set
|
|
343
|
+
"""Set ventilation mode, cancelling the temporary speed override for auto."""
|
|
339
344
|
if mode == VentilationMode.AUTO:
|
|
340
345
|
await self.cmd_rmi_request(bytes([0x85, UNIT_SCHEDULE, SUBUNIT_08, 0x01]))
|
|
346
|
+
await self.cmd_rmi_request(bytes([0x85, UNIT_SCHEDULE, SUBUNIT_01, 0x01]))
|
|
341
347
|
elif mode == VentilationMode.MANUAL:
|
|
342
348
|
await self.cmd_rmi_request(bytes([0x84, UNIT_SCHEDULE, SUBUNIT_08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01]))
|
|
343
349
|
else:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "aiocomfoconnect"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "aiocomfoconnect is an asyncio Python 3 library for communicating with a Zehnder ComfoAir Q350/450/600 ventilation system"
|
|
5
5
|
authors = ["Michaël Arnauts <michael.arnauts@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -10,7 +10,7 @@ homepage = "https://github.com/michaelarnauts/aiocomfoconnect"
|
|
|
10
10
|
aiocomfoconnect = "aiocomfoconnect.__main__:main_cli"
|
|
11
11
|
|
|
12
12
|
[tool.poetry.dependencies]
|
|
13
|
-
python = "^3.
|
|
13
|
+
python = "^3.13"
|
|
14
14
|
aiohttp = "^3.8.0"
|
|
15
15
|
protobuf = ">=6.31,<8"
|
|
16
16
|
|
|
@@ -20,8 +20,8 @@ dpkt = "^1.9.8"
|
|
|
20
20
|
black = "^24.4.0"
|
|
21
21
|
isort = "^5.10.1"
|
|
22
22
|
pylint = "^3.2"
|
|
23
|
-
pytest = "^8.
|
|
24
|
-
pytest-asyncio = "^
|
|
23
|
+
pytest = "^8.4"
|
|
24
|
+
pytest-asyncio = "^1.4.0"
|
|
25
25
|
|
|
26
26
|
[build-system]
|
|
27
27
|
requires = ["poetry-core"]
|
|
@@ -31,7 +31,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
31
31
|
profile = "black"
|
|
32
32
|
|
|
33
33
|
[tool.black]
|
|
34
|
-
target-version = ["
|
|
34
|
+
target-version = ["py313"]
|
|
35
35
|
line-length = 180
|
|
36
36
|
|
|
37
37
|
[tool.pylint.MAIN]
|
|
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
|