Ejemplo n.º 1
0
def uahistoryread():
    parser = argparse.ArgumentParser(description="Read history of a node")
    add_common_args(parser)
    parser.add_argument(
        "--starttime", default="", help="Start time, formatted as YYYY-MM-DD [HH:MM[:SS]]. Default: current time"
    )
    parser.add_argument(
        "--endtime", default="", help="End time, formatted as YYYY-MM-DD [HH:MM[:SS]]. Default: current time"
    )

    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        starttime = str_to_datetime(args.starttime)
        endtime = str_to_datetime(args.endtime)
        print(
            "Reading raw history of node {} at {}; start at {}, end at {}\n".format(node, args.url, starttime, endtime)
        )
        print_history(node.read_raw_history(starttime, endtime))
    finally:
        client.disconnect()
    sys.exit(0)
Ejemplo n.º 2
0
def uasubscribe():
    parser = argparse.ArgumentParser(description="Subscribe to a node and print results")
    add_common_args(parser)
    parser.add_argument("-t",
                        "--eventtype",
                        dest="eventtype",
                        default="datachange",
                        choices=['datachange', 'event'],
                        help="Event type to subscribe to")

    args = parse_args(parser, requirenodeid=False)
    if args.eventtype == "datachange":
        _require_nodeid(parser, args)
    else:
        # FIXME: this is broken, someone may have written i=84 on purpose
        if args.nodeid == "i=84" and args.path == "":
            args.nodeid = "i=2253"

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        handler = SubHandler()
        sub = client.create_subscription(500, handler)
        if args.eventtype == "datachange":
            sub.subscribe_data_change(node)
        else:
            sub.subscribe_events(node)
        embed()
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 3
0
def uaread():
    parser = argparse.ArgumentParser(description="Read attribute of a node, per default reads value of a node")
    add_common_args(parser)
    parser.add_argument("-a",
                        "--attribute",
                        dest="attribute",
                        type=int,
                        default=ua.AttributeIds.Value,
                        help="Set attribute to read")
    parser.add_argument("-t",
                        "--datatype",
                        dest="datatype",
                        default="python",
                        choices=['python', 'variant', 'datavalue'],
                        help="Data type to return")

    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        attr = node.get_attribute(args.attribute)
        if args.datatype == "python":
            print(attr.Value.Value)
        elif args.datatype == "variant":
            print(attr.Value)
        else:
            print(attr)
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 4
0
def uaclient():
    parser = argparse.ArgumentParser(description="Connect to server and start python shell. root and objects nodes are available. Node specificed in command line is available as mynode variable")
    add_common_args(parser)
    parser.add_argument("-c",
                        "--certificate",
                        help="set client certificate")
    parser.add_argument("-k",
                        "--private_key",
                        help="set client private key")
    args = parse_args(parser)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    if args.certificate:
        client.load_client_certificate(args.certificate)
    if args.private_key:
        client.load_private_key(args.private_key)
    client.connect()
    try:
        root = client.get_root_node()
        objects = client.get_objects_node()
        mynode = get_node(client, args)
        embed()
    finally:
        client.disconnect()
    sys.exit(0)
Ejemplo n.º 5
0
def uals():
    parser = argparse.ArgumentParser(description="Browse OPC-UA node and print result")
    add_common_args(parser)
    parser.add_argument("-l",
                        dest="long_format",
                        const=3,
                        nargs="?",
                        type=int,
                        help="use a long listing format")
    parser.add_argument("-d",
                        "--depth",
                        default=1,
                        type=int,
                        help="Browse depth")

    args = parse_args(parser)
    if args.long_format is None:
        args.long_format = 1

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        print("Browsing node {} at {}\n".format(node, args.url))
        if args.long_format == 0:
            _lsprint_0(node, args.depth - 1)
        elif args.long_format == 1:
            _lsprint_1(node, args.depth - 1)
        else:
            _lsprint_long(node, args.depth - 1)
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 6
0
def uahistoryread():
    parser = argparse.ArgumentParser(description="Read history of a node")
    add_common_args(parser)
    parser.add_argument(
        "--starttime",
        default="",
        help=
        "Start time, formatted as YYYY-MM-DD [HH:MM[:SS]]. Default: current time"
    )
    parser.add_argument(
        "--endtime",
        default="",
        help=
        "End time, formatted as YYYY-MM-DD [HH:MM[:SS]]. Default: current time"
    )

    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        starttime = str_to_datetime(args.starttime)
        endtime = str_to_datetime(args.endtime)
        print("Reading raw history of node {} at {}; start at {}, end at {}\n".
              format(node, args.url, starttime, endtime))
        print_history(node.read_raw_history(starttime, endtime))
    finally:
        client.disconnect()
    sys.exit(0)
Ejemplo n.º 7
0
def uasubscribe():
    parser = argparse.ArgumentParser(
        description="Subscribe to a node and print results")
    add_common_args(parser)
    parser.add_argument("-t",
                        "--eventtype",
                        dest="eventtype",
                        default="datachange",
                        choices=['datachange', 'event'],
                        help="Event type to subscribe to")

    args = parse_args(parser, requirenodeid=False)
    if args.eventtype == "datachange":
        _require_nodeid(parser, args)
    else:
        # FIXME: this is broken, someone may have written i=84 on purpose
        if args.nodeid == "i=84" and args.path == "":
            args.nodeid = "i=2253"

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        handler = SubHandler()
        sub = client.create_subscription(500, handler)
        if args.eventtype == "datachange":
            sub.subscribe_data_change(node)
        else:
            sub.subscribe_events(node)
        embed()
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 8
0
def uaread():
    parser = argparse.ArgumentParser(description="Read attribute of a node, per default reads value of a node")
    add_common_args(parser)
    parser.add_argument("-a",
                        "--attribute",
                        dest="attribute",
                        type=int,
                        default=ua.AttributeIds.Value,
                        help="Set attribute to read")
    parser.add_argument("-t",
                        "--datatype",
                        dest="datatype",
                        default="python",
                        choices=['python', 'variant', 'datavalue'],
                        help="Data type to return")

    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()

    try:
        node = get_node(client, args)
        attr = node.get_attribute(args.attribute)
        if args.datatype == "python":
            print(attr.Value.Value)
        elif args.datatype == "variant":
            print(attr.Value)
        else:
            print(attr)
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 9
0
def uaclient():
    parser = argparse.ArgumentParser(
        description=
        "Connect to server and start python shell. root and objects nodes are available. Node specificed in command line is available as mynode variable"
    )
    add_common_args(parser)
    parser.add_argument("-c", "--certificate", help="set client certificate")
    parser.add_argument("-k", "--private_key", help="set client private key")
    args = parse_args(parser)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    if args.certificate:
        client.load_client_certificate(args.certificate)
    if args.private_key:
        client.load_private_key(args.private_key)
    client.connect()
    try:
        root = client.get_root_node()
        objects = client.get_objects_node()
        mynode = get_node(client, args)
        embed()
    finally:
        client.disconnect()
    sys.exit(0)
Ejemplo n.º 10
0
def uals():
    parser = argparse.ArgumentParser(description="Browse OPC-UA node and print result")
    add_common_args(parser)
    parser.add_argument("-l",
                        dest="long_format",
                        const=3,
                        nargs="?",
                        type=int,
                        help="use a long listing format")
    parser.add_argument("-d",
                        "--depth",
                        default=1,
                        type=int,
                        help="Browse depth")

    args = parse_args(parser)
    if args.long_format is None:
        args.long_format = 1

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        print("Browsing node {} at {}\n".format(node, args.url))
        if args.long_format == 0:
            _lsprint_0(node, args.depth - 1)
        elif args.long_format == 1:
            _lsprint_1(node, args.depth - 1)
        else:
            _lsprint_long(node, args.depth - 1)
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 11
0
def uageneratestructs():
    parser = argparse.ArgumentParser(
        description=
        "Generate a Python module from the xml structure definition (.bsd)")
    add_common_args(parser, require_node=True)
    parser.add_argument(
        "-o",
        "--output",
        dest="output_path",
        required=True,
        type=str,
        default=None,
        help="The python file to be generated.",
    )
    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        generators, _ = client.load_type_definitions([node])
        generators[0].save_to_file(args.output_path, True)
    finally:
        client.disconnect()
    sys.exit(0)
Ejemplo n.º 12
0
 def test_basic256(self):
     client = Client("opc.tcp://" + os.environ['TEST_IP'] + ":" +
                     os.environ['TEST_PORT'])
     client.application_uri = "urn:127.0.0.1:ASNeG:FTestClient"
     client.set_security_string(
         "Basic128Rsa15,SignAndEncrypt,FTestClient.der,FTestClient.pem")
     client.connect()
     client.disconnect()
Ejemplo n.º 13
0
    def opcua_init(request):

        client = Client(request.get('url', 'opc.tcp://localhost:4841'),
                        timeout=request.get('timeout', 10))
        client.set_security_string(request.get('security', ''))
        client.connect()

        return client
 def test_basic256(self):
     clt = Client(self.uri_crypto)
     try:
         clt.set_security_string("Basic256,Sign,examples/example-certificate.der,examples/example-private-key.pem")
         clt.connect()
         self.assertTrue(clt.get_objects_node().get_children())
     finally:
         clt.disconnect()
Ejemplo n.º 15
0
 def test_basic256sha256_longkey(self):
     clt = Client(self.uri_crypto2)
     try:
         clt.set_security_string("Basic256Sha256,Sign,../examples/certificate-example.der,../examples/private-key-example.pem")
         clt.connect()
         self.assertTrue(clt.get_objects_node().get_children())
     finally:
         clt.disconnect()
 def test_basic128Rsa15_encrypt(self):
     clt = Client(self.uri_crypto)
     try:
         clt.set_security_string("Basic128Rsa15,SignAndEncrypt,examples/certificate-example.der,examples/private-key-example.pem")
         clt.connect()
         self.assertTrue(clt.get_objects_node().get_children())
     finally:
         clt.disconnect()
Ejemplo n.º 17
0
    def opcua_init(request):

        client = Client(
            request.get("url", "opc.tcp://localhost:4841"),
            timeout=request.get("timeout", 10),
        )
        client.set_security_string(request.get("security", ""))
        client.connect()

        return client
Ejemplo n.º 18
0
    def opcua_init(request):

        client = Client(
            request.get('url', 'opc.tcp://localhost:4841'),
            timeout=request.get('timeout', 10)
        )
        client.set_security_string(request.get('security', ''))
        client.connect()

        return client
Ejemplo n.º 19
0
 def test_basic128Rsa15_encrypt(self):
     clt = Client(self.uri_crypto)
     try:
         clt.set_security_string(
             "Basic128Rsa15,SignAndEncrypt,examples/certificate-example.der,examples/private-key-example.pem"
         )
         clt.connect()
         self.assertTrue(clt.get_objects_node().get_children())
     finally:
         clt.disconnect()
Ejemplo n.º 20
0
def uahistoryread():
    parser = argparse.ArgumentParser(description="Read history of a node")
    add_common_args(parser)
    parser.add_argument(
        "--starttime",
        default=None,
        help=
        "Start time, formatted as YYYY-MM-DD [HH:MM[:SS]]. Default: current time - one day"
    )
    parser.add_argument(
        "--endtime",
        default=None,
        help=
        "End time, formatted as YYYY-MM-DD [HH:MM[:SS]]. Default: current time"
    )
    parser.add_argument(
        "-e",
        "--events",
        action="store_true",
        help="Read event history instead of data change history")
    parser.add_argument("-l",
                        "--limit",
                        type=int,
                        default=10,
                        help="Maximum number of notfication to return")

    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        starttime = str_to_datetime(args.starttime,
                                    datetime.utcnow() - timedelta(days=1))
        endtime = str_to_datetime(args.endtime, datetime.utcnow())
        print(
            "Reading raw history of node {0} at {1}; start at {2}, end at {3}\n"
            .format(node, args.url, starttime, endtime))
        if args.events:
            evs = node.read_event_history(starttime,
                                          endtime,
                                          numvalues=args.limit)
            for ev in evs:
                print(ev)
        else:
            print_history(
                node.read_raw_history(starttime, endtime,
                                      numvalues=args.limit))
    finally:
        client.disconnect()
    sys.exit(0)
