iotconnect-lib 1.0.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.
- iotconnect_lib-1.0.0/LICENSE.md +20 -0
- iotconnect_lib-1.0.0/PKG-INFO +71 -0
- iotconnect_lib-1.0.0/README.md +41 -0
- iotconnect_lib-1.0.0/pyproject.toml +63 -0
- iotconnect_lib-1.0.0/setup.cfg +4 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/__init__.py +1 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/config.py +37 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/dra.py +157 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/error.py +18 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/mqtt.py +317 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/protocol/__init__.py +0 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/protocol/c2d.py +40 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/protocol/d2c.py +37 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/protocol/discovery.py +25 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/protocol/files.py +21 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/protocol/identity.py +79 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/util.py +142 -0
- iotconnect_lib-1.0.0/src/avnet/iotconnect/sdk/sdklib/version.py +0 -0
- iotconnect_lib-1.0.0/src/iotconnect_lib.egg-info/PKG-INFO +71 -0
- iotconnect_lib-1.0.0/src/iotconnect_lib.egg-info/SOURCES.txt +24 -0
- iotconnect_lib-1.0.0/src/iotconnect_lib.egg-info/dependency_links.txt +1 -0
- iotconnect_lib-1.0.0/src/iotconnect_lib.egg-info/requires.txt +4 -0
- iotconnect_lib-1.0.0/src/iotconnect_lib.egg-info/top_level.txt +1 -0
- iotconnect_lib-1.0.0/tests/test_c2d.py +89 -0
- iotconnect_lib-1.0.0/tests/test_discovery.py +56 -0
- iotconnect_lib-1.0.0/tests/test_telemetry.py +76 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2020-2024 Avnet
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iotconnect-lib
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Avnet IoTConnect SDK Library
|
|
5
|
+
Author-email: Nik Markovic <nikola.markovic@avnet.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/avnet-iotconnect/iotc-python-lib
|
|
7
|
+
Keywords: IoTconnect,AWS,IoTCore,Azure,IoTHub,Greengrass
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Natural Language :: English
|
|
12
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
|
+
Classifier: Operating System :: POSIX
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Communications
|
|
22
|
+
Classifier: Topic :: Internet
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE.md
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest; extra == "test"
|
|
28
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
> This document is reformatted to better viewing as a standalone document.
|
|
33
|
+
> We recommend visiting this [GitHub v1.0.0 link](https://github.com/avnet-iotconnect/iotc-python-lib/blob/v1.0.0/) for best experience.
|
|
34
|
+
|
|
35
|
+
# Introduction
|
|
36
|
+
This project is the library that abstracts the /IOTCONNECT protocols for the SDKs like the
|
|
37
|
+
[/IOTCONNECT Python Lite SDK](https://github.com/avnet-iotconnect/iotc-python-lite-sdk)
|
|
38
|
+
and the [/IOTCONNECT Greengrass SDK](https://github.com/avnet-iotconnect/iotc-python-greengrass-sdk).
|
|
39
|
+
|
|
40
|
+
This library should generally not be used in other projects as the SDKs should be able
|
|
41
|
+
to provide all the functionality that you would need in your python applications.
|
|
42
|
+
|
|
43
|
+
# Features
|
|
44
|
+
|
|
45
|
+
The library provides common code for interacting with /IOTCONNECT MQTT and HTTP device connectivity services:
|
|
46
|
+
* Format Telemetry (Reporting) messages
|
|
47
|
+
* Provide events for OTA and Command processing
|
|
48
|
+
* Streamline OTA and Command acknowledgements
|
|
49
|
+
* Obtain Discovery and Identity information
|
|
50
|
+
|
|
51
|
+
# Using The Library
|
|
52
|
+
|
|
53
|
+
To use this library in your project, ensure that your pyton project depends on iotconnect-lib.
|
|
54
|
+
Use a fixed major version dependency (E.g. "iotconnect-lib<2.0.0".) to
|
|
55
|
+
avoid potential major version breaking your application calls.
|
|
56
|
+
|
|
57
|
+
The best way to learn how to use this library is to examine the unit test usage examples
|
|
58
|
+
in the [tests](https://github.com/avnet-iotconnect/iotc-python-lib/blob/v1.0.0/tests) directory or use the SDK implementations listed above in this document
|
|
59
|
+
for reference.
|
|
60
|
+
|
|
61
|
+
# Testing
|
|
62
|
+
|
|
63
|
+
Regression tests should be run with every release using pytest.
|
|
64
|
+
|
|
65
|
+
See [tests/TESTS_CONFIGURATION.md](https://github.com/avnet-iotconnect/iotc-python-lib/blob/v1.0.0/tests/TESTS_CONFIGURATION.md) for more details.
|
|
66
|
+
|
|
67
|
+
# Licensing
|
|
68
|
+
|
|
69
|
+
This python package is distributed under the [MIT License](https://github.com/avnet-iotconnect/iotc-python-lib/blob/v1.0.0/LICENSE.md).
|
|
70
|
+
|
|
71
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
> This document is reformatted to better viewing as a standalone document.
|
|
3
|
+
> We recommend visiting this [GitHub v1.0.0 link](https://github.com/avnet-iotconnect/iotc-python-lib/blob/v1.0.0/) for best experience.
|
|
4
|
+
|
|
5
|
+
# Introduction
|
|
6
|
+
This project is the library that abstracts the /IOTCONNECT protocols for the SDKs like the
|
|
7
|
+
[/IOTCONNECT Python Lite SDK](https://github.com/avnet-iotconnect/iotc-python-lite-sdk)
|
|
8
|
+
and the [/IOTCONNECT Greengrass SDK](https://github.com/avnet-iotconnect/iotc-python-greengrass-sdk).
|
|
9
|
+
|
|
10
|
+
This library should generally not be used in other projects as the SDKs should be able
|
|
11
|
+
to provide all the functionality that you would need in your python applications.
|
|
12
|
+
|
|
13
|
+
# Features
|
|
14
|
+
|
|
15
|
+
The library provides common code for interacting with /IOTCONNECT MQTT and HTTP device connectivity services:
|
|
16
|
+
* Format Telemetry (Reporting) messages
|
|
17
|
+
* Provide events for OTA and Command processing
|
|
18
|
+
* Streamline OTA and Command acknowledgements
|
|
19
|
+
* Obtain Discovery and Identity information
|
|
20
|
+
|
|
21
|
+
# Using The Library
|
|
22
|
+
|
|
23
|
+
To use this library in your project, ensure that your pyton project depends on iotconnect-lib.
|
|
24
|
+
Use a fixed major version dependency (E.g. "iotconnect-lib<2.0.0".) to
|
|
25
|
+
avoid potential major version breaking your application calls.
|
|
26
|
+
|
|
27
|
+
The best way to learn how to use this library is to examine the unit test usage examples
|
|
28
|
+
in the [tests](https://github.com/avnet-iotconnect/iotc-python-lib/blob/v1.0.0/tests) directory or use the SDK implementations listed above in this document
|
|
29
|
+
for reference.
|
|
30
|
+
|
|
31
|
+
# Testing
|
|
32
|
+
|
|
33
|
+
Regression tests should be run with every release using pytest.
|
|
34
|
+
|
|
35
|
+
See [tests/TESTS_CONFIGURATION.md](https://github.com/avnet-iotconnect/iotc-python-lib/blob/v1.0.0/tests/TESTS_CONFIGURATION.md) for more details.
|
|
36
|
+
|
|
37
|
+
# Licensing
|
|
38
|
+
|
|
39
|
+
This python package is distributed under the [MIT License](https://github.com/avnet-iotconnect/iotc-python-lib/blob/v1.0.0/LICENSE.md).
|
|
40
|
+
|
|
41
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "iotconnect-lib"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Avnet IoTConnect SDK Library"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Nik Markovic", email = "nikola.markovic@avnet.com" },
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
keywords = [
|
|
16
|
+
"IoTconnect",
|
|
17
|
+
"AWS",
|
|
18
|
+
"IoTCore",
|
|
19
|
+
"Azure",
|
|
20
|
+
"IoTHub",
|
|
21
|
+
"Greengrass"
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 3 - Alpha",
|
|
25
|
+
"Intended Audience :: Developers",
|
|
26
|
+
"License :: OSI Approved :: MIT License",
|
|
27
|
+
"Natural Language :: English",
|
|
28
|
+
"Operating System :: MacOS :: MacOS X",
|
|
29
|
+
"Operating System :: Microsoft :: Windows",
|
|
30
|
+
"Operating System :: POSIX",
|
|
31
|
+
"Programming Language :: Python",
|
|
32
|
+
"Programming Language :: Python :: 3",
|
|
33
|
+
"Programming Language :: Python :: 3.9",
|
|
34
|
+
"Programming Language :: Python :: 3.10",
|
|
35
|
+
"Programming Language :: Python :: 3.11",
|
|
36
|
+
"Programming Language :: Python :: 3.12",
|
|
37
|
+
"Topic :: Communications",
|
|
38
|
+
"Topic :: Internet",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
test = ["pytest", "pytest-cov"]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
[project.urls]
|
|
46
|
+
Homepage = "https://github.com/avnet-iotconnect/iotc-python-lib"
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.packages.find]
|
|
49
|
+
where = ["src"]
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.dynamic]
|
|
52
|
+
version = {attr = "avnet.iotconnect.sdk.sdklib.__version__"}
|
|
53
|
+
|
|
54
|
+
[tool.coverage.run]
|
|
55
|
+
source = ["src"] # Basic source directory
|
|
56
|
+
omit = [
|
|
57
|
+
"*/tests/*",
|
|
58
|
+
"*/__pycache__/*"
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[tool.pytest.ini_options]
|
|
62
|
+
testpaths = ["tests"]
|
|
63
|
+
pythonpath = ["src"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '1.0.0'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (C) 2024 Avnet
|
|
3
|
+
# Authors: Nikola Markovic <nikola.markovic@avnet.com> et al.
|
|
4
|
+
|
|
5
|
+
from .error import DeviceConfigError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DeviceProperties:
|
|
10
|
+
"""
|
|
11
|
+
This class represents the /IOTCONNECT device properties
|
|
12
|
+
like device Unique ID (DUID) and account properties lke CPID, Environment etc.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, duid: str, cpid: str, env: str, platform: str):
|
|
16
|
+
"""
|
|
17
|
+
:param platform: The IoTconnect IoT platform - Either "aws" for AWS IoTCore or "az" for Azure IoTHub
|
|
18
|
+
:param env: Your account environment. You can locate this in you IoTConnect web UI at Settings -> Key Value
|
|
19
|
+
:param cpid: Your account CPID (Company ID). You can locate this in you IoTConnect web UI at Settings -> Key Value
|
|
20
|
+
:param duid: Your Device Unique ID
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
self.duid = duid
|
|
24
|
+
self.cpid = cpid
|
|
25
|
+
self.env = env
|
|
26
|
+
self.platform = platform
|
|
27
|
+
|
|
28
|
+
def validate(self):
|
|
29
|
+
""" Format validation in cases where custom topic configuration may be needed """
|
|
30
|
+
if self.duid is None or len(self.duid) < 2:
|
|
31
|
+
raise DeviceConfigError('DeviceProperties: Device Unique ID (DUID) is missing')
|
|
32
|
+
if self.cpid is None or len(self.cpid) < 2:
|
|
33
|
+
raise DeviceConfigError('DeviceProperties: CPID value is missing')
|
|
34
|
+
if self.env is None or len(self.env) < 2:
|
|
35
|
+
raise DeviceConfigError('DeviceProperties: Environment value is missing')
|
|
36
|
+
if self.platform not in ("aws", "az"):
|
|
37
|
+
raise DeviceConfigError('DeviceProperties: Platform must be "aws" or "az"')
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (C) 2024 Avnet
|
|
3
|
+
# Authors: Nikola Markovic <nikola.markovic@avnet.com> et al.
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import urllib.parse
|
|
7
|
+
import urllib.request
|
|
8
|
+
from typing import Final, Union, Optional
|
|
9
|
+
from urllib.error import HTTPError, URLError
|
|
10
|
+
|
|
11
|
+
from avnet.iotconnect.sdk.sdklib.config import DeviceProperties
|
|
12
|
+
from avnet.iotconnect.sdk.sdklib.error import DeviceConfigError
|
|
13
|
+
from avnet.iotconnect.sdk.sdklib.protocol.discovery import IotcDiscoveryResponseJson
|
|
14
|
+
from avnet.iotconnect.sdk.sdklib.protocol.identity import ProtocolIdentityPJson, ProtocolMetaJson, ProtocolIdentityResponseJson
|
|
15
|
+
from avnet.iotconnect.sdk.sdklib.util import deserialize_dataclass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class DeviceIdentityData:
|
|
19
|
+
def __init__(self, mqtt: ProtocolIdentityPJson, metadata: ProtocolMetaJson):
|
|
20
|
+
self.host = mqtt.h
|
|
21
|
+
self.client_id = mqtt.id
|
|
22
|
+
self.username = mqtt.un
|
|
23
|
+
self.topics = mqtt.topics
|
|
24
|
+
|
|
25
|
+
self.pf = metadata.pf
|
|
26
|
+
self.is_edge_device = metadata.edge
|
|
27
|
+
self.is_gateway_device = metadata.gtw
|
|
28
|
+
self.protocol_version = str(metadata.v)
|
|
29
|
+
|
|
30
|
+
class DraDiscoveryUrl:
|
|
31
|
+
method: str = "GET" # To clarify that get should be used to parse the response
|
|
32
|
+
API_URL_FORMAT: Final[str] = "https://discovery.iotconnect.io/api/v2.1/dsdk/cpId/%s/env/%s?pf=%s"
|
|
33
|
+
|
|
34
|
+
def __init__(self, config: DeviceProperties):
|
|
35
|
+
self.config = config
|
|
36
|
+
|
|
37
|
+
def get_api_url(self) -> str:
|
|
38
|
+
return DraDiscoveryUrl.API_URL_FORMAT % (
|
|
39
|
+
urllib.parse.quote(self.config.cpid, safe=''),
|
|
40
|
+
urllib.parse.quote(self.config.env, safe=''),
|
|
41
|
+
urllib.parse.quote(self.config.platform, safe='')
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class DraIdentityUrl:
|
|
46
|
+
UID_API_URL_FORMAT: Final[str] = "%s/uid/%s"
|
|
47
|
+
|
|
48
|
+
def __init__(self, base_url):
|
|
49
|
+
self.base_url = base_url
|
|
50
|
+
|
|
51
|
+
method: str = "GET" # To clarify that get should be used to parse the response
|
|
52
|
+
|
|
53
|
+
def get_uid_api_url(self, config: DeviceProperties) -> str:
|
|
54
|
+
return DraIdentityUrl.UID_API_URL_FORMAT % (
|
|
55
|
+
self.base_url,
|
|
56
|
+
urllib.parse.quote(config.duid, safe='')
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def _validate_identity_response(self, ird: ProtocolIdentityResponseJson):
|
|
60
|
+
# TODO: validate and throw DeviceConfigError
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class DraDeviceInfoParser:
|
|
65
|
+
EC_RESPONSE_MAPPING = [
|
|
66
|
+
"OK – No Error",
|
|
67
|
+
"Device not found. Device is not whitelisted to platform.",
|
|
68
|
+
"Device is not active.",
|
|
69
|
+
"Un-Associated. Device has not any template associated with it.",
|
|
70
|
+
"Device is not acquired. Device is created but it is in release state.",
|
|
71
|
+
"Device is disabled. It’s disabled from broker by Platform Admin",
|
|
72
|
+
"Company not found as SID is not valid",
|
|
73
|
+
"Subscription is expired.",
|
|
74
|
+
"Connection Not Allowed.",
|
|
75
|
+
"Invalid Bootstrap Certificate.",
|
|
76
|
+
"Invalid Operational Certificate."
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def _parsing_common(cls, what: str, rd: Union[IotcDiscoveryResponseJson, ProtocolIdentityResponseJson]):
|
|
81
|
+
""" Helper to parse either discovery or identity response common error fields """
|
|
82
|
+
|
|
83
|
+
ec_message = 'not available'
|
|
84
|
+
has_error = False
|
|
85
|
+
if rd.d is not None:
|
|
86
|
+
if rd.d.ec != 0:
|
|
87
|
+
has_error = True
|
|
88
|
+
if rd.d.ec <= len(cls.EC_RESPONSE_MAPPING):
|
|
89
|
+
ec_message = 'ec=%d (%s)' % (rd.d.ec, cls.EC_RESPONSE_MAPPING[rd.d.ec])
|
|
90
|
+
else:
|
|
91
|
+
ec_message = 'ec==%d' % rd.d.ec
|
|
92
|
+
else:
|
|
93
|
+
has_error = True
|
|
94
|
+
|
|
95
|
+
if rd.status != 200:
|
|
96
|
+
has_error = True
|
|
97
|
+
|
|
98
|
+
if has_error:
|
|
99
|
+
raise DeviceConfigError(
|
|
100
|
+
'%s failed. Error: "%s" status=%d message=%s' % (
|
|
101
|
+
what,
|
|
102
|
+
ec_message,
|
|
103
|
+
rd.status,
|
|
104
|
+
rd.message or "(message not available)"
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
@classmethod
|
|
109
|
+
def parse_discovery_response(cls, discovery_response: str) -> str:
|
|
110
|
+
""" Parses discovery response JSON and Returns base URL or raises DeviceConfigError """
|
|
111
|
+
|
|
112
|
+
drd: IotcDiscoveryResponseJson
|
|
113
|
+
try:
|
|
114
|
+
drd = deserialize_dataclass(IotcDiscoveryResponseJson, json.loads(discovery_response))
|
|
115
|
+
except json.JSONDecodeError as json_error:
|
|
116
|
+
raise DeviceConfigError("Discovery JSON Parsing Error: %s" % str(json_error))
|
|
117
|
+
cls._parsing_common("Discovery", drd)
|
|
118
|
+
|
|
119
|
+
if drd.d.bu is None:
|
|
120
|
+
raise DeviceConfigError("Discovery response is missing base URL")
|
|
121
|
+
|
|
122
|
+
return drd.d.bu
|
|
123
|
+
|
|
124
|
+
@classmethod
|
|
125
|
+
def parse_identity_response(cls, identity_response: str) -> DeviceIdentityData:
|
|
126
|
+
ird: ProtocolIdentityResponseJson
|
|
127
|
+
try:
|
|
128
|
+
ird = deserialize_dataclass(ProtocolIdentityResponseJson, json.loads(identity_response))
|
|
129
|
+
except json.JSONDecodeError as json_error:
|
|
130
|
+
raise DeviceConfigError("Identity JSON Parsing Error: %s" % str(json_error))
|
|
131
|
+
cls._parsing_common("Identity", ird)
|
|
132
|
+
|
|
133
|
+
return DeviceIdentityData(ird.d.p, ird.d.meta)
|
|
134
|
+
|
|
135
|
+
class DeviceRestApi:
|
|
136
|
+
def __init__(self, config: DeviceProperties, verbose: Optional[bool] = False):
|
|
137
|
+
self.config = config
|
|
138
|
+
self.verbose = verbose
|
|
139
|
+
|
|
140
|
+
def get_identity_data(self) -> DeviceIdentityData:
|
|
141
|
+
try:
|
|
142
|
+
if self.verbose:
|
|
143
|
+
print("Requesting Discovery Data %s..." % DraDiscoveryUrl(self.config).get_api_url())
|
|
144
|
+
resp = urllib.request.urlopen(urllib.request.Request(DraDiscoveryUrl(self.config).get_api_url()))
|
|
145
|
+
discovery_base_url = DraDeviceInfoParser.parse_discovery_response(resp.read())
|
|
146
|
+
|
|
147
|
+
if self.verbose:
|
|
148
|
+
print("Requesting Identity Data %s..." % DraIdentityUrl(discovery_base_url).get_uid_api_url(self.config))
|
|
149
|
+
resp = urllib.request.urlopen(DraIdentityUrl(discovery_base_url).get_uid_api_url(self.config))
|
|
150
|
+
identity_response = DraDeviceInfoParser.parse_identity_response(resp.read())
|
|
151
|
+
return identity_response
|
|
152
|
+
|
|
153
|
+
except HTTPError as http_error:
|
|
154
|
+
raise DeviceConfigError(http_error)
|
|
155
|
+
|
|
156
|
+
except URLError as url_error:
|
|
157
|
+
raise DeviceConfigError(str(url_error))
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (C) 2024 Avnet
|
|
3
|
+
# Authors: Nikola Markovic <nikola.markovic@avnet.com> et al.
|
|
4
|
+
|
|
5
|
+
class DeviceConfigError(RuntimeError):
|
|
6
|
+
def __init__(self, message: str):
|
|
7
|
+
self.msg = message
|
|
8
|
+
super().__init__(message)
|
|
9
|
+
|
|
10
|
+
class ClientError(RuntimeError):
|
|
11
|
+
def __init__(self, message: str):
|
|
12
|
+
self.msg = message
|
|
13
|
+
super().__init__(message)
|
|
14
|
+
|
|
15
|
+
class C2DDecodeError(RuntimeError):
|
|
16
|
+
def __init__(self, message: str):
|
|
17
|
+
self.msg = message
|
|
18
|
+
super().__init__(message)
|