コード例 #1
1
ファイル: tools.py プロジェクト: sunyiex/python-opcua
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="VALUE",
                        #choices=['VALUE', 'NODEID', 'BROWSENAME', 'ERROR', 'CRITICAL'],
                        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 = parser.parse_args()
    if args.nodeid == "i=84" and args.path == "" and args.attribute == ua.AttributeIds.Value:
        parser.print_usage()
        print("uaread: error: A NodeId or BrowsePath is required")
        sys.exit(1)
    logging.basicConfig(format="%(levelname)s: %(message)s", level=getattr(logging, args.loglevel))

    client = Client(args.url, timeout=args.timeout)
    client.connect()
    try:
        node = client.get_node(args.nodeid)
        if args.path:
            node = node.get_child(args.path.split(","))
        val = _val_to_variant(args.value, args)
        node.set_attribute(args.attribute, ua.DataValue(val))
    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
コード例 #2
0
ファイル: aas.py プロジェクト: yjy1120/openAAS_workshop
def getPVSL(endpointStr, listId):

    client = Client(endpointStr)
    pvsl = None
    try:
        client.connect()
        nsarray = client.get_node(ua.NodeId(2255, 0))
        nsList = nsarray.get_value()
        i = -1
        for entry in nsList:
            i = i + 1
            if entry == "http://acplt.org/propertyValueStatement/Ov":
                #print(entry)
                nsopenaas_propertyValueStatement = i
                break
        if i != -1:
            entryPoint = listId
            print("Looking for AAS at entry point %s,%s" %
                  (nsopenaas_propertyValueStatement, listId))
            path = client.get_node(
                ua.NodeId(entryPoint, nsopenaas_propertyValueStatement))
            pvsl = propertyValueStatementContainer.fromOPCUANodes(path)
            for statement in pvsl.statements:
                print(statement.Name)
    finally:
        client.disconnect()
        return pvsl
コード例 #3
0
class OPCUAClient:
    """
    定义opcuaclient
    """
    def __init__(self, url, username='', password=''):
        try:
            self.client = Client(url)  # 初始化OPCUA客户端
            if username != '' and password != '':  # 初始化时如果提供用户名密码则配置
                self.client.activate_session("username", "password")  # 配置用户名密码
            self.client.connect()
        except Exception as e:
            print("OPCUAClient INIT ERROR", e)

    def subscribeTag(self, stringNodeID):
        """
        通过StringNodeID订阅Tag
        """
        tag = self.client.get_node(stringNodeID)  # 获取需要读取的节点tag值
        print('tag节点值:', tag)
        handler = SubHandler()
        subobj = self.client.create_subscription(
            100, handler)  # 返回一个订阅对象第一个参数为发布间隔(毫秒)
        handle = subobj.subscribe_data_change(tag)  # 返回可用于退订的句柄
        return subobj, handle, stringNodeID  # 返回的三个参数可用于取消订阅

    def unsubscribeTag(self, subobj, handle):
        """
        取消订阅
        """
        subobj.unsubscribe(handle)

    def getNodeValue(self, stringNodeID, type=1):
        """
        通过StringNodeID读取节点tag值
        type = 1 获取值
        type = 2 获取DataValue object
        """
        tag = self.client.get_node(stringNodeID)
        return tag.get_value()

    def setNodeValue(self, stringNodeID, value):
        """
        通过StringNodeID设置节点tag值
        """
        tag = self.client.get_node(stringNodeID)
        tag.set_value(value)  # 使用隐含变量类型设置节点值

    def disconnect(self, client):
        """
        断开连接
        """
        return client.disconnect()
コード例 #4
0
    def ergodic(self):
        if __name__ == "__main__":
            logging.basicConfig(level=logging.WARN)
            client = Client("opc.tcp://" + self.host + ":" + self.port)
            try:
                client.connect()
                for i in client.get_node(
                        "ns=2;s=S7-300").get_children():  # 获取项目节点列表
                    r = i.get_browse_name().Name
                    if r != '_Statistics' and r != '_System':  # 筛选后将有效的项目列表存入pro列表
                        self.pro.append(r)
                print("------从kepserver中读取的项目名列表------------------------")
                print(self.pro)
                print(
                    "-----------------------------------------------------------"
                )

                for k in range(len(self.pro)):  # 按项目列表开始遍历
                    self.name.append([])
                    self.type.append([])
                    t = client.get_node(
                        "ns=2;s=S7-300." +
                        self.pro[k]).get_children()  # 获取项目下所有变量节点
                    for i in t:
                        tag8 = i.get_browse_name().Name
                        if tag8 != '_System' and tag8 != '_Statistics' and tag8 != '_InternalTags':  # 筛选有效变量
                            self.name[k].append(tag8)
                            tag9 = i.get_data_type_as_variant_type().name
                            self.type[k].append(tag9)
                self.pro_g = self.pro[:]  # 变量_a 用于订阅,原变量做删减后用于修改数据库表格
                self.name_g = self.name[:]  # 变量_a 用于订阅,原变量做删减后用于修改数据库表格
                self.type_g = self.type[:]  # 变量_a 用于订阅,原变量做删减后用于修改数据库表格

                for i in range(len(self.name)):
                    print(self.pro_g[i])
                    print(self.name_g[i])
                    print(self.type_g[i])
                global dic
                global dict
                dic = {}
                dict = {}
                for i in range(len(self.pro_g)):
                    dic[self.pro_g[i]] = {}
                    dict[self.pro_g[i]] = {}
                    for j in range(len(self.name_g[i])):
                        dic[self.pro_g[i]][self.name_g[i][j]] = "n"
                        dict[self.pro_g[i]][self.name_g[i]
                                            [j]] = self.type_g[i][j]
                client.disconnect()
            except:
                pass
コード例 #5
0
ファイル: client_opc_ua.py プロジェクト: ga83mir/netpi
class opc_ua_client(object):
	def __init__(self, url):
		self.client = None
		self.nodes = {}
		self.values = {}
		self.url = url
	
	def connect(self, opc_name, init_status):
		self.client = Client(self.url)
		CRED = '\33[31m'
		CGREEN = '\33[32m'
		CEND = '\033[0m'
		try:
			self.client.connect()
		except socket.error:
			connect_status = False
			print(opc_name + CRED + " disconnected" + CEND)
			time.sleep(1)
		else:
			if init_status:
				print(opc_name + CGREEN + " connected" + CEND)
			connect_status = True
		return connect_status

	def get_nodes(self, nodeIds):
		nodeId_header = 'ns=4;s=|var|CODESYS Control for Raspberry Pi SL.'
		local_nodes = {}
		for idx in nodeIds:
			var_name = idx.split(".")[-1]
			nodeId = nodeId_header + idx
			local_nodes[var_name] = self.client.get_node(nodeId)
			self.nodes[var_name] = self.client.get_node(nodeId)
		return local_nodes

	def get_value(self, var_name):
		try:
			value = self.nodes[var_name].get_value()
		except socket.error:
			print("can not get value because of no variable there")
			value = None
		return value

	def set_value(self, var_name, value, var_type):
		#""val type must be ua.VariantType, for example ua.VariantType.Boolean")
		try:
			self.nodes[var_name].set_value(value, var_type)
		except socket.error:
			print("can not set value because of no variable there")

	def disconnect(self):
		self.client.disconnect()
コード例 #6
0
    def open_connect_and_get_node_all(self):
        i = 0
        for name, node in self.opc_info.items():

            try:
                index = [x.values()[0] for x in self.url.values()].index(node['url'])

            except ValueError:
                self.url.update({i:{'url':node['url']}})
                index = i
                i = i + 1
            self.opc_id.update({name: {"opc_id": index, "node_id": node['node']}})

        for id_key, url in self.url.items():
            client = Client(url['url'])
            try:
                client.connect()
                url['open'] = 'yes'
                url['connect'] = client
            except:
                url['open'] = 'no'
        for name, node in self.opc_id.items():
            try:
                client = self.url[node['opc_id']]['connect']
                nodeHander = client.get_node(node['node_id'].encode('ascii'))
                node["nodeHander"] = nodeHander
            except:
                node["nodeHander"] = None
コード例 #7
0
def cambiar_valor2(server,nodo,avg_fv,median_fv,std_fv,moda_fv,perc50_fv,mom2_fv,mom3_fv,mom4_fv,skew1_fv,skew2_fv,skew3_fv,kurt_fv,logger):
  client = Client(server)
  try:
      client.connect()#conecta el servidor
      var=client.get_node("ns=1;s="+nodo)#se obtiene el primer nodo
      variable2=var.get_children()
      tamano=np.size(variable2)
      #datetime_object = datetime.strptime(tiemp, '%d/%m/%Y %H:%M:%S')
      if tamano>0:
        variable2[10].set_value(avg_fv)
        variable2[11].set_value(median_fv)
        variable2[12].set_value(std_fv)
        variable2[13].set_value(moda_fv)
        variable2[14].set_value(perc50_fv)
        variable2[15].set_value(mom2_fv)
        variable2[16].set_value(mom3_fv)
        variable2[17].set_value(mom4_fv)
        variable2[18].set_value(skew1_fv)
        variable2[19].set_value(skew2_fv)
        variable2[20].set_value(skew3_fv)
        variable2[21].set_value(kurt_fv)
      else:
        logger.warning("No se encuentra el nodo en el servidor opc")
      
      client.disconnect()
  
  except: 
      logger.error("No se puede conectar con el servidor opc")