Ejemplo n.º 21
0
def uawrite():
    parser = argparse.ArgumentParser(
        description="Write attribute of a node, per default write value of node"
    )
    add_common_args(parser)
    parser.add_argument("-a",
                        "--attribute",
                        dest="attribute",
                        type=int,
                        default=ua.AttributeIds.Value,
                        help="Set attribute to read")
    parser.add_argument("-l",
                        "--list",
                        "--array",
                        dest="array",
                        default="guess",
                        choices=["guess", "true", "false"],
                        help="Value is an array")
    parser.add_argument("-t",
                        "--datatype",
                        dest="datatype",
                        default="guess",
                        choices=[
                            "guess", 'byte', 'sbyte', 'nodeid',
                            'expandednodeid', 'qualifiedname', 'browsename',
                            'string', 'float', 'double', 'int16', 'int32',
                            "int64", 'uint16', 'uint32', 'uint64', "bool",
                            "string", 'datetime', 'bytestring', 'xmlelement',
                            'statuscode', 'localizedtext'
                        ],
                        help="Data type to return")
    parser.add_argument("value", help="Value to be written", metavar="VALUE")
    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        val = _val_to_variant(args.value, args)
        node.set_attribute(args.attribute, ua.DataValue(val))
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 22
0
def client_connection(index, server, security_policies_uri, printable=False):
	client = Client(server["address"])	
	try:
		best_endpoint = best_endpoint_selection(client, server, security_policies_uri, printable)
		
		client = Client(best_endpoint.EndpointUrl)	
		client.application_uri = "urn:freeopcua:client"
		client.description = "OPCUA-Client-Kafka-Gateway"
		
		client = client_auth(client, server)
		
		policy = best_endpoint.SecurityPolicyUri.split('#')[1]		
		if policy != "None": 
			security_string = str(policy) + ',' + str(MessageSecurityMode(best_endpoint.SecurityMode).name) + ',client_certificate.pem' + ',client_key.pem' 
			client.set_security_string(security_string)	
		
		client.connect()		
		return client		
	except Exception as ex:
		#print(f"\nEXCEPTION in client connection: {ex.__class__, ex.args}")
		return	
Ejemplo n.º 23
0
def uawrite():
    parser = argparse.ArgumentParser(description="Write attribute of a node, per default write value of node")
    add_common_args(parser)
    parser.add_argument("-a",
                        "--attribute",
                        dest="attribute",
                        type=int,
                        default=ua.AttributeIds.Value,
                        help="Set attribute to read")
    parser.add_argument("-l",
                        "--list",
                        "--array",
                        dest="array",
                        default="guess",
                        choices=["guess", "true", "false"],
                        help="Value is an array")
    parser.add_argument("-t",
                        "--datatype",
                        dest="datatype",
                        default="guess",
                        choices=["guess", 'byte', 'sbyte', 'nodeid', 'expandednodeid', 'qualifiedname', 'browsename', 'string', 'float', 'double', 'int16', 'int32', "int64", 'uint16', 'uint32', 'uint64', "bool", "string", 'datetime', 'bytestring', 'xmlelement', 'statuscode', 'localizedtext'],  
                        help="Data type to return")
    parser.add_argument("value",
                        help="Value to be written",
                        metavar="VALUE")
    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        val = _val_to_variant(args.value, args)
        node.set_attribute(args.attribute, ua.DataValue(val))
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 24
0
def uahistoryread():
    parser = argparse.ArgumentParser(description="Read history of a node")
    add_common_args(parser)
    parser.add_argument("--starttime",
                        default=None,
                        help="Start time, formatted as YYYY-MM-DD [HH:MM[:SS]]. Default: current time - one day")
    parser.add_argument("--endtime",
                        default=None,
                        help="End time, formatted as YYYY-MM-DD [HH:MM[:SS]]. Default: current time")
    parser.add_argument("-e",
                        "--events",
                        action="store_true",
                        help="Read event history instead of data change history")
    parser.add_argument("-l",
                        "--limit",
                        type=int,
                        default=10,
                        help="Maximum number of notfication to return")

    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        starttime = str_to_datetime(args.starttime, datetime.utcnow() - timedelta(days=1))
        endtime = str_to_datetime(args.endtime, datetime.utcnow())
        print("Reading raw history of node {0} at {1}; start at {2}, end at {3}\n".format(node, args.url, starttime, endtime))
        if args.events:
            evs = node.read_event_history(starttime, endtime, numvalues=args.limit)
            for ev in evs:
                print(ev)
        else:
            print_history(node.read_raw_history(starttime, endtime, numvalues=args.limit))
    finally:
        client.disconnect()
    sys.exit(0)
Ejemplo n.º 25
0
class OpcUaConnector(Thread, Connector):
    def __init__(self, gateway, config, connector_type):
        self.__connector_type = connector_type
        self.statistics = {'MessagesReceived': 0, 'MessagesSent': 0}
        super().__init__()
        self.__gateway = gateway
        self.__server_conf = config.get("server")
        self.__interest_nodes = []
        self.__available_object_resources = {}
        for mapping in self.__server_conf["mapping"]:
            if mapping.get("deviceNodePattern") is not None:
                self.__interest_nodes.append(
                    {mapping["deviceNodePattern"]: mapping})
            else:
                log.error(
                    "deviceNodePattern in mapping: %s - not found, add property deviceNodePattern to processing this mapping",
                    dumps(mapping))
        if "opc.tcp" not in self.__server_conf.get("url"):
            opcua_url = "opc.tcp://" + self.__server_conf.get("url")
        else:
            opcua_url = self.__server_conf.get("url")
        self.client = Client(
            opcua_url,
            timeout=self.__server_conf.get("timeoutInMillis", 4000) / 1000)
        if self.__server_conf["identity"]["type"] == "cert.PEM":
            try:
                ca_cert = self.__server_conf["identity"].get("caCert")
                private_key = self.__server_conf["identity"].get("privateKey")
                cert = self.__server_conf["identity"].get("cert")
                security_mode = self.__server_conf["identity"].get(
                    "mode", "SignAndEncrypt")
                policy = self.__server_conf["security"]
                if cert is None or private_key is None:
                    log.exception(
                        "Error in ssl configuration - cert or privateKey parameter not found"
                    )
                    raise
                security_string = policy + ',' + security_mode + ',' + cert + ',' + private_key
                if ca_cert is not None:
                    security_string = security_string + ',' + ca_cert
                self.client.set_security_string(security_string)

            except Exception as e:
                log.exception(e)
        if self.__server_conf["identity"].get("username"):
            self.client.set_user(
                self.__server_conf["identity"].get("username"))
            if self.__server_conf["identity"].get("password"):
                self.client.set_password(
                    self.__server_conf["identity"].get("password"))

        self.setName(
            self.__server_conf.get(
                "name", 'OPC-UA Default ' +
                ''.join(choice(ascii_lowercase)
                        for _ in range(5))) + " Connector")
        self.__opcua_nodes = {}
        self._subscribed = {}
        self.data_to_send = []
        self.__sub_handler = SubHandler(self)
        self.__stopped = False
        self.__connected = False
        self.daemon = True

    def is_connected(self):
        return self.__connected

    def open(self):
        self.__stopped = False
        self.start()
        log.info("Starting OPC-UA Connector")

    def run(self):
        while not self.__connected:
            try:
                self.__connected = self.client.connect()
                self.client.load_type_definitions()
                log.debug(self.client.get_namespace_array()[-1])
                log.debug(
                    self.client.get_namespace_index(
                        self.client.get_namespace_array()[-1]))
            except ConnectionRefusedError:
                log.error(
                    "Connection refused on connection to OPC-UA server with url %s",
                    self.__server_conf.get("url"))
                time.sleep(10)
            except Exception as e:
                log.debug("error on connection to OPC-UA server.")
                log.error(e)
                time.sleep(10)
            else:
                self.__connected = True
                log.info("OPC-UA connector %s connected to server %s",
                         self.get_name(), self.__server_conf.get("url"))
        self.__opcua_nodes["root"] = self.client.get_root_node()
        self.__opcua_nodes["objects"] = self.client.get_objects_node()
        sub = self.client.create_subscription(
            self.__server_conf.get("scanPeriodInMillis", 500),
            self.__sub_handler)
        self.__search_name(self.__opcua_nodes["objects"], 2)
        self.__search_tags(self.__opcua_nodes["objects"], 2, sub)
        log.debug('Subscriptions: %s', self.subscribed)

        log.debug("Available methods: %s", self.__available_object_resources)
        while True:
            try:
                time.sleep(1)
                if self.data_to_send:
                    self.__gateway.send_to_storage(self.get_name(),
                                                   self.data_to_send.pop())
                if self.__stopped:
                    break
            except (KeyboardInterrupt, SystemExit):
                self.close()
                raise
            except Exception as e:
                self.close()
                log.exception(e)

    def close(self):
        self.__stopped = True
        self.client.disconnect()
        self.__connected = False
        log.info('%s has been stopped.', self.get_name())

    def get_name(self):
        return self.name

    def on_attributes_update(self, content):
        log.debug(content)
        try:
            for server_variables in self.__available_object_resources[
                    content["device"]]['variables']:
                for attribute in content["data"]:
                    for variable in server_variables:
                        if attribute == variable:
                            server_variables[variable].set_value(
                                content["data"][variable])
        except Exception as e:
            log.exception(e)

    def server_side_rpc_handler(self, content):
        try:
            for method in self.__available_object_resources[
                    content["device"]]['methods']:
                rpc_method = content["data"].get("method")
                if rpc_method is not None and method.get(
                        rpc_method) is not None:
                    arguments = content["data"].get("params")
                    if type(arguments) is list:
                        result = method["node"].call_method(
                            method[rpc_method], *arguments)
                    elif arguments is not None:
                        result = method["node"].call_method(
                            method[rpc_method], arguments)
                    else:
                        result = method["node"].call_method(method[rpc_method])

                    self.__gateway.send_rpc_reply(
                        content["device"], content["data"]["id"],
                        {content["data"]["method"]: result})

                    log.debug("method %s result is: %s", method[rpc_method],
                              result)
        except Exception as e:
            log.exception(e)

    def __search_name(self, node, recursion_level):
        try:
            for childId in node.get_children():
                ch = self.client.get_node(childId)
                current_var_path = '.'.join(
                    x.split(":")[1] for x in ch.get_path(20000, True))
                if self.__interest_nodes:
                    if ch.get_node_class() == ua.NodeClass.Object:
                        for interest_node in self.__interest_nodes:
                            for int_node in interest_node:
                                subrecursion_level = recursion_level
                                if subrecursion_level != recursion_level + len(
                                        interest_node[int_node]
                                    ["deviceNamePattern"].split("\\.")):
                                    if ch.get_display_name().Text in TBUtility.get_value(interest_node[int_node]["deviceNamePattern"], get_tag=True).split('.') or \
                                            re.search(TBUtility.get_value(interest_node[int_node]["deviceNodePattern"], get_tag=True), ch.get_display_name().Text):
                                        self.__search_name(
                                            ch, subrecursion_level + 1)
                                else:
                                    return
                    elif ch.get_node_class() == ua.NodeClass.Variable:
                        try:
                            for interest_node in self.__interest_nodes:
                                for int_node in interest_node:
                                    if interest_node[int_node].get(
                                            "deviceName") is None:
                                        try:
                                            name_pattern = TBUtility.get_value(
                                                interest_node[int_node]
                                                ["deviceNamePattern"],
                                                get_tag=True)
                                            log.debug(current_var_path)
                                            device_name_node = re.search(
                                                name_pattern.split('\\.')[-1],
                                                current_var_path)
                                            if device_name_node is not None:
                                                device_name = ch.get_value()
                                                if "${" + name_pattern + "}" in interest_node[
                                                        int_node][
                                                            "deviceNamePattern"]:
                                                    full_device_name = interest_node[
                                                        int_node][
                                                            "deviceNamePattern"].replace(
                                                                "${" +
                                                                name_pattern +
                                                                "}",
                                                                device_name)
                                                elif device_name in interest_node[
                                                        int_node][
                                                            "deviceNamePattern"]:
                                                    full_device_name = interest_node[
                                                        int_node][
                                                            "deviceNamePattern"].replace(
                                                                name_pattern,
                                                                device_name)
                                                else:
                                                    log.error(
                                                        "Name pattern not found."
                                                    )
                                                    break
                                                interest_node[int_node][
                                                    "deviceName"] = full_device_name
                                                if self.__available_object_resources.get(
                                                        full_device_name
                                                ) is None:
                                                    self.__available_object_resources[
                                                        full_device_name] = {
                                                            'methods': [],
                                                            'variables': []
                                                        }
                                                if not self.__gateway.get_devices(
                                                ).get(full_device_name):
                                                    self.__gateway.add_device(
                                                        full_device_name,
                                                        {"connector": None})
                                                self.__gateway.update_device(
                                                    full_device_name,
                                                    "connector", self)
                                            else:
                                                try:
                                                    if re.search(
                                                            int_node.split(
                                                                '\\.')
                                                        [recursion_level - 2],
                                                            ch.
                                                            get_display_name(
                                                            ).Text):
                                                        self.__search_name(
                                                            ch,
                                                            recursion_level +
                                                            1)
                                                except IndexError:
                                                    if re.search(
                                                            int_node.split(
                                                                '\\.')[-1],
                                                            ch.
                                                            get_display_name(
                                                            ).Text):
                                                        self.__search_name(
                                                            ch,
                                                            recursion_level +
                                                            1)

                                        except Exception as e:
                                            log.exception(e)
                                    else:
                                        break
                        except BadWaitingForInitialData:
                            pass
                elif not self.__interest_nodes:
                    log.error(
                        "Nodes in mapping not found, check your settings.")
        except Exception as e:
            log.exception(e)

    def __search_tags(self, node, recursion_level, sub=None):
        try:
            for childId in node.get_children():
                ch = self.client.get_node(childId)
                current_var_path = '.'.join(
                    x.split(":")[1] for x in ch.get_path(20000, True))
                if self.__interest_nodes:
                    if ch.get_node_class() == ua.NodeClass.Object:
                        for interest_node in self.__interest_nodes:
                            for int_node in interest_node:
                                try:
                                    name_to_check = int_node.split('\\.')[
                                        recursion_level -
                                        1] if '\\.' in int_node else int_node
                                    name_to_check = int_node.split(
                                        '.'
                                    )[recursion_level -
                                      1] if '.' in int_node else name_to_check
                                except IndexError:
                                    name_to_check = int_node.split(
                                        '\\.'
                                    )[-1] if '\\.' in int_node else int_node
                                    name_to_check = int_node.split(
                                        '.'
                                    )[-1] if '.' in int_node else name_to_check
                                if re.search(name_to_check,
                                             ch.get_display_name().Text):
                                    try:
                                        methods = ch.get_methods()
                                        for method in methods:
                                            self.__available_object_resources[
                                                interest_node[int_node]
                                                ["deviceName"]][
                                                    "methods"].append({
                                                        method.get_display_name(
                                                        ).Text:
                                                        method,
                                                        "node":
                                                        ch
                                                    })
                                    except Exception as e:
                                        log.exception(e)
                                for tag in interest_node[int_node][
                                        "timeseries"] + interest_node[
                                            int_node]["attributes"]:
                                    subrecursion_level = recursion_level
                                    if subrecursion_level != recursion_level + len(
                                            tag["path"].split("\\.")):
                                        self.__search_tags(
                                            ch, subrecursion_level + 1, sub)
                                    else:
                                        return
                                self.__search_tags(ch, recursion_level + 1,
                                                   sub)
                    elif ch.get_node_class() == ua.NodeClass.Variable:
                        try:
                            for interest_node in self.__interest_nodes:
                                for int_node in interest_node:
                                    if interest_node[int_node].get(
                                            "attributes_updates"):
                                        try:
                                            for attribute_update in interest_node[
                                                    int_node][
                                                        "attributes_updates"]:
                                                if attribute_update[
                                                        "attributeOnDevice"] == ch.get_display_name(
                                                        ).Text:
                                                    self.__available_object_resources[
                                                        interest_node[int_node]
                                                        ["deviceName"]][
                                                            'variables'].append({
                                                                attribute_update["attributeOnThingsBoard"]:
                                                                ch,
                                                            })
                                        except Exception as e:
                                            log.exception(e)
                                    name_to_check = int_node.split(
                                        '\\.'
                                    )[-1] if '\\.' in int_node else int_node
                                    name_to_check = int_node.split(
                                        '.'
                                    )[-1] if '.' in int_node else name_to_check
                                    if re.search(
                                            name_to_check.replace('$', ''),
                                            current_var_path):
                                        tags = []
                                        if interest_node[int_node].get(
                                                "attributes"):
                                            tags.extend(interest_node[int_node]
                                                        ["attributes"])
                                        if interest_node[int_node].get(
                                                "timeseries"):
                                            tags.extend(interest_node[int_node]
                                                        ["timeseries"])
                                        for tag in tags:
                                            target = TBUtility.get_value(
                                                tag["path"], get_tag=True)
                                            try:
                                                tag_name_for_check = target.split(
                                                    '\\.'
                                                )[recursion_level -
                                                  1] if '\\.' in target else target
                                                tag_name_for_check = target.split(
                                                    '.'
                                                )[recursion_level -
                                                  1] if '.' in target else tag_name_for_check
                                            except IndexError:
                                                tag_name_for_check = target.split(
                                                    '\\.'
                                                )[-1] if '\\.' in target else target
                                                tag_name_for_check = target.split(
                                                    '.'
                                                )[-1] if '.' in target else tag_name_for_check
                                            current_node_name = ch.get_display_name(
                                            ).Text
                                            if current_node_name == tag_name_for_check:
                                                sub.subscribe_data_change(ch)
                                                if interest_node[int_node].get(
                                                        "uplink_converter"
                                                ) is None:
                                                    if interest_node[
                                                            int_node].get(
                                                                'converter'
                                                            ) is None:
                                                        converter = OpcUaUplinkConverter(
                                                            interest_node[
                                                                int_node])
                                                    else:
                                                        converter = TBUtility.check_and_import(
                                                            self.
                                                            __connector_type,
                                                            interest_node[
                                                                int_node]
                                                            ['converter'])
                                                    interest_node[int_node][
                                                        "uplink_converter"] = converter
                                                else:
                                                    converter = interest_node[
                                                        int_node][
                                                            "uplink_converter"]
                                                self.subscribed[ch] = {
                                                    "converter": converter,
                                                    "path": current_var_path
                                                }
                                    else:
                                        return
                        except BadWaitingForInitialData:
                            pass
                    elif not self.__interest_nodes:
                        log.error(
                            "Nodes in mapping not found, check your settings.")
        except Exception as e:
            log.exception(e)

    @property
    def subscribed(self):
        return self._subscribed
