def conn_opc(): # OPCサーバに接続 cl = Client("opc.tcp://192.168.10.5:51110/CogentDataHub/DataAccess") # クライアント証明書のapplication_uri cl.application_uri = "urn:desktop-i50i89m:Cogent DataHub" # policy設定 print("secPolicy: " + str(secPolicy)) if secPolicy != policies[0]: # None以外の場合SecurityPolicyを設定 mode = ua.MessageSecurityMode.SignAndEncrypt pc = getattr(security_policies, 'SecurityPolicy' + secPolicy) # 第二引数:クライアント証明書 cl.set_security( pc, "/Users/watarium/PycharmProjects/opcua/OPCUA_CL.der", "/Users/watarium/PycharmProjects/opcua/OPCUAClient.pem", "/Users/watarium/PycharmProjects/opcua/OPCUAServer.der", mode) # 認証設定 if setCert == certs[1]: # user/pass cl.set_user("admin") cl.set_password("1234") elif setCert == certs[2]: # certificate cl.load_private_key( "/Users/watarium/PycharmProjects/opcua/OPCUAClient.pem") cl.load_client_certificate( "/Users/watarium/PycharmProjects/opcua/OPCUA_CL.der") try: # 接続 print("Policy: {0}, Certificate: {1}".format(secPolicy, setCert)) print("---------------------Connection start-----------------------") cl.connect() sleep(5) # 情報取得 ep = cl.get_endpoints() print(ep[0].Server.ApplicationUri) root = cl.get_root_node() print("Objects node is: ", root) print(cl.get_namespace_array()) print(cl.get_namespace_index('urn:win-9hi38ajrojd:Cogent DataHub')) #これがうまくいかなかった(2019/06/27) #node = cl.get_node('ns=1;s=xxxxx') #print(node.get_value()) #node.set_attribute(ua.AttributeIds.Value, 1) # 切断 cl.disconnect() print("-------------------Connection Success!!!--------------------") except Exception as e: print("---------------------Connection Faild!!---------------------") print(e) cl.disconnect()
def test_basic256_encrypt_feil(self): # FIXME: how to make it feil??? clt = Client(self.uri_crypto) with self.assertRaises(ua.UaError): clt.set_security(security_policies.SecurityPolicyBasic256, 'examples/certificate-example.der', 'examples/private-key-example.pem', None, ua.MessageSecurityMode.None_)
def test_basic256_encrypt_feil(self): # FIXME: how to make it feil??? clt = Client(self.uri_crypto) with self.assertRaises(ua.UaError): clt.set_security(security_policies.SecurityPolicyBasic256, 'examples/certificate-example.der', 'examples/private-key-example.pem', None, ua.MessageSecurityMode.None_ )
def test_basic256_encrypt_success(self): clt = Client(self.uri_crypto) try: clt.set_security(security_policies.SecurityPolicyBasic256, 'examples/certificate-example.der', 'examples/private-key-example.pem', None, ua.MessageSecurityMode.SignAndEncrypt) clt.connect() self.assertTrue(clt.get_objects_node().get_children()) finally: clt.disconnect()
def test_basic256_encrypt_success(self): clt = Client(self.uri_crypto) try: clt.set_security(security_policies.SecurityPolicyBasic256, 'examples/certificate-example.der', 'examples/private-key-example.pem', None, ua.MessageSecurityMode.SignAndEncrypt ) clt.connect() self.assertTrue(clt.get_objects_node().get_children()) finally: clt.disconnect()
class UaClient(object): """ OPC-Ua client specialized for the need of GUI client return exactly what GUI needs, no customization possible """ def __init__(self): self.settings = QSettings() self.client = None self._connected = False self._datachange_sub = None self._event_sub = None self._subs_dc = {} self._subs_ev = {} self.security_mode = None self.security_policy = None self.certificate_path = None self.private_key_path = None @staticmethod def get_endpoints(uri): client = Client(uri, timeout=2) client.connect_and_get_server_endpoints() edps = client.connect_and_get_server_endpoints() for i, ep in enumerate(edps, start=1): logger.info('Endpoint %s:', i) for (n, v) in endpoint_to_strings(ep): logger.info(' %s: %s', n, v) logger.info('') return edps def load_security_settings(self, uri): self.security_mode = None self.security_policy = None self.certificate_path = None self.private_key_path = None mysettings = self.settings.value("security_settings", None) if mysettings is None: return if uri in mysettings: mode, policy, cert, key = mysettings[uri] self.security_mode = mode self.security_policy = policy self.certificate_path = cert self.private_key_path = key def save_security_settings(self, uri): mysettings = self.settings.value("security_settings", None) if mysettings is None: mysettings = {} mysettings[uri] = [ self.security_mode, self.security_policy, self.certificate_path, self.private_key_path ] self.settings.setValue("security_settings", mysettings) def get_node(self, nodeid): return self.client.get_node(nodeid) def connect(self, uri): self.disconnect() logger.info("Connecting to %s with parameters %s, %s, %s, %s", uri, self.security_mode, self.security_policy, self.certificate_path, self.private_key_path) self.client = Client(uri) if self.security_mode is not None and self.security_policy is not None: self.client.set_security(getattr( crypto.security_policies, 'SecurityPolicy' + self.security_policy), self.certificate_path, self.private_key_path, mode=getattr(ua.MessageSecurityMode, self.security_mode)) self.client.connect() self._connected = True self.save_security_settings(uri) def disconnect(self): if self._connected: print("Disconnecting from server") self._subs_dc = {} self._subs_ev = {} self._connected = False self.client.disconnect() self.client = None def subscribe_datachange(self, node, handler): if not self._datachange_sub: self._datachange_sub = self.client.create_subscription( 500, handler) handle = self._datachange_sub.subscribe_data_change(node) self._subs_dc[node.nodeid] = handle return handle def unsubscribe_datachange(self, node): self._datachange_sub.unsubscribe(self._subs_dc[node.nodeid]) def subscribe_events(self, node, handler): if not self._event_sub: print("subscirbing with handler: ", handler, dir(handler)) self._event_sub = self.client.create_subscription(500, handler) handle = self._event_sub.subscribe_events(node) self._subs_ev[node.nodeid] = handle return handle def unsubscribe_events(self, node): self._event_sub.unsubscribe(self._subs_ev[node.nodeid]) def get_node_attrs(self, node): if not isinstance(node, Node): node = self.client.get_node(node) attrs = node.get_attributes([ ua.AttributeIds.DisplayName, ua.AttributeIds.BrowseName, ua.AttributeIds.NodeId ]) return node, [attr.Value.Value.to_string() for attr in attrs] @staticmethod def get_children(node): descs = node.get_children_descriptions() descs.sort(key=lambda x: x.BrowseName) return descs
class ClientController: def __init__(self, view): self.ui = view self.client = None self._connected = False self.address_list = ["opc.tcp://10.42.0.2:4840/OPCUAproject"] self.security_mode = None self.security_policy = None self.certificate_path = None self.private_key_path = None self.ui.closeEvent = self.closeEvent for addr in self.address_list: self.ui.addressComboBox.addItem(addr) self.tree_ui = TreeWidget(self.ui.treeView) self.attrs_ui = AttrsWidget(self.ui.attrView) #self.refs_ui = RefsWidget(self.ui.refView) self.subscription_window = SubscriptionWindow() self.log_window = LogWindow() self.datachange_ui = DataChangeUI(self, self.subscription_window) #self.ui.treeView.selectionModel().selectionChanged.connect(lambda sel: self.show_refs(sel)) self.ui.treeView.selectionModel().selectionChanged.connect( lambda sel: self.show_attrs(sel)) # self.ui.endpointsButton.clicked.connect(lambda : self.get_endpoints()) # self.ui.connSettingsButton.clicked.connect(lambda : self.show_connection_dialog()) # self.ui.connectButton.clicked.connect(lambda : self.connect()) # self.ui.disconnectButton.clicked.connect(lambda: self.disconnect()) # self.ui.readButton.clicked.connect(lambda : self.read_value()) # self.ui.writeButton.clicked.connect(lambda : self.show_write_dialog()) # self.ui.showReferencesButton.clicked.connect(lambda : self.show_refs_dialog()) # self.ui.showSubscriptionsButton.clicked.connect(lambda : self.show_subs_dialog()) # self.ui.showLogsButton.clicked.connect(lambda : self.show_logs_dialog()) self.ui.actionQuery_endpoints.triggered.connect( lambda: self.get_endpoints()) self.ui.actionConnection_settings.triggered.connect( lambda: self.show_connection_dialog()) self.ui.actionConnect.triggered.connect(lambda: self.connect()) self.ui.actionDisconnect.triggered.connect(lambda: self.disconnect()) self.ui.actionRead.triggered.connect(lambda: self.read_value()) self.ui.actionWrite.triggered.connect(lambda: self.show_write_dialog()) self.ui.actionReferences.triggered.connect( lambda: self.show_refs_dialog()) self.ui.actionSubscriptions.triggered.connect( lambda: self.show_subs_dialog()) self.ui.actionLogs.triggered.connect(lambda: self.show_logs_dialog()) def closeEvent(self, event): self.disconnect() def get_endpoints(self): uri = self.ui.addressComboBox.currentText() client = Client(uri, timeout=2) try: edps = client.connect_and_get_server_endpoints() for i, ep in enumerate(edps, start=1): self.log_window.ui.logTextEdit.append('Endpoint %s:' % i) for (n, v) in endpoint_to_strings(ep): self.log_window.ui.logTextEdit.append(' %s: %s' % (n, v)) self.log_window.ui.logTextEdit.append('') except Exception as ex: self.log_window.ui.logTextEdit.append(str(ex)) raise return edps def show_connection_dialog(self): dia = ConnectionDialog(self, self.ui.addressComboBox.currentText()) #dia.security_mode = self.security_mode #dia.security_policy = self.security_policy #dia.certificate_path = self.certificate_path #dia.private_key_path = self.private_key_path ret = dia.exec_() if ret: #self.security_mode = dia.security_mode #self.security_policy = dia.security_policy self.certificate_path = dia.certificate_path self.private_key_path = dia.private_key_path def show_write_dialog(self): node = self.get_current_node() if node.get_node_class() == ua.NodeClass.Variable: dia = WriteDialog(node, self.log_window.ui.logTextEdit) ret = dia.exec_() else: self.log_window.ui.logTextEdit.append( "Only Variable can be written") def connect(self): self.disconnect() uri = self.ui.addressComboBox.currentText() self.log_window.ui.logTextEdit.append( "Connecting to %s with parameters %s, %s, %s, %s" % (uri, self.security_mode, self.security_policy, self.certificate_path, self.private_key_path)) try: self.client = Client(uri) self.client.application_uri = "urn:opcua:python:client" if self.security_mode is not None and self.security_policy is not None: self.client.set_security(getattr( crypto.security_policies, 'SecurityPolicy' + self.security_policy), self.certificate_path, self.private_key_path, mode=getattr(ua.MessageSecurityMode, self.security_mode)) self.client.connect() self._connected = True except Exception as ex: self.log_window.ui.logTextEdit.append(str(ex)) try: self.client.uaclient._uasocket._thread.isAlive() self.tree_ui.set_root_node(self.client.get_root_node()) self.ui.treeView.setFocus() except Exception as ex: print("Connection error") def _reset(self): self.client = None self._connected = False self.datachange_ui._datachange_sub = {} self.datachange_ui._subs_dc = {} def disconnect(self): try: if self._connected: self.log_window.ui.logTextEdit.append( "Disconnecting from server") self._connected = False if self.client: if self.datachange_ui._datachange_sub: sub_ids = list(self.datachange_ui._datachange_sub.keys()) for sub_id in sub_ids: self.datachange_ui.delete_subscription(sub_id) self.client.disconnect() self._reset() except Exception as ex: self.log_window.ui.logTextEdit.append(str(ex)) finally: self.tree_ui.clear() #self.refs_ui.clear() self.attrs_ui.clear() self.datachange_ui.clear() def show_attrs(self, selection): if isinstance(selection, QItemSelection): if not selection.indexes(): # no selection return node = self.get_current_node() if node: self.attrs_ui.show_attrs(node) '''def show_refs(self, selection): if isinstance(selection, QItemSelection): if not selection.indexes(): # no selection return node = self.get_current_node() if node: self.refs_ui.show_refs(node)''' def show_refs_dialog(self): self.references_window = ReferencesWindow(self) self.references_window.show() def show_subs_dialog(self): self.subscription_window.show() def show_logs_dialog(self): self.log_window.show() def get_current_node(self, idx=None): return self.tree_ui.get_current_node(idx) def read_value(self): node = self.get_current_node() try: self.attrs_ui.show_attrs(node) if node.get_node_class() == ua.NodeClass.Variable: value = node.get_value() data = "Node: %s, Value: %s" % (node.get_browse_name(), value) self.log_window.ui.logTextEdit.append(data) except Exception as ex: self.log_window.ui.logTextEdit.append(str(ex))
import sys sys.path.insert(0, "..") from opcua import Client, ua from opcua.crypto import security_policies if __name__ == "__main__": client = Client("opc.tcp://*****:*****@localhost:4840/freeopcua/server/") #connect using a user try: client.connect() # Client has a few methods to get proxy to UA nodes that should always be in address space such as Root or Objects root = client.get_root_node() print("Objects node is: ", root) # Node objects have methods to read and write node attributes as well as browse or populate address space print("Children of root are: ", root.get_children()) # get a specific node knowing its node id #var = client.get_node(ua.NodeId(1002, 2)) #var = client.get_node("ns=3;i=2002") #print(var)
policy = uasecurity.get_securitypolicy() if server_cert == None: print( 'tls is enabled, but server cert is missing with current configuration' ) sys.exit(-1) if private_key == None: print( 'tls is enabled, but private key is missing with current configuration' ) sys.exit(-1) #client.load_client_certificate(server_cert) #client.load_private_key(private_key) client.set_security(getattr(crypto.security_policies, 'SecurityPolicy' + policy), server_cert, private_key, mode=getattr(ua.MessageSecurityMode, mode)) try: client.connect() # Client has a few methods to get proxy to UA nodes that should always be in address space such as Root or Objects root = client.get_root_node() print("Root node is: ", root) objects = client.get_objects_node() print("Objects node is: ", objects) # Node objects have methods to read and write node attributes as well as browse or populate address space print("Children of root are: ", root.get_children())
class UaClient(object): """ OPC-Ua client specialized for the need of GUI client return exactly what GUI needs, no customization possible """ def __init__(self): self.settings = QSettings() self.client = None self._connected = False self._datachange_sub = None self._event_sub = None self._subs_dc = {} self._subs_ev = {} self.security_mode = None self.security_policy = None self.certificate_path = None self.private_key_path = None def _reset(self): self.client = None self._connected = False self._datachange_sub = None self._event_sub = None self._subs_dc = {} self._subs_ev = {} @staticmethod def get_endpoints(uri): client = Client(uri, timeout=2) client.connect_and_get_server_endpoints() edps = client.connect_and_get_server_endpoints() for i, ep in enumerate(edps, start=1): logger.info('Endpoint %s:', i) for (n, v) in endpoint_to_strings(ep): logger.info(' %s: %s', n, v) logger.info('') return edps def load_security_settings(self, uri): self.security_mode = None self.security_policy = None self.certificate_path = None self.private_key_path = None mysettings = self.settings.value("security_settings", None) if mysettings is None: return if uri in mysettings: mode, policy, cert, key = mysettings[uri] self.security_mode = mode self.security_policy = policy self.certificate_path = cert self.private_key_path = key def save_security_settings(self, uri): mysettings = self.settings.value("security_settings", None) if mysettings is None: mysettings = {} mysettings[uri] = [self.security_mode, self.security_policy, self.certificate_path, self.private_key_path] self.settings.setValue("security_settings", mysettings) def get_node(self, nodeid): return self.client.get_node(nodeid) def connect(self, uri): self.disconnect() logger.info("Connecting to %s with parameters %s, %s, %s, %s", uri, self.security_mode, self.security_policy, self.certificate_path, self.private_key_path) self.client = Client(uri) if self.security_mode is not None and self.security_policy is not None: self.client.set_security( getattr(crypto.security_policies, 'SecurityPolicy' + self.security_policy), self.certificate_path, self.private_key_path, mode=getattr(ua.MessageSecurityMode, self.security_mode) ) self.client.connect() self._connected = True self.save_security_settings(uri) def disconnect(self): if self._connected: print("Disconnecting from server") self._connected = False try: self.client.disconnect() finally: self._reset() def subscribe_datachange(self, node, handler): if not self._datachange_sub: self._datachange_sub = self.client.create_subscription(500, handler) handle = self._datachange_sub.subscribe_data_change(node) self._subs_dc[node.nodeid] = handle return handle def unsubscribe_datachange(self, node): self._datachange_sub.unsubscribe(self._subs_dc[node.nodeid]) def subscribe_events(self, node, handler): if not self._event_sub: print("subscirbing with handler: ", handler, dir(handler)) self._event_sub = self.client.create_subscription(500, handler) handle = self._event_sub.subscribe_events(node) self._subs_ev[node.nodeid] = handle return handle def unsubscribe_events(self, node): self._event_sub.unsubscribe(self._subs_ev[node.nodeid]) def get_node_attrs(self, node): if not isinstance(node, Node): node = self.client.get_node(node) attrs = node.get_attributes([ua.AttributeIds.DisplayName, ua.AttributeIds.BrowseName, ua.AttributeIds.NodeId]) return node, [attr.Value.Value.to_string() for attr in attrs] @staticmethod def get_children(node): descs = node.get_children_descriptions() descs.sort(key=lambda x: x.BrowseName) return descs
class OpcUaClient: def __init__(self): self.settings = QSettings() self.client = None self._connected = False # Subscriptions self._datachange_subs = [ ] # list of tuples with subscription and dict with nodeids as keys and handles as values self.publishingEnabled = True # Not necessary self.requestedPublishingInterval = 500 self.publishingIntervals = [] self.requestedMaxKeepAliveCount = 3000 self.requestedLifetimeCount = 10000 self.maxNotificationsPerPublish = 10000 self.priority = 0 # Monitored items self._client_handle = 0 self.samplingInterval = self.requestedPublishingInterval self.queueSize = 0 self.discardOldest = True self.dataChangeFilter = False self.dataChangeTrigger = ua.DataChangeTrigger.StatusValue # 0 = Status, 1 = StatusValue, 2 = StatusValueTimestamp self.deadbandType = ua.DeadbandType.None_ # 0 = None, 1 = Absolute, 2 = Percent self.deadbandValue = 0 self.numericTypes = [ ua.VariantType.SByte, ua.VariantType.Byte, ua.VariantType.Int16, ua.VariantType.UInt16, ua.VariantType.Int32, ua.VariantType.UInt32, ua.VariantType.Int64, ua.VariantType.UInt64, ua.VariantType.Float, ua.VariantType.Double ] # Security self.security_mode = "None" self.security_policy = "None" self.certificate_path = "" self.private_key_path = "" # Custom objects self.custom_objects = {} self.known_custom_types = [ "BoilerType", "MotorType", "ValveType", "TempSensorType", "LevelIndicatorType", "FlowSensorType" ] def _reset(self): self.client = None self._connected = False self._datachange_subs = [] self.custom_objects = {} @staticmethod def get_endpoints(uri): # Create client object and associate url of the server client = Client(uri) # Connect, ask server for endpoints, and disconnect edps = client.connect_and_get_server_endpoints() for i, ep in enumerate(edps, start=1): logger.info('Endpoint %s:', i) for n, v in endpoint_to_strings(ep): logger.info(' %s: %s', n, v) logger.info('') return edps def connect(self, uri): logger.info("Connecting to %s with parameters %s, %s, %s, %s", uri, self.security_mode, self.security_policy, self.certificate_path, self.private_key_path) # Create client object and associate url of the server self.client = Client(uri) if self.security_mode != "None" and self.security_policy != "None": # Set SecureConnection mode self.client.set_security(getattr( crypto.security_policies, 'SecurityPolicy' + self.security_policy), self.certificate_path, self.private_key_path, mode=getattr(ua.MessageSecurityMode, self.security_mode)) # self.client.secure_channel_timeout = 10000 # Timeout for the secure channel # self.client.session_timeout = 10000 # Timeout for the session self.client.application_uri = "urn:example.org:OpcUa:python-client" # Open secure channel, create and activate session self.client.connect() self._connected = True self.save_security_settings(uri) def disconnect(self): if self._connected: print("Disconnecting from server") self._connected = False try: # Close session and secure channel self.client.disconnect() finally: self._reset() def create_subscription(self, handler): # Set subscription parameters params = ua.CreateSubscriptionParameters() params.PublishingEnabled = self.publishingEnabled params.RequestedPublishingInterval = self.requestedPublishingInterval params.RequestedMaxKeepAliveCount = self.requestedMaxKeepAliveCount params.RequestedLifetimeCount = self.requestedLifetimeCount params.MaxNotificationsPerPublish = self.maxNotificationsPerPublish params.Priority = self.priority datachange_sub = self.client.create_subscription(params, handler) self._datachange_subs.append((datachange_sub, {})) self.publishingIntervals.append(self.requestedPublishingInterval) def create_monitored_items(self, nodes, index): monitored_items = [] if not isinstance(nodes, list): nodes = [nodes] for node in nodes: # Set item to monitor rv = ua.ReadValueId() rv.NodeId = node.nodeid rv.AttributeId = ua.AttributeIds.Value # Set monitoring parameters mparams = ua.MonitoringParameters() self._client_handle += 1 mparams.ClientHandle = self._client_handle mparams.SamplingInterval = self.samplingInterval mparams.QueueSize = self.queueSize mparams.DiscardOldest = self.discardOldest # Create monitored item filter if self.dataChangeFilter: mfilter = ua.DataChangeFilter() mfilter.Trigger = ua.DataChangeTrigger(self.dataChangeTrigger) if self.deadbandType == ua.DeadbandType.Absolute: if node.get_data_value( ).Value.VariantType in self.numericTypes: mfilter.DeadbandType = self.deadbandType mfilter.DeadbandValue = self.deadbandValue # absolute float value or from 0 to 100 for percentage deadband else: self.deadbandType = ua.DeadbandType.None_ mfilter.DeadbandType = self.deadbandType elif self.deadbandType == ua.DeadbandType.Percent: has_EURange = False if node.get_type_definition( ).Identifier == ua.object_ids.ObjectIds.AnalogItemType: # Get node properties descriptions = node.get_references( ua.ObjectIds.HasProperty, ua.BrowseDirection.Forward, ua.NodeClass.Variable, False) for desc in descriptions: if desc.BrowseName.Name == "EURange" and self.get_node( desc.NodeId).get_value() is not None: has_EURange = True if has_EURange: mfilter.DeadbandType = self.deadbandType mfilter.DeadbandValue = self.deadbandValue # absolute float value or from 0 to 100 for percentage deadband else: self.deadbandType = ua.DeadbandType.None_ mfilter.DeadbandType = self.deadbandType else: mfilter = None mparams.Filter = mfilter # Create monitored item request mir = ua.MonitoredItemCreateRequest() mir.ItemToMonitor = rv mir.MonitoringMode = ua.MonitoringMode.Reporting mir.RequestedParameters = mparams # Append to list monitored_items.append(mir) sub, monitored_items_handles = self._datachange_subs[index] handles = sub.create_monitored_items(monitored_items) for i in range(len(handles)): handle = handles[i] if type(handle) == ua.StatusCode: handle.check() monitored_items_handles[nodes[i].nodeid] = handle def remove_monitored_item(self, node, index): # Unsubscribe to data change using the handle stored while creating monitored item # This will remove the corresponding monitored item from subscription sub, monitored_items_handles = self._datachange_subs[index] sub.unsubscribe(monitored_items_handles[node.nodeid]) del monitored_items_handles[node.nodeid] def delete_subscription(self, index): sub, monitored_items_handles = self._datachange_subs[index] # Remove all monitored items from subscription for handle in monitored_items_handles.values(): sub.unsubscribe(handle) # Delete subscription on server sub.delete() del self._datachange_subs[index] del self.publishingIntervals[index] def delete_subscriptions(self): for sub, monitored_items_handles in self._datachange_subs: # Remove all monitored items from subscription for handle in monitored_items_handles.values(): sub.unsubscribe(handle) # Delete subscription on server sub.delete() def get_node(self, nodeid): # Get node using NodeId object or a string representing a NodeId return self.client.get_node(nodeid) def load_custom_objects(self): """ Function that populates custom_objects dictionary, with nodeids of custom objects as keys and string representations of their types as values """ # Get Objects folder objects_folder = self.client.get_objects_node() # Get Organize references to objects inside folder descriptions = objects_folder.get_references( ua.ObjectIds.Organizes, ua.BrowseDirection.Forward, ua.NodeClass.Object, False) for desc in descriptions: if desc.TypeDefinition == ua.TwoByteNodeId( ua.ObjectIds.FolderType): folder_name = desc.BrowseName.Name if folder_name == "Actuators" or folder_name == "Sensors": # Get folder node folder_node = self.get_node(desc.NodeId) # Get all objects inside folder objects = folder_node.get_children(ua.ObjectIds.Organizes, ua.NodeClass.Object) for obj in objects: # Get HasTypeDefinition references ref = obj.get_references( ua.ObjectIds.HasTypeDefinition, ua.BrowseDirection.Forward, ua.NodeClass.ObjectType, False)[0] custom_type = ref.BrowseName.Name if custom_type in self.known_custom_types: self.custom_objects[obj.nodeid] = custom_type def load_security_settings(self, uri): mysettings = self.settings.value("security_settings", None) if mysettings is not None and uri in mysettings: mode, policy, cert, key = mysettings[uri] self.security_mode = mode self.security_policy = policy self.certificate_path = cert self.private_key_path = key else: self.security_mode = "None" self.security_policy = "None" self.certificate_path = "" self.private_key_path = "" def save_security_settings(self, uri): mysettings = self.settings.value("security_settings", None) if mysettings is None: mysettings = {} mysettings[uri] = [ self.security_mode, self.security_policy, self.certificate_path, self.private_key_path ] self.settings.setValue("security_settings", mysettings) def load_subscription_settings(self, uri): mysettings = self.settings.value("subscription_settings", None) if mysettings is not None and uri in mysettings: pub_interval, max_keepalive_count, lifetime_count, max_notifications, priority = mysettings[ uri] self.requestedPublishingInterval = pub_interval self.requestedMaxKeepAliveCount = max_keepalive_count self.requestedLifetimeCount = lifetime_count self.maxNotificationsPerPublish = max_notifications self.priority = priority else: self.requestedPublishingInterval = 500 self.requestedMaxKeepAliveCount = 3000 self.requestedLifetimeCount = 10000 self.maxNotificationsPerPublish = 10000 self.priority = 0 def save_subscription_settings(self, uri): mysettings = self.settings.value("subscription_settings", None) if mysettings is None: mysettings = {} mysettings[uri] = [ self.requestedPublishingInterval, self.requestedMaxKeepAliveCount, self.requestedLifetimeCount, self.maxNotificationsPerPublish, self.priority ] self.settings.setValue("subscription_settings", mysettings) def load_monitored_items_settings(self, uri): mysettings = self.settings.value("monitored_items_settings", None) if mysettings is not None and uri in mysettings: sampling_interval, queue_size, discard_oldest, data_change_filter, trigger, deadband_type, deadband_value = mysettings[ uri] self.samplingInterval = sampling_interval self.queueSize = queue_size self.discardOldest = discard_oldest self.dataChangeFilter = data_change_filter self.dataChangeTrigger = trigger self.deadbandType = deadband_type self.deadbandValue = deadband_value else: self.samplingInterval = 250 self.queueSize = 0 self.discardOldest = True self.dataChangeFilter = False self.dataChangeTrigger = ua.DataChangeTrigger.StatusValue self.deadbandType = ua.DeadbandType.None_ self.deadbandValue = 0 def save_monitored_items_settings(self, uri): mysettings = self.settings.value("monitored_items_settings", None) if mysettings is None: mysettings = {} mysettings[uri] = [ self.samplingInterval, self.queueSize, self.discardOldest, self.dataChangeFilter, self.dataChangeTrigger, self.deadbandType, self.deadbandValue ] self.settings.setValue("monitored_items_settings", mysettings)
class OpcUaConnector(object): """The connector to OPC UA. This class manages all comms with DCS""" def __init__(self, app=None): self.app = app self._client = None if app is not None: self.init_app(app) def init_app(self, app): config = current_app.config if config is not None: self._server_address = config['OPC_SERVER_ADDRESS'] self._client_name = config['OPC_CLIENT_NAME'] self._client_description = config['OPC_CLIENT_DESCRIPTION'] self._certificate_path = config['OPC_CERTIFICATE_PATH'] self._private_key_path = config['OPC_PRIVATE_KEY_PATH'] self._application_uri = config['OPC_APPLICATION_URI'] self._max_time_out = config['OPC_MAX_TIME_OUT'] self._client = None def _connect(self): self._client = Client(self._server_address, self._max_time_out) if (self._certificate_path is not None and self._private_key_path is not None): self._client.set_security( getattr( crypto.security_policies, 'SecurityPolicy' + 'Basic256'), self._certificate_path, self._private_key_path, mode=getattr(ua.MessageSecurityMode, 'SignAndEncrypt')) self._client.application_uri = self._application_uri self._client.name = self._client_name self._client.description = self._client_description self._client.connect() # return _client def ensure_connection(self): if self._client is None: self._connect() def set_value(self, node_id, value_type_identifier, desired_value): """Set value on the OPC UA server. example parameters: Node_id=ns=4;s=node_name, value_type_identifier 0-25 see: https://github.com/FreeOpcUa/python-opcua/blob/master/opcua/ua/uatypes.py#L619), desired_value could be any value that matches the UA Type """ parsed_value, opc_type = map_to_opcua_type_and_value( value_type_identifier, desired_value) self.ensure_connection() node = self._client.get_node(node_id) dv = ua.DataValue(ua.Variant(parsed_value, opc_type)) node.set_value(dv) def get_value(self, node_id): self.ensure_connection() node = self._client.get_node(node_id) value = node.get_value() return str(value) def disconnect(self): if self._client is not None: self._client.disconnect()