コード例 #8
0
ファイル: aas.py プロジェクト: yjy1120/openAAS_workshop
def getSubModel(endpointStr, subModel_NodeId):

    client = Client(endpointStr)
    try:
        client.connect()
        #    nsarray = client.get_node(ua.NodeId(2255, 0))
        #    nsList = nsarray.get_value()
        #    i=-1
        #    for entry in nsList:
        #     i = i + 1

        #      if entry == "http://acplt.org/openaas/":
        #        nsopenaas_subModelType = i
        #
        #        break
        #    if i!= -1:
        #      print("Looking for AAS at entry point %s,%s" % (subModel_NodeId))

        path = client.get_node(subModel_NodeId)
        print("path is %s" % path)
        subModelInst = subModel.fromOPCUANodes(node=path)
        for pvsContainer in subModelInst.PropertyValueStatementContainers:
            print(pvsContainer.Name)
    finally:
        client.disconnect()
        return subModel
コード例 #9
0
def PT_calibration(n_meas):
    '''
    Parameters
    ----------
        n_meas: int
            number of measurement to store

    Returns
    -------
        dove: string
            data file path of measurement
    '''
    from m4.ground import tracking_number_folder
    from opcua import Client
    server = OpcUaParameters.server
    client = Client(url=server)
    client.connect()

    folder = config.PT_ROOT_FOLDER
    dove, tt = tracking_number_folder.createFolderToStoreMeasurements(folder)

    for i in range(n_meas):
        time.sleep(2)
        temp = client.get_node("ns=7;s=MAIN.i_Temperature_Sensor")
        temp_list = temp.get_value()
        temp_vector = np.array(temp_list.get_value())

        fits_file_name = os.path.join(dove, 'temperature_%04.fits' % i)
        pyfits.writeto(fits_file_name, temp_vector)

        print('Misura %04d' % i)
    return dove
コード例 #10
0
ファイル: tools.py プロジェクト: kevincolyar/python-opcua
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 = parser.parse_args()
    if args.nodeid == "i=84" and args.path == "":
        parser.print_usage()
        print("uaread: error: The NodeId or BrowsePath of a variable is required")
        sys.exit(1)
    logging.basicConfig(format="%(levelname)s: %(message)s", level=getattr(logging, args.loglevel))

    client = Client(args.url, timeout=args.timeout)
    client.connect()
    try:
        node = client.get_node(args.nodeid)
        if args.path:
            node = node.get_child(args.path.split(","))
        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)
コード例 #11
0
ファイル: tools.py プロジェクト: sunyiex/python-opcua
def uals():
    parser = argparse.ArgumentParser(description="Browse OPC-UA node and print result")
    add_common_args(parser)
    #parser.add_argument("-l",
                        #dest="long_format",
                        #default=ua.AttributeIds.Value,
                        #help="use a long listing format")
    parser.add_argument("-d",
                        "--depth",
                        default=1,
                        type=int,
                        help="Browse depth")

    args = parser.parse_args()
    logging.basicConfig(format="%(levelname)s: %(message)s", level=getattr(logging, args.loglevel))

    client = Client(args.url, timeout=args.timeout)
    client.connect()
    try:
        node = client.get_node(args.nodeid)
        if args.path:
            node = node.get_child(args.path.split(","))
        print("Browsing node {} at {}\n".format(node, args.url))
        _lsprint(client, node.nodeid, args.depth - 1)

    finally:
        client.disconnect()
    sys.exit(0)
    print(args)
コード例 #12
0
ファイル: tools.py プロジェクト: kevincolyar/python-opcua
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 = parser.parse_args()
    logging.basicConfig(format="%(levelname)s: %(message)s", level=getattr(logging, args.loglevel))

    client = Client(args.url, timeout=args.timeout)
    client.connect()
    if args.certificate:
        client.load_certificate(args.certificate)
    if args.private_key:
        client.load_certificate(args.private_key)
    try:
        root = client.get_root_node()
        objects = client.get_objects_node()
        mynode = client.get_node(args.nodeid)
        if args.path:
            mynode = mynode.get_child(args.path.split(","))
        embed()
    finally:
        client.disconnect()
    sys.exit(0)
コード例 #13
0
def cambiar_valor(server,nodo,tiemp,TFD,TFRS,RGTFD,RGTFRS,RGRS,RT,SP,EC,EE,logger):
  client = Client(server)
  try:
      client.connect()#conecta el servidor
      var=client.get_node("ns=1;s="+nodo)#se obtiene el primer nodo
      variable2=var.get_children()
      tamano=np.size(variable2)
      datetime_object = datetime.strptime(tiemp, '%d/%m/%Y %H:%M:%S')
      if tamano>0:
        variable2[0].set_value(datetime_object)
        variable2[1].set_value(TFD)
        variable2[2].set_value(TFRS)
        variable2[3].set_value(RGTFD)
        variable2[4].set_value(RGTFRS)
        variable2[5].set_value(RGRS)
        variable2[6].set_value(RT)
        variable2[7].set_value(SP)
        variable2[8].set_value(EC)
        variable2[9].set_value(EE)
      else:
        logger.warning("No se encuentra el nodo en el servidor opc")
      
      client.disconnect()
  
  except: 
      logger.error("No se puede conectar con el servidor opc")
コード例 #14
0
def getOpcConnection(ConfigFilePath: str) -> None:
    # Load json config file
    f = open(ConfigFilePath, )
    config = json.load(f)
    f.close()

    # Get network settings
    protocol = config['network_settings'][0]['protocol']
    host = config['network_settings'][0]['host']
    port = config['network_settings'][0]['port']
    address = protocol + '://' + host + ':' + port

    # Configure connection
    OpcConnection = Client(address)

    # Open connection and try to get all nodes
    try:
        OpcConnection.connect()

        ClientNodes = {}

        # Get nodes
        for node in config['opc_nodes']:
            ClientNodes[node['name']] = OpcConnection.get_node(
                'ns=' + node['namespace_index'] + ';s=' + node['string_id'])

        return OpcConnection, ClientNodes
    except:
        return None, None
コード例 #15
0
ファイル: aas.py プロジェクト: julianBac/openAAS_workshop
def getSubModel(endpointStr, subModel_NodeId):

    client = Client(endpointStr)
    subModel = None
    try:
        client.connect()
        #    nsarray = client.get_node(ua.NodeId(2255, 0))
        #    nsList = nsarray.get_value()
        #    i=-1
        #    for entry in nsList:
        #     i = i + 1

        #      if entry == "http://acplt.org/openaas/":
        #        nsopenaas_subModelType = i
        #
        #        break
        #    if i!= -1:

        #      print("Looking for AAS at entry point %s,%s" % (subModel_NodeId))

        path = client.get_node(subModel_NodeId)
        print("path is %s" % path)
        print("1")
        subModelInst = subModel.fromOPCUANodes(
            path)  #in line 259, classmethod of 'subModel' exists
        print("2")  #no print out of "2" during tests
        for statement in subModelInst.statements:
            print(statement.Name)
    finally:
        client.disconnect()
        return subModel
コード例 #16
0
ファイル: tools.py プロジェクト: kevincolyar/python-opcua
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 = parser.parse_args()
    if args.nodeid == "i=84" and args.path == "":
        parser.print_usage()
        print("uahistoryread: error: A NodeId or BrowsePath is required")
        sys.exit(1)
    logging.basicConfig(format="%(levelname)s: %(message)s", level=getattr(logging, args.loglevel))

    client = Client(args.url, timeout=args.timeout)
    client.connect()
    try:
        node = client.get_node(args.nodeid)
        if args.path:
            node = node.get_child(args.path.split(","))
        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)
コード例 #17
0
ファイル: client.py プロジェクト: AlexDikun/anomalies
def main():
    logging.basicConfig(level=logging.WARN)
    client = Client("opc.tcp://WIN-B3JSS0UOON2:49320")
    try:
        client.connect()

        tag1 = client.get_node("ns=2;s=Channel1.Device1.Tag1")
        tag2 = client.get_node("ns=2;s=Simulation Examples.Functions.Ramp3")
        tag3 = client.get_node("ns=2;s=Simulation Examples.Functions.Sine1")

        tags = [tag1, tag2, tag3]

        handler = SubHandler(tags)
        sub = client.create_subscription(500, handler)

        handles = [
            sub.subscribe_data_change(tag1),
            sub.subscribe_data_change(tag2),
            sub.subscribe_data_change(tag3)
        ]

        sleep(0.1)

        embed()

        print("")
        print("Tag1 is: ", handler.storage[0])
        print("")
        print("Tag2 is: ", handler.storage[1])
        print("")
        print("Tag3 is: ", handler.storage[2])
        print("")

        algorithm = SubHandler.extreme_value_analysis
        flags = list(map(lambda i: algorithm(np.array(i)), handler.storage))

        for i in range(len(handles)):
            if flags[i] == True:
                sub.unsubscribe(handles[i])
                print(tags[i], "is broken!")
            else:
                print(tags[i], "is OK!")

        sub.delete()

    finally:
        client.disconnect()
