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.
- {pystuderxcom-3.4.7/src/pystuderxcom.egg-info → pystuderxcom-3.5.0}/PKG-INFO +3 -3
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/README.md +2 -2
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/pyproject.toml +1 -1
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/__init__.py +1 -1
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/discover_async.py +34 -28
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/discover_sync.py +34 -28
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/families.py +47 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0/src/pystuderxcom.egg-info}/PKG-INFO +3 -3
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_datapoints_async.py +6 -6
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_datapoints_sync.py +6 -6
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_discover_async.py +12 -6
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/LICENSE +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/setup.cfg +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_base_async.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_base_sync.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_serial.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_tcp.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/api_udp.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/const.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/data.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/datapoints.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/datapoints_120v.json +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/datapoints_240v.json +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/datapoints_xcom.json +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/factory_async.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/factory_sync.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/messages.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/messages_en.json +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/protocol.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom/values.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom.egg-info/SOURCES.txt +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom.egg-info/dependency_links.txt +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom.egg-info/requires.txt +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/src/pystuderxcom.egg-info/top_level.txt +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_base_async.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_base_sync.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_serial_async.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_serial_sync.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_tcp_async.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_tcp_sync.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_udp_async.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_api_udp_sync.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_const.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_data.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_discover_sync.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_families.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_messageset_async.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_messageset_sync.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_package_async.py +0 -0
- {pystuderxcom-3.4.7 → pystuderxcom-3.5.0}/tests/test_package_sync.py +0 -0
- {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.
|
|
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)
|
|
26
26
|
[](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/) *->
|
|
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)
|
|
2
2
|
[](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/) *->
|
|
25
|
+
[Studer-Innotec Download Center](https://www.studer-innotec.com/en/downloads/) *-> Openstuder -> Communication protocol Xcom-232i*
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
# Prerequisites
|
|
@@ -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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
|
151
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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)
|
|
26
26
|
[](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/) *->
|
|
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,
|
|
21
|
-
(XcomVoltage.AC120, XcomVoltage.DC24,
|
|
22
|
-
(XcomVoltage.AC120, XcomVoltage.DC48,
|
|
23
|
-
(XcomVoltage.AC240, XcomVoltage.DC12,
|
|
24
|
-
(XcomVoltage.AC240, XcomVoltage.DC24,
|
|
25
|
-
(XcomVoltage.AC240, XcomVoltage.DC48,
|
|
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,
|
|
23
|
-
(XcomVoltage.AC120, XcomVoltage.DC24,
|
|
24
|
-
(XcomVoltage.AC120, XcomVoltage.DC48,
|
|
25
|
-
(XcomVoltage.AC240, XcomVoltage.DC12,
|
|
26
|
-
(XcomVoltage.AC240, XcomVoltage.DC24,
|
|
27
|
-
(XcomVoltage.AC240, XcomVoltage.DC48,
|
|
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
|
-
|
|
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
|
|
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
|