Ejemplo n.º 26
0
from opcua import Client
from firebase import Firebase
import csv
import time
# url and security 
url= 'opc.tcp://127.0.0.1:8080'
client = Client(url)
client.set_security_string("Basic256Sha256,SignAndEncrypt,certificate-example.der,private-key-example.pem") # add "server" certificate.dem file and private-key.pem file (Beckhoff_OpcUaServer.der,Beckhoff_OpcUaServer.pem)
client.application_uri = "urn:example.org:FreeOpcUa:python-opcua" # use the uri of the server. (urn:BeckhoffAutomation:TcOpcUaServer)

# client connection 
client.connect()
print('CLIENT CONNECTED SUCCESSFULLY')
# firebase initialization 
firebaseConfig = {
   # here the firebase configuration should be entered
}

firebase = Firebase(firebaseConfig)
db = firebase.database()
with open('historyAccess_client.csv',mode='a', newline='') as historyAccess:
    fieldnames= ['Temperature','Pressure','Flow','Time']
    thewriter = csv.DictWriter(historyAccess,fieldnames=fieldnames)
    thewriter.writeheader()
    while True:
        iTemp = client.get_node('ns=2;i=3')         
        Temperature = iTemp.get_value()
        print(f'Temperature is: {Temperature}')

        iprssure = client.get_node('ns=2;i=2')          
        Pressure = iprssure.get_value()
Ejemplo n.º 27
0
class CustomClient(object):
    def __init__(self,
                 server_endpoint,
                 namespace,
                 enable_cert,
                 client_cert_path,
                 client_key_path,
                 auth_name=None,
                 auth_password=None,
                 debug_print=False,
                 client_request_timeout=4):

        self.NAMESPACE = namespace
        self.DEBUG_MODE_PRINT = debug_print

        self.client = Client(server_endpoint, client_request_timeout)

        if auth_name is not None and auth_password is not None:
            self.client.set_user(auth_name)
            self.client.set_password(auth_password)
        if enable_cert:
            self.client.set_security_string("Basic256Sha256,SignAndEncrypt," +
                                            client_cert_path + "," +
                                            client_key_path)

        # TODO experimental( cf. client.py @line 60)
        # self.client.session_timeout = 10*1000            # 30h = 30*60*60*1000
        # self.client.secure_channel_timeout = 10*1000     # 30h

        self.root = None
        self.idx = None

    def start(self):
        try:
            self.client.connect()
        except ConnectionError as er:
            print(DateHelper.get_local_datetime(), er)
            raise
            # sys.exit(1)
        except Exception as ex:
            print(DateHelper.get_local_datetime(), ex)
            raise
            # sys.exit(1)

        # Now getting root variable node using its browse path
        self.root = self.client.get_root_node()
        uri = self.NAMESPACE
        self.idx = self.client.get_namespace_index(uri)

    def stop(self):
        try:
            self.client.disconnect()
        except Exception as ex:
            print("Couldn't stop OPC Client because of: ", ex)

    def get_server_vars(self, child):
        # TODO raise TimeOutError when called after subscription was set up, (cf. ua_client.py: send_request)
        try:
            obj = self.root.get_child(
                ["0:Objects", ("{}:" + child).format(self.idx)])
            # print(obj.get_browse_name())
            # print(obj.get_variables())
        except BadNoMatch:
            return None
        return obj.get_variables()

    def create_dir_on_server(self, child):
        # get object node
        objects_node = self.client.get_objects_node()

        # add new folder "child" first
        for method in objects_node.get_methods():
            # print(method.get_browse_name().Name)
            if "ADD_NEW_OBJECTS_FOLDER" in method.get_browse_name().Name:
                objects_node.call_method(method, child)

    def register_variables_to_server(self, child, file_path):
        # get object node
        objects_node = self.client.get_objects_node()
        # get tags of variables and register them serverside in folder "child"
        mtagfile = open(file_path, 'r')
        tags_pf_output = format_textfile(mtagfile.readlines())
        mtagfile.close()

        # VARIANT A
        for method in objects_node.get_methods():
            # print(method.get_browse_name().Name)
            if "ADD_OPC_TAG" in method.get_browse_name().Name:
                for i in tags_pf_output:
                    opctag, typ = i.split()
                    opctag, typ = opctag.strip(), int(typ)

                    # call method to register var
                    objects_node.call_method(method, opctag,
                                             numbers_to_typestrings(typ),
                                             child)

        # VARIANT B
        # for i in tags_pf_output:
        #     opctag, typ = i.split()
        #     opctag, typ = opctag.strip(), int(typ)
        #
        #
        #     # register vars at server
        #     mvar = folder.add_variable(self.idx, opctag.strip(), ua.Variant(0, numbers_to_vartyps(typ)))
        #     mvar.set_writable()
        #
        #     # Test
        #     # dv = DataValue()
        #     # dv.Value = ua.Variant(1,numbers_to_vartyps(typ))
        #     # mvar.set_value(dv)

    @staticmethod
    def set_vars(observed_nodes_list, ctrl_list, value_list):
        """
        Set new value for node.
        :param observed_nodes_list: list of nodes, the client subscribed to
        :param ctrl_list: list of nodes to update
        :param value_list: list of values to assign
        """
        i = 0
        for ctrl in ctrl_list:
            for var in observed_nodes_list:
                if var.nodeid == ctrl.nodeid:
                    try:
                        variant_type = var.get_data_value().Value.VariantType
                        var.set_value(value_list[i], variant_type)
                        break
                    except Exception as ex:
                        if type(ex).__name__ in TimeoutError.__name__:
                            print(
                                DateHelper.get_local_datetime(),
                                'TimeOutError ignored while set var in OPCClient'
                            )
                            pass
                        else:
                            print(DateHelper.get_local_datetime(), ex)
                            raise
            i += 1

    # region subscription
    def _subscribe(self, dir_name, sub_handler, subscription,
                   subscription_handle, list_of_nodes_to_subscribe,
                   already_subscribed_nodes, sub_interval):
        """
            Make a subscription for list of nodes and return handle for subscription
                :param dir_name: subfolder, which contains the requested nodes
                :param sub_handler: SubHandler which will call the update_data function
                :param subscription: subscription object
                :param subscription_handle: handle can used to unsubscribe
                :param list_of_nodes_to_subscribe: list of nodes/customVars
                :param already_subscribed_nodes: list of nodes which already within subscription
                :param sub_interval: time interval the subscribed node is checked (in ms)

                :return subscription:
                :return subscription_handle
                :return subscribed_nodes
        """
        if subscription is not None:
            self._unsubscribe(subscription, subscription_handle)
            already_subscribed_nodes = []

        all_server_nodes = self.get_server_vars(dir_name)

        for node in all_server_nodes:
            for var in list_of_nodes_to_subscribe:
                if node.nodeid == var.nodeid:
                    already_subscribed_nodes.append(node)

        # make subscription
        subscription = self.client.create_subscription(sub_interval,
                                                       sub_handler)
        subscription_handle = subscription.subscribe_data_change(
            already_subscribed_nodes)

        return subscription, subscription_handle, already_subscribed_nodes

    # will raise TimeoutError() - why? --> use self.subscription.delete() instead
    @staticmethod
    def _unsubscribe(self, subscription, subscription_handle):
        if subscription_handle is not None:
            # self.stop()
            # self.start()
            # self.subscription.delete()
            subscription.unsubscribe(subscription_handle)
 def test_nocrypto_feil(self):
     clt = Client(self.uri_no_crypto)
     with self.assertRaises(ua.UaError):
         clt.set_security_string("Basic256,Sign,examples/certificate-example.der,examples/private-key-example.pem")
