aiocomfoconnect 0.3.0__tar.gz → 0.3.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiocomfoconnect
3
- Version: 0.3.0
3
+ Version: 0.3.1
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
@@ -11,6 +11,7 @@ from typing import Literal, Optional
11
11
 
12
12
  from aiocomfoconnect import DEFAULT_NAME, DEFAULT_PIN, DEFAULT_UUID
13
13
  from aiocomfoconnect.comfoconnect import ComfoConnect
14
+ from aiocomfoconnect.const import ProductId
14
15
  from aiocomfoconnect.discovery import discover_bridges
15
16
  from aiocomfoconnect.exceptions import (
16
17
  AioComfoConnectNotConnected,
@@ -24,6 +25,8 @@ from aiocomfoconnect.sensors import SENSORS
24
25
 
25
26
  _LOGGER = logging.getLogger(__name__)
26
27
 
28
+ PRODUCT_NAMES = {value: name.lower() for name, value in vars(ProductId).items() if not name.startswith("_")}
29
+
27
30
 
28
31
  async def main(args):
29
32
  """Main function."""
@@ -57,6 +60,12 @@ async def main(args):
57
60
  elif args.action == "get-property":
58
61
  await run_get_property(args.host, args.uuid, args.node_id, args.unit, args.subunit, args.property_id, args.property_type)
59
62
 
63
+ elif args.action == "set-property":
64
+ await run_set_property(args.host, args.uuid, args.node_id, args.unit, args.subunit, args.property_id, args.property_type, args.value)
65
+
66
+ elif args.action == "list-nodes":
67
+ await run_list_nodes(args.host, args.uuid)
68
+
60
69
  elif args.action == "get-flow-for-speed":
61
70
  await run_get_flow_for_speed(args.host, args.uuid, args.speed)
62
71
 
@@ -341,6 +350,54 @@ async def run_get_property(host: str, uuid: str, node_id: Optional[int], unit: i
341
350
  await comfoconnect.disconnect()
342
351
 
343
352
 
353
+ async def run_set_property(host: str, uuid: str, node_id: Optional[int], unit: int, subunit: int, property_id: int, property_type: int, value: int):
354
+ """Set a property and print the value that is read back."""
355
+ # Discover bridge so we know the UUID
356
+ bridges = await discover_bridges(host)
357
+ if not bridges:
358
+ raise BridgeNotFoundException("No bridge found")
359
+
360
+ # Connect to the bridge
361
+ comfoconnect = ComfoConnect(bridges[0].host, bridges[0].uuid)
362
+ try:
363
+ await comfoconnect.connect(uuid)
364
+ except ComfoConnectNotAllowed:
365
+ print("Could not connect to bridge. Please register first.")
366
+ sys.exit(1)
367
+
368
+ await comfoconnect.set_property_typed(unit, subunit, property_id, value, property_type, node_id=node_id)
369
+ print(await comfoconnect.get_property(Property(unit, subunit, property_id, property_type), node_id))
370
+
371
+ await comfoconnect.disconnect()
372
+
373
+
374
+ async def run_list_nodes(host: str, uuid: str):
375
+ """List the nodes that the bridge sees on the ComfoNet bus."""
376
+ # Discover bridge so we know the UUID
377
+ bridges = await discover_bridges(host)
378
+ if not bridges:
379
+ raise BridgeNotFoundException("No bridge found")
380
+
381
+ # Connect to the bridge
382
+ comfoconnect = ComfoConnect(bridges[0].host, bridges[0].uuid)
383
+ try:
384
+ await comfoconnect.connect(uuid)
385
+ except ComfoConnectNotAllowed:
386
+ print("Could not connect to bridge. Please register first.")
387
+ sys.exit(1)
388
+
389
+ await comfoconnect.cmd_node_request()
390
+ # Nodes arrive as unsolicited notifications, so give the bridge a moment to report them all.
391
+ await asyncio.sleep(2)
392
+
393
+ print("Nodes on the ComfoNet bus:")
394
+ for node in sorted(comfoconnect.nodes.values(), key=lambda n: n.node_id):
395
+ product = PRODUCT_NAMES.get(node.product_id, "unknown")
396
+ print(f"* node {node.node_id}: product {node.product_id} ({product}), zone {node.zone_id}, mode {node.mode}")
397
+
398
+ await comfoconnect.disconnect()
399
+
400
+
344
401
  async def run_get_flow_for_speed(host: str, uuid: str, speed: Literal["away", "low", "medium", "high"]):
345
402
  """Get the configured airflow for the specified speed."""
346
403
  # Discover bridge so we know the UUID
@@ -444,6 +501,20 @@ def main_cli():
444
501
  p_sensor.add_argument("--host", help="Host address of the bridge")
445
502
  p_sensor.add_argument("--uuid", help="UUID of this app", default=DEFAULT_UUID)
446
503
 
504
+ p_set_property = subparsers.add_parser("set-property", help="set a property value")
505
+ p_set_property.add_argument("unit", help="The Unit of the property", type=int)
506
+ p_set_property.add_argument("subunit", help="The Subunit of the property", type=int)
507
+ p_set_property.add_argument("property_id", help="The id of the property", type=int)
508
+ p_set_property.add_argument("property_type", help="The type of the property", type=int)
509
+ p_set_property.add_argument("value", help="The raw value to write", type=int)
510
+ p_set_property.add_argument("--node_id", help="The Node ID to write to (defaults to the discovered ventilation unit)", type=int, default=None)
511
+ p_set_property.add_argument("--host", help="Host address of the bridge")
512
+ p_set_property.add_argument("--uuid", help="UUID of this app", default=DEFAULT_UUID)
513
+
514
+ p_list_nodes = subparsers.add_parser("list-nodes", help="list the nodes on the ComfoNet bus")
515
+ p_list_nodes.add_argument("--host", help="Host address of the bridge")
516
+ p_list_nodes.add_argument("--uuid", help="UUID of this app", default=DEFAULT_UUID)
517
+
447
518
  p_get_flow_speed = subparsers.add_parser("get-flow-for-speed", help="Get m³/h for given speed")
448
519
  p_get_flow_speed.add_argument("speed", help="Fan speed", choices=["low", "medium", "high", "away"])
449
520
  p_get_flow_speed.add_argument("--host", help="Host address of the bridge")
@@ -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, PdoType
16
+ from .const import VENTILATION_UNIT_PRODUCT_IDS, ProductId, PdoType
17
17
  from .exceptions import (
18
18
  AioComfoConnectNotConnected,
19
19
  AioComfoConnectNotReachable,
@@ -67,6 +67,11 @@ class Node:
67
67
  """Returns True if this node is the ventilation unit that handles RMI commands."""
68
68
  return self.product_id in VENTILATION_UNIT_PRODUCT_IDS
69
69
 
70
+ @property
71
+ def is_comfoclime(self) -> bool:
72
+ """Returns True if this node is a ComfoClime heat pump module."""
73
+ return self.product_id == ProductId.COMFOCLIME
74
+
70
75
 
71
76
  class EventBus:
72
77
  """An event bus for async replies."""
@@ -254,6 +259,18 @@ class Bridge:
254
259
  candidates = [node.node_id for node in self._nodes.values() if node.is_ventilation_unit]
255
260
  return min(candidates) if candidates else None
256
261
 
262
+ @property
263
+ def comfoclime_node_id(self) -> Optional[int]:
264
+ """The node id of the ComfoClime, or None when the bridge hasn't announced one."""
265
+ candidates = [node.node_id for node in self._nodes.values() if node.is_comfoclime]
266
+ return min(candidates) if candidates else None
267
+
268
+ @property
269
+ def comfoclime_zone_id(self) -> Optional[int]:
270
+ """The zone id of the ComfoClime, or None when the bridge hasn't announced one."""
271
+ candidates = [node for node in self._nodes.values() if node.is_comfoclime]
272
+ return min(candidates, key=lambda node: node.node_id).zone_id if candidates else None
273
+
257
274
  async def wait_for_ventilation_node(self, timeout: float = None) -> int:
258
275
  """Wait until the bridge has announced the ventilation unit and return its node id.
259
276
 
@@ -33,6 +33,7 @@ from aiocomfoconnect.exceptions import (
33
33
  AioComfoConnectNotConnected,
34
34
  AioComfoConnectNotReachable,
35
35
  AioComfoConnectTimeout,
36
+ ComfoClimeNotFoundException,
36
37
  ComfoConnectNotAllowed,
37
38
  VentilationUnitNotFoundException,
38
39
  )
@@ -289,6 +290,28 @@ class ComfoConnect(Bridge):
289
290
 
290
291
  return result.message
291
292
 
293
+ def _require_comfoclime_node_id(self) -> int:
294
+ """Return the node id of the ComfoClime, or raise when it isn't on the bus."""
295
+ node_id = self.comfoclime_node_id
296
+ if node_id is None:
297
+ raise ComfoClimeNotFoundException("The bridge has not announced a ComfoClime")
298
+ return node_id
299
+
300
+ async def get_comfoclime_property(self, prop: Property) -> Any:
301
+ """Get a property from the ComfoClime node."""
302
+ return await self.get_property(prop, node_id=self._require_comfoclime_node_id())
303
+
304
+ async def set_comfoclime_property(self, prop: Property, value: int) -> Any:
305
+ """Set a property on the ComfoClime node."""
306
+ return await self.set_property_typed(
307
+ prop.unit,
308
+ prop.subunit,
309
+ prop.property_id,
310
+ value,
311
+ prop.property_type,
312
+ node_id=self._require_comfoclime_node_id(),
313
+ )
314
+
292
315
  def _sensor_callback(self, sensor_id, sensor_value):
293
316
  """Callback function for sensor updates."""
294
317
  if self._sensor_callback_fn is None:
@@ -72,6 +72,11 @@ UNIT_POSTHEATER = 0x27
72
72
  UNIT_COMFOFOND = 0x28
73
73
  UNIT_CO2SENSOR = 0x2B
74
74
  UNIT_SERVICEPRINT = 0x2C
75
+
76
+ # Units that only exist on a ComfoClime node. Unit numbers are reused across product types,
77
+ # so 0x16 / 0x17 mean UNIT_VALVE / UNIT_FAN on a ComfoAir node.
78
+ UNIT_CLIME_TEMPCONFIG = 0x16
79
+ UNIT_CLIME_HEATPUMP = 0x17
75
80
  # UNIT_COOLER(21) = 0x15
76
81
  # UNIT_CC_TEMPERATURESENSOR(22) = 0x16
77
82
  # UNIT_IOSENSOR(21) = 0x15
@@ -245,3 +250,46 @@ class ComfoCoolMode:
245
250
 
246
251
  AUTO = "auto"
247
252
  OFF = "off"
253
+
254
+
255
+ class ComfoClimeSeason:
256
+ """Enum for ComfoClime seasons."""
257
+
258
+ TRANSITION = "transition"
259
+ HEATING = "heating"
260
+ COOLING = "cooling"
261
+
262
+
263
+ class ComfoClimeTemperatureProfile:
264
+ """Enum for ComfoClime temperature profiles."""
265
+
266
+ COMFORT = "comfort"
267
+ POWER = "power"
268
+ ECO = "eco"
269
+
270
+
271
+ class ComfoClimeDeviceMode:
272
+ """Enum for the ComfoClime device mode."""
273
+
274
+ OFF = "off"
275
+ HEATING = "heating"
276
+ COOLING = "cooling"
277
+
278
+
279
+ COMFOCLIME_SEASONS = {
280
+ 0: ComfoClimeSeason.TRANSITION,
281
+ 1: ComfoClimeSeason.HEATING,
282
+ 2: ComfoClimeSeason.COOLING,
283
+ }
284
+
285
+ COMFOCLIME_TEMPERATURE_PROFILES = {
286
+ 0: ComfoClimeTemperatureProfile.COMFORT,
287
+ 1: ComfoClimeTemperatureProfile.POWER,
288
+ 2: ComfoClimeTemperatureProfile.ECO,
289
+ }
290
+
291
+ COMFOCLIME_DEVICE_MODES = {
292
+ 0: ComfoClimeDeviceMode.OFF,
293
+ 1: ComfoClimeDeviceMode.HEATING,
294
+ 2: ComfoClimeDeviceMode.COOLING,
295
+ }
@@ -62,5 +62,9 @@ class VentilationUnitNotFoundException(Exception):
62
62
  """Exception raised when the bridge didn't announce a ventilation unit on the ComfoNet bus."""
63
63
 
64
64
 
65
+ class ComfoClimeNotFoundException(Exception):
66
+ """Exception raised when the bridge didn't announce a ComfoClime on the ComfoNet bus."""
67
+
68
+
65
69
  class UnknownActionException(Exception):
66
70
  """Exception raised when an unknown action is provided."""
@@ -0,0 +1,57 @@
1
+ """ Property definitions """
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ from .const import (
8
+ UNIT_CLIME_HEATPUMP,
9
+ UNIT_CLIME_TEMPCONFIG,
10
+ UNIT_NODE,
11
+ UNIT_NODECONFIGURATION,
12
+ UNIT_TEMPHUMCONTROL,
13
+ PdoType,
14
+ )
15
+
16
+
17
+ @dataclass
18
+ class Property:
19
+ """Dataclass for a Property"""
20
+
21
+ unit: int
22
+ subunit: int
23
+ property_id: int
24
+ property_type: int
25
+
26
+
27
+ PROPERTY_SERIAL_NUMBER = Property(UNIT_NODE, 0x01, 0x04, PdoType.TYPE_CN_STRING)
28
+ PROPERTY_FIRMWARE_VERSION = Property(UNIT_NODE, 0x01, 0x06, PdoType.TYPE_CN_UINT32)
29
+ PROPERTY_MODEL = Property(UNIT_NODE, 0x01, 0x08, PdoType.TYPE_CN_STRING)
30
+ PROPERTY_ARTICLE = Property(UNIT_NODE, 0x01, 0x0B, PdoType.TYPE_CN_STRING)
31
+ PROPERTY_COUNTRY = Property(UNIT_NODE, 0x01, 0x0D, PdoType.TYPE_CN_STRING)
32
+ PROPERTY_NAME = Property(UNIT_NODE, 0x01, 0x14, PdoType.TYPE_CN_STRING)
33
+
34
+ PROPERTY_MAINTAINER_PASSWORD = Property(UNIT_NODECONFIGURATION, 0x01, 0x03, PdoType.TYPE_CN_STRING)
35
+
36
+ PROPERTY_SENSOR_VENTILATION_TEMP_PASSIVE = Property(UNIT_TEMPHUMCONTROL, 0x01, 0x04, PdoType.TYPE_CN_UINT32)
37
+ PROPERTY_SENSOR_VENTILATION_HUMIDITY_COMFORT = Property(UNIT_TEMPHUMCONTROL, 0x01, 0x06, PdoType.TYPE_CN_UINT32)
38
+ PROPERTY_SENSOR_VENTILATION_HUMIDITY_PROTECTION = Property(UNIT_TEMPHUMCONTROL, 0x01, 0x07, PdoType.TYPE_CN_UINT32)
39
+
40
+ # Temperatures are stored in tenths of a degree.
41
+ PROPERTY_RMOT_HEATING_THRESHOLD = Property(UNIT_TEMPHUMCONTROL, 0x01, 0x02, PdoType.TYPE_CN_INT16)
42
+ PROPERTY_RMOT_COOLING_THRESHOLD = Property(UNIT_TEMPHUMCONTROL, 0x01, 0x03, PdoType.TYPE_CN_INT16)
43
+
44
+ # ComfoClime properties. These live on the ComfoClime node, not on the ventilation unit.
45
+ PROPERTY_CLIME_AUTO_SEASON = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x02, PdoType.TYPE_CN_UINT8)
46
+ PROPERTY_CLIME_SEASON = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x03, PdoType.TYPE_CN_UINT8)
47
+ PROPERTY_CLIME_HEATING_KNEE_POINT = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x04, PdoType.TYPE_CN_INT16)
48
+ PROPERTY_CLIME_COOLING_KNEE_POINT = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x05, PdoType.TYPE_CN_INT16)
49
+ PROPERTY_CLIME_HEATING_COMFORT_TEMP = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x09, PdoType.TYPE_CN_INT16)
50
+ PROPERTY_CLIME_COOLING_COMFORT_TEMP = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x0A, PdoType.TYPE_CN_INT16)
51
+ PROPERTY_CLIME_COOLING_TEMP_LIMIT = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x0B, PdoType.TYPE_CN_INT16)
52
+ PROPERTY_CLIME_HEATING_DELTA = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x0C, PdoType.TYPE_CN_INT16)
53
+ PROPERTY_CLIME_MANUAL_TARGET_TEMP = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x0D, PdoType.TYPE_CN_INT16)
54
+ PROPERTY_CLIME_TEMPERATURE_PROFILE = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x1D, PdoType.TYPE_CN_UINT8)
55
+ PROPERTY_CLIME_HEATPUMP_STANDBY = Property(UNIT_CLIME_TEMPCONFIG, 0x01, 0x15, PdoType.TYPE_CN_UINT8)
56
+ PROPERTY_CLIME_HEATPUMP_MAX_TEMP = Property(UNIT_CLIME_HEATPUMP, 0x01, 0x03, PdoType.TYPE_CN_INT16)
57
+ PROPERTY_CLIME_HEATPUMP_MIN_TEMP = Property(UNIT_CLIME_HEATPUMP, 0x01, 0x04, PdoType.TYPE_CN_INT16)
@@ -78,6 +78,20 @@ SENSOR_UNIT_TEMPERATURE = 208
78
78
  SENSOR_COMFOCOOL_STATE = 784
