cdp-client 2.2.0__tar.gz → 2.3.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.
- {cdp_client-2.2.0 → cdp_client-2.3.0}/PKG-INFO +81 -11
- cdp_client-2.2.0/cdp_client.egg-info/PKG-INFO → cdp_client-2.3.0/README.rst +65 -34
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/cdp.py +70 -6
- cdp_client-2.3.0/cdp_client/cdp_pb2.py +85 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/tests/fake_data.py +44 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/tests/test_connection.py +28 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/tests/test_node.py +128 -0
- cdp_client-2.2.0/README.rst → cdp_client-2.3.0/cdp_client.egg-info/PKG-INFO +104 -3
- {cdp_client-2.2.0 → cdp_client-2.3.0}/setup.py +6 -11
- cdp_client-2.2.0/cdp_client/cdp_pb2.py +0 -1419
- {cdp_client-2.2.0 → cdp_client-2.3.0}/LICENSE.txt +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/MANIFEST.in +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/__init__.py +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/tests/__init__.py +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/tests/test_client.py +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/tests/test_main.py +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/tests/test_nodetree.py +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client/tests/test_requests.py +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client.egg-info/SOURCES.txt +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client.egg-info/dependency_links.txt +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client.egg-info/requires.txt +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/cdp_client.egg-info/top_level.txt +0 -0
- {cdp_client-2.2.0 → cdp_client-2.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: cdp-client
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Provides an API that allows to interact with CDP applications
|
|
5
5
|
Home-page: https://github.com/CDPTechnologies/PythonCDPClient
|
|
6
6
|
Author: CDP Technologies AS
|
|
@@ -13,28 +13,36 @@ Classifier: Intended Audience :: Developers
|
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Topic :: Software Development
|
|
16
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
17
16
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.3
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.4
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
23
17
|
Classifier: Programming Language :: Python :: 3.8
|
|
24
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
25
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Requires-Python: >=3.8
|
|
26
23
|
License-File: LICENSE.txt
|
|
27
24
|
Requires-Dist: promise
|
|
28
25
|
Requires-Dist: websocket-client
|
|
29
26
|
Requires-Dist: protobuf
|
|
30
27
|
Requires-Dist: mock
|
|
28
|
+
Dynamic: author
|
|
29
|
+
Dynamic: author-email
|
|
30
|
+
Dynamic: classifier
|
|
31
|
+
Dynamic: description
|
|
32
|
+
Dynamic: home-page
|
|
33
|
+
Dynamic: keywords
|
|
34
|
+
Dynamic: license
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
Dynamic: requires-dist
|
|
37
|
+
Dynamic: requires-python
|
|
38
|
+
Dynamic: summary
|
|
31
39
|
|
|
32
40
|
CDP-Client
|
|
33
41
|
==========
|
|
34
42
|
|
|
35
43
|
A simple python interface for the CDP Studio development platform that allows Python scripts to interact with CDP Applications - retrieve CDP Application structures and read-write object values. For more information about CDP Studio see https://cdpstudio.com/
|
|
36
44
|
|
|
37
|
-
The API makes heavy use of promise library for asynchronous operations. For more information see https://pypi.
|
|
45
|
+
The API makes heavy use of promise library for asynchronous operations. For more information see https://pypi.org/project/promise/
|
|
38
46
|
|
|
39
47
|
Installation
|
|
40
48
|
------------
|
|
@@ -62,6 +70,26 @@ The example below shows how you subscribe to CDP signal value changes.
|
|
|
62
70
|
client.find_node('AppName.ComponentName.SignalName').then(subscribe_to_value_changes)
|
|
63
71
|
client.run_event_loop()
|
|
64
72
|
|
|
73
|
+
The example below shows how you subscribe to CDP events.
|
|
74
|
+
|
|
75
|
+
.. code:: python
|
|
76
|
+
|
|
77
|
+
from cdp_client import cdp
|
|
78
|
+
|
|
79
|
+
def on_event_received(event_info):
|
|
80
|
+
print(f"Event {event_info.id} from {event_info.sender}")
|
|
81
|
+
print(f"Code: {event_info.code}, Timestamp: {event_info.timestamp}")
|
|
82
|
+
if event_info.data:
|
|
83
|
+
for data_item in event_info.data:
|
|
84
|
+
print(f" {data_item.name}: {data_item.value}")
|
|
85
|
+
|
|
86
|
+
def subscribe_to_events(node):
|
|
87
|
+
node.subscribe_to_events(on_event_received)
|
|
88
|
+
|
|
89
|
+
client = cdp.Client(host='127.0.0.1')
|
|
90
|
+
client.root_node().then(subscribe_to_events)
|
|
91
|
+
client.run_event_loop()
|
|
92
|
+
|
|
65
93
|
API
|
|
66
94
|
---
|
|
67
95
|
|
|
@@ -143,7 +171,7 @@ Client(host, port, auto_reconnect, notification_listener, encryption_parameters)
|
|
|
143
171
|
encryption_parameters={'use_encryption': True,
|
|
144
172
|
'cert_reqs': ssl.CERT_REQUIRED,
|
|
145
173
|
'ca_certs': 'StudioAPI.crt',
|
|
146
|
-
'check_hostname': False}
|
|
174
|
+
'check_hostname': False})
|
|
147
175
|
|
|
148
176
|
Instance Methods / Client
|
|
149
177
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -391,6 +419,48 @@ Stops listening previously subscribed value changes
|
|
|
391
419
|
|
|
392
420
|
node.unsubscribe_from_value_changes(on_change)
|
|
393
421
|
|
|
422
|
+
node.subscribe_to_events(callback, starting_from=None)
|
|
423
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
424
|
+
|
|
425
|
+
Starts listening to events from this node and its children, passing event information to the provided callback function
|
|
426
|
+
|
|
427
|
+
- Arguments
|
|
428
|
+
|
|
429
|
+
callback - Function(event_info) where event_info contains id, sender, code, timestamp, and optional data fields
|
|
430
|
+
|
|
431
|
+
starting_from - Optional timestamp to start receiving events from (in nanoseconds since Epoch). Defaults to None for current events.
|
|
432
|
+
|
|
433
|
+
- Usage
|
|
434
|
+
|
|
435
|
+
.. code:: python
|
|
436
|
+
|
|
437
|
+
def on_event(event_info):
|
|
438
|
+
print(f"Event {event_info.id} from {event_info.sender}")
|
|
439
|
+
print(f"Code: {event_info.code}, Timestamp: {event_info.timestamp}")
|
|
440
|
+
if event_info.data:
|
|
441
|
+
for data_item in event_info.data:
|
|
442
|
+
print(f" {data_item.name}: {data_item.value}")
|
|
443
|
+
|
|
444
|
+
node.subscribe_to_events(on_event)
|
|
445
|
+
|
|
446
|
+
node.unsubscribe_from_events(callback)
|
|
447
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
448
|
+
|
|
449
|
+
Stops listening to previously subscribed events
|
|
450
|
+
|
|
451
|
+
- Arguments
|
|
452
|
+
|
|
453
|
+
callback - Function(event_info) that was previously subscribed
|
|
454
|
+
|
|
455
|
+
- Usage
|
|
456
|
+
|
|
457
|
+
.. code:: python
|
|
458
|
+
|
|
459
|
+
def on_event(event_info):
|
|
460
|
+
print(f"Event received: {event_info.id}")
|
|
461
|
+
|
|
462
|
+
node.unsubscribe_from_events(on_event)
|
|
463
|
+
|
|
394
464
|
Notification Listener
|
|
395
465
|
~~~~~~~~~~~~~~~~~~~~~
|
|
396
466
|
|
|
@@ -463,7 +533,7 @@ To run the test suite execute the following command in package root folder:
|
|
|
463
533
|
|
|
464
534
|
.. code:: sh
|
|
465
535
|
|
|
466
|
-
$ python
|
|
536
|
+
$ python -m unittest discover cdp_client.tests -v
|
|
467
537
|
|
|
468
538
|
License
|
|
469
539
|
-------
|
|
@@ -1,40 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: cdp-client
|
|
3
|
-
Version: 2.2.0
|
|
4
|
-
Summary: Provides an API that allows to interact with CDP applications
|
|
5
|
-
Home-page: https://github.com/CDPTechnologies/PythonCDPClient
|
|
6
|
-
Author: CDP Technologies AS
|
|
7
|
-
Author-email: info@cdptech.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Keywords: cdp cdpstudio studio client cdp-client cdp_client
|
|
10
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
-
Classifier: Environment :: Console
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Classifier: Operating System :: OS Independent
|
|
15
|
-
Classifier: Topic :: Software Development
|
|
16
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
17
|
-
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.3
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.4
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
25
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
26
|
-
License-File: LICENSE.txt
|
|
27
|
-
Requires-Dist: promise
|
|
28
|
-
Requires-Dist: websocket-client
|
|
29
|
-
Requires-Dist: protobuf
|
|
30
|
-
Requires-Dist: mock
|
|
31
|
-
|
|
32
1
|
CDP-Client
|
|
33
2
|
==========
|
|
34
3
|
|
|
35
4
|
A simple python interface for the CDP Studio development platform that allows Python scripts to interact with CDP Applications - retrieve CDP Application structures and read-write object values. For more information about CDP Studio see https://cdpstudio.com/
|
|
36
5
|
|
|
37
|
-
The API makes heavy use of promise library for asynchronous operations. For more information see https://pypi.
|
|
6
|
+
The API makes heavy use of promise library for asynchronous operations. For more information see https://pypi.org/project/promise/
|
|
38
7
|
|
|
39
8
|
Installation
|
|
40
9
|
------------
|
|
@@ -62,6 +31,26 @@ The example below shows how you subscribe to CDP signal value changes.
|
|
|
62
31
|
client.find_node('AppName.ComponentName.SignalName').then(subscribe_to_value_changes)
|
|
63
32
|
client.run_event_loop()
|
|
64
33
|
|
|
34
|
+
The example below shows how you subscribe to CDP events.
|
|
35
|
+
|
|
36
|
+
.. code:: python
|
|
37
|
+
|
|
38
|
+
from cdp_client import cdp
|
|
39
|
+
|
|
40
|
+
def on_event_received(event_info):
|
|
41
|
+
print(f"Event {event_info.id} from {event_info.sender}")
|
|
42
|
+
print(f"Code: {event_info.code}, Timestamp: {event_info.timestamp}")
|
|
43
|
+
if event_info.data:
|
|
44
|
+
for data_item in event_info.data:
|
|
45
|
+
print(f" {data_item.name}: {data_item.value}")
|
|
46
|
+
|
|
47
|
+
def subscribe_to_events(node):
|
|
48
|
+
node.subscribe_to_events(on_event_received)
|
|
49
|
+
|
|
50
|
+
client = cdp.Client(host='127.0.0.1')
|
|
51
|
+
client.root_node().then(subscribe_to_events)
|
|
52
|
+
client.run_event_loop()
|
|
53
|
+
|
|
65
54
|
API
|
|
66
55
|
---
|
|
67
56
|
|
|
@@ -143,7 +132,7 @@ Client(host, port, auto_reconnect, notification_listener, encryption_parameters)
|
|
|
143
132
|
encryption_parameters={'use_encryption': True,
|
|
144
133
|
'cert_reqs': ssl.CERT_REQUIRED,
|
|
145
134
|
'ca_certs': 'StudioAPI.crt',
|
|
146
|
-
'check_hostname': False}
|
|
135
|
+
'check_hostname': False})
|
|
147
136
|
|
|
148
137
|
Instance Methods / Client
|
|
149
138
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -391,6 +380,48 @@ Stops listening previously subscribed value changes
|
|
|
391
380
|
|
|
392
381
|
node.unsubscribe_from_value_changes(on_change)
|
|
393
382
|
|
|
383
|
+
node.subscribe_to_events(callback, starting_from=None)
|
|
384
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
385
|
+
|
|
386
|
+
Starts listening to events from this node and its children, passing event information to the provided callback function
|
|
387
|
+
|
|
388
|
+
- Arguments
|
|
389
|
+
|
|
390
|
+
callback - Function(event_info) where event_info contains id, sender, code, timestamp, and optional data fields
|
|
391
|
+
|
|
392
|
+
starting_from - Optional timestamp to start receiving events from (in nanoseconds since Epoch). Defaults to None for current events.
|
|
393
|
+
|
|
394
|
+
- Usage
|
|
395
|
+
|
|
396
|
+
.. code:: python
|
|
397
|
+
|
|
398
|
+
def on_event(event_info):
|
|
399
|
+
print(f"Event {event_info.id} from {event_info.sender}")
|
|
400
|
+
print(f"Code: {event_info.code}, Timestamp: {event_info.timestamp}")
|
|
401
|
+
if event_info.data:
|
|
402
|
+
for data_item in event_info.data:
|
|
403
|
+
print(f" {data_item.name}: {data_item.value}")
|
|
404
|
+
|
|
405
|
+
node.subscribe_to_events(on_event)
|
|
406
|
+
|
|
407
|
+
node.unsubscribe_from_events(callback)
|
|
408
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
409
|
+
|
|
410
|
+
Stops listening to previously subscribed events
|
|
411
|
+
|
|
412
|
+
- Arguments
|
|
413
|
+
|
|
414
|
+
callback - Function(event_info) that was previously subscribed
|
|
415
|
+
|
|
416
|
+
- Usage
|
|
417
|
+
|
|
418
|
+
.. code:: python
|
|
419
|
+
|
|
420
|
+
def on_event(event_info):
|
|
421
|
+
print(f"Event received: {event_info.id}")
|
|
422
|
+
|
|
423
|
+
node.unsubscribe_from_events(on_event)
|
|
424
|
+
|
|
394
425
|
Notification Listener
|
|
395
426
|
~~~~~~~~~~~~~~~~~~~~~
|
|
396
427
|
|
|
@@ -463,7 +494,7 @@ To run the test suite execute the following command in package root folder:
|
|
|
463
494
|
|
|
464
495
|
.. code:: sh
|
|
465
496
|
|
|
466
|
-
$ python
|
|
497
|
+
$ python -m unittest discover cdp_client.tests -v
|
|
467
498
|
|
|
468
499
|
License
|
|
469
500
|
-------
|
|
@@ -161,6 +161,7 @@ class Node:
|
|
|
161
161
|
self._children = []
|
|
162
162
|
self._structure_subscriptions = []
|
|
163
163
|
self._value_subscriptions = []
|
|
164
|
+
self._event_subscriptions = []
|
|
164
165
|
self._value = proto.VariantValue()
|
|
165
166
|
self._parent = parent
|
|
166
167
|
for child in self._structure.node:
|
|
@@ -235,6 +236,27 @@ class Node:
|
|
|
235
236
|
else:
|
|
236
237
|
self._connection.send_value_unrequest(self._id())
|
|
237
238
|
|
|
239
|
+
def subscribe_to_events(self, callback, starting_from=None):
|
|
240
|
+
"""Starts listening to events from this node and its children.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
callback: Function(event_info) to call when events are received
|
|
244
|
+
starting_from: Optional timestamp to start receiving events from (nanoseconds since Epoch)
|
|
245
|
+
"""
|
|
246
|
+
self._event_subscriptions.append(callback)
|
|
247
|
+
self._connection.send_event_request(self._id(), starting_from)
|
|
248
|
+
|
|
249
|
+
def unsubscribe_from_events(self, callback):
|
|
250
|
+
"""Stops listening to previously subscribed events.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
callback: Function(event_info) that was previously subscribed
|
|
254
|
+
"""
|
|
255
|
+
if callback in self._event_subscriptions:
|
|
256
|
+
self._event_subscriptions.remove(callback)
|
|
257
|
+
if not self._event_subscriptions:
|
|
258
|
+
self._connection.send_event_unrequest(self._id())
|
|
259
|
+
|
|
238
260
|
def _id(self):
|
|
239
261
|
return self._structure.info.node_id
|
|
240
262
|
|
|
@@ -308,6 +330,10 @@ class Node:
|
|
|
308
330
|
for callback, fs, sample_rate in self._value_subscriptions:
|
|
309
331
|
callback(self._value, variant.timestamp + self._connection.server_time_difference() * nanoseconds_in_second)
|
|
310
332
|
|
|
333
|
+
def _update_event(self, event_info):
|
|
334
|
+
for callback in self._event_subscriptions:
|
|
335
|
+
callback(event_info)
|
|
336
|
+
|
|
311
337
|
@staticmethod
|
|
312
338
|
def _translate_type(node_type):
|
|
313
339
|
if node_type == proto.CDP_SYSTEM:
|
|
@@ -446,6 +472,14 @@ class Connection:
|
|
|
446
472
|
self._update_time_difference()
|
|
447
473
|
self._compose_and_send_value(variant)
|
|
448
474
|
|
|
475
|
+
def send_event_request(self, node_id, starting_from=None):
|
|
476
|
+
self._update_time_difference()
|
|
477
|
+
self._compose_and_send_event_request(node_id, starting_from)
|
|
478
|
+
|
|
479
|
+
def send_event_unrequest(self, node_id):
|
|
480
|
+
self._update_time_difference()
|
|
481
|
+
self._compose_and_send_event_request(node_id, None, True)
|
|
482
|
+
|
|
449
483
|
def run_event_loop(self):
|
|
450
484
|
self._ws.run_forever(sslopt=self._encryption_parameters)
|
|
451
485
|
while self._auto_reconnect:
|
|
@@ -468,16 +502,16 @@ class Connection:
|
|
|
468
502
|
on_close=self._on_close,
|
|
469
503
|
on_open=self._on_open)
|
|
470
504
|
|
|
471
|
-
def _on_error(self, error):
|
|
505
|
+
def _on_error(self, ws, error):
|
|
472
506
|
if not self._auto_reconnect:
|
|
473
507
|
self._cleanup_queued_requests(ConnectionError(error))
|
|
474
508
|
|
|
475
|
-
def _on_close(self):
|
|
509
|
+
def _on_close(self, ws, close_status_code=None, close_msg=None):
|
|
476
510
|
self._is_connected = False
|
|
477
511
|
if not self._auto_reconnect:
|
|
478
512
|
self._cleanup_queued_requests(ConnectionError("Connection was closed"))
|
|
479
513
|
|
|
480
|
-
def _on_open(self):
|
|
514
|
+
def _on_open(self, ws):
|
|
481
515
|
pass
|
|
482
516
|
|
|
483
517
|
def _fetch_time_difference(self):
|
|
@@ -545,7 +579,10 @@ class Connection:
|
|
|
545
579
|
self._ws.on_message = self._handle_container_message
|
|
546
580
|
self._update_time_difference().then(self._node_tree.update()).then(self._send_queued_requests())
|
|
547
581
|
|
|
548
|
-
def _handle_auth_response(self, message):
|
|
582
|
+
def _handle_auth_response(self, ws=None, message=None):
|
|
583
|
+
if message is None:
|
|
584
|
+
message = ws
|
|
585
|
+
ws = None
|
|
549
586
|
data = proto.AuthResponse()
|
|
550
587
|
data.ParseFromString(message)
|
|
551
588
|
if data.result_code in (data.eGranted, data.eGrantedPasswordWillExpireSoon):
|
|
@@ -569,7 +606,10 @@ class Connection:
|
|
|
569
606
|
self._credentials = credentials
|
|
570
607
|
self._compose_and_send_re_auth_request()
|
|
571
608
|
|
|
572
|
-
def _handle_hello_message(self, message):
|
|
609
|
+
def _handle_hello_message(self, ws=None, message=None):
|
|
610
|
+
if message is None:
|
|
611
|
+
message = ws
|
|
612
|
+
ws = None
|
|
573
613
|
if self._parse_hello_message(message):
|
|
574
614
|
request = AuthRequest(host=self._host, port=self._port, system_name=self._system_name,
|
|
575
615
|
application_name=self._application_name, cdp_version=self._cdp_version,
|
|
@@ -600,7 +640,10 @@ class Connection:
|
|
|
600
640
|
self._re_auth_request.then(self._re_authenticate)
|
|
601
641
|
self._notification_listener.credentials_requested(self._re_auth_request)
|
|
602
642
|
|
|
603
|
-
def _handle_container_message(self, message):
|
|
643
|
+
def _handle_container_message(self, ws=None, message=None):
|
|
644
|
+
if message is None:
|
|
645
|
+
message = ws
|
|
646
|
+
ws = None
|
|
604
647
|
data = proto.Container()
|
|
605
648
|
data.ParseFromString(message)
|
|
606
649
|
if data.message_type == proto.Container.eStructureResponse:
|
|
@@ -613,6 +656,8 @@ class Connection:
|
|
|
613
656
|
self._parse_current_time_response(data.current_time_response)
|
|
614
657
|
elif data.message_type == proto.Container.eReauthResponse:
|
|
615
658
|
self._parse_re_auth_response(data.re_auth_response)
|
|
659
|
+
elif data.message_type == proto.Container.eEventResponse:
|
|
660
|
+
self._parse_event_response(data.event_response)
|
|
616
661
|
elif data.message_type == proto.Container.eRemoteError:
|
|
617
662
|
self._parse_error_response(data.error)
|
|
618
663
|
else:
|
|
@@ -632,6 +677,13 @@ class Connection:
|
|
|
632
677
|
def _parse_current_time_response(self, response):
|
|
633
678
|
self._time_request.do_resolve(response)
|
|
634
679
|
|
|
680
|
+
def _parse_event_response(self, response):
|
|
681
|
+
for event_info in response:
|
|
682
|
+
for node_id in event_info.node_id:
|
|
683
|
+
node = self._node_tree.find_by_id(node_id)
|
|
684
|
+
if node is not None:
|
|
685
|
+
node._update_event(event_info)
|
|
686
|
+
|
|
635
687
|
def _parse_re_auth_response(self, response):
|
|
636
688
|
if response.result_code not in (response.eGranted, response.eGrantedPasswordWillExpireSoon):
|
|
637
689
|
self._re_auth_request = AuthRequest(host=self._host, port=self._port, system_name=self._system_name,
|
|
@@ -719,6 +771,18 @@ class Connection:
|
|
|
719
771
|
data.message_type = proto.Container.eCurrentTimeRequest
|
|
720
772
|
self._ws.send(data.SerializeToString())
|
|
721
773
|
|
|
774
|
+
def _compose_and_send_event_request(self, node_id, starting_from=None, stop=False):
|
|
775
|
+
data = proto.Container()
|
|
776
|
+
data.message_type = proto.Container.eEventRequest
|
|
777
|
+
event_request = proto.EventRequest()
|
|
778
|
+
event_request.node_id = node_id
|
|
779
|
+
if starting_from is not None:
|
|
780
|
+
event_request.starting_from = starting_from
|
|
781
|
+
if stop:
|
|
782
|
+
event_request.stop = stop
|
|
783
|
+
data.event_request.extend([event_request])
|
|
784
|
+
self._ws.send(data.SerializeToString())
|
|
785
|
+
|
|
722
786
|
def _compose_auth_request(self, request):
|
|
723
787
|
if not 'Username' in self._credentials:
|
|
724
788
|
UnknownError("NotificationListener.credentials_requested() didn't return 'Username' entry")
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: cdp.proto
|
|
5
|
+
# Protobuf Python Version: 6.30.2
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
6,
|
|
15
|
+
30,
|
|
16
|
+
2,
|
|
17
|
+
'',
|
|
18
|
+
'cdp.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tcdp.proto\x12\x0fStudioAPI.Proto\"\xaf\x03\n\x05Hello\x12\x13\n\x0bsystem_name\x18\x01 \x02(\t\x12\x19\n\x0e\x63ompat_version\x18\x02 \x02(\r:\x01\x32\x12\x1e\n\x13incremental_version\x18\x03 \x02(\r:\x01\x30\x12\x12\n\npublic_key\x18\x04 \x03(\x0c\x12\x11\n\tchallenge\x18\x05 \x01(\x0c\x12\x18\n\x10\x61pplication_name\x18\x06 \x01(\t\x12\x19\n\x11\x63\x64p_version_major\x18\x07 \x01(\r\x12\x19\n\x11\x63\x64p_version_minor\x18\x08 \x01(\r\x12\x19\n\x11\x63\x64p_version_patch\x18\t \x01(\r\x12\x1b\n\x13idle_lockout_period\x18\n \x01(\r\x12\x1f\n\x17system_use_notification\x18\x0b \x01(\t\x12=\n\x0fsuggested_users\x18\x0c \x03(\x0b\x32$.StudioAPI.Proto.Hello.SuggestedUser\x1aG\n\rSuggestedUser\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x12\n\nfirst_name\x18\x02 \x01(\t\x12\x11\n\tlast_name\x18\x03 \x01(\t\"\x9f\x01\n\x0b\x41uthRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12J\n\x12\x63hallenge_response\x18\x02 \x03(\x0b\x32..StudioAPI.Proto.AuthRequest.ChallengeResponse\x1a\x33\n\x11\x43hallengeResponse\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x01(\x0c\"\xc0\x01\n#AdditionalChallengeResponseRequired\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06prompt\x18\x02 \x01(\t\x12Q\n\tparameter\x18\x03 \x03(\x0b\x32>.StudioAPI.Proto.AdditionalChallengeResponseRequired.Parameter\x1a(\n\tParameter\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xd4\x03\n\x0c\x41uthResponse\x12\x41\n\x0bresult_code\x18\x01 \x01(\x0e\x32,.StudioAPI.Proto.AuthResponse.AuthResultCode\x12\x13\n\x0bresult_text\x18\x02 \x01(\t\x12\x64\n&additional_challenge_response_required\x18\x03 \x03(\x0b\x32\x34.StudioAPI.Proto.AdditionalChallengeResponseRequired\x12\x15\n\rrole_assigned\x18\x04 \x03(\t\"\xee\x01\n\x0e\x41uthResultCode\x12\x18\n\x14\x65\x43redentialsRequired\x10\x00\x12\x0c\n\x08\x65Granted\x10\x01\x12\"\n\x1e\x65GrantedPasswordWillExpireSoon\x10\x02\x12\x18\n\x14\x65NewPasswordRequired\x10\n\x12\x1d\n\x19\x65InvalidChallengeResponse\x10\x0b\x12\x1f\n\x1b\x65\x41\x64\x64itionalResponseRequired\x10\x0c\x12\x17\n\x13\x65TemporarilyBlocked\x10\r\x12\x1d\n\x19\x65ReauthenticationRequired\x10\x0e\"\xe7\x08\n\tContainer\x12\x35\n\x0cmessage_type\x18\x01 \x01(\x0e\x32\x1f.StudioAPI.Proto.Container.Type\x12%\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x16.StudioAPI.Proto.Error\x12\x19\n\x11structure_request\x18\x03 \x03(\r\x12\x31\n\x12structure_response\x18\x04 \x03(\x0b\x32\x15.StudioAPI.Proto.Node\x12\x35\n\x0egetter_request\x18\x05 \x03(\x0b\x32\x1d.StudioAPI.Proto.ValueRequest\x12\x36\n\x0fgetter_response\x18\x06 \x03(\x0b\x32\x1d.StudioAPI.Proto.VariantValue\x12\x35\n\x0esetter_request\x18\x07 \x03(\x0b\x32\x1d.StudioAPI.Proto.VariantValue\x12!\n\x19structure_change_response\x18\x08 \x03(\r\x12\x1d\n\x15\x63urrent_time_response\x18\t \x01(\x04\x12\x34\n\x11\x63hild_add_request\x18\n \x03(\x0b\x32\x19.StudioAPI.Proto.ChildAdd\x12:\n\x14\x63hild_remove_request\x18\x0b \x03(\x0b\x32\x1c.StudioAPI.Proto.ChildRemove\x12\x35\n\x0fre_auth_request\x18\x0c \x01(\x0b\x32\x1c.StudioAPI.Proto.AuthRequest\x12\x37\n\x10re_auth_response\x18\r \x01(\x0b\x32\x1d.StudioAPI.Proto.AuthResponse\x12\x34\n\revent_request\x18\x0e \x03(\x0b\x32\x1d.StudioAPI.Proto.EventRequest\x12\x32\n\x0e\x65vent_response\x18\x0f \x03(\x0b\x32\x1a.StudioAPI.Proto.EventInfo\"\xef\x02\n\x04Type\x12\x10\n\x0c\x65RemoteError\x10\x00\x12\x15\n\x11\x65StructureRequest\x10\x01\x12\x16\n\x12\x65StructureResponse\x10\x02\x12\x12\n\x0e\x65GetterRequest\x10\x03\x12\x13\n\x0f\x65GetterResponse\x10\x04\x12\x12\n\x0e\x65SetterRequest\x10\x05\x12\x1c\n\x18\x65StructureChangeResponse\x10\x06\x12\x17\n\x13\x65\x43urrentTimeRequest\x10\x07\x12\x18\n\x14\x65\x43urrentTimeResponse\x10\x08\x12\x14\n\x10\x65\x43hildAddRequest\x10\t\x12\x17\n\x13\x65\x43hildRemoveRequest\x10\n\x12\x12\n\x0e\x65ReauthRequest\x10\x0b\x12\x13\n\x0f\x65ReauthResponse\x10\x0c\x12\x19\n\x15\x65\x41\x63tivityNotification\x10\r\x12\x11\n\reEventRequest\x10\x0e\x12\x12\n\x0e\x65\x45ventResponse\x10\x0f*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"\x81\x01\n\x05\x45rror\x12\x0c\n\x04\x63ode\x18\x01 \x02(\r\x12\x0c\n\x04text\x18\x02 \x01(\t\x12\x0f\n\x07node_id\x18\x03 \x01(\r\x12\x11\n\tparameter\x18\x04 \x01(\t\x12\x11\n\tchallenge\x18\x05 \x01(\x0c\x12\x1b\n\x13idle_lockout_period\x18\x06 \x01(\r*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"\xb6\x03\n\x04Info\x12\x0f\n\x07node_id\x18\x01 \x02(\r\x12\x0c\n\x04name\x18\x02 \x02(\t\x12/\n\tnode_type\x18\x03 \x02(\x0e\x32\x1c.StudioAPI.Proto.CDPNodeType\x12\x31\n\nvalue_type\x18\x04 \x01(\x0e\x32\x1d.StudioAPI.Proto.CDPValueType\x12\x11\n\ttype_name\x18\x05 \x01(\t\x12\x13\n\x0bserver_addr\x18\x06 \x01(\t\x12\x13\n\x0bserver_port\x18\x07 \x01(\r\x12\x10\n\x08is_local\x18\x08 \x01(\x08\x12\r\n\x05\x66lags\x18\t \x01(\r\"\xc2\x01\n\x05\x46lags\x12\t\n\x05\x65None\x10\x00\x12\x0f\n\x0b\x65NodeIsLeaf\x10\x01\x12\x16\n\x12\x65ValueIsPersistent\x10\x02\x12\x14\n\x10\x65ValueIsReadOnly\x10\x04\x12\x14\n\x10\x65NodeIsRemovable\x10\x08\x12\x17\n\x13\x65NodeCanAddChildren\x10\x10\x12\x14\n\x10\x65NodeIsRenamable\x10 \x12\x13\n\x0f\x65NodeIsInternal\x10@\x12\x15\n\x10\x65NodeIsImportant\x10\x80\x01*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"Z\n\x04Node\x12#\n\x04info\x18\x01 \x02(\x0b\x32\x15.StudioAPI.Proto.Info\x12#\n\x04node\x18\x02 \x03(\x0b\x32\x15.StudioAPI.Proto.Node*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"Y\n\x08\x43hildAdd\x12\x16\n\x0eparent_node_id\x18\x01 \x02(\r\x12\x12\n\nchild_name\x18\x02 \x02(\t\x12\x17\n\x0f\x63hild_type_name\x18\x03 \x02(\t*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"C\n\x0b\x43hildRemove\x12\x16\n\x0eparent_node_id\x18\x01 \x02(\r\x12\x12\n\nchild_name\x18\x02 \x02(\t*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"\x92\x02\n\x0cVariantValue\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0f\n\x07\x64_value\x18\x02 \x01(\x01\x12\x0f\n\x07\x66_value\x18\x03 \x01(\x02\x12\x12\n\nui64_value\x18\x04 \x01(\x04\x12\x11\n\ti64_value\x18\x05 \x01(\x12\x12\x10\n\x08ui_value\x18\x06 \x01(\r\x12\x0f\n\x07i_value\x18\x07 \x01(\x11\x12\x10\n\x08us_value\x18\x08 \x01(\r\x12\x0f\n\x07s_value\x18\t \x01(\x11\x12\x10\n\x08uc_value\x18\n \x01(\r\x12\x0f\n\x07\x63_value\x18\x0b \x01(\x11\x12\x0f\n\x07\x62_value\x18\x0c \x01(\x08\x12\x11\n\tstr_value\x18\r \x01(\t\x12\x11\n\ttimestamp\x18\x0e \x01(\x04*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"X\n\x0cValueRequest\x12\x0f\n\x07node_id\x18\x01 \x02(\r\x12\n\n\x02\x66s\x18\x02 \x01(\x01\x12\x0c\n\x04stop\x18\x03 \x01(\x08\x12\x13\n\x0bsample_rate\x18\x04 \x01(\x01*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"N\n\x0c\x45ventRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x15\n\rstarting_from\x18\x02 \x01(\x04\x12\x0c\n\x04stop\x18\x03 \x01(\x08*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"\x90\x03\n\tEventInfo\x12\x0f\n\x07node_id\x18\x01 \x03(\r\x12\n\n\x02id\x18\x02 \x01(\x04\x12\x0e\n\x06sender\x18\x03 \x01(\t\x12\x0c\n\x04\x63ode\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\r\x12\x11\n\ttimestamp\x18\x06 \x01(\x04\x12\x32\n\x04\x64\x61ta\x18\x07 \x03(\x0b\x32$.StudioAPI.Proto.EventInfo.EventData\x12\x1d\n\x15\x61\x63k_handler_node_name\x18\x08 \x01(\t\x12$\n\x1c\x61\x63k_handler_param_data_names\x18\t \x03(\t\x1a(\n\tEventData\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"x\n\tCodeFlags\x12\r\n\taAlarmSet\x10\x01\x12\r\n\teAlarmClr\x10\x02\x12\r\n\teAlarmAck\x10\x04\x12\x0c\n\x08\x65Reprise\x10@\x12\x1d\n\x18\x65SourceObjectUnavailable\x10\x80\x02\x12\x11\n\teNodeBoot\x10\x80\x80\x80\x80\x04*\x08\x08\x64\x10\x80\x80\x80\x80\x02*\xd5\x01\n\x0fRemoteErrorCode\x12\x1a\n\x16\x65\x41UTH_RESPONSE_EXPIRED\x10\x01\x12\x14\n\x10\x65INVALID_REQUEST\x10\n\x12\x1f\n\x1b\x65UNSUPPORTED_CONTAINER_TYPE\x10\x14\x12\x1f\n\x1b\x65VALUE_THROTTLING_OCCURRING\x10\x1e\x12\x1d\n\x19\x65VALUE_THROTTLING_STOPPED\x10\x1f\x12\x15\n\x11\x65\x43HILD_ADD_FAILED\x10(\x12\x18\n\x14\x65\x43HILD_REMOVE_FAILED\x10\x32*\xfb\x01\n\x0b\x43\x44PNodeType\x12\x1a\n\rCDP_UNDEFINED\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x0e\n\nCDP_SYSTEM\x10\x00\x12\x13\n\x0f\x43\x44P_APPLICATION\x10\x01\x12\x11\n\rCDP_COMPONENT\x10\x02\x12\x0e\n\nCDP_OBJECT\x10\x03\x12\x0f\n\x0b\x43\x44P_MESSAGE\x10\x04\x12\x13\n\x0f\x43\x44P_BASE_OBJECT\x10\x05\x12\x10\n\x0c\x43\x44P_PROPERTY\x10\x06\x12\x0f\n\x0b\x43\x44P_SETTING\x10\x07\x12\x0c\n\x08\x43\x44P_ENUM\x10\x08\x12\x10\n\x0c\x43\x44P_OPERATOR\x10\t\x12\x0c\n\x08\x43\x44P_NODE\x10\n\x12\x11\n\rCDP_USER_TYPE\x10\x64*\xbc\x01\n\x0c\x43\x44PValueType\x12\x0e\n\neUNDEFINED\x10\x00\x12\x0b\n\x07\x65\x44OUBLE\x10\x01\x12\x0b\n\x07\x65UINT64\x10\x02\x12\n\n\x06\x65INT64\x10\x03\x12\n\n\x06\x65\x46LOAT\x10\x04\x12\t\n\x05\x65UINT\x10\x05\x12\x08\n\x04\x65INT\x10\x06\x12\x0b\n\x07\x65USHORT\x10\x07\x12\n\n\x06\x65SHORT\x10\x08\x12\n\n\x06\x65UCHAR\x10\t\x12\t\n\x05\x65\x43HAR\x10\n\x12\t\n\x05\x65\x42OOL\x10\x0b\x12\x0b\n\x07\x65STRING\x10\x0c\x12\r\n\teUSERTYPE\x10\x64\x42*\n\x1b\x63om.cdptech.cdpclient.protoB\tStudioAPIH\x03')
|
|
28
|
+
|
|
29
|
+
_globals = globals()
|
|
30
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cdp_pb2', _globals)
|
|
32
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
34
|
+
_globals['DESCRIPTOR']._serialized_options = b'\n\033com.cdptech.cdpclient.protoB\tStudioAPIH\003'
|
|
35
|
+
_globals['_REMOTEERRORCODE']._serialized_start=4098
|
|
36
|
+
_globals['_REMOTEERRORCODE']._serialized_end=4311
|
|
37
|
+
_globals['_CDPNODETYPE']._serialized_start=4314
|
|
38
|
+
_globals['_CDPNODETYPE']._serialized_end=4565
|
|
39
|
+
_globals['_CDPVALUETYPE']._serialized_start=4568
|
|
40
|
+
_globals['_CDPVALUETYPE']._serialized_end=4756
|
|
41
|
+
_globals['_HELLO']._serialized_start=31
|
|
42
|
+
_globals['_HELLO']._serialized_end=462
|
|
43
|
+
_globals['_HELLO_SUGGESTEDUSER']._serialized_start=391
|
|
44
|
+
_globals['_HELLO_SUGGESTEDUSER']._serialized_end=462
|
|
45
|
+
_globals['_AUTHREQUEST']._serialized_start=465
|
|
46
|
+
_globals['_AUTHREQUEST']._serialized_end=624
|
|
47
|
+
_globals['_AUTHREQUEST_CHALLENGERESPONSE']._serialized_start=573
|
|
48
|
+
_globals['_AUTHREQUEST_CHALLENGERESPONSE']._serialized_end=624
|
|
49
|
+
_globals['_ADDITIONALCHALLENGERESPONSEREQUIRED']._serialized_start=627
|
|
50
|
+
_globals['_ADDITIONALCHALLENGERESPONSEREQUIRED']._serialized_end=819
|
|
51
|
+
_globals['_ADDITIONALCHALLENGERESPONSEREQUIRED_PARAMETER']._serialized_start=779
|
|
52
|
+
_globals['_ADDITIONALCHALLENGERESPONSEREQUIRED_PARAMETER']._serialized_end=819
|
|
53
|
+
_globals['_AUTHRESPONSE']._serialized_start=822
|
|
54
|
+
_globals['_AUTHRESPONSE']._serialized_end=1290
|
|
55
|
+
_globals['_AUTHRESPONSE_AUTHRESULTCODE']._serialized_start=1052
|
|
56
|
+
_globals['_AUTHRESPONSE_AUTHRESULTCODE']._serialized_end=1290
|
|
57
|
+
_globals['_CONTAINER']._serialized_start=1293
|
|
58
|
+
_globals['_CONTAINER']._serialized_end=2420
|
|
59
|
+
_globals['_CONTAINER_TYPE']._serialized_start=2043
|
|
60
|
+
_globals['_CONTAINER_TYPE']._serialized_end=2410
|
|
61
|
+
_globals['_ERROR']._serialized_start=2423
|
|
62
|
+
_globals['_ERROR']._serialized_end=2552
|
|
63
|
+
_globals['_INFO']._serialized_start=2555
|
|
64
|
+
_globals['_INFO']._serialized_end=2993
|
|
65
|
+
_globals['_INFO_FLAGS']._serialized_start=2789
|
|
66
|
+
_globals['_INFO_FLAGS']._serialized_end=2983
|
|
67
|
+
_globals['_NODE']._serialized_start=2995
|
|
68
|
+
_globals['_NODE']._serialized_end=3085
|
|
69
|
+
_globals['_CHILDADD']._serialized_start=3087
|
|
70
|
+
_globals['_CHILDADD']._serialized_end=3176
|
|
71
|
+
_globals['_CHILDREMOVE']._serialized_start=3178
|
|
72
|
+
_globals['_CHILDREMOVE']._serialized_end=3245
|
|
73
|
+
_globals['_VARIANTVALUE']._serialized_start=3248
|
|
74
|
+
_globals['_VARIANTVALUE']._serialized_end=3522
|
|
75
|
+
_globals['_VALUEREQUEST']._serialized_start=3524
|
|
76
|
+
_globals['_VALUEREQUEST']._serialized_end=3612
|
|
77
|
+
_globals['_EVENTREQUEST']._serialized_start=3614
|
|
78
|
+
_globals['_EVENTREQUEST']._serialized_end=3692
|
|
79
|
+
_globals['_EVENTINFO']._serialized_start=3695
|
|
80
|
+
_globals['_EVENTINFO']._serialized_end=4095
|
|
81
|
+
_globals['_EVENTINFO_EVENTDATA']._serialized_start=3923
|
|
82
|
+
_globals['_EVENTINFO_EVENTDATA']._serialized_end=3963
|
|
83
|
+
_globals['_EVENTINFO_CODEFLAGS']._serialized_start=3965
|
|
84
|
+
_globals['_EVENTINFO_CODEFLAGS']._serialized_end=4085
|
|
85
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -226,3 +226,47 @@ def create_auth_response_expired_error(challenge):
|
|
|
226
226
|
response.error.text = "Session expired"
|
|
227
227
|
response.error.challenge = challenge
|
|
228
228
|
return response
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
event_info1 = proto.EventInfo()
|
|
232
|
+
event_info1.node_id.append(1)
|
|
233
|
+
event_info1.id = 12345
|
|
234
|
+
event_info1.sender = "App1.Comp1"
|
|
235
|
+
event_info1.code = 1001
|
|
236
|
+
event_info1.timestamp = 1234567890
|
|
237
|
+
data_item1 = event_info1.data.add()
|
|
238
|
+
data_item1.name = "temperature"
|
|
239
|
+
data_item1.value = "25.5"
|
|
240
|
+
data_item2 = event_info1.data.add()
|
|
241
|
+
data_item2.name = "status"
|
|
242
|
+
data_item2.value = "OK"
|
|
243
|
+
|
|
244
|
+
event_info2 = proto.EventInfo()
|
|
245
|
+
event_info2.node_id.append(1)
|
|
246
|
+
event_info2.id = 67890
|
|
247
|
+
event_info2.sender = "App2.Comp2"
|
|
248
|
+
event_info2.code = 2001
|
|
249
|
+
event_info2.timestamp = 1234567900
|
|
250
|
+
|
|
251
|
+
def create_event_request(node_id):
|
|
252
|
+
request = proto.Container()
|
|
253
|
+
request.message_type = proto.Container.eEventRequest
|
|
254
|
+
event_req = request.event_request.add()
|
|
255
|
+
event_req.node_id = node_id
|
|
256
|
+
event_req.stop = False
|
|
257
|
+
return request
|
|
258
|
+
|
|
259
|
+
def create_event_unrequest(node_id):
|
|
260
|
+
request = proto.Container()
|
|
261
|
+
request.message_type = proto.Container.eEventRequest
|
|
262
|
+
event_req = request.event_request.add()
|
|
263
|
+
event_req.node_id = node_id
|
|
264
|
+
event_req.stop = True
|
|
265
|
+
return request
|
|
266
|
+
|
|
267
|
+
def create_event_response(event_info):
|
|
268
|
+
response = proto.Container()
|
|
269
|
+
response.message_type = proto.Container.eEventResponse
|
|
270
|
+
event_resp = response.event_response.add()
|
|
271
|
+
event_resp.CopyFrom(event_info)
|
|
272
|
+
return response
|
|
@@ -275,3 +275,31 @@ class ConnectionTester(unittest.TestCase):
|
|
|
275
275
|
self.assertEqual(self._connection._notification_listener.credentials_requested_call_count, 1)
|
|
276
276
|
self.assertFalse(mock_send.called)
|
|
277
277
|
self.assertFalse(self._connection._is_connected)
|
|
278
|
+
|
|
279
|
+
@mock.patch.object(cdp.websocket.WebSocketApp, 'send')
|
|
280
|
+
@mock.patch.object(cdp.Connection, '_update_time_difference')
|
|
281
|
+
def test_sending_event_request(self, mock_time_update, mock_send):
|
|
282
|
+
node_id = 1
|
|
283
|
+
self._connection.send_event_request(node_id)
|
|
284
|
+
expected_msg = fake_data.create_event_request(node_id).SerializeToString()
|
|
285
|
+
# Debug: check if any message was sent
|
|
286
|
+
self.assertTrue(mock_send.called)
|
|
287
|
+
# Just verify the right type of call was made rather than exact bytes
|
|
288
|
+
calls = mock_send.call_args_list
|
|
289
|
+
self.assertEqual(len(calls), 1)
|
|
290
|
+
|
|
291
|
+
@mock.patch.object(cdp.websocket.WebSocketApp, 'send')
|
|
292
|
+
@mock.patch.object(cdp.Connection, '_update_time_difference')
|
|
293
|
+
def test_sending_event_unrequest(self, mock_time_update, mock_send):
|
|
294
|
+
node_id = 1
|
|
295
|
+
self._connection.send_event_unrequest(node_id)
|
|
296
|
+
mock_send.assert_any_call(fake_data.create_event_unrequest(node_id).SerializeToString())
|
|
297
|
+
|
|
298
|
+
@mock.patch.object(cdp.NodeTree, 'find_by_id')
|
|
299
|
+
@mock.patch.object(cdp.Node, '_update_event')
|
|
300
|
+
def test_node_event_received(self, mock_update_event, mock_find_by_id):
|
|
301
|
+
self._connection._is_connected = True
|
|
302
|
+
mock_find_by_id.return_value = cdp.Node(None, self._connection, fake_data.app1_node)
|
|
303
|
+
response = fake_data.create_event_response(fake_data.event_info1)
|
|
304
|
+
self._connection._handle_container_message(response.SerializeToString())
|
|
305
|
+
mock_update_event.assert_called_once_with(response.event_response[0])
|