Ejemplo n.º 29
0
class OpcUaConnector(Thread, Connector):
    def __init__(self, gateway, config, connector_type):
        self._connector_type = connector_type
        self.statistics = {'MessagesReceived': 0, 'MessagesSent': 0}
        super().__init__()
        self.__gateway = gateway
        self.__server_conf = config.get("server")
        self.__interest_nodes = []
        self.__available_object_resources = {}
        self.__show_map = self.__server_conf.get("showMap", False)
        self.__previous_scan_time = 0
        for mapping in self.__server_conf["mapping"]:
            if mapping.get("deviceNodePattern") is not None:
                self.__interest_nodes.append(
                    {mapping["deviceNodePattern"]: mapping})
            else:
                log.error(
                    "deviceNodePattern in mapping: %s - not found, add property deviceNodePattern to processing this mapping",
                    dumps(mapping))
        if "opc.tcp" not in self.__server_conf.get("url"):
            opcua_url = "opc.tcp://" + self.__server_conf.get("url")
        else:
            opcua_url = self.__server_conf.get("url")
        self.client = Client(
            opcua_url,
            timeout=self.__server_conf.get("timeoutInMillis", 4000) / 1000)
        if self.__server_conf["identity"]["type"] == "cert.PEM":
            try:
                ca_cert = self.__server_conf["identity"].get("caCert")
                private_key = self.__server_conf["identity"].get("privateKey")
                cert = self.__server_conf["identity"].get("cert")
                security_mode = self.__server_conf["identity"].get(
                    "mode", "SignAndEncrypt")
                policy = self.__server_conf["security"]
                if cert is None or private_key is None:
                    log.exception(
                        "Error in ssl configuration - cert or privateKey parameter not found"
                    )
                    raise
                security_string = policy + ',' + security_mode + ',' + cert + ',' + private_key
                if ca_cert is not None:
                    security_string = security_string + ',' + ca_cert
                self.client.set_security_string(security_string)

            except Exception as e:
                log.exception(e)
        if self.__server_conf["identity"].get("username"):
            self.client.set_user(
                self.__server_conf["identity"].get("username"))
            if self.__server_conf["identity"].get("password"):
                self.client.set_password(
                    self.__server_conf["identity"].get("password"))

        self.setName(
            self.__server_conf.get(
                "name", 'OPC-UA ' +
                ''.join(choice(ascii_lowercase)
                        for _ in range(5))) + " Connector")
        self.__opcua_nodes = {}
        self._subscribed = {}
        self.data_to_send = []
        self.__sub_handler = SubHandler(self)
        self.__stopped = False
        self.__connected = False
        self.daemon = True

    def is_connected(self):
        return self.__connected

    def open(self):
        self.__stopped = False
        self.start()
        log.info("Starting OPC-UA Connector")

    def run(self):
        while not self.__connected:
            try:
                self.__connected = self.client.connect()
                try:
                    self.client.load_type_definitions()
                except Exception as e:
                    log.debug(e)
                    log.debug("Error on loading type definitions.")
                log.debug(self.client.get_namespace_array()[-1])
                log.debug(
                    self.client.get_namespace_index(
                        self.client.get_namespace_array()[-1]))
            except ConnectionRefusedError:
                log.error(
                    "Connection refused on connection to OPC-UA server with url %s",
                    self.__server_conf.get("url"))
                time.sleep(10)
            except OSError:
                log.error(
                    "Connection refused on connection to OPC-UA server with url %s",
                    self.__server_conf.get("url"))
                time.sleep(10)
            except Exception as e:
                log.debug("error on connection to OPC-UA server.")
                log.error(e)
                time.sleep(10)
            else:
                self.__connected = True
                log.info("OPC-UA connector %s connected to server %s",
                         self.get_name(), self.__server_conf.get("url"))
        self.__opcua_nodes["root"] = self.client.get_objects_node()
        self.__opcua_nodes["objects"] = self.client.get_objects_node()
        if not self.__server_conf.get("disableSubscriptions", False):
            self.__sub = self.client.create_subscription(
                self.__server_conf.get("subCheckPeriodInMillis", 500),
                self.__sub_handler)
        else:
            self.__sub = False
        self.__scan_nodes_from_config()
        self.__previous_scan_time = time.time() * 1000
        log.debug('Subscriptions: %s', self.subscribed)
        log.debug("Available methods: %s", self.__available_object_resources)
        while not self.__stopped:
            try:
                time.sleep(.1)
                self.__check_connection()
                if not self.__connected and not self.__stopped:
                    self.client.connect()
                elif not self.__stopped:
                    if self.__server_conf.get(
                            "disableSubscriptions", False
                    ) and time.time(
                    ) * 1000 - self.__previous_scan_time > self.__server_conf.get(
                            "scanPeriodInMillis", 60000):
                        self.__scan_nodes_from_config()
                        self.__previous_scan_time = time.time() * 1000

                    if self.data_to_send:
                        self.__gateway.send_to_storage(self.get_name(),
                                                       self.data_to_send.pop())
                if self.__stopped:
                    self.close()
                    break
            except (KeyboardInterrupt, SystemExit):
                self.close()
                raise
            except ConnectionRefusedError:
                log.error(
                    "Connection refused on connection to OPC-UA server with url %s",
                    self.__server_conf.get("url"))
                time.sleep(10)
            except Exception as e:
                self.close()
                log.exception(e)

    def __check_connection(self):
        try:
            node = self.client.get_root_node()
            node.get_children()
            self.__connected = True
        except ConnectionRefusedError:
            self.__connected = False
            self._subscribed = {}
            self.__sub = None
        except OSError:
            self.__connected = False
            self._subscribed = {}
            self.__sub = None
        except TimeoutError:
            self.__connected = False
            self._subscribed = {}
            self.__sub = None
        except AttributeError:
            self.__connected = False
            self._subscribed = {}
            self.__sub = None
        except Exception as e:
            self.__connected = False
            self._subscribed = {}
            self.__sub = None
            log.exception(e)

    def close(self):
        self.__stopped = True
        if self.__connected:
            self.client.disconnect()
        self.__connected = False
        log.info('%s has been stopped.', self.get_name())

    def get_name(self):
        return self.name

    def on_attributes_update(self, content):
        log.debug(content)
        try:
            for server_variables in self.__available_object_resources[
                    content["device"]]['variables']:
                for attribute in content["data"]:
                    for variable in server_variables:
                        if attribute == variable:
                            server_variables[variable].set_value(
                                content["data"][variable])
        except Exception as e:
            log.exception(e)

    def server_side_rpc_handler(self, content):
        try:
            for method in self.__available_object_resources[
                    content["device"]]['methods']:
                rpc_method = content["data"].get("method")
                if rpc_method is not None and method.get(
                        rpc_method) is not None:
                    arguments_from_config = method["arguments"]
                    arguments = content["data"].get(
                        "params") if content["data"].get(
                            "params") is not None else arguments_from_config
                    try:
                        if type(arguments) is list:
                            result = method["node"].call_method(
                                method[rpc_method], *arguments)
                        elif arguments is not None:
                            result = method["node"].call_method(
                                method[rpc_method], arguments)
                        else:
                            result = method["node"].call_method(
                                method[rpc_method])

                        self.__gateway.send_rpc_reply(
                            content["device"], content["data"]["id"], {
                                content["data"]["method"]: result,
                                "code": 200
                            })
                        log.debug("method %s result is: %s",
                                  method[rpc_method], result)
                    except Exception as e:
                        log.exception(e)
                        self.__gateway.send_rpc_reply(content["device"],
                                                      content["data"]["id"], {
                                                          "error": str(e),
                                                          "code": 500
                                                      })
                else:
                    log.error("Method %s not found for device %s", rpc_method,
                              content["device"])
                    self.__gateway.send_rpc_reply(
                        content["device"], content["data"]["id"], {
                            "error": "%s - Method not found" % (rpc_method),
                            "code": 404
                        })
        except Exception as e:
            log.exception(e)

    def __scan_nodes_from_config(self):
        try:
            if self.__interest_nodes:
                for device_object in self.__interest_nodes:
                    for current_device in device_object:
                        try:
                            device_configuration = device_object[
                                current_device]
                            devices_info_array = self.__search_general_info(
                                device_configuration)
                            for device_info in devices_info_array:
                                if device_info is not None and device_info.get(
                                        "deviceNode") is not None:
                                    self.__search_nodes_and_subscribe(
                                        device_info)
                                    self.__save_methods(device_info)
                                    self.__search_attribute_update_variables(
                                        device_info)
                                else:
                                    log.error(
                                        "Device node is None, please check your configuration."
                                    )
                                    log.debug(
                                        "Current device node is: %s",
                                        str(
                                            device_configuration.get(
                                                "deviceNodePattern")))
                                    break
                        except Exception as e:
                            log.exception(e)
                log.debug(self.__interest_nodes)
        except Exception as e:
            log.exception(e)

    def __search_nodes_and_subscribe(self, device_info):
        information_types = {
            "attributes": "attributes",
            "timeseries": "telemetry"
        }
        for information_type in information_types:
            for information in device_info["configuration"][information_type]:
                information_key = information["key"]
                config_path = TBUtility.get_value(information["path"],
                                                  get_tag=True)
                information_path = self._check_path(config_path,
                                                    device_info["deviceNode"])
                information["path"] = '${%s}' % information_path
                information_nodes = []
                self.__search_node(device_info["deviceNode"],
                                   information_path,
                                   result=information_nodes)
                for information_node in information_nodes:
                    if information_node is not None:
                        information_value = information_node.get_value()
                        log.debug(
                            "Node for %s \"%s\" with path: %s - FOUND! Current values is: %s",
                            information_type, information_key,
                            information_path, str(information_value))
                        if device_info.get("uplink_converter") is None:
                            configuration = {
                                **device_info["configuration"], "deviceName":
                                device_info["deviceName"],
                                "deviceType":
                                device_info["deviceType"]
                            }
                            if device_info["configuration"].get(
                                    'converter') is None:
                                converter = OpcUaUplinkConverter(configuration)
                            else:
                                converter = TBUtility.check_and_import(
                                    self._connector_type, configuration)
                            device_info["uplink_converter"] = converter
                        else:
                            converter = device_info["uplink_converter"]
                        self.subscribed[information_node] = {
                            "converter": converter,
                            "path": information_path,
                            "config_path": config_path
                        }
                        if not device_info.get(
                                information_types[information_type]):
                            device_info[
                                information_types[information_type]] = []
                        converted_data = converter.convert(
                            (config_path, information_path), information_value)
                        self.statistics['MessagesReceived'] += 1
                        self.data_to_send.append(converted_data)
                        self.statistics['MessagesSent'] += 1
                        if self.__sub is None:
                            self.__sub = self.client.create_subscription(
                                self.__server_conf.get(
                                    "subCheckPeriodInMillis", 500),
                                self.__sub_handler)
                        if self.__sub:
                            self.__sub.subscribe_data_change(information_node)
                        log.debug("Added subscription to node: %s",
                                  str(information_node))
                        log.debug("Data to ThingsBoard: %s", converted_data)
                    else:
                        log.error(
                            "Node for %s \"%s\" with path %s - NOT FOUND!",
                            information_type, information_key,
                            information_path)

    def __save_methods(self, device_info):
        try:
            if self.__available_object_resources.get(
                    device_info["deviceName"]) is None:
                self.__available_object_resources[
                    device_info["deviceName"]] = {}
            if self.__available_object_resources[
                    device_info["deviceName"]].get("methods") is None:
                self.__available_object_resources[
                    device_info["deviceName"]]["methods"] = []
            if device_info["configuration"].get("rpc_methods"):
                node = device_info["deviceNode"]
                for method_object in device_info["configuration"][
                        "rpc_methods"]:
                    method_node_path = self._check_path(
                        method_object["method"], node)
                    methods = []
                    self.__search_node(node,
                                       method_node_path,
                                       True,
                                       result=methods)
                    for method in methods:
                        if method is not None:
                            node_method_name = method.get_display_name().Text
                            self.__available_object_resources[
                                device_info["deviceName"]]["methods"].append({
                                    node_method_name:
                                    method,
                                    "node":
                                    node,
                                    "arguments":
                                    method_object.get("arguments")
                                })
                        else:
                            log.error(
                                "Node for method with path %s - NOT FOUND!",
                                method_node_path)
        except Exception as e:
            log.exception(e)

    def __search_attribute_update_variables(self, device_info):
        try:
            if device_info["configuration"].get("attributes_updates"):
                node = device_info["deviceNode"]
                device_name = device_info["deviceName"]
                if self.__available_object_resources.get(device_name) is None:
                    self.__available_object_resources[device_name] = {}
                if self.__available_object_resources[device_name].get(
                        "variables") is None:
                    self.__available_object_resources[device_name][
                        "variables"] = []
                for attribute_update in device_info["configuration"][
                        "attributes_updates"]:
                    attribute_path = self._check_path(
                        attribute_update["attributeOnDevice"], node)
                    attribute_nodes = []
                    self.__search_node(node,
                                       attribute_path,
                                       result=attribute_nodes)
                    for attribute_node in attribute_nodes:
                        if attribute_node is not None:
                            self.__available_object_resources[device_name][
                                "variables"].append({
                                    attribute_update["attributeOnThingsBoard"]:
                                    attribute_node
                                })
                        else:
                            log.error(
                                "Attribute update node with path \"%s\" - NOT FOUND!",
                                attribute_path)
        except Exception as e:
            log.exception(e)

    def __search_general_info(self, device):
        result = []
        match_devices = []
        self.__search_node(self.__opcua_nodes["root"],
                           TBUtility.get_value(device["deviceNodePattern"],
                                               get_tag=True),
                           result=match_devices)
        for device_node in match_devices:
            if device_node is not None:
                result_device_dict = {
                    "deviceName": None,
                    "deviceType": None,
                    "deviceNode": device_node,
                    "configuration": deepcopy(device)
                }
                name_pattern_config = device["deviceNamePattern"]
                name_expression = TBUtility.get_value(name_pattern_config,
                                                      get_tag=True)
                if "${" in name_pattern_config and "}" in name_pattern_config:
                    log.debug("Looking for device name")
                    name_path = self._check_path(name_expression, device_node)
                    device_name_node = []
                    self.__search_node(device_node,
                                       name_path,
                                       result=device_name_node)
                    device_name_node = device_name_node[0]
                    if device_name_node is not None:
                        device_name_from_node = device_name_node.get_value()
                        full_device_name = name_pattern_config.replace(
                            "${" + name_expression + "}",
                            str(device_name_from_node)).replace(
                                name_expression, str(device_name_from_node))
                    else:
                        log.error(
                            "Device name node not found with expression: %s",
                            name_expression)
                        return
                else:
                    full_device_name = name_expression
                result_device_dict["deviceName"] = full_device_name
                log.debug("Device name: %s", full_device_name)
                if device.get("deviceTypePattern"):
                    device_type_expression = TBUtility.get_value(
                        device["deviceTypePattern"], get_tag=True)
                    if "${" in device_type_expression and "}" in device_type_expression:
                        type_path = self._check_path(device_type_expression,
                                                     device_node)
                        device_type_node = []
                        self.__search_node(device_node,
                                           type_path,
                                           result=device_type_node)
                        device_type_node = device_type_node[0]
                        if device_type_node is not None:
                            device_type = device_type_node.get_value()
                            full_device_type = device_type_expression.replace(
                                "${" + device_type_expression + "}",
                                device_type).replace(device_type_expression,
                                                     device_type)
                        else:
                            log.error(
                                "Device type node not found with expression: %s",
                                device_type_expression)
                            full_device_type = "default"
                    else:
                        full_device_type = device_type_expression
                    result_device_dict["deviceType"] = full_device_type
                    log.debug("Device type: %s", full_device_type)
                else:
                    result_device_dict["deviceType"] = "default"
                result.append(result_device_dict)
            else:
                log.error(
                    "Device node not found with expression: %s",
                    TBUtility.get_value(device["deviceNodePattern"],
                                        get_tag=True))
        return result

    def __search_node(self,
                      current_node,
                      fullpath,
                      search_method=False,
                      result=[]):
        fullpath_pattern = regex.compile(fullpath)
        try:
            for child_node in current_node.get_children():
                new_node = self.client.get_node(child_node)
                new_node_path = '\\\\.'.join(
                    char.split(":")[1]
                    for char in new_node.get_path(200000, True))
                if self.__show_map:
                    log.debug("SHOW MAP: Current node path: %s", new_node_path)
                new_node_class = new_node.get_node_class()
                # regex_fullmatch = re.fullmatch(fullpath, new_node_path.replace('\\\\.', '.')) or new_node_path.replace('\\\\', '\\') == fullpath
                regex_fullmatch = regex.fullmatch(fullpath_pattern, new_node_path.replace('\\\\.', '.')) or \
                                  new_node_path.replace('\\\\', '\\') == fullpath.replace('\\\\', '\\') or \
                                  new_node_path.replace('\\\\', '\\') == fullpath
                regex_search = fullpath_pattern.fullmatch(new_node_path.replace('\\\\.', '.'), partial=True) or \
                                  new_node_path.replace('\\\\', '\\') in fullpath.replace('\\\\', '\\')
                # regex_search = re.search(new_node_path, fullpath.replace('\\\\', '\\'))
                if regex_fullmatch:
                    if self.__show_map:
                        log.debug(
                            "SHOW MAP: Current node path: %s - NODE FOUND",
                            new_node_path.replace('\\\\', '\\'))
                    result.append(new_node)
                elif regex_search:
                    if self.__show_map:
                        log.debug(
                            "SHOW MAP: Current node path: %s - NODE FOUND",
                            new_node_path)
                    if new_node_class == ua.NodeClass.Object:
                        if self.__show_map:
                            log.debug("SHOW MAP: Search in %s", new_node_path)
                        self.__search_node(new_node, fullpath, result=result)
                    elif new_node_class == ua.NodeClass.Variable:
                        log.debug("Found in %s", new_node_path)
                        result.append(new_node)
                    elif new_node_class == ua.NodeClass.Method and search_method:
                        log.debug("Found in %s", new_node_path)
                        result.append(new_node)
        except Exception as e:
            log.exception(e)

    def _check_path(self, config_path, node):
        if re.search("^root", config_path.lower()) is None:
            node_path = '\\\\.'.join(
                char.split(":")[1] for char in node.get_path(200000, True))
            if config_path[-3:] != '\\.':
                information_path = node_path + '\\\\.' + config_path.replace(
                    '\\', '\\\\')
            else:
                information_path = node_path + config_path.replace(
                    '\\', '\\\\')
        else:
            information_path = config_path
        return information_path[:]

    @property
    def subscribed(self):
        return self._subscribed