79
79
  SENSOR_COMFOCOOL_CONDENSOR_TEMP = 802
80
80
 
81
+ # ComfoClime sensors. These are only reported when a ComfoClime is present on the ComfoNet bus.
82
+ SENSOR_COMFOCLIME_TPMA_TEMPERATURE = 4145
83
+ SENSOR_COMFOCLIME_TARGET_TEMPERATURE = 4148
84
+ SENSOR_COMFOCLIME_DEVICE_MODE = 4149
85
+ SENSOR_COMFOCLIME_COMFORT_TEMPERATURE = 4151
86
+ SENSOR_COMFOCLIME_INDOOR_TEMPERATURE = 4154
87
+ SENSOR_COMFOCLIME_TEMPERATURE_SUPPLY = 4193
88
+ SENSOR_COMFOCLIME_TEMPERATURE_EXHAUST = 4194
89
+ SENSOR_COMFOCLIME_TEMPERATURE_SUPPLY_COIL = 4195
90
+ SENSOR_COMFOCLIME_TEMPERATURE_EXHAUST_COIL = 4196
91
+ SENSOR_COMFOCLIME_TEMPERATURE_COMPRESSOR = 4197
92
+ SENSOR_COMFOCLIME_HEATPUMP_DUTY = 4198
93
+ SENSOR_COMFOCLIME_POWER_USAGE = 4201
94
+
81
95
  UNIT_WATT = "W"