コード例 #18
0
class OPC_Client_Rpi(threading.Thread):
    def __init__(self):
        """
        * Module constructor function that connects OPC client at Raspberry pi with OPC Server
        """
        threading.Thread.__init__(self)
        self.opc_client = Client("opc.tcp://10.0.0.57:4048"
                                 )  # Connecting OPC Server Running ON Laptop
        self.opc_client.connect()
        self.initiate_nodes()  # Instantiating Nodes

    def initiate_nodes(self):
        """
        * Connecting with nodes created at OPC Server for continuous data exchange
        """
        self.temp_value = self.opc_client.get_node(
            'ns=2; s="Room_Temperature"')
        self.hum_value = self.opc_client.get_node('ns=2; s="Room_Humidity"')
        self.flux_value = self.opc_client.get_node('ns=2; s="Magnetic_Flux"')
        self.corona_level = self.opc_client.get_node('ns=3; s="Corona_Level"')
        self.resistance = self.opc_client.get_node('ns=3; s="Rod_Resistence"')

    def run(self):
        """
        * Runnable thread which sends the data collected from constrained device to OPC Server
        """
        time.sleep(5)
        while (1):
            time.sleep(5)
            temperature = SensorData_Object.getTemperature()
            self.temp_value.set_value(
                temperature)  # Publish Temperature Sensor Data

            humidity = SensorData_Object.getHumidity()
            self.hum_value.set_value(humidity)  # Publish Humidity Sensor Data

            flux = SensorData_Object.getMagFlux()
            self.flux_value.set_value(flux)  # Publish MagneticFlux Data

            corona_level = SensorData_Object.getCorona()
            self.corona_level.set_value(
                corona_level)  # Publish Corona Level Data

            Resistence = SensorData_Object.getResistence()
            self.resistance.set_value(Resistence)  # Publish Resistence Data

            logging.info("All Data Published to OPC Server")
コード例 #19
0
ファイル: aas.py プロジェクト: yjy1120/openAAS_workshop
def serialize_AAS(endpointStr, identifer, filename):
    """
  Serializes an Asset Administraiton Shell to a given file

  Args:
  ----------
  endpoint : string
    path to the shared object that provides the opc ua functionality
  identifierType : string
    opc ua endpoint to the aas repository server
  identifer:
    identifier for a node Id
  namespaceIndex
    opc ua namespace index
  Returns:
  -------
  string
    Status Code
  """

    client = Client(endpointStr)
    try:
        client.connect()
        nsarray = client.get_node(ua.NodeId(2255, 0))
        nsList = nsarray.get_value()
        i = -1
        for entry in nsList:
            i = i + 1
            if entry == "http://acplt.org/openaas/Ov":
                #print(entry)
                namespaceIndex = i
                break
        if i != -1:
            print("Looking for AAS at entry point %s,%s" %
                  (namespaceIndex, identifer))
            path = client.get_node(ua.NodeId(identifer, namespaceIndex))
            aas = AAS.fromOPCUANodes(node=path)
            #currentDir = cwd = os.getcwd()
            #filename = "JSON_%s" % (filename)
            #print("Writing AAS data of %s in %s" % (aas.Name, os.path.join(currentDir,filename)))
            file = open(filename, "w")

            file.write(json.dumps(aas, default=jdefault, indent=4))

            file.close()
    finally:
        client.disconnect()
コード例 #20
0
    def provision_node_instance(self, instance_id: str, service_id: str, plan_id: str,
                                parameters: dict=None) -> ProvisionedServiceSpec:
        url = parameters.get("url")
        if not url:
            print("Error: {0}\n".format("url not contained in provision parameters!"))
            return ProvisionedServiceSpec(state="failed")
        nodes_to_add = parameters.get("nodesToAdd")
        if not nodes_to_add:
            print("Error: {0}\n".format("nodes_to_add not contained in provision parameters!"))
            return ProvisionedServiceSpec(state="failed")

        add_nodes_items = []
        for node_to_add in nodes_to_add:
            add_nodes_item = ua.AddNodesItem()

            if "parentNodeId" in node_to_add:
                add_nodes_item.ParentNodeId = ua.ExpandedNodeId(node_to_add.get("parentNodeId"))
            if "referenceTypeId" in node_to_add:
                add_nodes_item.ReferenceTypeId = ua.NodeId(node_to_add.get("referenceTypeId"))
            if "requestedNewNodeId" in node_to_add:
                add_nodes_item.RequestedNewNodeId = ua.ExpandedNodeId(node_to_add.get("requestedNewNodeId"))
            if "browseName" in node_to_add:
                add_nodes_item.BrowseName = ua.QualifiedName(node_to_add.get("browseName"))
            if "nodeClass" in node_to_add:
                add_nodes_item.NodeClass = ua.NodeClass(node_to_add.get("nodeClass"))
            add_nodes_items.append(add_nodes_item)

        print(add_nodes_items)
        client = Client(url)
        try:
            client.connect()
            nodes = []
            for add_nodes_item in add_nodes_items:
                parent_node = client.get_node(add_nodes_item.ParentNodeId)
                if add_nodes_item.NodeClass == 1:
                    obj = parent_node.add_object(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName)
                    nodes.append(obj)
                elif add_nodes_item.NodeClass == 2:
                    var = parent_node.add_variable(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName)
                    nodes.append(var)
                elif add_nodes_item.NodeClass == 4:
                    method = parent_node.add_method()
                    nodes.append(method)
                else:
                    folder = parent_node.add_folder(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName)
                    nodes.append(folder)

            service_instance = OpcuaServiceInstance(instance_id, service_id, plan_id, parameters)
            service_instance.params["nodes"] = nodes

            service_instance_map = dict()
            service_instance_map[instance_id] = service_instance
            self.service_instance_map = service_instance_map
        except Exception as e:
            print("Error: {0}\n".format(e))
            return ProvisionedServiceSpec(state="failed")

        print("Node management service instance {0} is provisioned successfully\n".format(instance_id))
        return ProvisionedServiceSpec()
コード例 #21
0
def main(server_url, tag_id):
    client = Client(server_url)
    client.connect()

    node = client.get_node(tag_id)
    print(node)
    print(node.get_value())
    client.disconnect()
コード例 #22
0
class OpcuaBase(object):
    def __init__(self, address="opc.tcp://192.168.42.20:4840"):
        # self.client = Client("opc.tcp://100.102.7.5:4840")
        self.address = address
        self.client = Client(self.address)

        self.nodes = {}

    def get_node(self, nodeId):
        if not nodeId in self.nodes:
            self.nodes[nodeId] = self.client.get_node(ua.NodeId(nodeId, 2))
        return self.nodes[nodeId]

    def readValue_polling(self, nodeId, namespace):
        var = self.client.get_node(ua.NodeId(nodeId, namespace))
        return var.get_value()

    def writeBooleanValue(self, nodeId, namespace, value):
        self.get_node(nodeId).set_value(
            ua.Variant(value, ua.VariantType.Boolean))

    def writeFloatValue(self, nodeId, namespace, value):
        var = self.client.get_node(ua.NodeId(nodeId, namespace))
        var.set_value(ua.Variant(value, ua.VariantType.Float))

    def disconnect(self):
        self.client.disconnect()

    def add_subscription(self, AxisNo, AxisType,
                         MeasurementType):  # AxisNo [1...4], AxisType ["Trans","Rot"], MeasurementType ["Vel","Pos"]
        if AxisType == "Rot":
            atype = 0
        if AxisType == "Trans":
            atype = 1
        if MeasurementType == "Pos":
            mtype = 2
        if MeasurementType == "Trans":
            mtype = 3
        nodeId = Axis[AxisNo - 1][atype][mtype][0]
        namespace = Axis[AxisNo - 1][atype][mtype][1]
        var = self.client.get_node(ua.NodeId(nodeId, namespace))
        handler = SubScriptionHandler()
        sub = self.client.create_subscription(50, handler)
        sub.subscribe_data_change(var)
