ihcsdk 2.8.6__py3-none-any.whl → 2.8.8__py3-none-any.whl
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.
- ihcsdk/ihcclient.py +29 -28
- ihcsdk/ihcconnection.py +23 -14
- ihcsdk/ihccontroller.py +18 -12
- ihcsdk/ihcsslconnection.py +5 -2
- {ihcsdk-2.8.6.dist-info → ihcsdk-2.8.8.dist-info}/METADATA +1 -1
- ihcsdk-2.8.8.dist-info/RECORD +12 -0
- ihcsdk-2.8.6.dist-info/RECORD +0 -12
- {ihcsdk-2.8.6.dist-info → ihcsdk-2.8.8.dist-info}/WHEEL +0 -0
- {ihcsdk-2.8.6.dist-info → ihcsdk-2.8.8.dist-info}/license.txt +0 -0
- {ihcsdk-2.8.6.dist-info → ihcsdk-2.8.8.dist-info}/top_level.txt +0 -0
ihcsdk/ihcclient.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Implements the connection to the ihc controller
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
# pylint: disable=bare-except
|
|
5
6
|
import base64
|
|
6
7
|
import datetime
|
|
@@ -112,14 +113,17 @@ class IHCSoapClient:
|
|
|
112
113
|
"""Get the ihc project per segments.
|
|
113
114
|
Param: info .. reuse existing project info. If not provided, the get_project_info() is called internally.
|
|
114
115
|
"""
|
|
115
|
-
if info
|
|
116
|
+
if info is None:
|
|
116
117
|
info = self.get_project_info()
|
|
117
118
|
if info:
|
|
118
119
|
projectMajor = info.get("projectMajorRevision", 0)
|
|
119
120
|
projectMinor = info.get("projectMinorRevision", 0)
|
|
120
121
|
buffer = io.BytesIO()
|
|
121
122
|
for s in range(self.get_project_number_of_segments()):
|
|
122
|
-
|
|
123
|
+
segment = self.get_project_segment(s, projectMajor, projectMinor)
|
|
124
|
+
if segment is False:
|
|
125
|
+
return False
|
|
126
|
+
buffer.write(segment)
|
|
123
127
|
return zlib.decompress(buffer.getvalue(), 16 + zlib.MAX_WBITS).decode(
|
|
124
128
|
"ISO-8859-1"
|
|
125
129
|
)
|
|
@@ -342,32 +346,31 @@ class IHCSoapClient:
|
|
|
342
346
|
|
|
343
347
|
def __get_value(resource_value):
|
|
344
348
|
"""Get a runtime value from the xml base on the type in the xml"""
|
|
345
|
-
if resource_value
|
|
349
|
+
if resource_value is None:
|
|
346
350
|
return None
|
|
347
351
|
valuetype = resource_value.attrib[
|
|
348
352
|
"{http://www.w3.org/2001/XMLSchema-instance}type"
|
|
349
353
|
].split(":")[1]
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
"WSBooleanValue":
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
"
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
"
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
"
|
|
367
|
-
|
|
368
|
-
"int":
|
|
369
|
-
|
|
370
|
-
|
|
354
|
+
result = resource_value.text
|
|
355
|
+
match valuetype:
|
|
356
|
+
case "WSBooleanValue":
|
|
357
|
+
result = resource_value.find("./ns2:value", IHCSoapClient.ihcns).text == "true"
|
|
358
|
+
case "WSIntegerValue":
|
|
359
|
+
result = resource_value.find("./ns2:integer", IHCSoapClient.ihcns).text
|
|
360
|
+
case "WSFloatingPointValue":
|
|
361
|
+
result = round(float(resource_value.find("./ns2:floatingPointValue", IHCSoapClient.ihcns).text), 2)
|
|
362
|
+
case "WSEnumValue":
|
|
363
|
+
result = resource_value.find("./ns2:enumName", IHCSoapClient.ihcns).text
|
|
364
|
+
case "WSTimerValue":
|
|
365
|
+
return int(resource_value.find("./ns2:milliseconds", IHCSoapClient.ihcns).text)
|
|
366
|
+
case "WSTimeValue":
|
|
367
|
+
result = IHCSoapClient.get_time(resource_value)
|
|
368
|
+
case "WSDate":
|
|
369
|
+
result = IHCSoapClient.get_datetime(resource_value)
|
|
370
|
+
case "WSDateValue":
|
|
371
|
+
result = IHCSoapClient.get_date(resource_value)
|
|
372
|
+
case "int":
|
|
373
|
+
result = int(resource_value.text)
|
|
371
374
|
return result
|
|
372
375
|
|
|
373
376
|
def get_runtime_value(self, resourceid: int):
|
|
@@ -476,7 +479,7 @@ class IHCSoapClient:
|
|
|
476
479
|
if change_list is False:
|
|
477
480
|
return False
|
|
478
481
|
last_changes = {}
|
|
479
|
-
for
|
|
482
|
+
for id, value in change_list:
|
|
480
483
|
last_changes[id] = value
|
|
481
484
|
return last_changes
|
|
482
485
|
|
|
@@ -533,9 +536,7 @@ class IHCSoapClient:
|
|
|
533
536
|
|
|
534
537
|
def clear_user_log(self):
|
|
535
538
|
"""Clear the user log in the controller"""
|
|
536
|
-
|
|
537
|
-
"/ws/ConfigurationService", "clearUserLog", ""
|
|
538
|
-
)
|
|
539
|
+
self.connection.soap_action("/ws/ConfigurationService", "clearUserLog", "")
|
|
539
540
|
return
|
|
540
541
|
|
|
541
542
|
def get_system_info(self):
|
ihcsdk/ihcconnection.py
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"""Implements soap reqeust using the "requests" module"""
|
|
2
|
+
|
|
2
3
|
# pylint: disable=too-few-public-methods
|
|
3
4
|
import logging
|
|
4
5
|
import requests
|
|
5
6
|
import xml.etree.ElementTree
|
|
6
7
|
|
|
7
8
|
from urllib.parse import urlparse
|
|
9
|
+
from urllib3.util import Retry
|
|
10
|
+
from requests.adapters import HTTPAdapter
|
|
8
11
|
|
|
9
12
|
_LOGGER = logging.getLogger(__name__)
|
|
10
13
|
|
|
14
|
+
|
|
11
15
|
class IHCConnection(object):
|
|
12
16
|
"""Implements a http connection to the controller"""
|
|
13
17
|
|
|
@@ -24,6 +28,13 @@ class IHCConnection(object):
|
|
|
24
28
|
self.last_exception = None
|
|
25
29
|
self.last_response = None
|
|
26
30
|
self.session = requests.Session()
|
|
31
|
+
self.retries = Retry(
|
|
32
|
+
total=3,
|
|
33
|
+
backoff_factor=0.2,
|
|
34
|
+
status_forcelist=[502, 503, 504],
|
|
35
|
+
allowed_methods={"POST"},
|
|
36
|
+
)
|
|
37
|
+
self.session.mount("http://", HTTPAdapter(max_retries=self.retries))
|
|
27
38
|
|
|
28
39
|
def cert_verify(self):
|
|
29
40
|
return None
|
|
@@ -39,7 +50,7 @@ class IHCConnection(object):
|
|
|
39
50
|
"SOAPAction": action,
|
|
40
51
|
}
|
|
41
52
|
try:
|
|
42
|
-
_LOGGER.debug(
|
|
53
|
+
_LOGGER.debug("soap payload %s", payload)
|
|
43
54
|
self.last_exception = None
|
|
44
55
|
response = self.session.post(
|
|
45
56
|
url=self.url + service,
|
|
@@ -47,22 +58,20 @@ class IHCConnection(object):
|
|
|
47
58
|
data=payload,
|
|
48
59
|
verify=self.cert_verify(),
|
|
49
60
|
)
|
|
50
|
-
_LOGGER.debug(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if response.status_code != 200:
|
|
56
|
-
self.last_response = response
|
|
57
|
-
return False
|
|
58
|
-
try:
|
|
59
|
-
_LOGGER.debug( "soap request response %s",response.text)
|
|
61
|
+
_LOGGER.debug("soap request response status %d", response.status_code)
|
|
62
|
+
if response.status_code != 200:
|
|
63
|
+
self.last_response = response
|
|
64
|
+
return False
|
|
65
|
+
_LOGGER.debug("soap request response %s", response.text)
|
|
60
66
|
xdoc = xml.etree.ElementTree.fromstring(response.text)
|
|
61
67
|
if xdoc is None:
|
|
62
68
|
return False
|
|
69
|
+
return xdoc
|
|
70
|
+
except requests.exceptions.RequestException as exp:
|
|
71
|
+
_LOGGER.error("soap request exception %s", exp)
|
|
72
|
+
self.last_exception = exp
|
|
63
73
|
except xml.etree.ElementTree.ParseError as exp:
|
|
64
|
-
_LOGGER.error(
|
|
74
|
+
_LOGGER.error("soap request xml parse error %s", exp)
|
|
65
75
|
self.last_exception = exp
|
|
66
76
|
self.last_response = response
|
|
67
|
-
|
|
68
|
-
return xdoc
|
|
77
|
+
return False
|
ihcsdk/ihccontroller.py
CHANGED
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
Wraps the ihcclient in a more user friendly interface to handle lost connection
|
|
3
3
|
Notify thread to handle change notifications
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
# pylint: disable=invalid-name, bare-except, too-many-instance-attributes
|
|
6
7
|
from datetime import datetime, timedelta
|
|
7
8
|
import logging
|
|
8
9
|
import requests
|
|
9
|
-
import sys
|
|
10
10
|
import threading
|
|
11
11
|
import time
|
|
12
12
|
from ihcsdk.ihcclient import IHCSoapClient, IHCSTATE_READY
|
|
13
13
|
|
|
14
14
|
_LOGGER = logging.getLogger(__name__)
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
class IHCController:
|
|
17
18
|
"""
|
|
18
19
|
Implements the notification thread and
|
|
@@ -49,17 +50,17 @@ class IHCController:
|
|
|
49
50
|
return False
|
|
50
51
|
return True
|
|
51
52
|
except requests.exceptions.RequestException as exp:
|
|
52
|
-
_LOGGER.warning(
|
|
53
|
+
_LOGGER.warning("is_ihc_controller %s", exp)
|
|
53
54
|
return False
|
|
54
55
|
|
|
55
56
|
def authenticate(self) -> bool:
|
|
56
57
|
"""Authenticate and enable the registered notifications"""
|
|
57
58
|
with IHCController._mutex:
|
|
58
|
-
_LOGGER.debug(
|
|
59
|
+
_LOGGER.debug("Authenticating login on ihc controller")
|
|
59
60
|
if not self.client.authenticate(self._username, self._password):
|
|
60
|
-
_LOGGER.debug(
|
|
61
|
+
_LOGGER.debug("Authentication failed")
|
|
61
62
|
return False
|
|
62
|
-
_LOGGER.debug(
|
|
63
|
+
_LOGGER.debug("Authentication was successful")
|
|
63
64
|
if self._ihcevents:
|
|
64
65
|
self.client.enable_runtime_notifications(self._ihcevents.keys())
|
|
65
66
|
return True
|
|
@@ -131,7 +132,7 @@ class IHCController:
|
|
|
131
132
|
self.re_authenticate()
|
|
132
133
|
return self.client.set_runtime_value_time(ihcid, hours, minutes, seconds)
|
|
133
134
|
|
|
134
|
-
def get_project(self) -> str:
|
|
135
|
+
def get_project(self, insegments: bool = True) -> str:
|
|
135
136
|
"""Get the ihc project and make sure controller is ready before"""
|
|
136
137
|
with IHCController._mutex:
|
|
137
138
|
if self._project is None:
|
|
@@ -139,7 +140,10 @@ class IHCController:
|
|
|
139
140
|
ready = self.client.wait_for_state_change(IHCSTATE_READY, 10)
|
|
140
141
|
if ready != IHCSTATE_READY:
|
|
141
142
|
return None
|
|
142
|
-
|
|
143
|
+
if insegments:
|
|
144
|
+
self._project = self.client.get_project_in_segments()
|
|
145
|
+
else:
|
|
146
|
+
self._project = self.client.get_project()
|
|
143
147
|
return self._project
|
|
144
148
|
|
|
145
149
|
def add_notify_event(self, resourceid: int, callback, delayed=False):
|
|
@@ -165,7 +169,7 @@ class IHCController:
|
|
|
165
169
|
|
|
166
170
|
def _notify_fn(self):
|
|
167
171
|
"""The notify thread function."""
|
|
168
|
-
_LOGGER.debug(
|
|
172
|
+
_LOGGER.debug("Starting notify thread")
|
|
169
173
|
while self._notifyrunning:
|
|
170
174
|
try:
|
|
171
175
|
with IHCController._mutex:
|
|
@@ -178,7 +182,7 @@ class IHCController:
|
|
|
178
182
|
if changes is False:
|
|
179
183
|
self.re_authenticate(True)
|
|
180
184
|
continue
|
|
181
|
-
for
|
|
185
|
+
for ihcid, value in changes:
|
|
182
186
|
if ihcid in self._ihcevents:
|
|
183
187
|
for callback in self._ihcevents[ihcid]:
|
|
184
188
|
if (
|
|
@@ -188,7 +192,7 @@ class IHCController:
|
|
|
188
192
|
callback(ihcid, value)
|
|
189
193
|
self._ihcvalues[ihcid] = value
|
|
190
194
|
except Exception as exp:
|
|
191
|
-
_LOGGER.error(
|
|
195
|
+
_LOGGER.error("Exception in notify thread %s", exp)
|
|
192
196
|
self.re_authenticate(True)
|
|
193
197
|
|
|
194
198
|
def re_authenticate(self, notify: bool = False) -> bool:
|
|
@@ -200,10 +204,12 @@ class IHCController:
|
|
|
200
204
|
"""
|
|
201
205
|
timeout = datetime.now() + timedelta(seconds=self.reauthenticatetimeout)
|
|
202
206
|
while True:
|
|
203
|
-
_LOGGER.debug(
|
|
207
|
+
_LOGGER.debug("Reauthenticating login on ihc controller")
|
|
204
208
|
if self.authenticate():
|
|
205
209
|
return True
|
|
206
|
-
_LOGGER.debug(
|
|
210
|
+
_LOGGER.debug(
|
|
211
|
+
"Authenticate failed - Reauthenticating login on ihc controller in 10 sec"
|
|
212
|
+
)
|
|
207
213
|
|
|
208
214
|
# if called from the notify and notify a cancled we do not want to retry
|
|
209
215
|
if notify:
|
ihcsdk/ihcsslconnection.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Implements soap reqeust using the "requests" module"""
|
|
2
|
+
|
|
2
3
|
# pylint: disable=too-few-public-methods
|
|
3
4
|
import os
|
|
4
5
|
import requests
|
|
@@ -6,7 +7,6 @@ import requests
|
|
|
6
7
|
from cryptography.x509 import load_pem_x509_certificate
|
|
7
8
|
from cryptography.hazmat.backends import default_backend
|
|
8
9
|
from cryptography.hazmat.primitives import hashes
|
|
9
|
-
from requests.adapters import HTTPAdapter
|
|
10
10
|
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
|
|
11
11
|
|
|
12
12
|
from ihcsdk.ihcconnection import IHCConnection
|
|
@@ -19,7 +19,10 @@ class IHCSSLConnection(IHCConnection):
|
|
|
19
19
|
"""Initialize the IHCSSLConnection with a url for the controller"""
|
|
20
20
|
super(IHCSSLConnection, self).__init__(url)
|
|
21
21
|
self.cert_file = os.path.dirname(__file__) + "/certs/ihc3.crt"
|
|
22
|
-
self.session.mount(
|
|
22
|
+
self.session.mount(
|
|
23
|
+
"https://",
|
|
24
|
+
CertAdapter(self.get_fingerprint_from_cert(), max_retries=self.retries),
|
|
25
|
+
)
|
|
23
26
|
|
|
24
27
|
def get_fingerprint_from_cert(self):
|
|
25
28
|
"""Get the fingerprint from the certificate"""
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
ihcsdk/__init__.py,sha256=ocAoa28ZKxGgMlDEHWEsd7n00OtGB0R9N7XQfRlih9Q,28
|
|
2
|
+
ihcsdk/ihcclient.py,sha256=LzcO0ZfIqfdQxF3TzoIfo2jVBU2u3QoZeZA4Fj3psqc,24302
|
|
3
|
+
ihcsdk/ihcconnection.py,sha256=qCFhU4cAWYnqgiXWF-xjUZj1TMBZ83caDj8jEE1qaoc,2889
|
|
4
|
+
ihcsdk/ihccontroller.py,sha256=9D97RX8DrFMLMxDBcIrhoYY-QEeKNjbVv_PiRW0wNyU,9180
|
|
5
|
+
ihcsdk/ihcsslconnection.py,sha256=q7gDchCN2_SXItp2T3dMvlXmHC7zVO5M0bqGnepiKiU,2079
|
|
6
|
+
ihcsdk/certs/ihc.crt,sha256=VYY_DiHrctlXBTNXGdJ2FN4TYuVnwnpVZ1i8t2_0cec,1002
|
|
7
|
+
ihcsdk/certs/ihc3.crt,sha256=Ka2L8zQ06A76W6fZc0ckScdrj1Cn-mhgqdhc61-cCrk,1398
|
|
8
|
+
ihcsdk-2.8.8.dist-info/METADATA,sha256=I2qpZJjWGY0Yad46vDMjNBljsRURFsopM0Ep8vgrn24,339
|
|
9
|
+
ihcsdk-2.8.8.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
10
|
+
ihcsdk-2.8.8.dist-info/license.txt,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
|
11
|
+
ihcsdk-2.8.8.dist-info/top_level.txt,sha256=QgKE7TWblC-uXe5-7MVO5JtzvrPiMoVmGgKKsVR43hU,7
|
|
12
|
+
ihcsdk-2.8.8.dist-info/RECORD,,
|
ihcsdk-2.8.6.dist-info/RECORD
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
ihcsdk/__init__.py,sha256=ocAoa28ZKxGgMlDEHWEsd7n00OtGB0R9N7XQfRlih9Q,28
|
|
2
|
-
ihcsdk/ihcclient.py,sha256=VY46_PS0jMHVilJ_ViGJ_r9G5fk3--Xujf1qOrzlmx4,24118
|
|
3
|
-
ihcsdk/ihcconnection.py,sha256=qnOEEsgKulIUGRS223o9YSy9qmEVR1D6jNt2XxGFGho,2577
|
|
4
|
-
ihcsdk/ihccontroller.py,sha256=eYmeNGR29y5eJfU3GpRSfwZvsPMqPDjjYIYGwmtq9cE,9017
|
|
5
|
-
ihcsdk/ihcsslconnection.py,sha256=4IFVg1bpdJ25yN76tnFLndvL5Rl9-qbXrbENUjyTfzw,2056
|
|
6
|
-
ihcsdk/certs/ihc.crt,sha256=VYY_DiHrctlXBTNXGdJ2FN4TYuVnwnpVZ1i8t2_0cec,1002
|
|
7
|
-
ihcsdk/certs/ihc3.crt,sha256=Ka2L8zQ06A76W6fZc0ckScdrj1Cn-mhgqdhc61-cCrk,1398
|
|
8
|
-
ihcsdk-2.8.6.dist-info/METADATA,sha256=f9m3QS2eyYX9icV_tw6l9-Vxwmcnj5tSwCUuGmlRQcg,339
|
|
9
|
-
ihcsdk-2.8.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
10
|
-
ihcsdk-2.8.6.dist-info/license.txt,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
|
11
|
-
ihcsdk-2.8.6.dist-info/top_level.txt,sha256=QgKE7TWblC-uXe5-7MVO5JtzvrPiMoVmGgKKsVR43hU,7
|
|
12
|
-
ihcsdk-2.8.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|