82
96
  UNIT_KWH = "kWh"
83
97
  UNIT_VOLT = "V"
@@ -133,7 +147,7 @@ SENSORS: Dict[int, Sensor] = {
133
147
  SENSOR_PREHEATER_POWER: Sensor("Preheater Power Usage", UNIT_WATT, 146, PdoType.TYPE_CN_UINT16),
134
148
  SENSOR_RF_PAIRING_MODE: Sensor("RF Pairing Mode", None, 176, PdoType.TYPE_CN_UINT8),
135
149
  SENSOR_DAYS_TO_REPLACE_FILTER: Sensor("Days remaining to replace the filter", None, 192, PdoType.TYPE_CN_UINT16),
136
- SENSOR_UNIT_TEMPERATURE: Sensor("Device Temperature Unit", None, 208, PdoType.TYPE_CN_UINT8, lambda x: "celcius" if x == 0 else "farenheit"),
150
+ SENSOR_UNIT_TEMPERATURE: Sensor("Device Temperature Unit", None, 208, PdoType.TYPE_CN_UINT8, lambda x: {0: "celsius", 1: "fahrenheit"}.get(x, x)),
137
151
  SENSOR_RMOT: Sensor("Running Mean Outdoor Temperature (RMOT)", UNIT_CELCIUS, 209, PdoType.TYPE_CN_INT16, lambda x: x / 10),
138
152
  SENSOR_SEASON_HEATING_ACTIVE: Sensor("Heating Season is active", None, 210, PdoType.TYPE_CN_BOOL, bool),
139
153
  SENSOR_SEASON_COOLING_ACTIVE: Sensor("Cooling Season is active", None, 211, PdoType.TYPE_CN_BOOL, bool),
@@ -147,7 +161,7 @@ SENSORS: Dict[int, Sensor] = {
147
161
  219: Sensor("sensor_219", None, 219, PdoType.TYPE_CN_UINT16),
148
162
  220: Sensor("Outdoor Air Temperature (?)", None, 220, PdoType.TYPE_CN_INT16, lambda x: x / 10),
149
163
  SENSOR_TEMPERATURE_SUPPLY: Sensor("Supply Air Temperature", UNIT_CELCIUS, 221, PdoType.TYPE_CN_INT16, lambda x: x / 10),
150
- SENSOR_UNIT_AIRFLOW: Sensor("Device Airflow Unit", None, 224, PdoType.TYPE_CN_UINT8, lambda x: "m3ph" if x == 3 else "lps"),
164
+ SENSOR_UNIT_AIRFLOW: Sensor("Device Airflow Unit", None, 224, PdoType.TYPE_CN_UINT8, lambda x: {1: "kgph", 2: "lps", 3: "m3ph"}.get(x, x)),
151
165
  SENSOR_COMFORTCONTROL_MODE: Sensor("Sensor based ventilation mode", None, 225, PdoType.TYPE_CN_UINT8),
152
166
  SENSOR_FAN_SPEED_MODE_MODULATED: Sensor("Fan Speed (modulated)", None, 226, PdoType.TYPE_CN_UINT16),
153
167
  SENSOR_BYPASS_STATE: Sensor("Bypass State", UNIT_PERCENT, 227, PdoType.TYPE_CN_UINT8),
@@ -186,4 +200,23 @@ SENSORS: Dict[int, Sensor] = {
186
200
  SENSOR_COMFOCOOL_STATE: Sensor("ComfoCool State", None, 784, PdoType.TYPE_CN_UINT8),
187
201
  785: Sensor("sensor_785", None, 785, PdoType.TYPE_CN_BOOL),
188
202
  SENSOR_COMFOCOOL_CONDENSOR_TEMP: Sensor("ComfoCool Condensor Temperature", None, 802, PdoType.TYPE_CN_INT16, lambda x: x / 10),
203
+ SENSOR_COMFOCLIME_TPMA_TEMPERATURE: Sensor("ComfoClime TPMA Temperature", UNIT_CELCIUS, 4145, PdoType.TYPE_CN_INT16, lambda x: x / 10),
204
+ SENSOR_COMFOCLIME_TARGET_TEMPERATURE: Sensor("ComfoClime Target Temperature", UNIT_CELCIUS, 4148, PdoType.TYPE_CN_INT16, lambda x: x / 10),
205
+ SENSOR_COMFOCLIME_DEVICE_MODE: Sensor("ComfoClime Device Mode", None, 4149, PdoType.TYPE_CN_UINT8),
206
+ SENSOR_COMFOCLIME_COMFORT_TEMPERATURE: Sensor("ComfoClime Comfort Temperature", UNIT_CELCIUS, 4151, PdoType.TYPE_CN_INT16, lambda x: x / 10),
207
+ SENSOR_COMFOCLIME_INDOOR_TEMPERATURE: Sensor("ComfoClime Indoor Temperature", UNIT_CELCIUS, 4154, PdoType.TYPE_CN_INT16, lambda x: x / 10),
208
+ SENSOR_COMFOCLIME_TEMPERATURE_SUPPLY: Sensor("ComfoClime Supply Air Temperature", UNIT_CELCIUS, 4193, PdoType.TYPE_CN_INT16, lambda x: x / 10),
209
+ SENSOR_COMFOCLIME_TEMPERATURE_EXHAUST: Sensor("ComfoClime Exhaust Air Temperature", UNIT_CELCIUS, 4194, PdoType.TYPE_CN_INT16, lambda x: x / 10),
210
+ SENSOR_COMFOCLIME_TEMPERATURE_SUPPLY_COIL: Sensor("ComfoClime Supply Coil Temperature", UNIT_CELCIUS, 4195, PdoType.TYPE_CN_INT16, lambda x: x / 10),
211
+ SENSOR_COMFOCLIME_TEMPERATURE_EXHAUST_COIL: Sensor("ComfoClime Exhaust Coil Temperature", UNIT_CELCIUS, 4196, PdoType.TYPE_CN_INT16, lambda x: x / 10),
212
+ SENSOR_COMFOCLIME_TEMPERATURE_COMPRESSOR: Sensor("ComfoClime Compressor Temperature", UNIT_CELCIUS, 4197, PdoType.TYPE_CN_INT16, lambda x: x / 10),
213
+ SENSOR_COMFOCLIME_HEATPUMP_DUTY: Sensor("ComfoClime Heat Pump Duty", UNIT_PERCENT, 4198, PdoType.TYPE_CN_UINT8),
214
+ SENSOR_COMFOCLIME_POWER_USAGE: Sensor("ComfoClime Power Usage", UNIT_WATT, 4201, PdoType.TYPE_CN_UINT16),
215
+ 4202: Sensor("sensor_4202", None, 4202, PdoType.TYPE_CN_UINT16),
216
+ 4203: Sensor("sensor_4203", None, 4203, PdoType.TYPE_CN_UINT16),
217
+ 4204: Sensor("sensor_4204", None, 4204, PdoType.TYPE_CN_UINT16),
218
+ 4205: Sensor("sensor_4205", None, 4205, PdoType.TYPE_CN_UINT16),
219
+ 4206: Sensor("sensor_4206", None, 4206, PdoType.TYPE_CN_UINT16),
220
+ 4207: Sensor("sensor_4207", None, 4207, PdoType.TYPE_CN_UINT16),
221
+ 4208: Sensor("sensor_4208", None, 4208, PdoType.TYPE_CN_UINT16),
189
222
  }
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "aiocomfoconnect"
3
- version = "0.3.0"
3
+ version = "0.3.1"
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"
@@ -1,31 +0,0 @@
1
- """ Property definitions """
2
-
3
- from __future__ import annotations
4
-
5
- from dataclasses import dataclass
6
-
7
- from .const import UNIT_NODE, UNIT_NODECONFIGURATION, UNIT_TEMPHUMCONTROL, PdoType
8
-
9
-
10
- @dataclass
11
- class Property:
12
- """Dataclass for a Property"""
13
-
14
- unit: int
15
- subunit: int
16
- property_id: int
17
- property_type: int
18
-
19
-
20
- PROPERTY_SERIAL_NUMBER = Property(UNIT_NODE, 0x01, 0x04, PdoType.TYPE_CN_STRING)
21
- PROPERTY_FIRMWARE_VERSION = Property(UNIT_NODE, 0x01, 0x06, PdoType.TYPE_CN_UINT32)
22
- PROPERTY_MODEL = Property(UNIT_NODE, 0x01, 0x08, PdoType.TYPE_CN_STRING)
23
- PROPERTY_ARTICLE = Property(UNIT_NODE, 0x01, 0x0B, PdoType.TYPE_CN_STRING)
24
- PROPERTY_COUNTRY = Property(UNIT_NODE, 0x01, 0x0D, PdoType.TYPE_CN_STRING)
25
- PROPERTY_NAME = Property(UNIT_NODE, 0x01, 0x14, PdoType.TYPE_CN_STRING)
26
-
27
- PROPERTY_MAINTAINER_PASSWORD = Property(UNIT_NODECONFIGURATION, 0x01, 0x03, PdoType.TYPE_CN_STRING)
28
-
29
- PROPERTY_SENSOR_VENTILATION_TEMP_PASSIVE = Property(UNIT_TEMPHUMCONTROL, 0x01, 0x04, PdoType.TYPE_CN_UINT32)
30
- PROPERTY_SENSOR_VENTILATION_HUMIDITY_COMFORT = Property(UNIT_TEMPHUMCONTROL, 0x01, 0x06, PdoType.TYPE_CN_UINT32)
31
- PROPERTY_SENSOR_VENTILATION_HUMIDITY_PROTECTION = Property(UNIT_TEMPHUMCONTROL, 0x01, 0x07, PdoType.TYPE_CN_UINT32)
File without changes