Ejemplo n.º 30
0
class Client_opc():

    def __init__(self, cert_path, server_path, policy, mode, AggrObject, handle_dict):
        self.cert_path = cert_path #certificates path
        self.server_path = server_path
        self.policy = policy
        self.mode = mode
        self.AggrObject = AggrObject
        self.handle_dict = handle_dict


    #istantiating Client calling "Client" constructor into stack opcua, set name and calling set_security_string method in the stack
    def client_instantiate(self):
        self.client = Client(self.server_path) #instaniate client
        self.client.name = "AggregationClient"
        if ((self.policy != "None") and (self.mode != "None")):
            #this method take a string as input that contains policy, mode, client certificate path and private key path. The endpoint that satisfies this characteristichs is choosed
            self.client.set_security_string(self.policy+","+self.mode+","+self.cert_path+"client_certificate.der,"+self.cert_path+"client_private_key.pem") #SecurityPolicy, Mode, Certificate path, Private key path


    #This method call the "connect" method in the stack. This method creates secure channel, create the session and activate it
    def secure_channel_and_session_activation(self):
        #params requested from the client. Server can set another value based on its requirements
        self.client.secure_channel_timeout = 10000
        self.client.session_timeout = 10000
        try:
            self.client.connect() #create secure channel and session; activate session
            print("Client instantiated; secure channel and session created; session activated ")
        except: 
            #if exception occures, disconnect the client
            self.client.disconnect()


    #This method disconnect the client from the server, closing session and secure channel
    def disconnect(self):
        self.client.disconnect()


    #This method is called when we want only to read Data
    def readData(self,node_id, polling_dict):
        #Get node
        node = self.client.get_node(node_id) #Client.py stack function
        #Get values
        value = node.get_data_value() #Node.py stack function
        print(f"Polling Service readed value : {value} ")
        #Set readed values in the local variables
        AggrVar = self.AggrObject.get_variables()
        for var in AggrVar: 
            for key in polling_dict:
                remote_node = self.client.get_node(polling_dict[key])
                if(remote_node == node and str(var.nodeid) == key):
                    var.set_value(value)
                    

    '''This method is our stack method revisitation to set our parameter values'''
    #This method is used in the "subscribe" method to create the filter for making the monitored item request
    def set_datachange_filter(self, deadband_val, deadbandtype=1):
        deadband_filter = ua.DataChangeFilter()
        deadband_filter.Trigger = ua.DataChangeTrigger(1)  # send notification when status or value change
        deadband_filter.DeadbandType = deadbandtype #type = 0 -> notification every change; type = 1 -> absolute deadband_val is considered; type = 2 -> percent deadband_val is considered
        deadband_filter.DeadbandValue = deadband_val
        return deadband_filter


    '''This method is our stack method revisitation to set our parameter values'''
    #This method is called in the "subscribe" method for creating the monitored items for the nodes passed. 
    def create_monitored_item(self, subscription, nodes , sampling_interval, client_handle, filter=None, queuesize = 0, discard_oldest = True, attr=ua.AttributeIds.Value):
        is_list = True
        if isinstance(nodes, Iterable):
            nodes = list(nodes)
        else:
            nodes = [nodes]
            is_list = False
        mirs = []
        for node in nodes:
            mir = self.make_monitored_item_request(subscription, node, attr, sampling_interval, client_handle, filter, queuesize, discard_oldest) #making monitored item request
            mirs.append(mir)

        mids = subscription.create_monitored_items(mirs)
        if is_list:
            return mids
        if type(mids[0]) == ua.StatusCode:
            mids[0].check()
        return mids[0] #return a list of handles (monitored item ids)


    '''This method is our stack method revisitation to set our parameter values'''
    #This method sets our params obtained from the conf file and make the monitored item request
    def make_monitored_item_request(self, subscription, node, attr, sampling_interval, client_handle, filter, queuesize, discard_oldest):
        rv = ua.ReadValueId()
        rv.NodeId = node.nodeid
        rv.AttributeId = attr
        mparams = ua.MonitoringParameters()
        with subscription._lock:
            subscription._client_handle = client_handle
            mparams.ClientHandle = subscription._client_handle
        mparams.SamplingInterval = sampling_interval
        mparams.QueueSize = queuesize
        mparams.DiscardOldest = discard_oldest
        if filter:
            mparams.Filter = filter
        mir = ua.MonitoredItemCreateRequest() #stack request
        mir.ItemToMonitor = rv
        mir.MonitoringMode = ua.MonitoringMode.Reporting
        mir.RequestedParameters = mparams
        return mir


    #This method is called when we want only to subscribe to Data. It takes as input sub infos and mon_item infos from conf file
    def subscribe(self, monitored_nodes, sub_infos):
            #Create the handlers
            handler = []
            for i in range(len(sub_infos)):
                handler.append(SubHandler(self.AggrObject, self.handle_dict))
            #Creating a subscription for ech 'sub_infos' element in the config file (different types of subscriptions -> different parameters)
            sub = []
            sub_index_list = []
            for i in range(len(monitored_nodes)):
                sub_index_list.append(monitored_nodes[i]["subIndex"])
            for i in range(len(sub_infos)):
                if(i in sub_index_list):
                    #Set sub parameters
                    params = ua.CreateSubscriptionParameters()
                    params.RequestedPublishingInterval = sub_infos[i]['requested_publish_interval']
                    params.RequestedLifetimeCount = sub_infos[i]['requested_lifetime_count']
                    params.RequestedMaxKeepAliveCount = sub_infos[i]['requested_max_keepalive_timer']
                    params.MaxNotificationsPerPublish = sub_infos[i]['max_notif_per_publish']
                    params.PublishingEnabled = sub_infos[i]['publishing_enabled']
                    params.Priority = sub_infos[i]['priority']
                    #Create the subscription
                    sub.append(self.client.create_subscription(params, handler[i]))
            #handle will contains mon_item_ids 
            handle = []
            Aggr_key = []
            for key in self.handle_dict:
                Aggr_key.append(key)
            for i in range(len(monitored_nodes)):                     
                filter = self.set_datachange_filter(monitored_nodes[i]['deadbandval'], monitored_nodes[i]['deadbandtype']) #Set filter from config parameters setted in the config file
                handle.append(self.create_monitored_item(sub[monitored_nodes[i]['subIndex']], self.client.get_node(monitored_nodes[i]['nodeTomonitor']),  monitored_nodes[i]['sampling_interval'] ,self.handle_dict[Aggr_key[i]], filter, monitored_nodes[i]['queue_size'], monitored_nodes[i]['discard_oldest'])) #handle = list of monitored items ids
            #handler.datachange_notification is called when a value of the monitored nodes has changed
            return sub, handle
    

    #This method take as input the subscription list and handle list of monitored items that we want to delete
    def delete_monit_items(self, sub, handle):
       for i in range(len(sub)):
            for mid in handle:
                try:
                    #stack function called on the subscription
                    sub[i].unsubscribe(mid) #unsubscribe to data_change/events of the selected monitored items (handle -> list of monitored items ids)
                except ua.uaerrors._auto.BadMonitoredItemIdInvalid: 
                    #This except is added because we call the unsubscribe stack method (delete monitored_item) for every subscription, but the monitored item is present only in one of them                        #So, in the other subscriptions, the BadMonitoredItemInvalid is raised, but we want to ignore this error
                    pass
    


    #This method takes as input the subscriptions list and delete them
    def delete_sub(self, sub):
        try:
            for i in range(len(sub)):
                sub[i].delete() #Stack method call on the subscription(this method delete every monitored item in the subscription and delete the subscription)
        except Exception:
            print("An Error was occured in client.delete function!")
