Example #1
0
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)
Example #2
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())))
Example #3
0
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")