def __init__(self, isession, etype=ObjectIds.BaseEventType, source=ObjectIds.Server): self.isession = isession if isinstance(etype, Node): self.node = etype elif isinstance(etype, ua.NodeId): self.node = Node(self.isession, etype) else: self.node = Node(self.isession, ua.NodeId(etype)) self.set_members_from_node(self.node) if isinstance(source, Node): self.SourceNode = source.NodeId elif isinstance(etype, ua.NodeId): self.SourceNode = source.NodeId else: self.SourceNode = ua.NodeId(source) # set some default values for attributes from BaseEventType, thus that all event must have self.EventId = uuid.uuid4().bytes self.EventType = self.node.nodeid self.LocaleTime = datetime.now() self.ReceiveTime = datetime.now() self.Time = datetime.now() self.Message = ua.LocalizedText() self.Severity = ua.Variant(1, ua.VariantType.UInt16) self.SourceName = "Server" # og set some node attributed we also are expected to have self.BrowseName = self.node.get_browse_name() self.DisplayName = self.node.get_display_name() self.NodeId = self.node.nodeid self.NodeClass = self.node.get_node_class() self.Description = self.node.get_description()
def _instantiate_node(server, parentid, rdesc, nodeid, bname, recursive=True): """ instantiate a node type under parent """ addnode = ua.AddNodesItem() addnode.RequestedNewNodeId = nodeid addnode.BrowseName = bname addnode.ParentNodeId = parentid addnode.ReferenceTypeId = rdesc.ReferenceTypeId addnode.TypeDefinition = rdesc.TypeDefinition node_type = Node(server, rdesc.NodeId) if rdesc.NodeClass in (ua.NodeClass.Object, ua.NodeClass.ObjectType): addnode.NodeClass = ua.NodeClass.Object _read_and_copy_attrs(node_type, ua.ObjectAttributes(), addnode) elif rdesc.NodeClass in (ua.NodeClass.Variable, ua.NodeClass.VariableType): addnode.NodeClass = ua.NodeClass.Variable _read_and_copy_attrs(node_type, ua.VariableAttributes(), addnode) elif rdesc.NodeClass in (ua.NodeClass.Method,): addnode.NodeClass = ua.NodeClass.Method _read_and_copy_attrs(node_type, ua.MethodAttributes(), addnode) else: print("Instantiate: Node class not supported: ", rdesc.NodeClass) return res = server.add_nodes([addnode])[0] if recursive: descs = node_type.get_children_descriptions(includesubtypes=False) for c_rdesc in descs: _instantiate_node(server, res.AddedNodeId, c_rdesc, nodeid=ua.NodeId(namespaceidx=res.AddedNodeId.NamespaceIndex), bname=c_rdesc.BrowseName) return Node(server, res.AddedNodeId)
def instantiate(parent, node_type, nodeid=None, bname=None, dname=None, idx=0, instantiate_optional=True): """ instantiate a node type under a parent node. nodeid and browse name of new node can be specified, or just namespace index If they exists children of the node type, such as components, variables and properties are also instantiated """ rdesc = _rdesc_from_node(parent, node_type) rdesc.TypeDefinition = node_type.nodeid if nodeid is None: nodeid = ua.NodeId( namespaceidx=idx ) # will trigger automatic node generation in namespace idx if bname is None: bname = rdesc.BrowseName elif isinstance(bname, str): bname = ua.QualifiedName.from_string(bname) nodeids = _instantiate_node(parent.server, Node(parent.server, rdesc.NodeId), parent.nodeid, rdesc, nodeid, bname, dname=dname, instantiate_optional=instantiate_optional) return [Node(parent.server, nid) for nid in nodeids]
def __init__(self, isession, etype=ua.ObjectIds.BaseEventType, source=ua.ObjectIds.Server): self.isession = isession if isinstance(etype, Node): self.node = etype elif isinstance(etype, ua.NodeId): self.node = Node(self.isession, etype) else: self.node = Node(self.isession, ua.NodeId(etype)) self.set_members_from_node(self.node) if isinstance(source, Node): self.SourceNode = source.NodeId elif isinstance(etype, ua.NodeId): self.SourceNode = source.NodeId else: self.SourceNode = ua.NodeId(source) # set some default values for attributes from BaseEventType, thus that all event must have self.EventId = uuid.uuid4().bytes self.EventType = self.node.nodeid self.LocaleTime = datetime.now() self.ReceiveTime = datetime.now() self.Time = datetime.now() self.Message = ua.LocalizedText() self.Severity = ua.Variant(1, ua.VariantType.UInt16) self.SourceName = "Server" # og set some node attributed we also are expected to have self.BrowseName = self.node.get_browse_name() self.DisplayName = self.node.get_display_name() self.NodeId = self.node.nodeid self.NodeClass = self.node.get_node_class() self.Description = self.node.get_description()
def subscribe_events(self, sourcenode=ua.ObjectIds.Server, evtypes=ua.ObjectIds.BaseEventType, evfilter=None, queuesize=0): """ Subscribe to events from a node. Default node is Server node. In most servers the server node is the only one you can subscribe to. if evtypes is not provided, evtype defaults to BaseEventType if evtypes is a list or tuple of custom event types, the events will be filtered to the supplied types Return a handle which can be used to unsubscribe """ sourcenode = Node(self.server, sourcenode) if evfilter is None: if not type(evtypes) in (list, tuple): evtypes = [evtypes] evtypes = [Node(self.server, evtype) for evtype in evtypes] evfilter = events.get_filter_from_event_type(evtypes) return self._subscribe(sourcenode, ua.AttributeIds.EventNotifier, evfilter, queuesize=queuesize)
def __init__(self): self.logger = logging.getLogger(__name__) self.endpoints = [] self._channel_id_counter = 5 self.allow_remote_admin = True self.aspace = AddressSpace() self.attribute_service = AttributeService(self.aspace) self.view_service = ViewService(self.aspace) self.method_service = MethodService(self.aspace) self.node_mgt_service = NodeManagementService(self.aspace) standard_address_space.fill_address_space(self.node_mgt_service) # import address space from code generated from xml #standard_address_space.fill_address_space_from_disk(self.aspace) # import address space from save db to disc # import address space directly from xml, this has preformance impact so disabled #importer = xmlimporter.XmlImporter(self.node_mgt_service) #importer.import_xml("/home/olivier/python-opcua/schemas/Opc.Ua.NodeSet2.xml") self.loop = utils.ThreadLoop() self.subscription_service = SubscriptionService(self.loop, self.aspace) # create a session to use on server side self.isession = InternalSession(self, self.aspace, self.subscription_service, "Internal", user=User.Admin) self.current_time_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime)) uries = ["http://opcfoundation.org/UA/"] ns_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_NamespaceArray)) ns_node.set_value(uries)
def createEditor(self, parent, option, idx): if idx.column() != 1: return None item = self.attrs_widget.model.itemFromIndex(idx) attr, dv = item.data(Qt.UserRole) text = item.text() if attr == ua.AttributeIds.NodeId: return None if dv.Value.VariantType == ua.VariantType.Boolean: combo = QComboBox(parent) combo.addItem("True") combo.addItem("False") combo.setCurrentText(text) return combo elif attr == ua.AttributeIds.NodeClass: combo = QComboBox(parent) for nclass in ua.NodeClass: combo.addItem(nclass.name) combo.setCurrentText(text) return combo elif attr == ua.AttributeIds.DataType: nodeid = getattr(ua.ObjectIds, text) node = Node(self.attrs_widget.current_node.server, nodeid) startnode = Node(self.attrs_widget.current_node.server, ua.ObjectIds.BaseDataType) button = GetNodeButton(parent, node, startnode) return button elif attr in (ua.AttributeIds.AccessLevel, ua.AttributeIds.UserAccessLevel, ua.AttributeIds.WriteMask, ua.AttributeIds.UserWriteMask, ua.AttributeIds.EventNotifier): return BitEditor(parent, attr, dv.Value.Value) else: return QStyledItemDelegate.createEditor(self, parent, option, idx)
def _get_node(self, nodeid): if isinstance(nodeid, ua.NodeId): node = Node(self.server, nodeid) elif isinstance(nodeid, Node): node = nodeid else: node = Node(self.server, ua.NodeId(nodeid)) return node
class Event(object): """ Create an event based on an event type. Per default is BaseEventType used. arguments are: server: The InternalSession object to use for query and event triggering source: The emiting source for the node, either an objectId, NodeId or a Node etype: The event type, either an objectId, a NodeId or a Node object """ def __init__(self, isession, etype=ua.ObjectIds.BaseEventType, source=ua.ObjectIds.Server): self.isession = isession if isinstance(etype, Node): self.node = etype elif isinstance(etype, ua.NodeId): self.node = Node(self.isession, etype) else: self.node = Node(self.isession, ua.NodeId(etype)) self.set_members_from_node(self.node) if isinstance(source, Node): self.SourceNode = source.NodeId elif isinstance(etype, ua.NodeId): self.SourceNode = source.NodeId else: self.SourceNode = ua.NodeId(source) # set some default values for attributes from BaseEventType, thus that all event must have self.EventId = uuid.uuid4().bytes self.EventType = self.node.nodeid self.LocaleTime = datetime.now() self.ReceiveTime = datetime.now() self.Time = datetime.now() self.Message = ua.LocalizedText() self.Severity = ua.Variant(1, ua.VariantType.UInt16) self.SourceName = "Server" # og set some node attributed we also are expected to have self.BrowseName = self.node.get_browse_name() self.DisplayName = self.node.get_display_name() self.NodeId = self.node.nodeid self.NodeClass = self.node.get_node_class() self.Description = self.node.get_description() def __str__(self): return "Event(Type:{}, Source:{}, Time:{}, Message: {})".format(self.EventType, self.SourceNode, self.Time, self.Message) __repr__ = __str__ def trigger(self): self.isession.subscription_service.trigger_event(self) def set_members_from_node(self, node): references = node.get_children_descriptions(refs=ua.ObjectIds.HasProperty) for desc in references: node = Node(self.isession, desc.NodeId) setattr(self, desc.BrowseName.Name, node.get_value())
class Event(object): """ Create an event based on an event type. Per default is BaseEventType used. arguments are: server: The InternalSession object to use for query and event triggering source: The emiting source for the node, either an objectId, NodeId or a Node etype: The event type, either an objectId, a NodeId or a Node object """ def __init__(self, isession, etype=ObjectIds.BaseEventType, source=ObjectIds.Server): self.isession = isession if isinstance(etype, Node): self.node = etype elif isinstance(etype, ua.NodeId): self.node = Node(self.isession, etype) else: self.node = Node(self.isession, ua.NodeId(etype)) self.set_members_from_node(self.node) if isinstance(source, Node): self.SourceNode = source.NodeId elif isinstance(etype, ua.NodeId): self.SourceNode = source.NodeId else: self.SourceNode = ua.NodeId(source) # set some default values for attributes from BaseEventType, thus that all event must have self.EventId = uuid.uuid4().bytes self.EventType = self.node.nodeid self.LocaleTime = datetime.now() self.ReceiveTime = datetime.now() self.Time = datetime.now() self.Message = ua.LocalizedText() self.Severity = ua.Variant(1, ua.VariantType.UInt16) self.SourceName = "Server" # og set some node attributed we also are expected to have self.BrowseName = self.node.get_browse_name() self.DisplayName = self.node.get_display_name() self.NodeId = self.node.nodeid self.NodeClass = self.node.get_node_class() self.Description = self.node.get_description() def __str__(self): return "Event(Type:{}, Source:{}, Time:{}, Message: {})".format(self.EventType, self.SourceNode, self.Time, self.Message) __repr__ = __str__ def trigger(self): self.isession.subscription_service.trigger_event(self) def set_members_from_node(self, node): references = node.get_children_descriptions(refs=ua.ObjectIds.HasProperty) for desc in references: node = Node(self.isession, desc.NodeId) setattr(self, desc.BrowseName.Name, node.get_value())
def start(self): self.logger.info("starting internal server") self.loop.start() Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_State)).set_value(0) Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_StartTime)).set_value( datetime.now()) self._set_current_time()
def _instantiate_node(server, parentid, rdesc, nodeid, bname, recursive=True): """ instantiate a node type under parent """ node_type = Node(server, rdesc.NodeId) refs = node_type.get_referenced_nodes(refs=ua.ObjectIds.HasModellingRule) # skip optional elements if len(refs) == 1 and refs[0].nodeid == ua.NodeId( ua.ObjectIds.ModellingRule_Optional): return [] addnode = ua.AddNodesItem() addnode.RequestedNewNodeId = nodeid addnode.BrowseName = bname addnode.ParentNodeId = parentid addnode.ReferenceTypeId = rdesc.ReferenceTypeId addnode.TypeDefinition = rdesc.TypeDefinition if rdesc.NodeClass in (ua.NodeClass.Object, ua.NodeClass.ObjectType): addnode.NodeClass = ua.NodeClass.Object _read_and_copy_attrs(node_type, ua.ObjectAttributes(), addnode) elif rdesc.NodeClass in (ua.NodeClass.Variable, ua.NodeClass.VariableType): addnode.NodeClass = ua.NodeClass.Variable _read_and_copy_attrs(node_type, ua.VariableAttributes(), addnode) elif rdesc.NodeClass in (ua.NodeClass.Method, ): addnode.NodeClass = ua.NodeClass.Method _read_and_copy_attrs(node_type, ua.MethodAttributes(), addnode) else: print("Instantiate: Node class not supported: ", rdesc.NodeClass) return res = server.add_nodes([addnode])[0] added_nodes = [res.AddedNodeId] if recursive: parents = ua_utils.get_node_supertypes(node_type, includeitself=True) node = Node(server, res.AddedNodeId) for parent in parents: descs = parent.get_children_descriptions(includesubtypes=False) for c_rdesc in descs: # skip items that already exists, prefer the 'lowest' one in object hierarchy if not ua_utils.is_child_present(node, c_rdesc.BrowseName): nodeids = _instantiate_node( server, res.AddedNodeId, c_rdesc, nodeid=ua.NodeId( namespaceidx=res.AddedNodeId.NamespaceIndex), bname=c_rdesc.BrowseName) added_nodes.extend(nodeids) return added_nodes
def _instantiate_node(server, parentid, rdesc, nodeid, bname, dname=None, recursive=True): """ instantiate a node type under parent """ node_type = Node(server, rdesc.NodeId) refs = node_type.get_referenced_nodes(refs=ua.ObjectIds.HasModellingRule) # skip optional elements if len(refs) == 1 and refs[0].nodeid == ua.NodeId(ua.ObjectIds.ModellingRule_Optional): return [] addnode = ua.AddNodesItem() addnode.RequestedNewNodeId = nodeid addnode.BrowseName = bname addnode.ParentNodeId = parentid addnode.ReferenceTypeId = rdesc.ReferenceTypeId addnode.TypeDefinition = rdesc.TypeDefinition if rdesc.NodeClass in (ua.NodeClass.Object, ua.NodeClass.ObjectType): addnode.NodeClass = ua.NodeClass.Object _read_and_copy_attrs(node_type, ua.ObjectAttributes(), addnode) elif rdesc.NodeClass in (ua.NodeClass.Variable, ua.NodeClass.VariableType): addnode.NodeClass = ua.NodeClass.Variable _read_and_copy_attrs(node_type, ua.VariableAttributes(), addnode) elif rdesc.NodeClass in (ua.NodeClass.Method,): addnode.NodeClass = ua.NodeClass.Method _read_and_copy_attrs(node_type, ua.MethodAttributes(), addnode) else: logger.warning("Instantiate: Node class not supported: %s", rdesc.NodeClass) return if dname is not None: addnode.NodeAttributes.DisplayName = dname res = server.add_nodes([addnode])[0] added_nodes = [res.AddedNodeId] if recursive: parents = ua_utils.get_node_supertypes(node_type, includeitself=True) node = Node(server, res.AddedNodeId) for parent in parents: descs = parent.get_children_descriptions(includesubtypes=False) for c_rdesc in descs: # skip items that already exists, prefer the 'lowest' one in object hierarchy if not ua_utils.is_child_present(node, c_rdesc.BrowseName): # if root node being instantiated has a String NodeId, create the children with a String NodeId if res.AddedNodeId.NodeIdType is ua.NodeIdType.String: inst_nodeid = res.AddedNodeId.Identifier + "." + c_rdesc.BrowseName.Name nodeids = _instantiate_node(server, res.AddedNodeId, c_rdesc, nodeid=ua.NodeId(identifier=inst_nodeid, namespaceidx=res.AddedNodeId.NamespaceIndex), bname=c_rdesc.BrowseName) else: nodeids = _instantiate_node(server, res.AddedNodeId, c_rdesc, nodeid=ua.NodeId(namespaceidx=res.AddedNodeId.NamespaceIndex), bname=c_rdesc.BrowseName) added_nodes.extend(nodeids) return added_nodes
def __init__(self, server, nodeid, name, parent, server_id, **kwargs): OpcNode.__init__(self, server=server, nodeid=nodeid) AnyTreeNode.__init__(self, name=name, parent=parent, **kwargs) self.namespace_index = self.nodeid.NamespaceIndex self.node_class = None self.variant_type = None self.string_nodeid = self.nodeid.to_string() self.node_id = self.nodeid.to_string() self.server_id = server_id self.web_client_ids = set() self.handle = None
def start(self): self.logger.info("starting internal server") for edp in self.endpoints: self._known_servers[edp.Server.ApplicationUri] = ServerDesc( edp.Server) self.loop.start() Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_State)).set_value(0) Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_StartTime)).set_value( datetime.now()) if not self.disabled_clock: self._set_current_time()
def _lsprint_1(node, depth, indent=""): if not indent: print("{:30} {:25} {:25} {:25}".format("DisplayName", "NodeId", "BrowseName", "Value")) print("") for desc in node.get_children_descriptions(): if desc.NodeClass == ua.NodeClass.Variable: val = Node(node.server, desc.NodeId).get_value() print("{}{:30} {!s:25} {!s:25}, {!s:3}".format(indent, desc.DisplayName.to_string(), desc.NodeId.to_string(), desc.BrowseName.to_string(), val)) else: print("{}{:30} {!s:25} {!s:25}".format(indent, desc.DisplayName.to_string(), desc.NodeId.to_string(), desc.BrowseName.to_string())) if depth: _lsprint_1(Node(node.server, desc.NodeId), depth - 1, indent + " ")
def _instanciate_node(server, parentid, rdesc, idx): """ Instanciate a new node under 'parent' using a type """ print("Instanciating: node %s in %s" % (rdesc, parentid)) addnode = ua.AddNodesItem() addnode.RequestedNewNodeId = ua.generate_nodeid(idx) addnode.BrowseName = rdesc.BrowseName addnode.NodeClass = rdesc.NodeClass addnode.ParentNodeId = parentid addnode.ReferenceTypeId = ua.TwoByteNodeId(ua.ObjectIds.HasComponent) addnode.TypeDefinition = rdesc.TypeDefinition print("ADDNODE", addnode) node_type = Node(server, rdesc.NodeId) if rdesc.NodeClass in (ua.NodeClass.Object, ua.NodeClass.ObjectType): print(node_type, " is object") _read_and_copy_attrs(node_type, ua.ObjectAttributes(), addnode) #_add_object_attrs(addnode, rdesc, node_type) elif rdesc.NodeClass in (ua.NodeClass.Variable, ua.NodeClass.VariableType): print(node_type, " is variable") _read_and_copy_attrs(node_type, ua.VariableAttributes(), addnode) #_add_variable_attrs(addnode, rdesc, node_type) else: print("Node class not supported: ", rdesc.NodeClass) print("ADDNODE FINAL ", addnode) server.add_nodes([addnode]) refs = [] ref = ua.AddReferencesItem() ref.IsForward = True ref.ReferenceTypeId = addnode.ReferenceTypeId ref.SourceNodeId = parentid ref.TargetNodeClass = addnode.NodeClass ref.TargetNodeId = addnode.RequestedNewNodeId refs.append(ref) server.add_references(refs) descs = node_type.get_children_descriptions( includesubtypes=False) #FIXME: should be false print("node is", rdesc.NodeId, node_type, node_type.get_children()) print("Children are: ", descs) for rdesc in descs: _instanciate_node(server, addnode.RequestedNewNodeId, rdesc, idx) return Node(server, addnode.RequestedNewNodeId)
def __init__(self, server): self.root = Node(server, ObjectIds.RootFolder) self.objects = Node(server, ObjectIds.ObjectsFolder) self.server = Node(server, ObjectIds.Server) self.types = Node(server, ObjectIds.TypesFolder) self.base_object_type = Node(server, ObjectIds.BaseObjectType) self.base_data_type = Node(server, ObjectIds.BaseDataType) self.base_event_type = Node(server, ObjectIds.BaseEventType) self.base_variable_type = Node(server, ObjectIds.BaseVariableType) self.folder_type = Node(server, ObjectIds.FolderType)
def _instanciate_node(server, parentid, rdesc, idx): """ Instanciate a new node under 'parent' using a type """ print("Instanciating: node %s in %s" % (rdesc, parentid)) addnode = ua.AddNodesItem() addnode.RequestedNewNodeId = ua.generate_nodeid(idx) addnode.BrowseName = rdesc.BrowseName addnode.NodeClass = rdesc.NodeClass addnode.ParentNodeId = parentid addnode.ReferenceTypeId = ua.TwoByteNodeId(ua.ObjectIds.HasComponent) addnode.TypeDefinition = rdesc.TypeDefinition print("ADDNODE", addnode) node_type = Node(server, rdesc.NodeId) if rdesc.NodeClass in (ua.NodeClass.Object, ua.NodeClass.ObjectType): print(node_type, " is object") _read_and_copy_attrs(node_type, ua.ObjectAttributes(), addnode) #_add_object_attrs(addnode, rdesc, node_type) elif rdesc.NodeClass in (ua.NodeClass.Variable, ua.NodeClass.VariableType): print(node_type, " is variable") _read_and_copy_attrs(node_type, ua.VariableAttributes(), addnode) #_add_variable_attrs(addnode, rdesc, node_type) else: print("Node class not supported: ", rdesc.NodeClass) print("ADDNODE FINAL ", addnode) server.add_nodes([addnode]) refs = [] ref = ua.AddReferencesItem() ref.IsForward = True ref.ReferenceTypeId = addnode.ReferenceTypeId ref.SourceNodeId = parentid ref.TargetNodeClass = addnode.NodeClass ref.TargetNodeId = addnode.RequestedNewNodeId refs.append(ref) server.add_references(refs) descs = node_type.get_children_descriptions(includesubtypes=False) # FIXME: should be false print("node is", rdesc.NodeId, node_type, node_type.get_children()) print("Children are: ", descs) for rdesc in descs: _instanciate_node(server, addnode.RequestedNewNodeId, rdesc, idx) return Node(server, addnode.RequestedNewNodeId)
def __init__(self): self.logger = logging.getLogger(__name__) self.endpoints = [] self._channel_id_counter = 5 self.aspace = AddressSpace() self.load_standard_address_space() self.loop = ThreadLoop() self.submanager = SubscriptionManager(self.loop, self.aspace) # create a session to use on server side self.isession = InternalSession(self, self.aspace, self.submanager, "Internal") self._timer = None self.current_time_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime)) uries = ["http://opcfoundation.org/UA/"] ns_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_NamespaceArray)) ns_node.set_value(uries)
def _instantiate_node(server, parentid, rdesc, nodeid, bname, recursive=True): """ instantiate a node type under parent """ addnode = ua.AddNodesItem() addnode.RequestedNewNodeId = nodeid addnode.BrowseName = bname addnode.ParentNodeId = parentid addnode.ReferenceTypeId = rdesc.ReferenceTypeId addnode.TypeDefinition = rdesc.TypeDefinition node_type = Node(server, rdesc.NodeId) refs = node_type.get_referenced_nodes(refs=ua.ObjectIds.HasModellingRule) # skip optional elements if not(len(refs) == 1 and refs[0].nodeid == ua.NodeId(ua.ObjectIds.ModellingRule_Optional) ): if rdesc.NodeClass in (ua.NodeClass.Object, ua.NodeClass.ObjectType): addnode.NodeClass = ua.NodeClass.Object _read_and_copy_attrs(node_type, ua.ObjectAttributes(), addnode) elif rdesc.NodeClass in (ua.NodeClass.Variable, ua.NodeClass.VariableType): addnode.NodeClass = ua.NodeClass.Variable _read_and_copy_attrs(node_type, ua.VariableAttributes(), addnode) elif rdesc.NodeClass in (ua.NodeClass.Method,): addnode.NodeClass = ua.NodeClass.Method _read_and_copy_attrs(node_type, ua.MethodAttributes(), addnode) else: print("Instantiate: Node class not supported: ", rdesc.NodeClass) return res = server.add_nodes([addnode])[0] if recursive: parents = ua_utils.get_node_supertypes(node_type, includeitself = True) node = Node(server, res.AddedNodeId) for parent in parents: descs = parent.get_children_descriptions(includesubtypes=False) for c_rdesc in descs: # skip items that already exists, prefer the 'lowest' one in object hierarchy if not ua_utils.is_child_present(node, c_rdesc.BrowseName): _instantiate_node(server, res.AddedNodeId, c_rdesc, nodeid=ua.NodeId(namespaceidx=res.AddedNodeId.NamespaceIndex), bname=c_rdesc.BrowseName) return Node(server, res.AddedNodeId) else: return None
def trigger(self, time_attr=None, message=None): """ Trigger the event. This will send a notification to all subscribed clients """ self.event.EventId = ua.Variant(uuid.uuid4().hex.encode('utf-8'), ua.VariantType.ByteString) if time_attr: self.event.Time = time_attr else: self.event.Time = datetime.utcnow() self.event.ReceiveTime = datetime.utcnow() self.event.LocalTime = ua.uaprotocol_auto.TimeZoneDataType() if sys.version_info.major > 2: localtime = time.localtime(self.event.Time.timestamp()) self.event.LocalTime.Offset = localtime.tm_gmtoff // 60 else: localtime = time.localtime(time.mktime( self.event.Time.timetuple())) self.event.LocalTime.Offset = -(time.altzone if localtime.tm_isdst else time.timezone) self.event.LocalTime.DaylightSavingInOffset = bool( localtime.tm_isdst != -1) if message: self.event.Message = ua.LocalizedText(message) elif not self.event.Message: self.event.Message = ua.LocalizedText( Node(self.isession, self.event.SourceNode).get_browse_name().Text) self.isession.subscription_service.trigger_event(self.event)
def create_monitored_items(self, monitored_items): """ low level method to have full control over subscription parameters Client handle must be unique since it will be used as key for internal registration of data """ params = ua.CreateMonitoredItemsParameters() params.SubscriptionId = self.subscription_id params.ItemsToCreate = monitored_items params.TimestampsToReturn = ua.TimestampsToReturn.Both # insert monitored item into map to avoid notification arrive before result return # server_handle is left as None in purpose as we don't get it yet. with self._lock: for mi in monitored_items: data = SubscriptionItemData() data.client_handle = mi.RequestedParameters.ClientHandle data.node = Node(self.server, mi.ItemToMonitor.NodeId) data.attribute = mi.ItemToMonitor.AttributeId #TODO: Either use the filter from request or from response. Here it uses from request, in modify it uses from response data.mfilter = mi.RequestedParameters.Filter self._monitoreditems_map[mi.RequestedParameters.ClientHandle] = data results = self.server.create_monitored_items(params) mids = [] # process result, add server_handle, or remove it if failed with self._lock: for idx, result in enumerate(results): mi = params.ItemsToCreate[idx] if not result.StatusCode.is_good(): del self._monitoreditems_map[mi.RequestedParameters.ClientHandle] mids.append(result.StatusCode) continue data = self._monitoreditems_map[mi.RequestedParameters.ClientHandle] data.server_handle = result.MonitoredItemId mids.append(result.MonitoredItemId) return mids
def get_node(self): text = self.lineEdit.text() if text and text not in ("None", "Null"): current = ua.NodeId.from_string(text) else: current = ua.NodeId() return Node(self.server, current)
def add_item(self, desc, parent=None, node=None): item = [QStandardItem(desc.DisplayName.to_string()), QStandardItem(desc.BrowseName.to_string()), QStandardItem(desc.NodeId.to_string())] if desc.NodeClass == ua.NodeClass.Object: if desc.TypeDefinition == ua.TwoByteNodeId(ua.ObjectIds.FolderType): item[0].setIcon(QIcon(":/folder.svg")) else: item[0].setIcon(QIcon(":/object.svg")) elif desc.NodeClass == ua.NodeClass.Variable: if desc.TypeDefinition == ua.TwoByteNodeId(ua.ObjectIds.PropertyType): item[0].setIcon(QIcon(":/property.svg")) else: item[0].setIcon(QIcon(":/variable.svg")) elif desc.NodeClass == ua.NodeClass.Method: item[0].setIcon(QIcon(":/method.svg")) elif desc.NodeClass == ua.NodeClass.ObjectType: item[0].setIcon(QIcon(":/object_type.svg")) elif desc.NodeClass == ua.NodeClass.VariableType: item[0].setIcon(QIcon(":/variable_type.svg")) elif desc.NodeClass == ua.NodeClass.DataType: item[0].setIcon(QIcon(":/data_type.svg")) elif desc.NodeClass == ua.NodeClass.ReferenceType: item[0].setIcon(QIcon(":/reference_type.svg")) if node: item[0].setData(node) else: parent_node = parent.data() item[0].setData(Node(parent_node.server, desc.NodeId)) if parent: return parent.appendRow(item) else: return self.appendRow(item)
def _save_structs(self): """ Save struct and delete our design nodes. They will need to be recreated """ struct_node = self.server_mgr.get_node(ua.ObjectIds.Structure) structs = [] to_delete = [] for node in self.new_nodes: # FIXME: we do not support inheritance parent = node.get_parent() if parent == struct_node: bname = node.get_browse_name() st = _Struct(bname.Name, "ExtensionObject") childs = node.get_children() for child in childs: bname = child.get_browse_name() try: dtype = child.get_data_type() except ua.UaError: logger.warning( "could not get data type for node %s, %s, skipping", child, child.get_browse_name()) continue dtype_name = Node(node.server, dtype).get_browse_name() st.fields.append([bname.Name, dtype_name.Name]) to_delete.append(child) structs.append(st) if structs: self._save_bsd(structs) for node in to_delete: node.delete() if node in self.new_nodes: self.new_nodes.remove(node)
def create_monitored_items(self, monitored_items): """ low level method to have full control over subscription parameters Client handle must be unique since it will be used as key for internal registration of data """ params = ua.CreateMonitoredItemsParameters() params.SubscriptionId = self.subscription_id params.ItemsToCreate = monitored_items params.TimestampsToReturn = ua.TimestampsToReturn.Neither mids = [] results = self.server.create_monitored_items(params) # FIXME: Race condition here # We lock as early as possible. But in some situation, a notification may arrives before # locking and we will not be able to prosess it. To avoid issues, users should subscribe # to all nodes at once with self._lock: for idx, result in enumerate(results): mi = params.ItemsToCreate[idx] if not result.StatusCode.is_good(): mids.append(result.StatusCode) continue data = SubscriptionItemData() data.client_handle = mi.RequestedParameters.ClientHandle data.node = Node(self.server, mi.ItemToMonitor.NodeId) data.attribute = mi.ItemToMonitor.AttributeId data.server_handle = result.MonitoredItemId #data.mfilter = result.FilterResult data.mfilter = mi.RequestedParameters.Filter self._monitoreditems_map[mi.RequestedParameters.ClientHandle] = data mids.append(result.MonitoredItemId) return mids
def subscribe_events(self, sourcenode=ua.ObjectIds.Server, evtype=ua.ObjectIds.BaseEventType, evfilter=None): """ Subscribe to events from a node. Default node is Server node. In most servers the server node is the only one you can subscribe to. if evfilter is provided, evtype is ignored Return a handle which can be used to unsubscribe """ sourcenode = Node(self.server, sourcenode) if evfilter is None: evfilter = events.get_filter_from_event_type( Node(self.server, evtype)) return self._subscribe(sourcenode, ua.AttributeIds.EventNotifier, evfilter)
def test_guid_node_id(self): """ Test that a Node can be instantiated with a GUID string and that the NodeId ca be converted to binary. """ node = Node(None, "ns=4;g=35d5f86f-2777-4550-9d48-b098f5ee285c") binary_node_id = ua.ua_binary.nodeid_to_binary(node.nodeid) assert type(binary_node_id) is bytes
def __init__(self, isession, etype=None, emitting_node=ua.ObjectIds.Server): if not etype: etype = event_objects.BaseEvent() self.logger = logging.getLogger(__name__) self.isession = isession self.event = None node = None if isinstance(etype, event_objects.BaseEvent): self.event = etype elif isinstance(etype, Node): node = etype elif isinstance(etype, ua.NodeId): node = Node(self.isession, etype) else: node = Node(self.isession, ua.NodeId(etype)) if node: self.event = events.get_event_obj_from_type_node(node) if isinstance(emitting_node, Node): pass elif isinstance(emitting_node, ua.NodeId): emitting_node = Node(isession, emitting_node) else: emitting_node = Node(isession, ua.NodeId(emitting_node)) self.event.emitting_node = emitting_node.nodeid if not self.event.SourceNode: self.event.SourceNode = emitting_node.nodeid self.event.SourceName = emitting_node.get_browse_name().Name emitting_node.set_event_notifier([ua.EventNotifier.SubscribeToEvents]) refs = [] ref = ua.AddReferencesItem() ref.IsForward = True ref.ReferenceTypeId = ua.NodeId(ua.ObjectIds.GeneratesEvent) ref.SourceNodeId = emitting_node.nodeid ref.TargetNodeClass = ua.NodeClass.ObjectType ref.TargetNodeId = self.event.EventType refs.append(ref) results = self.isession.add_references(refs) # result.StatusCode.check() self.emitting_node = emitting_node
def _lsprint_0(node, depth, indent=""): if not indent: print("{:30} {:25}".format("DisplayName", "NodeId")) print("") for desc in node.get_children_descriptions(): print("{}{:30} {:25}".format(indent, desc.DisplayName.to_string(), desc.NodeId.to_string())) if depth: _lsprint_0(Node(node.server, desc.NodeId), depth - 1, indent + " ")
def createEditor(self, parent, option, idx): if idx.column() > 1: return None data_idx = idx.sibling(idx.row(), 0) item = self._widget.model.itemFromIndex(data_idx) ref = item.data(Qt.UserRole) if idx.column() == 1: node = Node(self._widget.node.server, ref.NodeId) startnode = Node(self._widget.node.server, ua.ObjectIds.RootFolder) button = GetNodeTextButton(parent, node, startnode) return button elif idx.column() == 0: node = Node(self._widget.node.server, ref.ReferenceTypeId) startnode = Node(self._widget.node.server, ua.ObjectIds.ReferenceTypesFolder) button = GetNodeTextButton(parent, node, startnode) return button
def createEditor(self, parent, option, idx): if idx.column() != 1: return None item = self.attrs_widget.model.itemFromIndex(idx) data = item.data(Qt.UserRole) if not data.is_editable(): return None text = item.text() if isinstance(data, (ListData, MemberData)): return QStyledItemDelegate.createEditor(self, parent, option, idx) elif data.attr == ua.AttributeIds.NodeId: return None elif data.uatype == ua.VariantType.Boolean: combo = QComboBox(parent) combo.addItem("True") combo.addItem("False") combo.setCurrentText(text) return combo elif data.attr == ua.AttributeIds.NodeClass: combo = QComboBox(parent) for nclass in ua.NodeClass: combo.addItem(nclass.name) combo.setCurrentText(text) return combo elif data.attr == ua.AttributeIds.ValueRank: combo = QComboBox(parent) for rank in ua.ValueRank: combo.addItem(rank.name) combo.setCurrentText(text) return combo elif data.attr == ua.AttributeIds.DataType: #nodeid = getattr(ua.ObjectIds, text) nodeid = data.value node = Node(self.attrs_widget.current_node.server, nodeid) startnode = Node(self.attrs_widget.current_node.server, ua.ObjectIds.BaseDataType) button = GetNodeButton(parent, node, startnode) return button elif data.attr in (ua.AttributeIds.AccessLevel, ua.AttributeIds.UserAccessLevel, ua.AttributeIds.WriteMask, ua.AttributeIds.UserWriteMask, ua.AttributeIds.EventNotifier): return BitEditor(parent, data.attr, data.value) else: return QStyledItemDelegate.createEditor(self, parent, option, idx)
def __init__(self): self.logger = logging.getLogger(__name__) self.endpoints = [] self._channel_id_counter = 5 self.allow_remote_admin = True self.aspace = AddressSpace() self.attribute_service = AttributeService(self.aspace) self.view_service = ViewService(self.aspace) self.method_service = MethodService(self.aspace) self.node_mgt_service = NodeManagementService(self.aspace) standard_address_space.fill_address_space(self.node_mgt_service) #standard_address_space.fill_address_space_from_disk(self.aspace) self.loop = utils.ThreadLoop() self.subscription_service = SubscriptionService(self.loop, self.aspace) # create a session to use on server side self.isession = InternalSession(self, self.aspace, self.subscription_service, "Internal", user=User.Admin) self.current_time_node = Node( self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime)) uries = ["http://opcfoundation.org/UA/"] ns_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_NamespaceArray)) ns_node.set_value(uries)
def _lsprint_1(node, depth, indent=""): if not indent: print("{0:30} {1:25} {2:25} {3:25}".format("DisplayName", "NodeId", "BrowseName", "Value")) print("") for desc in node.get_children_descriptions(): if desc.NodeClass == ua.NodeClass.Variable: try: val = Node(node.server, desc.NodeId).get_value() except UaStatusCodeError as err: val = "Bad (0x{0:x})".format(err.code) print("{0}{1:30} {2!s:25} {3!s:25}, {4!s:3}".format( indent, desc.DisplayName.to_string(), desc.NodeId.to_string(), desc.BrowseName.to_string(), val)) else: print("{0}{1:30} {2!s:25} {3!s:25}".format( indent, desc.DisplayName.to_string(), desc.NodeId.to_string(), desc.BrowseName.to_string())) if depth: _lsprint_1(Node(node.server, desc.NodeId), depth - 1, indent + " ")
def __init__(self): self.logger = logging.getLogger(__name__) self.endpoints = [] self._channel_id_counter = 5 self.aspace = AddressSpace() self.attribute_service = AttributeService(self.aspace) self.view_service = ViewService(self.aspace) self.method_service = MethodService(self.aspace) self.node_mgt_service = NodeManagementService(self.aspace) standard_address_space.fill_address_space(self.node_mgt_service) #standard_address_space.fill_address_space_from_disk(self.aspace) self.loop = utils.ThreadLoop() self.subscription_service = SubscriptionService(self.loop, self.aspace) # create a session to use on server side self.isession = InternalSession(self, self.aspace, self.subscription_service, "Internal", user=User.Admin) self.current_time_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime)) uries = ["http://opcfoundation.org/UA/"] ns_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_NamespaceArray)) ns_node.set_value(uries)
def _save_structs(self): """ Save struct and delete our design nodes. They will need to be recreated """ struct_node = self.server_mgr.get_node(ua.ObjectIds.Structure) dict_name = "TypeDictionary" idx = 1 urn = self.server_mgr.get_namespace_array()[1] to_delete = [] have_structs = False to_add = [] for node in self.new_nodes: # FIXME: we do not support inheritance parent = node.get_parent() if parent == struct_node: if not have_structs: dict_builder = self._create_type_dict_node(idx, urn, dict_name) dict_node = self.server_mgr.get_node(dict_builder.dict_id) have_structs = True bname = node.get_browse_name() try: dict_node.get_child(f"{idx}:{bname.Name}") struct = dict_builder.create_data_type(bname.Name, node.nodeid, init=False) except ua.UaError: logger.warning("DataType %s has not been initialized, doing it", bname) struct = dict_builder.create_data_type(bname.Name, node.nodeid, init=True) childs = node.get_children() for child in childs: bname = child.get_browse_name() try: dtype = child.get_data_type() except ua.UaError: logger.warning("could not get data type for node %s, %s, skipping", child, child.get_browse_name()) continue array = False if isinstance(child.get_value(), list) or child.get_array_dimensions(): array = True dtype_name = Node(node.server, dtype).get_browse_name() struct.add_field(bname.Name, dtype_name.Name, is_array=array) to_delete.append(child) to_add.extend([self.server_mgr.get_node(nodeid) for nodeid in struct.node_ids]) if have_structs: dict_builder.set_dict_byte_string() self.new_nodes.extend(to_add) for node in to_delete: self.delete_node(node, False)
def add_item(self, desc, parent=None, node=None): dname = bname = "No Value" if desc.DisplayName: dname = desc.DisplayName.to_string() if desc.BrowseName: bname = desc.BrowseName.to_string() nodeid = desc.NodeId.to_string() item = [ QStandardItem(dname), QStandardItem(bname), QStandardItem(nodeid) ] if desc.NodeClass == ua.NodeClass.Object: if desc.TypeDefinition == ua.TwoByteNodeId( ua.ObjectIds.FolderType): item[0].setIcon(QIcon("icons/folder.svg")) else: try: object_type = self.custom_objects[desc.NodeId] icon = get_icon(object_type) except KeyError: icon = "icons/object.svg" item[0].setIcon(QIcon(icon)) elif desc.NodeClass == ua.NodeClass.Variable: if desc.TypeDefinition == ua.TwoByteNodeId( ua.ObjectIds.PropertyType): item[0].setIcon(QIcon("icons/property.svg")) else: item[0].setIcon(QIcon("icons/variable.svg")) elif desc.NodeClass == ua.NodeClass.Method: item[0].setIcon(QIcon("icons/method.svg")) elif desc.NodeClass == ua.NodeClass.ObjectType: item[0].setIcon(QIcon("icons/objecttype.svg")) elif desc.NodeClass == ua.NodeClass.VariableType: item[0].setIcon(QIcon("icons/variabletype.svg")) elif desc.NodeClass == ua.NodeClass.DataType: item[0].setIcon(QIcon("icons/datatype.svg")) elif desc.NodeClass == ua.NodeClass.ReferenceType: item[0].setIcon(QIcon("icons/referencetype.svg")) if node: item[0].setData(node, Qt.UserRole) else: parent_node = parent.data(Qt.UserRole) item[0].setData(Node(parent_node.server, desc.NodeId), Qt.UserRole) if parent: return parent.appendRow(item) else: return self.appendRow(item)
def __init__(self, isession, etype=None, source=ua.ObjectIds.Server): if not etype: etype = event_objects.BaseEvent() self.logger = logging.getLogger(__name__) self.isession = isession self.event = None node = None if isinstance(etype, event_objects.BaseEvent): self.event = etype elif isinstance(etype, Node): node = etype elif isinstance(etype, ua.NodeId): node = Node(self.isession, etype) else: node = Node(self.isession, ua.NodeId(etype)) if node: self.event = events.get_event_obj_from_type_node(node) if isinstance(source, Node): pass elif isinstance(source, ua.NodeId): source = Node(isession, source) else: source = Node(isession, ua.NodeId(source)) if self.event.SourceNode: if source.nodeid != self.event.SourceNode: self.logger.warning( "Source NodeId: '%s' and event SourceNode: '%s' are not the same. Using '%s' as SourceNode", str(source.nodeid), str(self.event.SourceNode), str(self.event.SourceNode)) source = Node(self.isession, self.event.SourceNode) self.event.SourceNode = source.nodeid self.event.SourceName = source.get_browse_name().Name source.set_event_notifier([ua.EventNotifier.SubscribeToEvents]) refs = [] ref = ua.AddReferencesItem() ref.IsForward = True ref.ReferenceTypeId = ua.NodeId(ua.ObjectIds.GeneratesEvent) ref.SourceNodeId = source.nodeid ref.TargetNodeClass = ua.NodeClass.ObjectType ref.TargetNodeId = self.event.EventType refs.append(ref) results = self.isession.add_references(refs)
class InternalServer(object): def __init__(self): self.logger = logging.getLogger(__name__) self.endpoints = [] self._channel_id_counter = 5 self.allow_remote_admin = True self.disabled_clock = False # for debugging we may want to disable clock that writes too much in log self._known_servers = {} # used if we are a discovery server self.aspace = AddressSpace() self.attribute_service = AttributeService(self.aspace) self.view_service = ViewService(self.aspace) self.method_service = MethodService(self.aspace) self.node_mgt_service = NodeManagementService(self.aspace) # import address space from code generated from xml standard_address_space.fill_address_space(self.node_mgt_service) # import address space from save db to disc #standard_address_space.fill_address_space_from_disk(self.aspace) # import address space directly from xml, this has preformance impact so disabled #importer = xmlimporter.XmlImporter(self.node_mgt_service) #importer.import_xml("/home/olivier/python-opcua/schemas/Opc.Ua.NodeSet2.xml") self.loop = utils.ThreadLoop() self.subscription_service = SubscriptionService(self.loop, self.aspace) # create a session to use on server side self.isession = InternalSession(self, self.aspace, self.subscription_service, "Internal", user=User.Admin) self.current_time_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime)) uries = ["http://opcfoundation.org/UA/"] ns_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_NamespaceArray)) ns_node.set_value(uries) def load_address_space(self, path): self.aspace.load(path) def dump_address_space(self, path): self.aspace.dump(path) def start(self): self.logger.info("starting internal server") self.loop.start() Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_State)).set_value(0) Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_StartTime)).set_value(datetime.now()) if not self.disabled_clock: self._set_current_time() def stop(self): self.logger.info("stopping internal server") self.loop.stop() def _set_current_time(self): self.current_time_node.set_value(datetime.now()) self.loop.call_later(1, self._set_current_time) def get_new_channel_id(self): self._channel_id_counter += 1 return self._channel_id_counter def add_endpoint(self, endpoint): self.endpoints.append(endpoint) def get_endpoints(self, params=None, sockname=None): self.logger.info("get endpoint") if sockname: #return to client the ip address it has access to edps = [] for edp in self.endpoints: edp1 = copy(edp) url = urlparse(edp1.EndpointUrl) url = url._replace(netloc=sockname[0] + ":" + str(sockname[1])) edp1.EndpointUrl = url.geturl() edps.append(edp1) return edps return self.endpoints[:] def find_servers(self, params): #FIXME: implement filtering from parmams.uri servers = [] for edp in self.endpoints: servers.append(edp.Server) return servers + [desc.Server for desc in self._known_servers.values()] def register_server(self, server, conf=None): appdesc = ua.ApplicationDescription() appdesc.ApplicationUri = server.ServerUri appdesc.ProductUri = server.ProductUri appdesc.ApplicationName = server.ServerNames[0] # FIXME: select name from client locale appdesc.ApplicationType = server.ServerType appdesc.GatewayServerUri = server.GatewayServerUri appdesc.DiscoveryUrls = server.DiscoveryUrls # FIXME: select discovery uri using reachability from client network self._known_servers[server.ServerUri] = ServerDesc(appdesc, conf) def register_server2(self, params): return self.register_server(params.Server, params.DiscoveryConfiguration) def create_session(self, name, user=User.Anonymous): return InternalSession(self, self.aspace, self.subscription_service, name, user=user)
class InternalServer(object): def __init__(self): self.logger = logging.getLogger(__name__) self.endpoints = [] self._channel_id_counter = 5 self.aspace = AddressSpace() self.load_standard_address_space() self.loop = ThreadLoop() self.submanager = SubscriptionManager(self.loop, self.aspace) # create a session to use on server side self.isession = InternalSession(self, self.aspace, self.submanager, "Internal") self._timer = None self.current_time_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime)) uries = ["http://opcfoundation.org/UA/"] ns_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_NamespaceArray)) ns_node.set_value(uries) def load_address_space(self, path): self.aspace.load(path) def dump_address_space(self, path): self.aspace.dump(path) def load_standard_address_space(self): create_standard_address_space_Part3(self.aspace) create_standard_address_space_Part4(self.aspace) create_standard_address_space_Part5(self.aspace) create_standard_address_space_Part8(self.aspace) create_standard_address_space_Part9(self.aspace) create_standard_address_space_Part10(self.aspace) create_standard_address_space_Part11(self.aspace) create_standard_address_space_Part13(self.aspace) def start(self): self.logger.info("starting internal server") self.loop.start() Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_State)).set_value(0) Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_StartTime)).set_value(datetime.now()) self._set_current_time() def stop(self): self.logger.info("stopping internal server") self.loop.stop() def _set_current_time(self): self.current_time_node.set_value(datetime.now()) self.loop.call_later(1, self._set_current_time) def get_new_channel_id(self): self._channel_id_counter += 1 return self._channel_id_counter def add_endpoint(self, endpoint): self.endpoints.append(endpoint) def get_endpoints(self, params=None): self.logger.info("get endpoint") #FIXME check params return self.endpoints[:] def create_session(self, name): return InternalSession(self, self.aspace, self.submanager, name)
class InternalServer(object): def __init__(self): self.logger = logging.getLogger(__name__) self.endpoints = [] self._channel_id_counter = 5 self.aspace = AddressSpace() self.attribute_service = AttributeService(self.aspace) self.view_service = ViewService(self.aspace) self.method_service = MethodService(self.aspace) self.node_mgt_service = NodeManagementService(self.aspace) standard_address_space.fill_address_space(self.node_mgt_service) #standard_address_space.fill_address_space_from_disk(self.aspace) self.loop = utils.ThreadLoop() self.subscription_service = SubscriptionService(self.loop, self.aspace) # create a session to use on server side self.isession = InternalSession(self, self.aspace, self.subscription_service, "Internal", user=User.Admin) self.current_time_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime)) uries = ["http://opcfoundation.org/UA/"] ns_node = Node(self.isession, ua.NodeId(ua.ObjectIds.Server_NamespaceArray)) ns_node.set_value(uries) def load_address_space(self, path): self.aspace.load(path) def dump_address_space(self, path): self.aspace.dump(path) def start(self): self.logger.info("starting internal server") self.loop.start() Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_State)).set_value(0) Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_StartTime)).set_value(datetime.now()) self._set_current_time() def stop(self): self.logger.info("stopping internal server") self.loop.stop() def _set_current_time(self): self.current_time_node.set_value(datetime.now()) self.loop.call_later(1, self._set_current_time) def get_new_channel_id(self): self._channel_id_counter += 1 return self._channel_id_counter def add_endpoint(self, endpoint): self.endpoints.append(endpoint) def get_endpoints(self, params=None, sockname=None): self.logger.info("get endpoint") if sockname: #return to client the ip address it has access to edps = [] for edp in self.endpoints: edp1 = copy(edp) url = urlparse(edp1.EndpointUrl) url = url._replace(netloc=sockname[0] + ":" + str(sockname[1])) edp1.EndpointUrl = url.geturl() edps.append(edp1) return edps return self.endpoints[:] def find_servers(self, params): #FIXME: implement correctly servers = [] for edp in self.endpoints: servers.append(edp.Server) return servers def create_session(self, name, user=User.Anonymous): return InternalSession(self, self.aspace, self.subscription_service, name, user=user)
def set_members_from_node(self, node): references = node.get_children_descriptions(refs=ua.ObjectIds.HasProperty) for desc in references: node = Node(self.isession, desc.NodeId) setattr(self, desc.BrowseName.Name, node.get_value())