コード例 #23
0
class AsssetEndPointHandler(AsssetEndPointHandler):
    def __init__(self, saas, ip, port, username, password, propertylist):
        super(AsssetEndPointHandler, self).__init__(saas, ip, port, username,
                                                    password, propertylist)

        self.plc_opcua_Client = Client("opc.tcp://" + ip + ":" + port + "/")

        if (self.username != "-"):
            self.plc_opcua_Client._username = self.username
            self.plc_opcua_Client._password = self.password

    def read(self, nodeID):

        MW_VALUE = 0

        try:
            self.plc_opcua_Client.connect()
            MW_VALUE = self.plc_opcua_Client.get_node(nodeID).get_value()

        except Exception as e:
            print(e)
            self.plc_opcua_Client.disconnect()
            MW_VALUE = 1

        finally:
            self.plc_opcua_Client.disconnect()
            return MW_VALUE

    def write(self, nodeID, value):

        MW_VALUE = 0

        try:
            self.plc_opcua_Client.connect()
            plcnode = self.plc_opcua_Client.get_node(nodeID)
            plcnode.set_value(value)

        except:
            self.plc_opcua_Client.disconnect()
            MW_VALUE = 1

        finally:
            self.plc_opcua_Client.disconnect()
            return MW_VALUE
コード例 #24
0
ファイル: jobs.py プロジェクト: zerolugithub/PLC_App
def manualMode(data):
    client = Client("opc.tcp://192.168.0.211:4870")  # Set OPC-UA Server
    if data['runmode'] == "False":
        # print("STOP")
        client.connect()
        estop = client.get_node("ns=4;s=M_E_Stop")
        estop.set_value(True)
        sendorder = client.get_node("ns=4;s=M_Send_Order")
        sendorder.set_value(False)
        client.disconnect()
    else:
        # print("START")
        client.connect()
        estop = client.get_node("ns=4;s=M_E_Stop")
        estop.set_value(False)
        sendorder = client.get_node("ns=4;s=M_Send_Order")
        sendorder.set_value(True)
        client.disconnect()
    return True
コード例 #25
0
class Plc:
    def __init__(self, opc_connection):
        """ Create a new plc connection """
        self.client = Client(opc_connection)

    def getTagValue(self, tag_name):
        self.client.connect()
        tag = self.client.get_node(tag_name)
        value = tag.get_value()
        self.client.disconnect()
        if loader.KEY or loader.NOT_KEY():
            return value
        else:
            return -1
コード例 #26
0
def plugin_start(handle):
    global loop, t
    _LOGGER.info("opcua_py plugin_start called")

    url = handle['url']['value']
    userName = handle['userName']['value']
    password = handle['password']['value']

    _LOGGER.info('opcua_py: Attempting to connect to %s', url)

    client = Client(url=url)

    if userName:
        _LOGGER.info('opcua_py: Attempting to connect to OPC UA server with username and password.')
        client.set_user(userName)
        client.set_password(password)
    else:
        _LOGGER.info('opcua_py: Attempting to connect anonymously to OPC UA server.')

    client.connect()

    #Need to add some error checking on the connection

    subs = json.loads(handle['subscriptions']['value'])

    subs = subs["subscriptions"]
    _LOGGER.info('opcua_py: Attempting to subscribe to %s', subs)

    nodes = []

    for sub in subs:
        nodes.append(client.get_node(sub))

    handler = SubscriptionHandler()
    # We create a Client Subscription.
    subscription = client.create_subscription(500, handler)

    # We subscribe to data changes for our nodes (variables).
    subscription.subscribe_data_change(nodes)


    def run():
            global loop
            loop.run_forever()


    t = Thread(target=run)

    t.start()
コード例 #27
0
ファイル: aas.py プロジェクト: yjy1120/openAAS_workshop
def getAASIDByAssetID(ResolutionServerEndpoint, AssetIDSpec, AssetIDType):
    client = Client(ResolutionServerEndpoint)
    # client = Client("opc.tcp://localhost:16664) #connect using a user
    res = ["", "", ""]
    try:
        client.connect()

        nsarray = client.get_node(ua.NodeId(2255, 0))
        nsList = nsarray.get_value()
        i = -1
        for entry in nsList:
            i = i + 1
            if entry == "http://acplt.org/subModelDiscovery/Ov":
                print(entry)
                nsopenaas_discovery = i
                break
        if i == -1:
            return res
        getAASIDFromAssetId_nodeId = ua.NodeId(
            "/TechUnits/openAAS/AASFolder/NetworkAAS.Body/NameResolution",
            nsopenaas_discovery)
        getAASIDFromASsetIdMethod_nodeId = ua.NodeId(
            "/TechUnits/openAAS/AASFolder/NetworkAAS.Body/NameResolution.GetAASIDByAssetIDService",
            nsopenaas_discovery)
        discoveryNode = client.get_node(getAASIDFromAssetId_nodeId)
        discoveryMethodNode = client.get_node(getAASIDFromASsetIdMethod_nodeId)
        print(discoveryNode.get_browse_name().Name)
        print(discoveryMethodNode.get_browse_name().Name)
        res = discoveryNode.call_method(
            discoveryMethodNode, ua.Variant(AssetIDType,
                                            ua.VariantType.UInt32),
            ua.Variant(AssetIDSpec, ua.VariantType.String))
        print("result of method call is %s" % res)
    finally:
        client.disconnect()
        return res
コード例 #28
0
def cambiar_nombre(server,nodo,nombre,logger):
  client = Client(server)
  try:
      client.connect()#conecta el servidor
      var=client.get_node("ns=1;s="+nodo)#se obtiene el primer nodo
      variable2=var.get_children()
      tamano=np.size(variable2)
      if tamano==5:
        nombre=variable2[0].set_value(nombre)
      else:
        logger.warning("No se encuentra el nodo en el servidor opc")
      client.disconnect()
  except:
	    #desconeccion
      logger.error("No se puede conectar con el servidor opc")
コード例 #29
0
 def subscribe(self):
     global dic
     if __name__ == "__main__":
         logging.basicConfig(level=logging.WARN)
         client = Client("opc.tcp://" + self.host + ":" + self.port)
         try:
             client.connect()
             for i, j in dic.items():
                 for k, l in j.items():
                     ss = client.get_node("ns=2;s=S7-300." + i + "." + k)
                     self.taglist.append(ss)
             print("订阅变量总数为:", len(self.taglist))
         except:
             pass
         handler = SubHandler()
         sub = client.create_subscription(5000, handler)
         handle1 = sub.subscribe_data_change(self.taglist)
コード例 #30
0
ファイル: client.py プロジェクト: danildanil86660/CKIA
class OPCClient:
    def __init__(self, url="opc.tcp://127.0.0.1:48402/freeopcua/server/"):
        self.url = url
        self.client = Client(self.url)

    def get_value(self, count):
        num = 2
        list_value = list()
        while num < count + 2:
            list_value.append(
                self.client.get_node(f'ns=2; i={num}').get_value())
            num += 1
        return list_value

    def run(self):
        self.client.connect()
        print(f'Client connected to {self.url}')
コード例 #31
0
ファイル: 1026.py プロジェクト: zhaojianfei08/KM6
def get_data():
    c = Client(url=URL)
    try:
        c.connect()
        nodeid_list = [
            c.get_node(one.decode()).nodeid for one in R1.smembers('nodes')
        ]
        res = c.uaclient.get_attributes(nodeid_list, ua.AttributeIds.Value)
        res_ = list(zip(nodeid_list, res))
        res__ = [(i[0].Identifier,
                  datetime.datetime.now().strftime(r"%Y-%m-%d %H:%M:%S"),
                  i[1].Value.Value, i[1].StatusCode.value) for i in res_]
        insert_obj(str(res__).replace('[', '').replace(']', ''))
    except Exception as e:
        print(e)
    finally:
        c.disconnect()
コード例 #32
0
class ServerC(object):
    def __init__(self):
        self._server = None
        self._client = None
        self.nodes = None
        self.get_node = None
        self.get_namespace_array = None

    def start_server(self, endpoint):
        self._server = UAServer()
        self._server.endpoint = 48400  # enpoint not supported yet
        #self._server.endpoint = endpoint
        self._server.start()
        #self._server.set_server_name("OpcUa Modeler Server")
        time.sleep(0.2)
        self._client = Client(endpoint)
        self._client.connect()

        self.nodes = self._client.nodes
        self.get_node = self._client.get_node
        self.get_namespace_array = self._client.get_namespace_array
        # now remove freeopcua namespace, not necessary when modeling and
        # ensures correct idx for exported nodesets
        ns_node = self._client.get_node(
            ua.NodeId(ua.ObjectIds.Server_NamespaceArray))
        nss = ns_node.get_value()
        #ns_node.set_value(nss[1:])

    def stop_server(self):
        if self._server is not None:
            self._client.disconnect()
            self._client = None
            self._server.stop()
            time.sleep(0.2)
            self._server = None
            self.get_node = None
            self.get_namespace_array = None

    def import_xml(self, path):
        return self._client.import_xml(path)

    def export_xml(self, nodes, uris, path):
        exp = XmlExporter(self._client)
        exp.build_etree(nodes, uris=uris)
        exp.write_xml(path)
