async def _uaserver(): parser = argparse.ArgumentParser( description= "Run an example OPC-UA server. By importing xml definition and using uawrite command line, it is even possible to expose real data using this server" ) # we setup a server, this is a bit different from other tool so we do not reuse common arguments parser.add_argument( "-u", "--url", help="URL of OPC UA server, default is opc.tcp://0.0.0.0:4840", default='opc.tcp://0.0.0.0:4840', metavar="URL") parser.add_argument( "-v", "--verbose", dest="loglevel", choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], default='WARNING', help="Set log level") parser.add_argument( "-x", "--xml", metavar="XML_FILE", help="Populate address space with nodes defined in XML") parser.add_argument("-p", "--populate", action="store_true", help="Populate address space with some sample nodes") parser.add_argument( "-c", "--disable-clock", action="store_true", help= "Disable clock, to avoid seeing many write if debugging an application" ) parser.add_argument( "-s", "--shell", action="store_true", help="Start python shell instead of randomly changing node values") parser.add_argument("--certificate", help="set server certificate") parser.add_argument("--private_key", help="set server private key") args = parser.parse_args() logging.basicConfig(format="%(levelname)s: %(message)s", level=getattr(logging, args.loglevel)) server = Server() server.set_endpoint(args.url) if args.certificate: server.load_certificate(args.certificate) if args.private_key: server.load_private_key(args.private_key) server.disable_clock(args.disable_clock) server.set_server_name("FreeOpcUa Example Server") if args.xml: server.import_xml(args.xml) if args.populate: @uamethod def multiply(parent, x, y): print("multiply method call with parameters: ", x, y) return x * y uri = "http://examples.freeopcua.github.io" idx = server.register_namespace(uri) objects = server.nodes.objects myobj = objects.add_object(idx, "MyObject") mywritablevar = myobj.add_variable(idx, "MyWritableVariable", 6.7) mywritablevar.set_writable( ) # Set MyVariable to be writable by clients myvar = myobj.add_variable(idx, "MyVariable", 6.7) myarrayvar = myobj.add_variable(idx, "MyVarArray", [6.7, 7.9]) myprop = myobj.add_property(idx, "MyProperty", "I am a property") mymethod = myobj.add_method( idx, "MyMethod", multiply, [ua.VariantType.Double, ua.VariantType.Int64], [ua.VariantType.Double]) try: await server.init() async with server: if args.shell: embed() elif args.populate: count = 0 while True: await asyncio.sleep(1) myvar.write_value(math.sin(count / 10)) myarrayvar.write_value( [math.sin(count / 10), math.sin(count / 100)]) count += 1 else: while True: await asyncio.sleep(1) except OSError as e: print(e) sys.exit(1) except KeyboardInterrupt: pass sys.exit(0)
async def main(): # optional: setup logging #logger = logging.getLogger("asyncua.address_space") # logger.setLevel(logging.DEBUG) #logger = logging.getLogger("asyncua.internal_server") # logger.setLevel(logging.DEBUG) #logger = logging.getLogger("asyncua.binary_server_asyncio") # logger.setLevel(logging.DEBUG) #logger = logging.getLogger("asyncua.uaprocessor") # logger.setLevel(logging.DEBUG) # now setup our server server = Server() await server.init() server.disable_clock() #for debuging #server.set_endpoint("opc.tcp://localhost:4840/freeopcua/server/") server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/") server.set_server_name("FreeOpcUa Example Server") # set all possible endpoint policies for clients to connect through server.set_security_policy([ ua.SecurityPolicyType.NoSecurity, ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt, ua.SecurityPolicyType.Basic256Sha256_Sign ]) # setup our own namespace uri = "http://examples.freeopcua.github.io" idx = await server.register_namespace(uri) # create a new node type we can instantiate in our address space dev = await server.nodes.base_object_type.add_object_type(idx, "MyDevice") await (await dev.add_variable(idx, "sensor1", 1.0)).set_modelling_rule(True) await (await dev.add_property(idx, "device_id", "0340")).set_modelling_rule(True) ctrl = await dev.add_object(idx, "controller") await ctrl.set_modelling_rule(True) await (await ctrl.add_property(idx, "state", "Idle")).set_modelling_rule(True) # populating our address space # First a folder to organise our nodes myfolder = await server.nodes.objects.add_folder(idx, "myEmptyFolder") # instanciate one instance of our device mydevice = await server.nodes.objects.add_object(idx, "Device0001", dev) mydevice_var = await mydevice.get_child( [f"{idx}:controller", f"{idx}:state"]) # get proxy to our device state variable # create directly some objects and variables myobj = await server.nodes.objects.add_object(idx, "MyObject") myvar = await myobj.add_variable(idx, "MyVariable", 6.7) await myvar.set_writable() # Set MyVariable to be writable by clients mystringvar = await myobj.add_variable(idx, "MyStringVariable", "Really nice string") await mystringvar.set_writable( ) # Set MyVariable to be writable by clients mydtvar = await myobj.add_variable(idx, "MyDateTimeVar", datetime.utcnow()) await mydtvar.set_writable() # Set MyVariable to be writable by clients myarrayvar = await myobj.add_variable(idx, "myarrayvar", [6.7, 7.9]) myarrayvar = await myobj.add_variable( idx, "myStronglytTypedVariable", ua.Variant([], ua.VariantType.UInt32)) myprop = await myobj.add_property(idx, "myproperty", "I am a property") mymethod = await myobj.add_method(idx, "mymethod", func, [ua.VariantType.Int64], [ua.VariantType.Boolean]) multiply_node = await myobj.add_method( idx, "multiply", multiply, [ua.VariantType.Int64, ua.VariantType.Int64], [ua.VariantType.Int64]) # import some nodes from xml await server.import_xml("custom_nodes.xml") # creating a default event object # The event object automatically will have members for all events properties # you probably want to create a custom event type, see other examples myevgen = await server.get_event_generator() myevgen.event.Severity = 300 # starting! async with server: print("Available loggers are: ", logging.Logger.manager.loggerDict.keys()) # enable following if you want to subscribe to nodes on server side #handler = SubHandler() #sub = server.create_subscription(500, handler) #handle = sub.subscribe_data_change(myvar) # trigger event, all subscribed clients wil receive it var = await myarrayvar.read_value( ) # return a ref to value in db server side! not a copy! var = copy.copy( var ) # WARNING: we need to copy before writting again otherwise no data change event will be generated var.append(9.3) await myarrayvar.write_value(var) await mydevice_var.write_value("Running") await myevgen.trigger(message="This is BaseEvent") await server.write_attribute_value( myvar.nodeid, ua.DataValue(0.9) ) # Server side write method which is a bit faster than using write_value while True: await asyncio.sleep(0.1) await server.write_attribute_value(myvar.nodeid, ua.DataValue(sin(time.time())))
class server: def __init__(self): logging.info("Creating a opc server") self._server = Server() self._config = False self.nsindex = "" async def NewOPCServer(self, IP): # now setup our server await self._server.init() self._server.disable_clock() #for debuging self.IP = IP.strip() self.mynodes = [] self._server.set_endpoint( self.IP ) #ip removing whitespace Address to pass "opc.tcp://0.0.0.0:4840/freeopcua/server/" self._server.set_server_name("OPC Server Name") # set all possible endpoint policies for clients to connect through self._server.set_security_policy([ ua.SecurityPolicyType.NoSecurity, ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt, ua.SecurityPolicyType.Basic256Sha256_Sign ]) def checkdata(self, data): if len(data) < 5: return False if len(data['measure']) < 1: return False #TODO implement more data check async def LoadConfig(self, path): with open(path) as f: data = json.load(f) if not self.checkdata(data): return False # setup our own namespace await self._server.register_namespace(self.nsindex) self._config = False self.scan = data['scaninterval'] self.nsindex = data['namespaceindex'] self.namespace = data['namespace'] self.devices = data['device'] # create a new node type we can instantiate in our address space dev = await self._server.nodes.base_object_type.add_object_type( int(self.nsindex), self.devices) #Creating the nodes i = 0 for element in data['measure']: self.mynodes.append(await dev.add_variable( ua.NodeId.from_string('ns=' + self.nsindex + ';s=' + self.namespace + '.' + self.devices + '.' + element['name']), element['name'], 0)) await self.mynodes[i].set_writable() i += 1 myevgen = await self._server.get_event_generator() myevgen.event.Severity = 300 logging.info("Configuration loaded") self._config = True async def Start(self): if self._config: async with self._server: #print("Available loggers are: ", logging.Logger.manager.loggerDict.keys()) logging.info("Server Started") while True: await asyncio.sleep(self.scan) for element in self.mynodes: #updating values await self._server.write_attribute_value( element.nodeid, ua.DataValue(sin(time.time()))) logging.warning("The server need to be configure it first") async def CreateXML(self): ipremove = self.IP.replace("opc.tcp://", "") port = ipremove[ipremove.index(":") + 1:] #creating the xml await self._server.export_xml_by_ns( "gen/Configuration" + port + ".xml", int(self.nsindex)) logging.info("XML File created successfully")