Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
107 lines (93 loc) · 4.2 KB

File metadata and controls

107 lines (93 loc) · 4.2 KB
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import inspect
import sys
import unittest
from datetime import datetime
from enum import EnumMeta
from opcua import ua
from opcua.common.structures import StructGenerator, Struct, EnumType
from opcua.ua.ua_binary import struct_to_binary, struct_from_binary
# An ExtensionObject that is decoded becomes a generated class of a custom name.
# The class below represents an example that includes OPC UA optional fields.
class ObjectWithOptionalFields(object):
ua_switches = {
'cavityId': ('BitEncoding0', 0),
'description': ('BitEncoding0', 1),
# This exists in xml but gets ignored because no matching switches.
# 'Reserved1': ('ByteEncoding0', 2)
}
ua_types = [
# The bits fields are not necessary because 'ua_switches' provides us with
# the related bit we care about.
# ('cavityIdSpecified', 'Bit'),
# ('descriptionSpecified', 'Bit'),
# ('Reserved1', 'Bit'),
('BitEncoding0', 'UInt32'),
('name', 'CharArray'),
('value', 'Double'),
('assignment', 'UInt32'),
('source', 'UInt32'),
('cavityId', 'UInt32'),
('id', 'CharArray'),
('description', 'CharArray'),
]
def __str__(self):
vals = [name + ": " + str(val) for name, val in self.__dict__.items()]
return self.__class__.__name__ + "(" + ", ".join(vals) + ")"
__repr__ = __str__
def __init__(self):
self.BitEncoding0 = 0x03
self.name = 'SomeAmazingCycleParameter'
self.value = 8
self.assignment = 8
self.source = 8
self.cavityId = 5
self.id = 'abcdefgh'
self.description = 'BBA'
class CustomStructTestCase(unittest.TestCase):
def setUp(self):
self.identifier_count = 0
def _generate_node_id(self):
self.identifier_count += 1
return f"ns=0;i={self.identifier_count}"
@staticmethod
def is_struct(obj):
# TODO: putting this definition in the generated class would be better
return hasattr(obj, 'ua_types')
def assertCustomStructEqual(self, original, deserialized):
if hasattr(original, 'ua_switches'):
self.assertEqual(len(original.ua_switches), len(deserialized.ua_switches))
self.assertEqual(len(original.ua_types), len(deserialized.ua_types))
for field, _ in original.ua_types:
field_obj = getattr(original, field)
deserialized_obj = getattr(deserialized, field)
if self.is_struct(field_obj):
self.assertCustomStructEqual(field_obj, deserialized_obj)
else:
self.assertEqual(getattr(original, field), getattr(deserialized, field))
def test_binary_struct_example(self):
# Example test so that we can manually control the object that gets
# generated and see how it gets serialized/deserialized
original = ObjectWithOptionalFields()
serialized = struct_to_binary(original)
deserialized = struct_from_binary(ObjectWithOptionalFields, ua.utils.Buffer(serialized))
self.assertEqual(len(original.ua_switches), len(deserialized.ua_switches))
self.assertEqual(len(original.ua_types), len(deserialized.ua_types))
for field, _ in original.ua_types:
self.assertEqual(getattr(original, field), getattr(deserialized, field))
def test_custom_struct_with_optional_fields(self):
xmlpath = "custom_extension_with_optional_fields.xml"
c = StructGenerator()
c.make_model_from_file(xmlpath)
for m in c.model:
if type(m) in (Struct, EnumType):
m.typeid = self._generate_node_id()
c.save_to_file("custom_extension_with_optional_fields.py", register=True)
import como_structures as s
for name, obj in inspect.getmembers(sys.modules[s.__name__], predicate=inspect.isclass):
if name.startswith('__') or obj in (datetime,) or isinstance(obj, EnumMeta):
continue
with self.subTest(name=name):
original = obj()
serialized = struct_to_binary(original)
deserialized = struct_from_binary(obj, ua.utils.Buffer(serialized))
self.assertCustomStructEqual(original, deserialized)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.