コード例 #33
0
def cambiar_valor(server,nodo,tiemp,valor,estatus,logger):
  client = Client(server)
  try:
      client.connect()#conecta el servidor
      var=client.get_node("ns=1;s="+nodo)#se obtiene el primer nodo
      variable2=var.get_children()
      tamano=np.size(variable2)
      datetime_object = datetime.strptime(tiemp, '%d/%m/%Y %H:%M:%S')
      if tamano>0:
        tiempo=variable2[2].set_value(datetime_object)
        val=variable2[3].set_value(valor)
        status=variable2[4].set_value(estatus)
      else:
        logger.warning("No se encuentra el nodo en el servidor opc")
      client.disconnect()
  
  except: 
      logger.error("No se puede conectar con el servidor opc")
コード例 #34
0
class ServerC(object):
    def __init__(self):
        self._server = None
        self._client = None
        self.nodes = None
        self.get_node = None
        self.get_namespace_array = None

    def start_server(self, endpoint):
        self._server = UAServer()
        self._server.endpoint = 48400  # enpoint not supported yet
        #self._server.endpoint = endpoint
        self._server.start()
        #self._server.set_server_name("OpcUa Modeler Server")
        time.sleep(0.2)
        self._client = Client(endpoint)
        self._client.connect()

        self.nodes = self._client.nodes
        self.get_node = self._client.get_node
        self.get_namespace_array = self._client.get_namespace_array
        # now remove freeopcua namespace, not necessary when modeling and
        # ensures correct idx for exported nodesets
        ns_node = self._client.get_node(ua.NodeId(ua.ObjectIds.Server_NamespaceArray))
        nss = ns_node.get_value()
        #ns_node.set_value(nss[1:])

    def stop_server(self):
        if self._server is not None:
            self._client.disconnect()
            self._client = None
            self._server.stop()
            time.sleep(0.2)
            self._server = None
            self.get_node = None
            self.get_namespace_array = None

    def import_xml(self, path):
        return self._client.import_xml(path)

    def export_xml(self, nodes, uris, path):
        exp = XmlExporter(self._client)
        exp.build_etree(nodes, uris=uris)
        exp.write_xml(path)
コード例 #35
0
def get_certain_data(request):
    client = Client("opc.tcp://192.168.160.215:4840")
    client.connect()
    # ns = request.POST['ns']
    s = request.POST['s']
    # node = client.get_node("ns="+ns+';'+'s=\"'+s+'\"').get_variables()

    vars = {}
    for i in range(1, 6):
        node = client.get_node("ns=" + str(i) + ';' + 's=\"' + s + '\"').get_variables()

        for v in node:
            display_name = str(v.get_display_name())
            start = display_name.index('Text:') + 5
            node_name = display_name[start:-1]
            vars[node_name] = v.get_value()

    client.disconnect()
    return render(request, 'certain-data.html', {'data': vars, 's': s})
コード例 #36
0
def cambiar_tipo(server,nodo,tipo,logger):
  client = Client(server)
  try:
      client.connect()
      #conecta el servidor
      var=client.get_node("ns=1;s="+nodo)#se obtiene el primer nodo
      variable2=var.get_children()
      tamano=np.size(variable2)
      if tamano==5:
        tipo=variable2[1].set_value(tipo)
        tiempo=variable2[2].get_value()
        val=variable2[3].get_value()
        status=variable2[4].get_value()
      else:
        logger.warning("No se encuentra el nodo en el servidor opc")
      client.disconnect()
  except:
	    #desconeccion
      logger.error("No se puede conectar con el servidor opc")
コード例 #37
0
ファイル: tools.py プロジェクト: sunyiex/python-opcua
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="VALUE",
                        #choices=['VALUE', 'NODEID', 'BROWSENAME', 'ERROR', 'CRITICAL'],
                        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 = parser.parse_args()
    if args.nodeid == "i=84" and args.path == "" and args.attribute == ua.AttributeIds.Value:
        parser.print_usage()
        print("uaread: error: A NodeId or BrowsePath is required")
        sys.exit(1)
    logging.basicConfig(format="%(levelname)s: %(message)s", level=getattr(logging, args.loglevel))

    client = Client(args.url, timeout=args.timeout)
    client.connect()
    try:
        node = client.get_node(args.nodeid)
        if args.path:
            node = node.get_child(args.path.split(","))
        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)
コード例 #38
0
ファイル: uaclient.py プロジェクト: stanti/opcua-client-gui
class UaClient(object):
    """
    OPC-Ua client specialized for the need of GUI client
    return exactly whant GUI needs, no customization possible
    """
    def __init__(self):
        self.client = None
        self._connected = False
        self._subscription = None

    def connect(self, uri):
        self.disconnect()
        print("Connecting to ", uri)
        self.client = Client(uri)
        self.client.connect()
        self._connected = True
        print("Connected, root is: ", self.client.get_root_node())
        print(self.get_root_attrs())

    def disconnect(self):
        if self._connected:
            print("Disconnecting from server")
            self._connected = False
            self._subscription = None
            self.client.disconnect()
            self.client = None

    def subscribe(self, node, handler):
        if not self._subscription:
            self._subscription = self.client.create_subscription(500, handler)
        self._subscription.subscribe_data_change(node)

    def get_root_attrs(self):
        return self.get_node_attrs(self.client.get_root_node())

    def get_node_attrs(self, node):
        if not type(node) is Node:
            node = self.client.get_node(node)
        attrs = node.get_attributes([AttributeIds.DisplayName, AttributeIds.BrowseName, AttributeIds.NodeId])
        return [node] + [attr.Value.Value.to_string() for attr in attrs] 

    def get_children(self, node):
        descs = node.get_children_descriptions()
        children = []
        for desc in descs:
            children.append([self.client.get_node(desc.NodeId), desc.DisplayName.to_string(), desc.BrowseName.to_string(), desc.NodeId.to_string()])
        return children

    def get_all_attrs(self, node):
        names = []
        vals = []
        for name, val in ua.AttributeIds.__dict__.items():
            if not name.startswith("_"):
                names.append(name)
                vals.append(val)

        attrs = node.get_attributes(vals)
        res = {}
        for idx, name in enumerate(names):
            if attrs[idx].StatusCode.is_good():
                res[name] = attrs[idx].Value.Value
        return res

    def get_all_refs(self, node):
        return node.get_children_descriptions(refs=ObjectIds.References)
コード例 #39
0
ファイル: opc_connection.py プロジェクト: dewabe/Thesis
class OpcProtocol():
    '''
    OPC Protocol settings
    '''
    def string_to_node_type(self, type='string'):
        if type == 'string':
            return ua.NodeIdType.String
        elif type == 'numeric':
            return ua.NodeIdType.Numeric
        else:
            return ua.NodeIdType.ByteString

    def __del__(self):
        self.Disconnect()

    def __init__(self, server_name):
        self.server_name = server_name

        namespaces = VAR.OPC_SERVERS[server_name]["namespaces"]

        # Get OPC UA node type
        for namespace in namespaces.keys():
            nodes = VAR.OPC_SERVERS[server_name]["namespaces"][namespace]["nodes"]
            for node in nodes:
                type = nodes[node]["opc_type"]
                nodes[node]["opc_type"] = self.string_to_node_type(type)

        self.Connect()

    def Connect(self):
        '''
        For creating connection to OPC UA Server
        '''
        server = VAR.OPC_SERVERS[self.server_name]["opc_server"]
        namespaces = VAR.OPC_SERVERS[self.server_name]["namespaces"]
        
        self.client = Client(server)
        try:
            self.client.connect()
            
            for namespace in namespaces.keys():
                VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["index"] = self.client.get_namespace_index(namespace)

        except Exception as e:
            print('Connect error:', e)
        finally:
            self.firstrun()


    def remove_subscribe(self):
        namespaces = VAR.OPC_SERVERS[self.server_name]["namespaces"]
        for namespace in namespaces.keys():
            nodes = VAR.OPC_SERVERS[self.server_name]['namespaces'][namespace]["nodes"]
            for node in nodes.keys():
                VAR.OPC_SERVERS[self.server_name]['namespaces'][namespace]["nodes"][node]["subscribe"].unsubscribe(
                    VAR.OPC_SERVERS[self.server_name]['namespaces'][namespace]["nodes"][node]["handler"]
                )
                VAR.OPC_SERVERS[self.server_name]['namespaces'][namespace]["nodes"][node]["subscribe"].delete()
        return True


    def Disconnect(self):
        '''
        Disconnect from OPC UA Server
        '''
        try:
            self.remove_subscribe()
            self.client.disconnect()
        except Exception as e:
            print('Disconnect error:', e)
        return "disconnect done"

    def create_node(self, node, namespace, type):
        return ua.NodeId(identifier=node, namespaceidx=namespace, nodeidtype=type)

    def firstrun(self):
        '''
        When OPC UA Server connection has been established, do this once
        '''
        try:
            if VAR.FIRST_RUN:
                namespaces = VAR.OPC_SERVERS[self.server_name]["namespaces"]

                for namespace in namespaces.keys():
                    index = VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["index"]
                    nodes = VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"]
                    for node in nodes.keys():
                        type = VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["opc_type"]
                        nodeid = self.create_node(node, index, type)
                        VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["opc_nodeid"] = nodeid

                        this_node = self.client.get_node(nodeid)
                        VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["opc_variable"] = this_node

                        value = this_node.get_value()

                        VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["value"] = value
                        VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["timestamp"] = str(datetime.datetime.utcnow())

                        VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["handler"] = NodeHandler(self.server_name, namespace)
                        VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["subscribe"] = self.client.create_subscription(
                            100,
                            VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["handler"]
                        )
                        VAR.OPC_SERVERS[self.server_name]["namespaces"][namespace]["nodes"][node]["subscribe"].subscribe_data_change(this_node)
        except Exception as e:
            print('firstRun error:', e)
        finally:
            VAR.FIRST_RUN = False

    def reset(self):
        self.remove_subscribe()
        VAR.FIRST_RUN = True
        self.firstrun()
