Completed
Push — master ( 9dff57...6f1d28 )
by Olivier
01:51 queued 53s
created

UAServer.stop()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
1
import time
2
import logging
3
from threading import Thread
4
5
from PyQt5.QtCore import QSettings
6
7
from opcua import ua
8
from opcua import Server
9
from opcua import Client
10
from opcua.common.xmlexporter import XmlExporter
11
12
logger = logging.getLogger(__name__)
13
14
OPENUA = True
15
try:
16
    import openua
17
except ImportError as ex:
18
    logger.info("Could not import open62541 python wrapper: %s ", ex)
19
    OPENUA = False
20
21
22
class ServerManager(object):
23
    def __init__(self, action):
24
        self._backend = ServerPython()
25
        self._action = action
26
        self._settings = QSettings()
27
28
        if OPENUA:
29
            use_openua = int(self._settings.value("use_openua_server", 0))
30
            logger.info("Using open62541: %s", openua)
31
            self._action.setChecked(use_openua)
32
            self._action.toggled.connect(self._toggle_use_openua)
33
            self._toggle_use_openua(use_openua)  # init state
34
        else:
35
            logger.info("Open62541 python wrappers not available, disabling action")
36
            self._action.setChecked(False)
37
            self._action.setEnabled(False)
38
39
40
    def close(self):
41
        if OPENUA:
42
            self._settings.setValue("use_openua_server", int(self._action.isChecked()))
43
        self.stop_server()
44
45
    def _toggle_use_openua(self, val):
46
        print("SET SERVER", val)
47
        if val:
48
            print("use C")
49
            self._backend = ServerC()
50
        else:
51
            self._backend = ServerPython()
52
53
    @property
54
    def nodes(self):
55
        return self._backend.nodes
56
57
    def get_node(self, node):
58
        return self._backend.get_node(node)
59
60
    def get_namespace_array(self):
61
        return self._backend.get_namespace_array()
62
63
    def start_server(self, endpoint):
64
        self._action.setEnabled(False)
65
        self._backend.start_server(endpoint)
66
67
    def stop_server(self):
68
        self._backend.stop_server()
69
        self._action.setEnabled(True)
70
71
    def import_xml(self, path):
72
        return self._backend.import_xml(path)
73
74
    def export_xml(self, nodes, uris, path):
75
        return self._backend.export_xml(nodes, uris, path)
76
77
78
class ServerPython(object):
79
    def __init__(self):
80
        self._server = None
81
        self.nodes = None
82
        self.get_node = None
83
        self.get_namespace_array = None
84
85
    def start_server(self, endpoint):
86
        self._server = Server()
87
        self._server.set_endpoint(endpoint)
88
        self._server.set_server_name("OpcUa Modeler Server")
89
        self.nodes = self._server.nodes
90
        self.get_node = self._server.get_node
91
        self.get_namespace_array = self._server.get_namespace_array
92
        # now remove freeopcua namespace, not necessary when modeling and
93
        # ensures correct idx for exported nodesets
94
        ns_node = self._server.get_node(ua.NodeId(ua.ObjectIds.Server_NamespaceArray))
95
        nss = ns_node.get_value()
96
        ns_node.set_value(nss[1:])
97
        self._server.start()
98
99
    def stop_server(self):
100
        if self._server is not None:
101
            self._server.stop()
102
            self._server = None
103
104
    def import_xml(self, path):
105
        return self._server.import_xml(path)
106
107
    def export_xml(self, nodes, uris, path):
108
        exp = XmlExporter(self._server)
109
        exp.build_etree(nodes, uris=uris)
110
        exp.write_xml(path)
111
112
113
class UAServer(Thread):
114
    def __init__(self):
115
        Thread.__init__(self)
116
        self.server = openua.Server()
117
        self.status = None
118
        self.endpoint = None
119
120
    def run(self):
121
        print("start server")
122
        self.status = self.server.run(self.endpoint)
123
        print("server stopped")
124
125
    def stop(self):
126
        print("trying to stop server")
127
        self.server.stop()
128
129
130
class ServerC(object):
131
    def __init__(self):
132
        self._server = None
133
        self._client = None
134
        self.nodes = None
135
        self.get_node = None
136
        self.get_namespace_array = None
137
138
    def start_server(self, endpoint):
139
        self._server = UAServer()
140
        self._server.endpoint = 48400  # enpoint not supported yet
141
        #self._server.endpoint = endpoint
142
        self._server.start()
143
        #self._server.set_server_name("OpcUa Modeler Server")
144
        time.sleep(0.2)
145
        self._client = Client(endpoint)
146
        self._client.connect()
147
148
        self.nodes = self._client.nodes
149
        self.get_node = self._client.get_node
150
        self.get_namespace_array = self._client.get_namespace_array
151
        # now remove freeopcua namespace, not necessary when modeling and
152
        # ensures correct idx for exported nodesets
153
        ns_node = self._client.get_node(ua.NodeId(ua.ObjectIds.Server_NamespaceArray))
154
        nss = ns_node.get_value()
155
        #ns_node.set_value(nss[1:])
156
157
    def stop_server(self):
158
        if self._server is not None:
159
            self._client.disconnect()
160
            self._client = None
161
            self._server.stop()
162
            time.sleep(0.2)
163
            self._server = None
164
165
    def import_xml(self, path):
166
        return self._client.import_xml(path)
167
168
    def export_xml(self, nodes, uris, path):
169
        exp = XmlExporter(self._client)
170
        exp.build_etree(nodes, uris=uris)
171
        exp.write_xml(path)
172
173