pystuderxcom 3.4.7__tar.gz → 3.5.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.
Files changed (51) hide show
  1. {pystuderxcom-3.4.7/src/pystuderxcom.egg-info → pystuderxcom-3.5.0}/PKG-INFO +3 -3
  2. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/README.md +2 -2
  3. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/pyproject.toml +1 -1
  4. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/__init__.py +1 -1
  5. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/discover_async.py +34 -28
  6. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/discover_sync.py +34 -28
  7. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/families.py +47 -0
  8. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0/src/pystuderxcom.egg-info}/PKG-INFO +3 -3
  9. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_datapoints_async.py +6 -6
  10. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_datapoints_sync.py +6 -6
  11. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_discover_async.py +12 -6
  12. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/LICENSE +0 -0
  13. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/setup.cfg +0 -0
  14. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_base_async.py +0 -0
  15. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_base_sync.py +0 -0
  16. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_serial.py +0 -0
  17. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_tcp.py +0 -0
  18. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_udp.py +0 -0
  19. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/const.py +0 -0
  20. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/data.py +0 -0
  21. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/datapoints.py +0 -0
  22. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/datapoints_120v.json +0 -0
  23. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/datapoints_240v.json +0 -0
  24. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/datapoints_xcom.json +0 -0
  25. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/factory_async.py +0 -0
  26. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/factory_sync.py +0 -0
  27. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/messages.py +0 -0
  28. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/messages_en.json +0 -0
  29. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/protocol.py +0 -0
  30. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/values.py +0 -0
  31. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom.egg-info/SOURCES.txt +0 -0
  32. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom.egg-info/dependency_links.txt +0 -0
  33. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom.egg-info/requires.txt +0 -0
  34. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom.egg-info/top_level.txt +0 -0
  35. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_base_async.py +0 -0
  36. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_base_sync.py +0 -0
  37. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_serial_async.py +0 -0
  38. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_serial_sync.py +0 -0
  39. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_tcp_async.py +0 -0
  40. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_tcp_sync.py +0 -0
  41. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_udp_async.py +0 -0
  42. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_udp_sync.py +0 -0
  43. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_const.py +0 -0
  44. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_data.py +0 -0
  45. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_discover_sync.py +0 -0
  46. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_families.py +0 -0
  47. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_messageset_async.py +0 -0
  48. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_messageset_sync.py +0 -0
  49. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_package_async.py +0 -0
  50. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_package_sync.py +0 -0
  51. {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_values.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pystuderxcom
3
- Version: 3.4.7
3
+ Version: 3.5.0
4
4
  Summary: Python library to communicate with Studer-Innotec devices on the local network via Xcom protocol
5
5
  Author-email: Anko Hanse <anko_hanse@hotmail.com>
6
6
  Project-URL: Homepage, https://github.com/ankohanse/pystuderxcom
@@ -22,7 +22,7 @@ Requires-Dist: pytest; extra == "tests"
22
22
  Requires-Dist: pytest-asyncio; extra == "tests"
23
23
  Dynamic: license-file
24
24
 
25
- [![license](https://img.shields.io/github/license/toreamun/amshan-homeassistant?style=for-the-badge)](LICENSE)
25
+ [![license](https://img.shields.io/github/license/ankohanse/pystuderxcom?style=for-the-badge)](LICENSE)
26
26
  [![buy_me_a_coffee](https://img.shields.io/badge/If%20you%20like%20it-Buy%20me%20a%20coffee-yellow.svg?style=for-the-badge)](https://www.buymeacoffee.com/ankohanse)
27
27
 
28
28
 
@@ -46,7 +46,7 @@ It should also be able to detect and handle
46
46
 
47
47
  Disclaimer: this library is NOT created by Studer-Innotec, but is based on their documentation of the Xcom protocol.
48
48
  That documentation can be found on:
49
- [Studer-Innotec Download Center](https://www.studer-innotec.com/en/downloads/) *-> Software and Updates -> Communication protocol Xcom-232i*
49
+ [Studer-Innotec Download Center](https://www.studer-innotec.com/en/downloads/) *-> Openstuder -> Communication protocol Xcom-232i*
50
50
 
51
51
 
52
52
  # Prerequisites
@@ -1,4 +1,4 @@
1
- [![license](https://img.shields.io/github/license/toreamun/amshan-homeassistant?style=for-the-badge)](LICENSE)
1
+ [![license](https://img.shields.io/github/license/ankohanse/pystuderxcom?style=for-the-badge)](LICENSE)
2
2
  [![buy_me_a_coffee](https://img.shields.io/badge/If%20you%20like%20it-Buy%20me%20a%20coffee-yellow.svg?style=for-the-badge)](https://www.buymeacoffee.com/ankohanse)
3
3
 
4
4
 
@@ -22,7 +22,7 @@ It should also be able to detect and handle
22
22
 
23
23
  Disclaimer: this library is NOT created by Studer-Innotec, but is based on their documentation of the Xcom protocol.
24
24
  That documentation can be found on:
25
- [Studer-Innotec Download Center](https://www.studer-innotec.com/en/downloads/) *-> Software and Updates -> Communication protocol Xcom-232i*
25
+ [Studer-Innotec Download Center](https://www.studer-innotec.com/en/downloads/) *-> Openstuder -> Communication protocol Xcom-232i*
26
26
 
27
27
 
28
28
  # Prerequisites
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pystuderxcom"
3
- version = "3.4.7"
3
+ version = "3.5.0"
4
4
  authors = [
5
5
  { name="Anko Hanse", email="anko_hanse@hotmail.com" },
6
6
  ]
@@ -7,7 +7,7 @@ from .discover_async import AsyncXcomDiscover
7
7
  from .factory_async import AsyncXcomFactory
8
8
 
9
9
  from .api_base_sync import XcomApiBase
10
- from .discover_sync import XcomDiscover
10
+ from .discover_sync import XcomDiscover, XcomDiscoverFlags
11
11
  from .factory_sync import XcomFactory
12
12
 
13
13
  from .const import XcomApiTcpMode, XcomVoltage, XcomLevel, XcomFormat, XcomTarget, XcomCategory, XcomAggregationType
@@ -8,6 +8,7 @@ import os
8
8
  import struct
9
9
 
10
10
  from dataclasses import dataclass
11
+ from enum import StrEnum
11
12
 
12
13
  from .api_base_async import (
13
14
  AsyncXcomApiBase,
@@ -37,6 +38,10 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
37
38
  logging.getLogger("httpcore").setLevel(logging.WARNING)
38
39
 
39
40
 
41
+ class XcomDiscoverFlags(StrEnum):
42
+ SKIP_GUID = "skip_guid"
43
+
44
+
40
45
  class AsyncXcomDiscover:
41
46
 
42
47
  def __init__(self, api: AsyncXcomApiBase, dataset: XcomDataset):
@@ -114,25 +119,31 @@ class AsyncXcomDiscover:
114
119
 
115
120
  async def get_extended_device_info(self, device: XcomDiscoveredDevice, verbose=False) -> XcomDiscoveredDevice:
116
121
  # ID type
117
- # ID HW
118
- # ID HW PWR
122
+ # ID HW (cmd)/PWR
119
123
  # ID SOFT msb/lsb
120
- # ID SID
121
124
  # ID FID msb/lsb
122
125
  try:
123
126
  _LOGGER.info(f"Trying to get extended device info for device {device.code})")
124
127
  family = XcomDeviceFamilies.get_by_id(device.family_id)
125
128
 
126
- id_type = await self._request_value_by_name("ID type", family.id, device.addr, verbose=verbose)
127
- id_hw = await self._request_value_by_name("ID HW", family.id, device.addr, verbose=verbose)
128
- id_hw_pwr = await self._request_value_by_name("ID HW PWR", family.id, device.addr, verbose=verbose)
129
- id_sw_msb = await self._request_value_by_name("ID SOFT msb", family.id, device.addr, verbose=verbose)
130
- id_sw_lsb = await self._request_value_by_name("ID SOFT lsb", family.id, device.addr, verbose=verbose)
131
- id_fid_msb = await self._request_value_by_name("ID FID msb", family.id, device.addr, verbose=verbose)
132
- id_fid_lsb = await self._request_value_by_name("ID FID lsb", family.id, device.addr, verbose=verbose)
133
-
134
- device.device_model = self._decode_type(id_type, "ID type", family.id_for_nr)
135
- device.hw_version = self._decode_id_hw(id_hw, id_hw_pwr)
129
+ param_id_type = self._dataset.get_by_nr(family.nr_id_type, family.id) if family.nr_id_type is not None else None
130
+ param_id_hw_cmd = self._dataset.get_by_nr(family.nr_id_hw_cmd, family.id) if family.nr_id_hw_cmd is not None else None
131
+ param_id_hw_pwr = self._dataset.get_by_nr(family.nr_id_hw_pwr, family.id) if family.nr_id_hw_pwr is not None else None
132
+ param_id_sw_msb = self._dataset.get_by_nr(family.nr_id_sw_msb, family.id) if family.nr_id_sw_msb is not None else None
133
+ param_id_sw_lsb = self._dataset.get_by_nr(family.nr_id_sw_lsb, family.id) if family.nr_id_sw_lsb is not None else None
134
+ param_id_fid_msb = self._dataset.get_by_nr(family.nr_id_fid_msb, family.id) if family.nr_id_fid_msb is not None else None
135
+ param_id_fid_lsb = self._dataset.get_by_nr(family.nr_id_fid_lsb, family.id) if family.nr_id_fid_lsb is not None else None
136
+
137
+ id_type = await self._api.request_value(param_id_type, device.addr, verbose=verbose) if param_id_type is not None else None
138
+ id_hw_cmd = await self._api.request_value(param_id_hw_cmd, device.addr, verbose=verbose) if param_id_hw_cmd is not None else None
139
+ id_hw_pwr = await self._api.request_value(param_id_hw_pwr, device.addr, verbose=verbose) if param_id_hw_pwr is not None else None
140
+ id_sw_msb = await self._api.request_value(param_id_sw_msb, device.addr, verbose=verbose) if param_id_sw_msb is not None else None
141
+ id_sw_lsb = await self._api.request_value(param_id_sw_lsb, device.addr, verbose=verbose) if param_id_sw_lsb is not None else None
142
+ id_fid_msb = await self._api.request_value(param_id_fid_msb, device.addr, verbose=verbose) if param_id_fid_msb is not None else None
143
+ id_fid_lsb = await self._api.request_value(param_id_fid_lsb, device.addr, verbose=verbose) if param_id_fid_lsb is not None else None
144
+
145
+ device.device_model = self._decode_type(id_type, param_id_type)
146
+ device.hw_version = self._decode_id_hw(id_hw_cmd, id_hw_pwr)
136
147
  device.sw_version = self._decode_id_sw(id_sw_msb, id_sw_lsb)
137
148
  device.fid = self._decode_fid(id_fid_msb, id_fid_lsb)
138
149
 
@@ -144,20 +155,10 @@ class AsyncXcomDiscover:
144
155
  return device
145
156
 
146
157
 
147
- async def _request_value_by_name(self, param_name, family_id, device_addr, verbose=False):
148
- try:
149
- param = self._dataset.get_by_name(param_name, family_id)
150
- return await self._api.request_value(param, device_addr, verbose=verbose)
151
- except:
152
- # Not all devices have these IDs
153
- return None
154
-
155
-
156
- def _decode_type(self, val, param_name, family_id):
157
- if val is None:
158
+ def _decode_type(self, val, param):
159
+ if val is None or param is None:
158
160
  return None
159
161
 
160
- param = self._dataset.get_by_name(param_name, family_id)
161
162
  return param.options.get(str(int(val)), None) if param.options else None
162
163
 
163
164
 
@@ -189,7 +190,7 @@ class AsyncXcomDiscover:
189
190
  return bytes.hex(' ',4).upper()
190
191
 
191
192
 
192
- async def discover_client_info(self, verbose=False) -> XcomDiscoveredClient:
193
+ async def discover_client_info(self, flags:dict={}, verbose=False) -> XcomDiscoveredClient:
193
194
  """
194
195
  Discover extended info about the remote Xcom client connected to us
195
196
  """
@@ -201,6 +202,8 @@ class AsyncXcomDiscover:
201
202
  if not self._api.remote_ip:
202
203
  raise XcomDiscoverNotConnected("No IP address was detected for the remote client")
203
204
 
205
+ flags = flags or {}
206
+
204
207
  _LOGGER.info(f"Trying to get client info")
205
208
  client_ip = None
206
209
  client_guid = None
@@ -214,9 +217,12 @@ class AsyncXcomDiscover:
214
217
  _LOGGER.warning(f" Exception in discoverClientInfo: {e}")
215
218
 
216
219
  try:
217
- client_guid = await self._api.request_guid(verbose=verbose)
220
+ if flags.get(XcomDiscoverFlags.SKIP_GUID, False):
221
+ _LOGGER.info(f" Skip guid discover")
222
+ else:
223
+ client_guid = await self._api.request_guid(verbose=verbose)
218
224
 
219
- _LOGGER.info(f" Found guid: {client_guid}")
225
+ _LOGGER.info(f" Found guid: {client_guid}")
220
226
 
221
227
  except Exception as e:
222
228
  _LOGGER.warning(f" Exception in discoverClientInfo: {e}")
@@ -10,6 +10,7 @@ import os
10
10
  import struct
11
11
 
12
12
  from dataclasses import dataclass
13
+ from enum import StrEnum
13
14
 
14
15
  from .api_base_async import (
15
16
  AsyncXcomApiBase,
@@ -40,6 +41,10 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
40
41
  logging.getLogger("httpcore").setLevel(logging.WARNING)
41
42
 
42
43
 
44
+ class XcomDiscoverFlags(StrEnum):
45
+ SKIP_GUID = "skip_guid"
46
+
47
+
43
48
  class XcomDiscover:
44
49
 
45
50
  def __init__(self, api: XcomApiBase, dataset: XcomDataset):
@@ -117,25 +122,31 @@ class XcomDiscover:
117
122
 
118
123
  def get_extended_device_info(self, device: XcomDiscoveredDevice, verbose=False) -> XcomDiscoveredDevice:
119
124
  # ID type
120
- # ID HW
121
- # ID HW PWR
125
+ # ID HW (cmd)/PWR
122
126
  # ID SOFT msb/lsb
123
- # ID SID
124
127
  # ID FID msb/lsb
125
128
  try:
126
129
  _LOGGER.info(f"Trying to get extended device info for device {device.code})")
127
130
  family = XcomDeviceFamilies.get_by_id(device.family_id)
128
131
 
129
- id_type = self._request_value_by_name("ID type", family.id, device.addr, verbose=verbose)
130
- id_hw = self._request_value_by_name("ID HW", family.id, device.addr, verbose=verbose)
131
- id_hw_pwr = self._request_value_by_name("ID HW PWR", family.id, device.addr, verbose=verbose)
132
- id_sw_msb = self._request_value_by_name("ID SOFT msb", family.id, device.addr, verbose=verbose)
133
- id_sw_lsb = self._request_value_by_name("ID SOFT lsb", family.id, device.addr, verbose=verbose)
134
- id_fid_msb = self._request_value_by_name("ID FID msb", family.id, device.addr, verbose=verbose)
135
- id_fid_lsb = self._request_value_by_name("ID FID lsb", family.id, device.addr, verbose=verbose)
136
-
137
- device.device_model = self._decode_type(id_type, "ID type", family.id_for_nr)
138
- device.hw_version = self._decode_id_hw(id_hw, id_hw_pwr)
132
+ param_id_type = self._dataset.get_by_nr(family.nr_id_type, family.id) if family.nr_id_type is not None else None
133
+ param_id_hw_cmd = self._dataset.get_by_nr(family.nr_id_hw_cmd, family.id) if family.nr_id_hw_cmd is not None else None
134
+ param_id_hw_pwr = self._dataset.get_by_nr(family.nr_id_hw_pwr, family.id) if family.nr_id_hw_pwr is not None else None
135
+ param_id_sw_msb = self._dataset.get_by_nr(family.nr_id_sw_msb, family.id) if family.nr_id_sw_msb is not None else None
136
+ param_id_sw_lsb = self._dataset.get_by_nr(family.nr_id_sw_lsb, family.id) if family.nr_id_sw_lsb is not None else None
137
+ param_id_fid_msb = self._dataset.get_by_nr(family.nr_id_fid_msb, family.id) if family.nr_id_fid_msb is not None else None
138
+ param_id_fid_lsb = self._dataset.get_by_nr(family.nr_id_fid_lsb, family.id) if family.nr_id_fid_lsb is not None else None
139
+
140
+ id_type = self._api.request_value(param_id_type, device.addr, verbose=verbose) if param_id_type is not None else None
141
+ id_hw_cmd = self._api.request_value(param_id_hw_cmd, device.addr, verbose=verbose) if param_id_hw_cmd is not None else None
142
+ id_hw_pwr = self._api.request_value(param_id_hw_pwr, device.addr, verbose=verbose) if param_id_hw_pwr is not None else None
143
+ id_sw_msb = self._api.request_value(param_id_sw_msb, device.addr, verbose=verbose) if param_id_sw_msb is not None else None
144
+ id_sw_lsb = self._api.request_value(param_id_sw_lsb, device.addr, verbose=verbose) if param_id_sw_lsb is not None else None
145
+ id_fid_msb = self._api.request_value(param_id_fid_msb, device.addr, verbose=verbose) if param_id_fid_msb is not None else None
146
+ id_fid_lsb = self._api.request_value(param_id_fid_lsb, device.addr, verbose=verbose) if param_id_fid_lsb is not None else None
147
+
148
+ device.device_model = self._decode_type(id_type, param_id_type)
149
+ device.hw_version = self._decode_id_hw(id_hw_cmd, id_hw_pwr)
139
150
  device.sw_version = self._decode_id_sw(id_sw_msb, id_sw_lsb)
140
151
  device.fid = self._decode_fid(id_fid_msb, id_fid_lsb)
141
152
 
@@ -147,20 +158,10 @@ class XcomDiscover:
147
158
  return device
148
159
 
149
160
 
150
- def _request_value_by_name(self, param_name, family_id, device_addr, verbose=False):
151
- try:
152
- param = self._dataset.get_by_name(param_name, family_id)
153
- return self._api.request_value(param, device_addr, verbose=verbose)
154
- except:
155
- # Not all devices have these IDs
156
- return None
157
-
158
-
159
- def _decode_type(self, val, param_name, family_id):
160
- if val is None:
161
+ def _decode_type(self, val, param):
162
+ if val is None or param is None:
161
163
  return None
162
164
 
163
- param = self._dataset.get_by_name(param_name, family_id)
164
165
  return param.options.get(str(int(val)), None) if param.options else None
165
166
 
166
167
 
@@ -192,7 +193,7 @@ class XcomDiscover:
192
193
  return bytes.hex(' ',4).upper()
193
194
 
194
195
 
195
- def discover_client_info(self, verbose=False) -> XcomDiscoveredClient:
196
+ def discover_client_info(self, flags:dict={}, verbose=False) -> XcomDiscoveredClient:
196
197
  """
197
198
  Discover extended info about the remote Xcom client connected to us
198
199
  """
@@ -204,6 +205,8 @@ class XcomDiscover:
204
205
  if not self._api.remote_ip:
205
206
  raise XcomDiscoverNotConnected("No IP address was detected for the remote client")
206
207
 
208
+ flags = flags or {}
209
+
207
210
  _LOGGER.info(f"Trying to get client info")
208
211
  client_ip = None
209
212
  client_guid = None
@@ -217,9 +220,12 @@ class XcomDiscover:
217
220
  _LOGGER.warning(f" Exception in discoverClientInfo: {e}")
218
221
 
219
222
  try:
220
- client_guid = self._api.request_guid(verbose=verbose)
223
+ if flags.get(XcomDiscoverFlags.SKIP_GUID, False):
224
+ _LOGGER.info(f" Skip guid discover")
225
+ else:
226
+ client_guid = self._api.request_guid(verbose=verbose)
221
227
 
222
- _LOGGER.info(f" Found guid: {client_guid}")
228
+ _LOGGER.info(f" Found guid: {client_guid}")
223
229
 
224
230
  except Exception as e:
225
231
  _LOGGER.warning(f" Exception in discoverClientInfo: {e}")
@@ -39,6 +39,13 @@ class XcomDeviceFamily:
39
39
  nr_infos_start: int
40
40
  nr_infos_end: int
41
41
  nr_discover: int
42
+ nr_id_type: int | None
43
+ nr_id_hw_cmd: int | None
44
+ nr_id_hw_pwr: int | None
45
+ nr_id_sw_msb: int | None
46
+ nr_id_sw_lsb: int | None
47
+ nr_id_fid_msb: int | None
48
+ nr_id_fid_lsb: int | None
42
49
 
43
50
  def get_code(self, addr):
44
51
  if addr == self.addr_multicast:
@@ -64,6 +71,10 @@ class XcomDeviceFamilies:
64
71
  1000, 1999, # nr for params, start to end
65
72
  3000, 3999, # nr for infos, start to end
66
73
  3000, # nr for discovery
74
+ 3124, # nr for model/type
75
+ 3129, 3132, # nr for hardware version (cmd, pwr)
76
+ 3130, 3131, # nr for software version (msb, lsb)
77
+ 3156, 3157, # nr for fid (msb, lsb)
67
78
  )
68
79
  L1 = XcomDeviceFamily(
69
80
  "l1", "xt",
@@ -73,6 +84,10 @@ class XcomDeviceFamilies:
73
84
  1000, 1999, # nr for params, start to end
74
85
  3000, 3999, # nr for infos, start to end
75
86
  3000, # nr for discovery
87
+ None, # nr for model/type
88
+ None, None, # nr for hardware version (cmd, pwr)
89
+ None, None, # nr for software version (msb, lsb)
90
+ None, None, # nr for fid (msb, lsb)
76
91
  )
77
92
  L2 = XcomDeviceFamily(
78
93
  "l2", "xt",
@@ -82,6 +97,10 @@ class XcomDeviceFamilies:
82
97
  1000, 1999, # nr for params, start to end
83
98
  3000, 3999, # nr for infos, start to end
84
99
  3000, # nr for discovery
100
+ None, # nr for model/type
101
+ None, None, # nr for hardware version (cmd, pwr)
102
+ None, None, # nr for software version (msb, lsb)
103
+ None, None, # nr for fid (msb, lsb)
85
104
  )
86
105
  L3 = XcomDeviceFamily(
87
106
  "l3", "xt",
@@ -91,6 +110,10 @@ class XcomDeviceFamilies:
91
110
  1000, 1999, # nr for params, start to end
92
111
  3000, 3999, # nr for infos, start to end
93
112
  3000, # nr for discovery
113
+ None, # nr for model/type
114
+ None, None, # nr for hardware version (cmd, pwr)
115
+ None, None, # nr for software version (msb, lsb)
116
+ None, None, # nr for fid (msb, lsb)
94
117
  )
95
118
  RCC = XcomDeviceFamily(
96
119
  "rcc", "rcc",
@@ -100,6 +123,10 @@ class XcomDeviceFamilies:
100
123
  5000, 5999, # nr for params, start to end
101
124
  0, 0, # nr for infos, start to end
102
125
  5002, # nr for discovery
126
+ None, # nr for model/type
127
+ None, None, # nr for hardware version (cmd, pwr)
128
+ None, None, # nr for software version (msb, lsb)
129
+ None, None, # nr for fid (msb, lsb)
103
130
  )
104
131
  BMS = XcomDeviceFamily(
105
132
  "bms", "bms",
@@ -109,6 +136,10 @@ class XcomDeviceFamilies:
109
136
  6000, 6999, # nr for params, start to end
110
137
  7000, 7999, # nr for infos, start to end
111
138
  7054, # nr for discovery
139
+ 7034, # nr for model/type
140
+ 7036, None, # nr for hardware version (cmd, pwr)
141
+ 7037, 7038, # nr for software version (msb, lsb)
142
+ 7048, 7049, # nr for fid (msb, lsb)
112
143
  )
113
144
  BSP = XcomDeviceFamily( # Place AFTER BMS; during Discovery BSP is only tested if no BMS is found
114
145
  "bsp", "bsp",
@@ -118,6 +149,10 @@ class XcomDeviceFamilies:
118
149
  6000, 6999, # nr for params, start to end
119
150
  7000, 7999, # nr for infos, start to end
120
151
  7034, # nr for discovery
152
+ 7034, # nr for model/type
153
+ 7036, None, # nr for hardware version (cmd, pwr)
154
+ 7037, 7038, # nr for software version (msb, lsb)
155
+ 7048, 7049, # nr for fid (msb, lsb)
121
156
  )
122
157
  VARIOTRACK = XcomDeviceFamily(
123
158
  "vt", "vt",
@@ -127,6 +162,10 @@ class XcomDeviceFamilies:
127
162
  10000, 10999, # nr for params, start to end
128
163
  11000, 11999, # nr for infos, start to end
129
164
  11000, # nr for discovery
165
+ 11047, # nr for model/type
166
+ 11049, None, # nr for hardware version (cmd, pwr)
167
+ 11050, 11051, # nr for software version (msb, lsb)
168
+ 11067, 11068, # nr for fid (msb, lsb)
130
169
  )
131
170
  VARIOSTRING = XcomDeviceFamily(
132
171
  "vs", "vs",
@@ -136,6 +175,10 @@ class XcomDeviceFamilies:
136
175
  14000, 14999, # nr for params, start to end
137
176
  15000, 15999, # nr for infos, start to end
138
177
  15000, # nr for discovery
178
+ 15074, # nr for model/type
179
+ 15076, None, # nr for hardware version (cmd, pwr)
180
+ 15077, 15078, # nr for software version (msb, lsb)
181
+ 15102, 15103, # nr for fid (msb, lsb)
139
182
  )
140
183
  XCOM = XcomDeviceFamily(
141
184
  "xcom", "xcom", # virtual device to expose additional values in a uniform way
@@ -145,6 +188,10 @@ class XcomDeviceFamilies:
145
188
  98000, 98999, # nr for params, start to end
146
189
  99000, 99999, # nr for infos, start to end
147
190
  99000, # nr for discovery
191
+ None, # nr for model/type
192
+ None, None, # nr for hardware version (cmd, pwr)
193
+ None, None, # nr for software version (msb, lsb)
194
+ None, None, # nr for fid (msb, lsb)
148
195
  )
149
196
 
150
197
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pystuderxcom
3
- Version: 3.4.7
3
+ Version: 3.5.0
4
4
  Summary: Python library to communicate with Studer-Innotec devices on the local network via Xcom protocol
5
5
  Author-email: Anko Hanse <anko_hanse@hotmail.com>
6
6
  Project-URL: Homepage, https://github.com/ankohanse/pystuderxcom
@@ -22,7 +22,7 @@ Requires-Dist: pytest; extra == "tests"
22
22
  Requires-Dist: pytest-asyncio; extra == "tests"
23
23
  Dynamic: license-file
24
24
 
25
- [![license](https://img.shields.io/github/license/toreamun/amshan-homeassistant?style=for-the-badge)](LICENSE)
25
+ [![license](https://img.shields.io/github/license/ankohanse/pystuderxcom?style=for-the-badge)](LICENSE)
26
26
  [![buy_me_a_coffee](https://img.shields.io/badge/If%20you%20like%20it-Buy%20me%20a%20coffee-yellow.svg?style=for-the-badge)](https://www.buymeacoffee.com/ankohanse)
27
27
 
28
28
 
@@ -46,7 +46,7 @@ It should also be able to detect and handle
46
46
 
47
47
  Disclaimer: this library is NOT created by Studer-Innotec, but is based on their documentation of the Xcom protocol.
48
48
  That documentation can be found on:
49
- [Studer-Innotec Download Center](https://www.studer-innotec.com/en/downloads/) *-> Software and Updates -> Communication protocol Xcom-232i*
49
+ [Studer-Innotec Download Center](https://www.studer-innotec.com/en/downloads/) *-> Openstuder -> Communication protocol Xcom-232i*
50
50
 
51
51
 
52
52
  # Prerequisites
@@ -17,12 +17,12 @@ from pystuderxcom import (
17
17
  @pytest.mark.parametrize(
18
18
  "voltageAC, voltageDC, exp_len",
19
19
  [
20
- (XcomVoltage.AC120, XcomVoltage.DC12, 1460),
21
- (XcomVoltage.AC120, XcomVoltage.DC24, 1460),
22
- (XcomVoltage.AC120, XcomVoltage.DC48, 1460),
23
- (XcomVoltage.AC240, XcomVoltage.DC12, 1460),
24
- (XcomVoltage.AC240, XcomVoltage.DC24, 1460),
25
- (XcomVoltage.AC240, XcomVoltage.DC48, 1460),
20
+ (XcomVoltage.AC120, XcomVoltage.DC12, 1461),
21
+ (XcomVoltage.AC120, XcomVoltage.DC24, 1461),
22
+ (XcomVoltage.AC120, XcomVoltage.DC48, 1461),
23
+ (XcomVoltage.AC240, XcomVoltage.DC12, 1461),
24
+ (XcomVoltage.AC240, XcomVoltage.DC24, 1461),
25
+ (XcomVoltage.AC240, XcomVoltage.DC48, 1461),
26
26
  ]
27
27
  )
28
28
  async def test_create(voltageAC, voltageDC, exp_len):
@@ -19,12 +19,12 @@ from pystuderxcom import (
19
19
  @pytest.mark.parametrize(
20
20
  "voltageAC, voltageDC, exp_len",
21
21
  [
22
- (XcomVoltage.AC120, XcomVoltage.DC12, 1460),
23
- (XcomVoltage.AC120, XcomVoltage.DC24, 1460),
24
- (XcomVoltage.AC120, XcomVoltage.DC48, 1460),
25
- (XcomVoltage.AC240, XcomVoltage.DC12, 1460),
26
- (XcomVoltage.AC240, XcomVoltage.DC24, 1460),
27
- (XcomVoltage.AC240, XcomVoltage.DC48, 1460),
22
+ (XcomVoltage.AC120, XcomVoltage.DC12, 1461),
23
+ (XcomVoltage.AC120, XcomVoltage.DC24, 1461),
24
+ (XcomVoltage.AC120, XcomVoltage.DC48, 1461),
25
+ (XcomVoltage.AC240, XcomVoltage.DC12, 1461),
26
+ (XcomVoltage.AC240, XcomVoltage.DC24, 1461),
27
+ (XcomVoltage.AC240, XcomVoltage.DC48, 1461),
28
28
  ]
29
29
  )
30
30
  def test_create(voltageAC, voltageDC, exp_len):
@@ -4,7 +4,7 @@ import threading
4
4
  import pytest
5
5
  import pytest_asyncio
6
6
 
7
- from pystuderxcom import AsyncXcomDiscover, XcomDiscover
7
+ from pystuderxcom import AsyncXcomDiscover, XcomDiscover, XcomDiscoverFlags
8
8
  from pystuderxcom import AsyncXcomFactory, XcomFactory
9
9
  from pystuderxcom import XcomDataset, XcomData, XcomPackage
10
10
  from pystuderxcom import XcomApiTimeoutException, XcomApiResponseIsError
@@ -184,23 +184,29 @@ async def test_discover_extendedinfo(name, rsp_dest, rsp_dict, exp_code, exp_mod
184
184
  @pytest.mark.asyncio
185
185
  @pytest.mark.usefixtures("context", "unused_tcp_port")
186
186
  @pytest.mark.parametrize(
187
- "name, rsp_dest, rsp_dict, exp_ip, exp_guid",
187
+ "name, flag_skip_guid, rsp_dest, rsp_dict, exp_ip, exp_guid",
188
188
  [
189
- ("guid none", [501], {
189
+ ("guid none", False, [501], {
190
190
  "5002": XcomData.pack("137aef81-08b7-4e70-ad89-0dad0563d627", XcomFormat.GUID),
191
191
  }, "127.0.0.1", None),
192
- ("guid ok", [501], {
192
+ ("guid ok", False, [501], {
193
193
  "0": XcomData.pack("137aef81-08b7-4e70-ad89-0dad0563d627", XcomFormat.GUID),
194
194
  }, "127.0.0.1", "137aef81-08b7-4e70-ad89-0dad0563d627"),
195
+ ("guid skip", True, [501], {
196
+ "0": XcomData.pack("137aef81-08b7-4e70-ad89-0dad0563d627", XcomFormat.GUID),
197
+ }, "127.0.0.1", None),
195
198
  ]
196
199
  )
197
- async def test_clientinfo(name, rsp_dest, rsp_dict, exp_ip, exp_guid, request):
200
+ async def test_clientinfo(name, flag_skip_guid, rsp_dest, rsp_dict, exp_ip, exp_guid, request):
198
201
  # Create discover instance
199
202
  context = request.getfixturevalue("context")
200
203
  await context.start_discover(rsp_dest, rsp_dict)
201
204
 
202
205
  # Perform the discover
203
- client_info = await context.discover.discover_client_info()
206
+ flags = {
207
+ XcomDiscoverFlags.SKIP_GUID: flag_skip_guid,
208
+ }
209
+ client_info = await context.discover.discover_client_info(flags)
204
210
 
205
211
  # Check discovered info
206
212
  assert client_info is not None
File without changes
File without changes