コード例 #40
0
    #from IPython import embed
    logging.basicConfig(level=logging.WARN)
    client = Client("opc.tcp://192.168.56.100:49320/OPCUA/SimulationServer/")
    #client = Client("opc.tcp://192.168.56.100:4841/OPCUA/SimulationServer/")
    #client = Client("opc.tcp://*****:*****@localhost:53530/OPCUA/SimulationServer/")
    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())


        tag1 = client.get_node("ns=2;s=Channel1.Device1.Tag1")
        print("tag1 is: {} with value {} ".format(tag1, tag1.get_value()))
        tag2 = client.get_node("ns=2;s=Channel1.Device1.Tag2")
        print("tag2 is: {} with value {} ".format(tag2, tag2.get_value()))

        handler = SubHandler()
        sub = client.create_subscription(500, handler)
        handle = sub.subscribe_data_change(tag1)
        handle = sub.subscribe_data_change(tag2)

        from IPython import embed
        embed()

        
        sub.unsubscribe(handle)
        sub.delete()
コード例 #41
0
import sys
sys.path.insert(0, "..")
import time
import logging
from IPython import embed

from opcua import Client
from opcua import ua



if __name__ == "__main__":
    logging.basicConfig(level=logging.WARN)
    client = Client("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer")
    try:
        client.connect()
        root = client.get_root_node()
        objects = client.get_objects_node()
        struct = client.get_node("ns=2;i=10239")
        struct_array = client.get_node("ns=2;i=10323")
        before = struct.get_value()
        before_array = struct_array.get_value()
        client.load_type_definitions()  # scan server for custom structures and import them
        after = struct.get_value()
        after_array = struct_array.get_value()
        

        embed()
    finally:
        client.disconnect()
コード例 #42
0
import sys
sys.path.insert(0, "..")
import time
import logging
from IPython import embed

from opcua import Client
from opcua import ua



if __name__ == "__main__":
    logging.basicConfig(level=logging.WARN)
    client = Client("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer")
    try:
        client.connect()
        root = client.get_root_node()
        objects = client.get_objects_node()
        struct = client.get_node("ns=2;i=10239")
        before = struct.get_value()
        client.load_type_definitions()  # scan server for custom structures and import them
        after = struct.get_value()
        

        embed()
    finally:
        client.disconnect()
コード例 #43
0
class UaClient(object):
    """
    OPC-Ua client specialized for the need of GUI client
    return exactly what GUI needs, no customization possible
    """

    def __init__(self):
        self.settings = QSettings()
        self.client = None
        self._connected = False
        self._datachange_sub = None
        self._event_sub = None
        self._subs_dc = {}
        self._subs_ev = {}
        self.security_mode = None
        self.security_policy = None
        self.certificate_path = None
        self.private_key_path = None

    def _reset(self):
        self.client = None
        self._connected = False
        self._datachange_sub = None
        self._event_sub = None
        self._subs_dc = {}
        self._subs_ev = {}

    @staticmethod
    def get_endpoints(uri):
        client = Client(uri, timeout=2)
        client.connect_and_get_server_endpoints()
        edps = client.connect_and_get_server_endpoints()
        for i, ep in enumerate(edps, start=1):
            logger.info('Endpoint %s:', i)
            for (n, v) in endpoint_to_strings(ep):
                logger.info('  %s: %s', n, v)
            logger.info('')
        return edps

    def load_security_settings(self, uri):
        self.security_mode = None
        self.security_policy = None
        self.certificate_path = None
        self.private_key_path = None

        mysettings = self.settings.value("security_settings", None)
        if mysettings is None:
            return
        if uri in mysettings:
            mode, policy, cert, key = mysettings[uri]
            self.security_mode = mode
            self.security_policy = policy
            self.certificate_path = cert
            self.private_key_path = key

    def save_security_settings(self, uri):
        mysettings = self.settings.value("security_settings", None)
        if mysettings is None:
            mysettings = {}
        mysettings[uri] = [self.security_mode,
                           self.security_policy,
                           self.certificate_path,
                           self.private_key_path]
        self.settings.setValue("security_settings", mysettings)

    def get_node(self, nodeid):
        return self.client.get_node(nodeid)
    
    def connect(self, uri):
        self.disconnect()
        logger.info("Connecting to %s with parameters %s, %s, %s, %s", uri, self.security_mode, self.security_policy, self.certificate_path, self.private_key_path)
        self.client = Client(uri)
        if self.security_mode is not None and self.security_policy is not None:
            self.client.set_security(
                getattr(crypto.security_policies, 'SecurityPolicy' + self.security_policy),
                self.certificate_path,
                self.private_key_path,
                mode=getattr(ua.MessageSecurityMode, self.security_mode)
            )
        self.client.connect()
        self._connected = True
        self.save_security_settings(uri)

    def disconnect(self):
        if self._connected:
            print("Disconnecting from server")
            self._connected = False
            try:
                self.client.disconnect()
            finally:
                self._reset()

    def subscribe_datachange(self, node, handler):
        if not self._datachange_sub:
            self._datachange_sub = self.client.create_subscription(500, handler)
        handle = self._datachange_sub.subscribe_data_change(node)
        self._subs_dc[node.nodeid] = handle
        return handle

    def unsubscribe_datachange(self, node):
        self._datachange_sub.unsubscribe(self._subs_dc[node.nodeid])

    def subscribe_events(self, node, handler):
        if not self._event_sub:
            print("subscirbing with handler: ", handler, dir(handler))
            self._event_sub = self.client.create_subscription(500, handler)
        handle = self._event_sub.subscribe_events(node)
        self._subs_ev[node.nodeid] = handle
        return handle

    def unsubscribe_events(self, node):
        self._event_sub.unsubscribe(self._subs_ev[node.nodeid])

    def get_node_attrs(self, node):
        if not isinstance(node, Node):
            node = self.client.get_node(node)
        attrs = node.get_attributes([ua.AttributeIds.DisplayName, ua.AttributeIds.BrowseName, ua.AttributeIds.NodeId])
        return node, [attr.Value.Value.to_string() for attr in attrs]

    @staticmethod
    def get_children(node):
        descs = node.get_children_descriptions()
        descs.sort(key=lambda x: x.BrowseName)
        return descs
コード例 #44
0
class TestClient(unittest.TestCase, CommonTests, SubscriptionTests):

    '''
    Run common tests on client side
    Of course we need a server so we start also start a server
    Tests that can only be run on client side must be defined  in this class
    '''
    @classmethod
    def setUpClass(self):
        # start our own server
        self.srv = Server()
        self.srv.set_endpoint('opc.tcp://*****:*****@localhost:%d' % port_num1, timeout=10)
        self.clt.connect()
        self.opc = self.clt

        # start anonymous client
        self.ro_clt = Client('opc.tcp://localhost:%d' % port_num1)
        self.ro_clt.connect()



    @classmethod
    def tearDownClass(self):
        #stop our clients
        self.ro_clt.disconnect()
        self.clt.disconnect()
        # stop the server 
        self.srv.stop()

    def test_service_fault(self):
        request = ua.ReadRequest()
        request.TypeId = ua.FourByteNodeId(999)  # bad type!
        with self.assertRaises(ua.UaStatusCodeError):
            self.clt.uaclient._uasocket.send_request(request)

    def test_objects_anonymous(self):
        objects = self.ro_clt.get_objects_node()
        with self.assertRaises(ua.UaStatusCodeError):
            objects.set_attribute(ua.AttributeIds.WriteMask, ua.DataValue(999))
        with self.assertRaises(ua.UaStatusCodeError):
            f = objects.add_folder(3, 'MyFolder')

    def test_folder_anonymous(self):
        objects = self.clt.get_objects_node()
        f = objects.add_folder(3, 'MyFolderRO')
        f_ro = self.ro_clt.get_node(f.nodeid)
        self.assertEqual(f, f_ro)
        with self.assertRaises(ua.UaStatusCodeError):
            f2 = f_ro.add_folder(3, 'MyFolder2')

    def test_variable_anonymous(self):
        objects = self.clt.get_objects_node()
        v = objects.add_variable(3, 'MyROVariable', 6)
        v.set_value(4) #this should work
        v_ro = self.ro_clt.get_node(v.nodeid)
        with self.assertRaises(ua.UaStatusCodeError):
            v_ro.set_value(2)
        self.assertEqual(v_ro.get_value(), 4)
        v.set_writable(True)
        v_ro.set_value(2) #now it should work
        self.assertEqual(v_ro.get_value(), 2)
        v.set_writable(False)
        with self.assertRaises(ua.UaStatusCodeError):
            v_ro.set_value(9)
        self.assertEqual(v_ro.get_value(), 2)

    def test_context_manager(self):
        """ Context manager calls connect() and disconnect()
        """
        state = [0]
        def increment_state(self, *args, **kwargs):
            state[0] += 1

        # create client and replace instance methods with dummy methods
        client = Client('opc.tcp://dummy_address:10000')
        client.connect    = increment_state.__get__(client)
        client.disconnect = increment_state.__get__(client)

        assert state[0] == 0
        with client:
            # test if client connected
            self.assertEqual(state[0], 1)
        # test if client disconnected
        self.assertEqual(state[0], 2)
