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)
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
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()
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
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()
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
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")
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
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
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)
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)
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)
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")
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
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
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)
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()
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")
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()
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()
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()
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)
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
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
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
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()
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
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")
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)
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}')
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()
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)
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")
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)
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})
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")
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)
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)
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()
#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()
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()
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()
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
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)
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)
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("<", "<") val2 = val.replace(">", ">") val3 = val2.replace(""",'"'); 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())
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)
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
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()
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)