Ejemplo n.º 31
0
def uacall():
    parser = argparse.ArgumentParser(description="Call method of a node")
    add_common_args(parser)
    parser.add_argument(
        "-m",
        "--method",
        dest="method",
        type=int,
        default=None,
        help=
        "Set method to call. If not given then (single) method of the selected node is used."
    )
    parser.add_argument("-l",
                        "--list",
                        "--array",
                        dest="array",
                        default="guess",
                        choices=["guess", "true", "false"],
                        help="Value is an array")
    parser.add_argument("-t",
                        "--datatype",
                        dest="datatype",
                        default="guess",
                        choices=[
                            "guess", 'byte', 'sbyte', 'nodeid',
                            'expandednodeid', 'qualifiedname', 'browsename',
                            'string', 'float', 'double', 'int16', 'int32',
                            "int64", 'uint16', 'uint32', 'uint64', "bool",
                            "string", 'datetime', 'bytestring', 'xmlelement',
                            'statuscode', 'localizedtext'
                        ],
                        help="Data type to return")
    parser.add_argument("value",
                        help="Value to use for call to method, if any",
                        nargs="?",
                        metavar="VALUE")

    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        # val must be a tuple in order to enable method calls without arguments
        if (args.value is None):
            val = ()  #empty tuple
        else:
            val = (_val_to_variant(args.value, args),
                   )  # tuple with one element

        # determine method to call: Either explicitly given or automatically select the method of the selected node.
        methods = node.get_methods()
        method_id = None
        #print( "methods=%s" % (methods) )

        if (args.method is None):
            if (len(methods) == 0):
                raise ValueError(
                    "No methods in selected node and no method given")
            elif (len(methods) == 1):
                method_id = methods[0]
            else:
                raise ValueError(
                    "Selected node has {0:d} methods but no method given. Provide one of {1!s}"
                    .format(*(methods)))
        else:
            for m in methods:
                if (m.nodeid.Identifier == args.method):
                    method_id = m.nodeid
                    break

        if (method_id is None):
            # last resort:
            method_id = ua.NodeId(
                identifier=args.method)  #, namespaceidx=? )#, nodeidtype=?): )

        #print( "method_id=%s\nval=%s" % (method_id,val) )

        result_variants = node.call_method(method_id, *val)
        print("resulting result_variants={0!s}".format(result_variants))
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 32
0
from opcua import Client, ua

url = "opc.tcp://127.0.0.1:4840"
client = Client(url)

client.set_user("user1")
client.set_password("pw1")
client.set_security_string("Basic256Sha256,SignAndEncrypt,cert.pem,key.pem")
client.application_uri = "urn:example.org:FreeOpcUa:python-opcua"

client.connect()
print(f"Connected to: {url}")

servicelevel_node = client.get_node("ns=0;i=2267")

servicelevel_node_value = servicelevel_node.get_value()
print(servicelevel_node_value)

client.disconnect()
Ejemplo n.º 33
0
    def datachange_notification(self, node, val, data):
        print("Python: New data change event", node, val)

    def event_notification(self, event):
        print("Python: New event", event)


if __name__ == "__main__":
    #from IPython import embed
    logging.basicConfig(level=logging.DEBUG)
    #client = Client("opc.tcp://*****:*****@localhost:53530/OPCUA/SimulationServer/"
    )
    client.set_security_string(
        "Basic256,SignAndEncrypt,example-certificate.der,example-private-key.pem"
    )
    try:
        client.connect()
        root = client.get_root_node()
        print("Root is", root)
        print("childs of root are: ", root.get_children())
        print("name of root is", root.get_browse_name())
        objects = client.get_objects_node()
        print("childs og objects are: ", objects.get_children())
        myfloat = client.get_node("ns=4;s=Float")
        mydouble = client.get_node("ns=4;s=Double")
        myint64 = client.get_node("ns=4;s=Int64")
        myuint64 = client.get_node("ns=4;s=UInt64")
        myint32 = client.get_node("ns=4;s=Int32")
        myuint32 = client.get_node("ns=4;s=UInt32")