コード例 #45
0
ファイル: tests.py プロジェクト: jadro/python-opcua
class AdminTestClient(unittest.TestCase, CommonTests):

    '''
    Run common tests on client side
    Of course we need a server so we start a server in another
    process using python Process module
    Tests that can only be run on client side must be defined here
    '''
    @classmethod
    def setUpClass(self):
        # start our own server
        self.srv = Server()
        self.srv.set_endpoint('opc.tcp://*****:*****@localhost:%d' % port_num1)
        self.clt.connect()
        self.opc = self.clt

        # start anonymous client
        self.ro_clt = Client('opc.tcp://localhost:%d' % port_num1)
        self.ro_clt.connect()



    @classmethod
    def tearDownClass(self):
        #stop our clients
        self.ro_clt.disconnect()
        self.clt.disconnect()
        # stop the server
        self.srv.stop()

    def test_service_fault(self):
        request = ua.ReadRequest()
        request.TypeId = ua.FourByteNodeId(999)  # bad type!
        with self.assertRaises(Exception):
            self.clt.bclient._send_request(request)

    def test_objects_anonymous(self):
        objects = self.ro_clt.get_objects_node()
        with self.assertRaises(Exception):
            objects.set_attribute(ua.AttributeIds.WriteMask, ua.DataValue(999))
        with self.assertRaises(Exception):
            f = objects.add_folder(3, 'MyFolder')

    def test_folder_anonymous(self):
        objects = self.clt.get_objects_node()
        f = objects.add_folder(3, 'MyFolderRO')
        f_ro = self.ro_clt.get_node(f.nodeid)
        self.assertEqual(f, f_ro)
        with self.assertRaises(Exception):
            f2 = f_ro.add_folder(3, 'MyFolder2')

    def test_variable_anonymous(self):
        objects = self.clt.get_objects_node()
        v = objects.add_variable(3, 'MyROVariable', 6)
        v.set_value(4) #this should work
        v_ro = self.ro_clt.get_node(v.nodeid)
        with self.assertRaises(Exception):
            v_ro.set_value(2)
        self.assertEqual(v_ro.get_value(), 4)
        v.set_writable(True)
        v_ro.set_value(2) #now it should work
        self.assertEqual(v_ro.get_value(), 2)
        v.set_writable(False)
        with self.assertRaises(Exception):
            v_ro.set_value(9)
        self.assertEqual(v_ro.get_value(), 2)
コード例 #46
0
ファイル: main.py プロジェクト: web-experiments/Atvise2Editor
class OPCUAConnector():
    def __init__(self):
        self.client = ""
        self.displays = []

    def setAddress(self,adress):
        self.client = Client(adress)


    def connect(self):
        try:
            self.display = []
            #self.client.set_security(self.client.server_policy_uri(ua.MessageSecurityMode.None_), "uaclient_untrustedRootCert.der", "uaclient_privateKey.pem")
            self.client.connect()
            #print(self.client.load_client_certificate("../uaclient_untrustedRootCert.der"))
            #print(self.client.load_private_key("../uaclient_privateKey.pem"))
            #print(self.client.user_certificate);


        except:
            print("Unexpected error:", sys.exc_info())

            print("Keine Verbindung möglich")


    def disconnect(self):
        try:
            self.client.disconnect()

        except ConnectionError:
            print("Es besteht keine Verbindung")

    def browse(self,start,filtertype):
        address = start
        filter = filtertype
        root = self.client.get_node(start).get_children()
        if len(root) > 0:
            for idx in root:

                if (self.client.get_node(idx).get_type_definition() == filtertype):
                    self.displays.append(self.client.get_node(idx).nodeid.to_string())
                self.browse(idx,filter)

    def getDisplays(self):
        return self.displays

    def getValue(self,item):
        value = self.client.get_node(item).get_value().Value
        return value;


    def writeValue(self,item,value):
        th = self.client.get_node(item)
        print(value);
        root = ET.fromstring(self.getValue(item))
        for node in root.iter('{http://www.w3.org/2000/svg}script'):
            node.text = '<![CDATA[' + value + ']]>';
            print(node.text);

        #  node.text = '<![CDATA['.encode() + value + ']]>';
        ET.register_namespace("", "http://www.w3.org/2000/svg")
        ET.register_namespace("atv","http://webmi.atvise.com/2007/svgext")
        ET.register_namespace("xlink", "http://www.w3.org/1999/xlink")
        root_string = ET.tostring(root,encoding="UTF-8",method="html")

        print(root_string)
        test=  minidom.parseString(ET.tostring(root,encoding="UTF-8")).toprettyxml()

        try:
            print(th.get_type_definition())
            tet = th.get_attribute(13)
            #th.set_writable(True)
            val = str(test).replace("&lt;", "<")
            val2 = val.replace("&gt;", ">")
            val3 = val2.replace("&quot;",'"');
            length = int(len(val3)-1)
            print(length)
            tet.Value.Value.Value = val3

            print(tet.Value.Value.Value);
            th.set_value(tet)


        except:
            print("Unexpected error:", sys.exc_info())
コード例 #47
0
ファイル: uaclient.py プロジェクト: fville/opcua-client-gui
class UaClient(object):
    """
    OPC-Ua client specialized for the need of GUI client
    return exactly whant GUI needs, no customization possible
    """

    def __init__(self):
        self.client = None
        self._connected = False
        self._datachange_sub = None
        self._event_sub = None
        self._subs_dc = {}
        self._subs_ev = {}

    def connect(self, uri):
        self.disconnect()
        print("Connecting to ", uri)
        self.client = Client(uri)
        self.client.connect()
        self._connected = True

    def disconnect(self):
        if self._connected:
            print("Disconnecting from server")
            self._subs_dc = {}
            self._subs_ev = {}
            self._connected = False
            self._subscription = None
            self.client.disconnect()
            self.client = None

    def subscribe_datachange(self, node, handler):
        if not self._datachange_sub:
            self._datachange_sub = self.client.create_subscription(500, handler)
        handle = self._datachange_sub.subscribe_data_change(node)
        self._subs_dc[node.nodeid] = handle
        return handle

    def unsubscribe_datachange(self, node):
        self._datachange_sub.unsubscribe(self._subs_dc[node.nodeid])

    def subscribe_events(self, node, handler):
        if not self._event_sub:
            print("subscirbing with handler: ", handler, dir(handler))
            self._event_sub = self.client.create_subscription(500, handler)
        handle = self._event_sub.subscribe_events(node)
        self._subs_ev[node.nodeid] = handle
        return handle

    def unsubscribe_events(self, node):
        self._event_sub.unsubscribe(self._subs_ev[node.nodeid])

    def get_root_node_and_desc(self):
        node = self.client.get_root_node()
        attrs = node.get_attributes([ua.AttributeIds.DisplayName, ua.AttributeIds.BrowseName, ua.AttributeIds.NodeId, ua.AttributeIds.NodeClass])
        desc = ua.ReferenceDescription()
        desc.DisplayName = attrs[0].Value.Value
        desc.BrowseName = attrs[1].Value.Value
        desc.NodeId = attrs[2].Value.Value
        desc.NodeClass = attrs[3].Value.Value
        desc.TypeDefinition = ua.TwoByteNodeId(ua.ObjectIds.FolderType)
        return node, desc

    def get_node_attrs(self, node):
        if not isinstance(node, Node):
            node = self.client.get_node(node)
        attrs = node.get_attributes([ua.AttributeIds.DisplayName, ua.AttributeIds.BrowseName, ua.AttributeIds.NodeId])
        return node, [attr.Value.Value.to_string() for attr in attrs]

    def get_children(self, node):
        descs = node.get_children_descriptions()
        children = []
        for desc in descs:
            children.append((self.client.get_node(desc.NodeId), desc))
        return children

    def get_all_attrs(self, node):
        names = []
        vals = []
        for name, val in ua.AttributeIds.__dict__.items():
            if not name.startswith("_"):
                names.append(name)
                vals.append(val)

        attrs = node.get_attributes(vals)
        res = []
        for idx, name in enumerate(names):
            if attrs[idx].StatusCode.is_good():
                res.append((name, attrs[idx]))
        res.sort()
        return res

    def get_all_refs(self, node):
        return node.get_children_descriptions(refs=ua.ObjectIds.References)
コード例 #48
0
class UaClient(object):
    """
    OPC-Ua client specialized for the need of GUI client
    return exactly whant GUI needs, no customization possible
    """

    def __init__(self):
        self.client = None
        self._connected = False
        self._datachange_sub = None
        self._event_sub = None
        self._subs_dc = {}
        self._subs_ev = {}

    def get_node(self, nodeid):
        return self.client.get_node(nodeid)

    def connect(self, uri):
        self.disconnect()
        print("Connecting to ", uri)
        self.client = Client(uri)
        self.client.connect()
        self._connected = True

    def disconnect(self):
        if self._connected:
            print("Disconnecting from server")
            self._subs_dc = {}
            self._subs_ev = {}
            self._connected = False
            self._subscription = None
            self.client.disconnect()
            self.client = None

    def subscribe_datachange(self, node, handler):
        if not self._datachange_sub:
            self._datachange_sub = self.client.create_subscription(500, handler)
        handle = self._datachange_sub.subscribe_data_change(node)
        self._subs_dc[node.nodeid] = handle
        return handle

    def unsubscribe_datachange(self, node):
        self._datachange_sub.unsubscribe(self._subs_dc[node.nodeid])

    def subscribe_events(self, node, handler):
        if not self._event_sub:
            print("subscirbing with handler: ", handler, dir(handler))
            self._event_sub = self.client.create_subscription(500, handler)
        handle = self._event_sub.subscribe_events(node)
        self._subs_ev[node.nodeid] = handle
        return handle

    def unsubscribe_events(self, node):
        self._event_sub.unsubscribe(self._subs_ev[node.nodeid])

    def get_node_attrs(self, node):
        if not isinstance(node, Node):
            node = self.client.get_node(node)
        attrs = node.get_attributes([ua.AttributeIds.DisplayName, ua.AttributeIds.BrowseName, ua.AttributeIds.NodeId])
        return node, [attr.Value.Value.to_string() for attr in attrs]

    def get_children(self, node):
        descs = node.get_children_descriptions()
        descs.sort(key=lambda x: x.BrowseName)
        return descs
コード例 #49
0

if __name__ == "__main__":
    #from IPython import embed
    logging.basicConfig(level=logging.WARN)
    client = Client("opc.tcp://*****:*****@localhost:53530/OPCUA/SimulationServer/")
    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")

        var = client.get_node(ua.NodeId("Random1", 5))
        print("var is: ", var)
        print("value of var is: ", var.get_value())
        var.set_value(ua.Variant([23], ua.VariantType.Double))
        print("setting float value")
        myfloat.set_value(ua.Variant(1.234, ua.VariantType.Float))
        print("reading float value: ", myfloat.get_value())

        handler = SubHandler()
コード例 #50
0
ファイル: OPCPLCModule.py プロジェクト: josecasares/UWS
class OPCPLC(PLC):
    """PLC con comunicación OPC UA.

    Args::
    address (str): Dirección IP (o nombre) del controlador.
    port (int): Puerto de conexión.
    interval (float): Intervalo de actualización en segundos.

    Attributes:
    subscription: Grupo al que se suscriben las variables.
    handler: Manejador de las actualizaciones de los valores.
    objects: Nodo de objetos.
    tagbynodeid (Tag{}): Diccionario de variables por identificador de nodo.
    client: Cliente OPC UA.
    opctype (VariantType{}): Principales tipos de datos OPC.
    
    """
    opctype={
        1:ua.VariantType.Boolean,
        2:ua.VariantType.SByte,
        3:ua.VariantType.Byte,
        4:ua.VariantType.Int16,
        5:ua.VariantType.UInt16,
        6:ua.VariantType.Int32,
        7:ua.VariantType.UInt32,
        8:ua.VariantType.Int64,
        9:ua.VariantType.UInt64,
        10:ua.VariantType.Float,
        11:ua.VariantType.Double,
        12:ua.VariantType.String,
        13:ua.VariantType.DateTime}

    class Memory(PLC.Memory):
        ''' Representacióne un área de memoria.

        No usada en OPC.

        Args:
        plc (PLC): Controlador al que pertenece.

        Attributes:
        tag (tag{}): Diccionario de variables ordenadas por nombre.
        tagbyaddress (tag{}): Diccionario de variables ordenadas por dirección.

        '''

        class Tag(PLC.Memory.Tag):
            ''' Variable

            Args:
            memory (Memory): Memoria a la que pertenece (no usada en OPC).
            key (str): Nombre.
            description (str): Descripción.
            address: Dirección. Se pasa la ruta hasta el nodo con el carácter '\' como separación.
                Los nodos vienen precedidos del tipo en forma de entero, separados por dos puntos.
                Por ejemplo, una dirección podria ser "2:Data\2:Static\2:Scalar\2:Variable".
                Para más información de una estructura en particular, una vez conectado
                llamar al método print_tree().
            
            Attributes:
            node: Nodo OPC asociado.
            type: Tipo de dato.
            value: Valor.
            subscriptor (Subcriptor[]): Objetos suscritos a los cambios.
            
            '''

            def __init__(self, memory:PLC.Memory, key:str, description:str="", address=None):
                self.node=None
                self.type=None
                super().__init__(memory,key,description,address)

            def opcsubscribe(self):
                ''' Suscripción al nodo OPC.

                '''
                plc=self.memory.plc
                address=self.address.split("\\")
                self.node=plc.objects.get_child(address)
                self.type=int(self.node.get_data_type().Identifier)
                plc.tagbynodeid[self.node.nodeid.Identifier]=self
                plc.subscription.subscribe_data_change(self.node)
                self.node.get_value()

            def set(self,value):
                ''' Modifica o asigna el valor de una variable.

                Args:
                value: Nuevo valor de la variable.

                '''
                try:
                    if self.type==1:
                        self.node.set_value(ua.Variant(bool(value),OPCPLC.opctype[self.type])) 
                    if self.type>=2 and self.type<=9:
                        self.node.set_value(ua.Variant(int(value),OPCPLC.opctype[self.type]))
                    if self.type>=10 and self.type<=11:
                        self.node.set_value(ua.Variant(float(value),OPCPLC.opctype[self.type]))
                    if self.type==12:
                        self.node.set_value(ua.Variant(str(value),OPCPLC.opctype[self.type]))
                    if self.type==13:
                        self.node.set_value(ua.Variant(datetime.strptime(value,"%Y-%m-%d %H:%M:%S"),OPCPLC.opctype[self.type]))

                    self.__update(value)
                except Exception as e:
                    printexception(e,"Error in assignment. Tag="+self.key+", Value="+value)


    def __init__(self, address:str, port:int=502, interval:float=3):
        super().__init__()
        self.address=address
        self.port=port
        self.interval=interval
        self.handler=OPCPLC.Handler(self)
        self.subscription=None
        self.objects=None
        self.tagbynodeid={}
        self.client = Client("opc.tcp://"+self.address+":"+str(self.port)+"/")
        self.create("")

    def connect(self):
        ''' Conexión con el controlador

        '''
        try:
            self.client.connect()
            self.objects=self.client.get_objects_node()
            self.subscription=self.client.create_subscription(self.interval, self.handler)
            for key_memory in self.memory:
                memory=self.get(key_memory)
                for key_tag in memory:
                    memory.get(key_tag).opcsubscribe()
            self.connected=True
        except Exception as e:
            printexception(e,"Error connecting to OPC server")
        
    def __tree(self, root, level:int=0):
        ''' Recursión para imprimir el árbol de nodos.

        Args:
        root: nodo raíz en la recursión.
        level (int): Nivel de recursión.

        '''        
        nodes=root.get_children()
        for node in nodes:
            node2=self.client.get_node(node.nodeid)
            name=node2.get_browse_name().to_string()
            print(('   '*level)+name)
            self.tree(node, level+1)

            
    def print_tree(self):
        ''' Imprime la estructura de nodos.

        '''
        self.__tree(self.client.get_objects_node())


    class Handler(object):
        ''' Manejador de los cambios en los valores de los nodos.

        Args:
        plc (PLC): Controlador.

        '''
        
        def __init__(self,plc):
            self.plc=plc

        def datachange_notification(self, node, val, data):
            ''' Método llamado cuando cambia el valor de un nodo.

            Args:
            node: Nodo.
            val: Valor.
            data: Datos.

            '''
            self.plc.tagbynodeid[node.nodeid.Identifier].update(val)