Ejemplo n.º 34
0
    Client to subscription. It will receive events from server
    """

    def datachange_notification(self, node, val, data):
        print("Python: New data change event", node, val)

    def event_notification(self, event):
        print("Python: New event", event)


if __name__ == "__main__":
    #from IPython import embed
    logging.basicConfig(level=logging.DEBUG)
    #client = Client("opc.tcp://*****:*****@localhost:53530/OPCUA/SimulationServer/")
    client.set_security_string("Basic256,SignAndEncrypt,example-certificate.der,example-private-key.pem")
    try:
        client.connect()
        root = client.get_root_node()
        print("Root is", root)
        print("childs of root are: ", root.get_children())
        print("name of root is", root.get_browse_name())
        objects = client.get_objects_node()
        print("childs og objects are: ", objects.get_children())
        myfloat = client.get_node("ns=4;s=Float")
        mydouble = client.get_node("ns=4;s=Double")
        myint64 = client.get_node("ns=4;s=Int64")
        myuint64 = client.get_node("ns=4;s=UInt64")
        myint32 = client.get_node("ns=4;s=Int32")
        myuint32 = client.get_node("ns=4;s=UInt32")
Ejemplo n.º 35
0
 def FINISH_test_connect_basic256(self):
     c = Client(URL)
     c.set_security_string("basic256,sign,XXXX")
     c.connect()
     c.disconnect()
Ejemplo n.º 36
0
from opcua import Client
import flask
import time
import flask

url = "opc.tcp://192.168.1.33:48010"  #server url

client = Client(url)

#set security mode and certificate. Use server's certificate instead. Certificate path need to be modified
client.set_security_string(
    "Basic256,SignAndEncrypt,C:/Users/RSONG/Documents/InduSoft Web Studio v8.1 Projects/Project/Config/uaserver/own/studio.der,C:/Users/RSONG/Documents/InduSoft Web Studio v8.1 Projects/Project/Config/uaserver/own/studio.pem"
)

#Set client uri to match server's certificate
client.application_uri = "urn:DESKTOP-U34UL7P:Studio:OpcUaServer"


def connect_to_server(client):
    connection_times = 0
    while True:
        connection_times += 1
        try:
            if connection_times > 100:
                raise ValueError('Failed to connect to opcua server')
            client.connect()
            break
        except:
            time.sleep(1)
            print(f"reconnecting to server, {connection_times} times")
            continue
Ejemplo n.º 37
0
def uacall():
    parser = argparse.ArgumentParser(description="Call method of a node")
    add_common_args(parser)
    parser.add_argument("-m",
                        "--method",
                        dest="method",
                        type=int,
                        default=None,
                        help="Set method to call. If not given then (single) method of the selected node is used.")
    parser.add_argument("-l",
                        "--list",
                        "--array",
                        dest="array",
                        default="guess",
                        choices=["guess", "true", "false"],
                        help="Value is an array")
    parser.add_argument("-t",
                        "--datatype",
                        dest="datatype",
                        default="guess",
                        choices=["guess", 'byte', 'sbyte', 'nodeid', 'expandednodeid', 'qualifiedname', 'browsename', 'string', 'float', 'double', 'int16', 'int32', "int64", 'uint16', 'uint32', 'uint64', "bool", "string", 'datetime', 'bytestring', 'xmlelement', 'statuscode', 'localizedtext'],
                        help="Data type to return")
    parser.add_argument("value",
                        help="Value to use for call to method, if any",
                        nargs="?",
                        metavar="VALUE")

    args = parse_args(parser, requirenodeid=True)

    client = Client(args.url, timeout=args.timeout)
    client.set_security_string(args.security)
    client.connect()
    try:
        node = get_node(client, args)
        # val must be a tuple in order to enable method calls without arguments
        if ( args.value is None ):
            val = () #empty tuple
        else:
            val = (_val_to_variant(args.value, args),) # tuple with one element

        # determine method to call: Either explicitly given or automatically select the method of the selected node.
        methods = node.get_methods()
        method_id = None
        #print( "methods=%s" % (methods) )

        if ( args.method is None ):
            if ( len( methods ) == 0 ):
                raise ValueError( "No methods in selected node and no method given" )
            elif ( len( methods ) == 1 ):
                method_id = methods[0]
            else:
                raise ValueError( "Selected node has {0:d} methods but no method given. Provide one of {1!s}".format(*(methods)) )
        else:
            for m in methods:
                if ( m.nodeid.Identifier == args.method ):
                    method_id = m.nodeid
                    break

        if ( method_id is None):
            # last resort:
            method_id = ua.NodeId( identifier=args.method )#, namespaceidx=? )#, nodeidtype=?): )

        #print( "method_id=%s\nval=%s" % (method_id,val) )

        result_variants = node.call_method( method_id, *val )
        print( "resulting result_variants={0!s}".format(result_variants) )
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
Ejemplo n.º 38
0
    def datachange_notification(self, node, val, data):
        print("Python: New data change event", node, val)

    def event_notification(self, event):
        print("Python: New event", event)


if __name__ == "__main__":
    #from IPython import embed
    #logging.basicConfig(level=logging.DEBUG)

    client = Client("opc.tcp://192.168.10.10:4840/")
    client.set_user('admin')
    client.set_password('ca895987')

    client.set_security_string(
        "Basic256Sha256,SignAndEncrypt,opcua_client.der,opcua_client.pem")
    client.application_uri = "urn:example.org:FreeOpcUa:python-opcua"

    i = 0

    try:

        client.connect()

        while i < 5:

            ua_LevelMaximum = client.get_node(
                "ns=5;s=Arp.Plc.Eclr/LevelMaximum")
            ua_LevelMinimum = client.get_node(
                "ns=5;s=Arp.Plc.Eclr/LevelMinimum")
            ua_robot_test = client.get_node(
Ejemplo n.º 39
0
import sys
sys.path.insert(0, "..")
import logging

from IPython import embed

from opcua import Client

if __name__ == "__main__":
    logging.basicConfig(level=logging.WARNING)
    client = Client("opc.tcp://localhost:4840/freeopcua/server/")
    #client = Client("opc.tcp://localhost:53530/OPCUA/SimulationServer/")
    client.set_security_string(
        "Basic256Sha256,SignAndEncrypt,certificate-example.der,private-key-example.pem"
    )
    # client.application_uri = "urn:example.org:FreeOpcUa:python-opcua"
    # client.secure_channel_timeout = 10000
    # client.session_timeout = 10000
    try:
        client.connect()
        root = client.get_root_node()
        objects = client.get_objects_node()
        print("childs og objects are: ", objects.get_children())

        embed()
    finally:
        client.disconnect()
Ejemplo n.º 40
0
class OpcUaConnector(Thread, Connector):
    def __init__(self, gateway, config, connector_type):
        self._connector_type = connector_type
        self.statistics = {'MessagesReceived': 0, 'MessagesSent': 0}
        super().__init__()
        self.__gateway = gateway
        self.__server_conf = config.get("server")
        self.__interest_nodes = []
        self.__available_object_resources = {}
        self.__show_map = self.__server_conf.get("showMap", False)
        self.__previous_scan_time = 0
        for mapping in self.__server_conf["mapping"]:
            if mapping.get("deviceNodePattern") is not None:
                self.__interest_nodes.append(
                    {mapping["deviceNodePattern"]: mapping})
            else:
                log.error(
                    "deviceNodePattern in mapping: %s - not found, add property deviceNodePattern to processing this mapping",
                    dumps(mapping))
        if "opc.tcp" not in self.__server_conf.get("url"):
            self.__opcua_url = "opc.tcp://" + self.__server_conf.get("url")
        else:
            self.__opcua_url = self.__server_conf.get("url")
        self.client = Client(
            self.__opcua_url,
            timeout=self.__server_conf.get("timeoutInMillis", 4000) / 1000)
        if self.__server_conf["identity"].get("type") == "cert.PEM":
            try:
                ca_cert = self.__server_conf["identity"].get("caCert")
                private_key = self.__server_conf["identity"].get("privateKey")
                cert = self.__server_conf["identity"].get("cert")
                security_mode = self.__server_conf["identity"].get(
                    "mode", "SignAndEncrypt")
                policy = self.__server_conf["security"]
                if cert is None or private_key is None:
                    log.exception(
                        "Error in ssl configuration - cert or privateKey parameter not found"
                    )
                    raise RuntimeError(
                        "Error in ssl configuration - cert or privateKey parameter not found"
                    )
                security_string = policy + ',' + security_mode + ',' + cert + ',' + private_key
                if ca_cert is not None:
                    security_string = security_string + ',' + ca_cert
                self.client.set_security_string(security_string)

            except Exception as e:
                log.exception(e)
        if self.__server_conf["identity"].get("username"):
            self.client.set_user(
                self.__server_conf["identity"].get("username"))
            if self.__server_conf["identity"].get("password"):
                self.client.set_password(
                    self.__server_conf["identity"].get("password"))

        self.setName(
            self.__server_conf.get(
                "name", 'OPC-UA ' +
                ''.join(choice(ascii_lowercase)
                        for _ in range(5))) + " Connector")
        self.__opcua_nodes = {}
        self._subscribed = {}
        self.__sub = None
        self.__sub_handler = SubHandler(self)
        self.data_to_send = []
        self.__stopped = False
        self.__connected = False
        self.daemon = True

    def is_connected(self):
        return self.__connected

    def open(self):
        self.__stopped = False
        self.start()
        log.info("Starting OPC-UA Connector")

    def run(self):
        while not self.__connected:
            try:
                self.client.connect()
                try:
                    self.client.load_type_definitions()
                except Exception as e:
                    log.debug(e)
                    log.debug("Error on loading type definitions.")
                log.debug(self.client.get_namespace_array()[-1])
                log.debug(
                    self.client.get_namespace_index(
                        self.client.get_namespace_array()[-1]))
            except ConnectionRefusedError:
                log.error(
                    "Connection refused on connection to OPC-UA server with url %s",
                    self.__server_conf.get("url"))
                time.sleep(10)
            except OSError:
                log.error(
                    "Connection refused on connection to OPC-UA server with url %s",
                    self.__server_conf.get("url"))
                time.sleep(10)
            except Exception as e:
                log.debug("error on connection to OPC-UA server.")
                log.error(e)
                time.sleep(10)
            else:
                self.__connected = True
                log.info("OPC-UA connector %s connected to server %s",
                         self.get_name(), self.__server_conf.get("url"))
        self.__initialize_client()
        while not self.__stopped:
            try:
                time.sleep(.1)
                self.__check_connection()
                if not self.__connected and not self.__stopped:
                    self.client.connect()
                    self.__initialize_client()
                    log.info("Reconnected to the OPC-UA server - %s",
                             self.__server_conf.get("url"))
                elif not self.__stopped:
                    if self.__server_conf.get(
                            "disableSubscriptions", False
                    ) and time.time(
                    ) * 1000 - self.__previous_scan_time > self.__server_conf.get(
                            "scanPeriodInMillis", 60000):
                        self.scan_nodes_from_config()
                        self.__previous_scan_time = time.time() * 1000
                    # giusguerrini, 2020-09-24: Fix: flush event set and send all data to platform,
                    # so data_to_send doesn't grow indefinitely in case of more than one value change
                    # per cycle, and platform doesn't lose events.
                    # NOTE: possible performance improvement: use a map to store only one event per
                    # variable to reduce frequency of messages to platform.
                    while self.data_to_send:
                        self.__gateway.send_to_storage(self.get_name(),
                                                       self.data_to_send.pop())
                if self.__stopped:
                    self.close()
                    break
            except (KeyboardInterrupt, SystemExit):
                self.close()
                raise
            except FuturesTimeoutError:
                self.__check_connection()
            except Exception as e:
                log.error(
                    "Connection failed on connection to OPC-UA server with url %s",
                    self.__server_conf.get("url"))
                log.exception(e)
                self.client = Client(
                    self.__opcua_url,
                    timeout=self.__server_conf.get("timeoutInMillis", 4000) /
                    1000)
                self._subscribed = {}
                self.__available_object_resources = {}
                time.sleep(10)

    def __check_connection(self):
        try:
            node = self.client.get_root_node()
            node.get_children()
            if not self.__server_conf.get("disableSubscriptions", False) and (
                    not self.__connected or not self.subscribed):
                self.__sub = self.client.create_subscription(
                    self.__server_conf.get("subCheckPeriodInMillis", 500),
                    self.__sub_handler)
            self.__connected = True
        except ConnectionRefusedError:
            self.__connected = False
            self._subscribed = {}
            self.__available_object_resources = {}
            self.__sub = None
        except OSError:
            self.__connected = False
            self._subscribed = {}
            self.__available_object_resources = {}
            self.__sub = None
        except FuturesTimeoutError:
            self.__connected = False
            self._subscribed = {}
            self.__available_object_resources = {}
            self.__sub = None
        except AttributeError:
            self.__connected = False
            self._subscribed = {}
            self.__available_object_resources = {}
            self.__sub = None
        except Exception as e:
            self.__connected = False
            self._subscribed = {}
            self.__available_object_resources = {}
            self.__sub = None
            log.exception(e)

    def close(self):
        self.__stopped = True
        if self.__connected:
            self.client.disconnect()
        self.__connected = False
        log.info('%s has been stopped.', self.get_name())

    def get_name(self):
        return self.name

    def on_attributes_update(self, content):
        log.debug(content)
        try:
            for server_variables in self.__available_object_resources[
                    content["device"]]['variables']:
                for attribute in content["data"]:
                    for variable in server_variables:
                        if attribute == variable:
                            try:
                                server_variables[variable].set_value(
                                    content["data"][variable])
                            except Exception:
                                server_variables[variable].set_attribute(
                                    ua.AttributeIds.Value,
                                    ua.DataValue(content["data"][variable]))
        except Exception as e:
            log.exception(e)

    def server_side_rpc_handler(self, content):
        try:
            rpc_method = content["data"].get("method")
            for method in self.__available_object_resources[
                    content["device"]]['methods']:
                if rpc_method is not None and method.get(
                        rpc_method) is not None:
                    arguments_from_config = method["arguments"]
                    arguments = content["data"].get(
                        "params") if content["data"].get(
                            "params") is not None else arguments_from_config
                    try:
                        if isinstance(arguments, list):
                            result = method["node"].call_method(
                                method[rpc_method], *arguments)
                        elif arguments is not None:
                            try:
                                result = method["node"].call_method(
                                    method[rpc_method], arguments)
                            except ua.UaStatusCodeError as e:
                                if "BadTypeMismatch" in str(e) and isinstance(
                                        arguments, int):
                                    result = method["node"].call_method(
                                        method[rpc_method], float(arguments))
                        else:
                            result = method["node"].call_method(
                                method[rpc_method])

                        self.__gateway.send_rpc_reply(
                            content["device"], content["data"]["id"], {
                                content["data"]["method"]: result,
                                "code": 200
                            })
                        log.debug("method %s result is: %s",
                                  method[rpc_method], result)
                    except Exception as e:
                        log.exception(e)
                        self.__gateway.send_rpc_reply(content["device"],
                                                      content["data"]["id"], {
                                                          "error": str(e),
                                                          "code": 500
                                                      })
                else:
                    log.error("Method %s not found for device %s", rpc_method,
                              content["device"])
                    self.__gateway.send_rpc_reply(
                        content["device"], content["data"]["id"], {
                            "error": "%s - Method not found" % (rpc_method),
                            "code": 404
                        })
        except Exception as e:
            log.exception(e)

    def __initialize_client(self):
        self.__opcua_nodes["root"] = self.client.get_objects_node()
        self.__opcua_nodes["objects"] = self.client.get_objects_node()
        self.scan_nodes_from_config()
        self.__previous_scan_time = time.time() * 1000
        log.debug('Subscriptions: %s', self.subscribed)
        log.debug("Available methods: %s", self.__available_object_resources)

    def scan_nodes_from_config(self):
        try:
            if self.__interest_nodes:
                for device_object in self.__interest_nodes:
                    for current_device in device_object:
                        try:
                            device_configuration = device_object[
                                current_device]
                            devices_info_array = self.__search_general_info(
                                device_configuration)
                            for device_info in devices_info_array:
                                if device_info is not None and device_info.get(
                                        "deviceNode") is not None:
                                    self.__search_nodes_and_subscribe(
                                        device_info)
                                    self.__save_methods(device_info)
                                    self.__search_attribute_update_variables(
                                        device_info)
                                else:
                                    log.error(
                                        "Device node is None, please check your configuration."
                                    )
                                    log.debug(
                                        "Current device node is: %s",
                                        str(
                                            device_configuration.get(
                                                "deviceNodePattern")))
                                    break
                        except BrokenPipeError:
                            log.debug("Broken Pipe. Connection lost.")
                        except OSError:
                            log.debug("Stop on scanning.")
                        except FuturesTimeoutError:
                            self.__check_connection()
                        except Exception as e:
                            log.exception(e)
                log.debug(self.__interest_nodes)
        except Exception as e:
            log.exception(e)

    def __search_nodes_and_subscribe(self, device_info):
        sub_nodes = []
        information_types = {
            "attributes": "attributes",
            "timeseries": "telemetry"
        }
        for information_type in information_types:
            for information in device_info["configuration"][information_type]:
                information_key = information["key"]
                config_path = TBUtility.get_value(information["path"],
                                                  get_tag=True)
                information_path = self._check_path(config_path,
                                                    device_info["deviceNode"])
                information["path"] = '${%s}' % information_path
                information_nodes = []
                self.__search_node(device_info["deviceNode"],
                                   information_path,
                                   result=information_nodes)
                for information_node in information_nodes:
                    if information_node is not None:
                        try:
                            information_value = information_node.get_value()
                        except:
                            log.error("Err get_value: %s",
                                      str(information_node))
                            continue
                        log.debug(
                            "Node for %s \"%s\" with path: %s - FOUND! Current values is: %s",
                            information_type, information_key,
                            information_path, str(information_value))
                        if device_info.get("uplink_converter") is None:
                            configuration = {
                                **device_info["configuration"], "deviceName":
                                device_info["deviceName"],
                                "deviceType":
                                device_info["deviceType"]
                            }
                            if device_info["configuration"].get(
                                    'converter') is None:
                                converter = OpcUaUplinkConverter(configuration)
                            else:
                                converter = TBModuleLoader.import_module(
                                    self._connector_type, configuration)
                            device_info["uplink_converter"] = converter
                        else:
                            converter = device_info["uplink_converter"]
                        self.subscribed[information_node] = {
                            "converter": converter,
                            "path": information_path,
                            "config_path": config_path
                        }
                        if not device_info.get(
                                information_types[information_type]):
                            device_info[
                                information_types[information_type]] = []
                        converted_data = converter.convert(
                            (config_path, information_path), information_value)
                        self.statistics['MessagesReceived'] = self.statistics[
                            'MessagesReceived'] + 1
                        self.data_to_send.append(converted_data)
                        self.statistics['MessagesSent'] = self.statistics[
                            'MessagesSent'] + 1
                        log.debug("Data to ThingsBoard: %s", converted_data)
                        if not self.__server_conf.get("disableSubscriptions",
                                                      False):
                            sub_nodes.append(information_node)
                    else:
                        log.error(
                            "Node for %s \"%s\" with path %s - NOT FOUND!",
                            information_type, information_key,
                            information_path)
        if not self.__server_conf.get("disableSubscriptions", False):
            if self.__sub is None:
                self.__sub = self.client.create_subscription(
                    self.__server_conf.get("subCheckPeriodInMillis", 500),
                    self.__sub_handler)
            if sub_nodes:
                self.__sub.subscribe_data_change(sub_nodes)
                log.debug("Added subscription to nodes: %s", str(sub_nodes))

    def __save_methods(self, device_info):
        try:
            if self.__available_object_resources.get(
                    device_info["deviceName"]) is None:
                self.__available_object_resources[
                    device_info["deviceName"]] = {}
            if self.__available_object_resources[
                    device_info["deviceName"]].get("methods") is None:
                self.__available_object_resources[
                    device_info["deviceName"]]["methods"] = []
            if device_info["configuration"].get("rpc_methods", []):
                node = device_info["deviceNode"]
                for method_object in device_info["configuration"][
                        "rpc_methods"]:
                    method_node_path = self._check_path(
                        method_object["method"], node)
                    methods = []
                    self.__search_node(node,
                                       method_node_path,
                                       True,
                                       result=methods)
                    for method in methods:
                        if method is not None:
                            node_method_name = method.get_display_name().Text
                            self.__available_object_resources[
                                device_info["deviceName"]]["methods"].append({
                                    node_method_name:
                                    method,
                                    "node":
                                    node,
                                    "arguments":
                                    method_object.get("arguments")
                                })
                        else:
                            log.error(
                                "Node for method with path %s - NOT FOUND!",
                                method_node_path)
        except Exception as e:
            log.exception(e)

    def __search_attribute_update_variables(self, device_info):
        try:
            if device_info["configuration"].get("attributes_updates", []):
                node = device_info["deviceNode"]
                device_name = device_info["deviceName"]
                if self.__available_object_resources.get(device_name) is None:
                    self.__available_object_resources[device_name] = {}
                if self.__available_object_resources[device_name].get(
                        "variables") is None:
                    self.__available_object_resources[device_name][
                        "variables"] = []
                for attribute_update in device_info["configuration"][
                        "attributes_updates"]:
                    attribute_path = self._check_path(
                        attribute_update["attributeOnDevice"], node)
                    attribute_nodes = []
                    self.__search_node(node,
                                       attribute_path,
                                       result=attribute_nodes)
                    for attribute_node in attribute_nodes:
                        if attribute_node is not None:
                            self.__available_object_resources[device_name][
                                "variables"].append({
                                    attribute_update["attributeOnThingsBoard"]:
                                    attribute_node
                                })
                        else:
                            log.error(
                                "Attribute update node with path \"%s\" - NOT FOUND!",
                                attribute_path)
        except Exception as e:
            log.exception(e)

    def __search_general_info(self, device):
        result = []
        match_devices = []
        self.__search_node(self.__opcua_nodes["root"],
                           TBUtility.get_value(device["deviceNodePattern"],
                                               get_tag=True),
                           result=match_devices)
        for device_node in match_devices:
            if device_node is not None:
                result_device_dict = {
                    "deviceName": None,
                    "deviceType": None,
                    "deviceNode": device_node,
                    "configuration": deepcopy(device)
                }
                name_pattern_config = device["deviceNamePattern"]
                name_expression = TBUtility.get_value(name_pattern_config,
                                                      get_tag=True)
                if "${" in name_pattern_config and "}" in name_pattern_config:
                    log.debug("Looking for device name")
                    device_name_from_node = ""
                    if name_expression == "$DisplayName":
                        device_name_from_node = device_node.get_display_name(
                        ).Text
                    elif name_expression == "$BrowseName":
                        device_name_from_node = device_node.get_browse_name(
                        ).Name
                    elif name_expression == "$NodeId.Identifier":
                        device_name_from_node = str(
                            device_node.nodeid.Identifier)
                    else:
                        name_path = self._check_path(name_expression,
                                                     device_node)
                        device_name_node = []
                        self.__search_node(device_node,
                                           name_path,
                                           result=device_name_node)
                        device_name_node = device_name_node[0]
                        if device_name_node is not None:
                            device_name_from_node = device_name_node.get_value(
                            )
                    if device_name_from_node == "":
                        log.error(
                            "Device name node not found with expression: %s",
                            name_expression)
                        return None
                    full_device_name = name_pattern_config.replace(
                        "${" + name_expression + "}",
                        str(device_name_from_node)).replace(
                            name_expression, str(device_name_from_node))
                else:
                    full_device_name = name_expression
                result_device_dict["deviceName"] = full_device_name
                log.debug("Device name: %s", full_device_name)
                if device.get("deviceTypePattern"):
                    device_type_expression = TBUtility.get_value(
                        device["deviceTypePattern"], get_tag=True)
                    if "${" in device_type_expression and "}" in device_type_expression:
                        type_path = self._check_path(device_type_expression,
                                                     device_node)
                        device_type_node = []
                        self.__search_node(device_node,
                                           type_path,
                                           result=device_type_node)
                        device_type_node = device_type_node[0]
                        if device_type_node is not None:
                            device_type = device_type_node.get_value()
                            full_device_type = device_type_expression.replace(
                                "${" + device_type_expression + "}",
                                device_type).replace(device_type_expression,
                                                     device_type)
                        else:
                            log.error(
                                "Device type node not found with expression: %s",
                                device_type_expression)
                            full_device_type = "default"
                    else:
                        full_device_type = device_type_expression
                    result_device_dict["deviceType"] = full_device_type
                    log.debug("Device type: %s", full_device_type)
                else:
                    result_device_dict["deviceType"] = "default"
                result.append(result_device_dict)
            else:
                log.error(
                    "Device node not found with expression: %s",
                    TBUtility.get_value(device["deviceNodePattern"],
                                        get_tag=True))
        return result

    #
    # get fullpath of node as string
    #
    # this is verry slow
    # path = '\\.'.join(char.split(":")[1] for char in node.get_path(200000, True))
    # i think we don't need \\.
    #
    def get_node_path(self, node):
        ID = node.nodeid.Identifier
        if ID == 85:
            return 'Root.Objects'  # this is Root
        if type(ID) == int:
            ID = node.get_browse_name(
            ).Name  # for int Identifer we take browsename
        return 'Root.Objects.' + ID

    def __search_node(self,
                      current_node,
                      fullpath,
                      search_method=False,
                      result=None):
        if result is None:
            result = []
        try:
            if regex.match(r"ns=\d*;[isgb]=.*", fullpath, regex.IGNORECASE):
                if self.__show_map:
                    log.debug("Looking for node with config")
                node = self.client.get_node(fullpath)
                if node is None:
                    log.warning("NODE NOT FOUND - using configuration %s",
                                fullpath)
                else:
                    log.debug("Found in %s", node)
                    result.append(node)
            else:
                fullpath_pattern = regex.compile(fullpath)
                full1 = fullpath.replace('\\\\.', '.')
                #current_node_path = '\\.'.join(char.split(":")[1] for char in current_node.get_path(200000, True))
                current_node_path = self.get_node_path(current_node)
                # we are allways the parent
                child_node_parent_class = current_node.get_node_class()
                new_parent = current_node
                for child_node in current_node.get_children():
                    new_node_class = child_node.get_node_class()
                    # this will not change you can do it outside th loop
                    # basis Description of node.get_parent() function, sometime child_node.get_parent() return None
                    #new_parent = child_node.get_parent()
                    #if (new_parent is None):
                    #    child_node_parent_class = current_node.get_node_class()
                    #else:
                    #    child_node_parent_class = child_node.get_parent().get_node_class()
                    #current_node_path = '\\.'.join(char.split(":")[1] for char in current_node.get_path(200000, True))
                    #new_node_path = '\\\\.'.join(char.split(":")[1] for char in child_node.get_path(200000, True))
                    new_node_path = self.get_node_path(child_node)
                    if child_node_parent_class == ua.NodeClass.View and new_parent is not None:
                        parent_path = self.get_node_path(new_parent)
                        #parent_path = '\\.'.join(char.split(":")[1] for char in new_parent.get_path(200000, True))
                        fullpath = fullpath.replace(current_node_path,
                                                    parent_path)
                    nnp1 = new_node_path.replace('\\\\.', '.')
                    nnp2 = new_node_path.replace('\\\\', '\\')
                    if self.__show_map:
                        log.debug("SHOW MAP: Current node path: %s",
                                  new_node_path)
                    regex_fullmatch = regex.fullmatch(fullpath_pattern,  nnp1) or \
                                      nnp2 == full1 or \
                                      nnp2 == fullpath or \
                                      nnp1 == full1
                    if regex_fullmatch:
                        if self.__show_map:
                            log.debug(
                                "SHOW MAP: Current node path: %s - NODE FOUND",
                                nnp2)
                        result.append(child_node)
                    else:
                        regex_search = fullpath_pattern.fullmatch(nnp1, partial=True) or \
                                          nnp2 in full1 or \
                                          nnp1 in full1
                        if regex_search:
                            if self.__show_map:
                                log.debug(
                                    "SHOW MAP: Current node path: %s - NODE FOUND",
                                    new_node_path)
                            if new_node_class == ua.NodeClass.Object:
                                if self.__show_map:
                                    log.debug("SHOW MAP: Search in %s",
                                              new_node_path)
                                self.__search_node(child_node,
                                                   fullpath,
                                                   result=result)
                            elif new_node_class == ua.NodeClass.Variable:
                                log.debug("Found in %s", new_node_path)
                                result.append(child_node)
                            elif new_node_class == ua.NodeClass.Method and search_method:
                                log.debug("Found in %s", new_node_path)
                                result.append(child_node)
        except CancelledError:
            log.error(
                "Request during search has been canceled by the OPC-UA server."
            )
        except BrokenPipeError:
            log.error("Broken Pipe. Connection lost.")
        except OSError:
            log.debug("Stop on scanning.")
        except Exception as e:
            log.exception(e)

    def _check_path(self, config_path, node):
        if regex.match(r"ns=\d*;[isgb]=.*", config_path, regex.IGNORECASE):
            return config_path
        if re.search(r"^root", config_path.lower()) is None:
            node_path = self.get_node_path(node)
            #node_path = '\\\\.'.join(char.split(":")[1] for char in node.get_path(200000, True))
            if config_path[-3:] != '\\.':
                information_path = node_path + '\\\\.' + config_path.replace(
                    '\\', '\\\\')
            else:
                information_path = node_path + config_path.replace(
                    '\\', '\\\\')
        else:
            information_path = config_path
        result = information_path[:]
        return result

    @property
    def subscribed(self):
        return self._subscribed
Ejemplo n.º 41
0
 def FINISH_test_connect_basic256(self):
     c = Client(URL)
     c.set_security_string("basic256,sign,XXXX")
     c.connect()
     c.disconnect()
Ejemplo n.º 42
0
 def test_nocrypto_fail(self):
     clt = Client(self.uri_no_crypto)
     with self.assertRaises(ua.UaError):
         clt.set_security_string("Basic256Sha256,Sign,../examples/certificate-example.der,../examples/private-key-example.pem")
import sys
sys.path.insert(0, "..")
import logging

from IPython import embed

from opcua import Client


if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)
    client = Client("opc.tcp://localhost:53530/OPCUA/SimulationServer/")
    client.set_security_string("Basic256Sha256,Sign,certificate-example.der,private-key-example.pem")
    try:
        client.connect()
        root = client.get_root_node()
        objects = client.get_objects_node()
        print("childs og objects are: ", objects.get_children())

        embed()
    finally:
        client.disconnect()