edouard@3364: # opcua/client.py edouard@3364: edouard@3364: from __future__ import absolute_import edouard@3364: edouard@3364: import os edouard@3364: edouard@3364: from editors.ConfTreeNodeEditor import ConfTreeNodeEditor edouard@3366: from PLCControler import LOCATION_CONFNODE, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT edouard@3366: from .opcua_client_maker import OPCUAClientPanel, OPCUAClientModel, UA_IEC_types edouard@3364: edouard@3364: import util.paths as paths edouard@3364: edouard@3364: # Paths to open62541 assume that edouard@3364: # - open62541 directory is aside beremiz directory edouard@3364: # - open62541 was just built (not installed) edouard@3364: edouard@3364: Open62541Path = paths.ThirdPartyPath("open62541") edouard@3364: Open62541LibraryPath = os.path.join(Open62541Path,"build","bin") edouard@3364: Open62541IncludePaths = [os.path.join(Open62541Path, *dirs) for dirs in [ edouard@3364: ("plugins","include"), edouard@3364: ("build","src_generated"), edouard@3364: ("include",), edouard@3364: ("arch",)]] edouard@3364: edouard@3364: class OPCUAClientEditor(ConfTreeNodeEditor): edouard@3364: CONFNODEEDITOR_TABS = [ edouard@3364: (_("OPC-UA Client"), "CreateOPCUAClient_UI")] edouard@3364: edouard@3364: def Log(self, msg): edouard@3364: self.Controler.GetCTRoot().logger.write(msg) edouard@3364: edouard@3364: def UriGetter(self): edouard@3364: return self.Controler.GetServerURI() edouard@3364: edouard@3364: def CreateOPCUAClient_UI(self, parent): edouard@3364: return OPCUAClientPanel(parent, self.Controler.GetModelData(), self.Log, self.UriGetter) edouard@3364: edouard@3364: class OPCUAClient(object): edouard@3364: XSD = """ edouard@3364: edouard@3364: edouard@3364: edouard@3364: edouard@3364: edouard@3364: edouard@3364: edouard@3364: """ edouard@3364: edouard@3364: EditorType = OPCUAClientEditor edouard@3364: edouard@3364: def __init__(self): edouard@3378: self.modeldata = OPCUAClientModel(self.Log) edouard@3364: edouard@3364: filepath = self.GetFileName() edouard@3364: if os.path.isfile(filepath): edouard@3364: self.modeldata.LoadCSV(filepath) edouard@3364: edouard@3378: def Log(self, msg): edouard@3378: self.GetCTRoot().logger.write(msg) edouard@3378: edouard@3364: def GetModelData(self): edouard@3364: return self.modeldata edouard@3364: edouard@3364: def GetServerURI(self): edouard@3364: return self.GetParamsAttributes("OPCUAClient.Server_URI")["value"] edouard@3364: edouard@3364: def GetFileName(self): edouard@3364: return os.path.join(self.CTNPath(), 'selected.csv') edouard@3364: edouard@3364: def OnCTNSave(self, from_project_path=None): edouard@3364: self.modeldata.SaveCSV(self.GetFileName()) edouard@3364: return True edouard@3364: edouard@3364: def CTNGenerate_C(self, buildpath, locations): edouard@3364: current_location = self.GetCurrentLocation() edouard@3364: locstr = "_".join(map(str, current_location)) edouard@3364: c_path = os.path.join(buildpath, "opcua_client__%s.c" % locstr) edouard@3364: edouard@3364: c_code = self.modeldata.GenerateC(c_path, locstr, edouard@3364: self.GetParamsAttributes("OPCUAClient.Server_URI")["value"]) edouard@3364: edouard@3364: with open(c_path, 'wb') as c_file: edouard@3364: c_file.write(c_code) edouard@3364: edouard@3364: LDFLAGS = [' "' + os.path.join(Open62541LibraryPath, "libopen62541.a") + '"'] edouard@3364: edouard@3364: CFLAGS = ' '.join(['-I"' + path + '"' for path in Open62541IncludePaths]) edouard@3364: edouard@3364: return [(c_path, CFLAGS)], LDFLAGS, True edouard@3364: edouard@3366: def GetVariableLocationTree(self): edouard@3366: current_location = self.GetCurrentLocation() edouard@3366: locstr = "_".join(map(str, current_location)) edouard@3366: name = self.BaseParams.getName() edouard@3366: entries = [] edouard@3366: for direction, data in self.modeldata.iteritems(): edouard@3366: iec_direction_prefix = {"input": "__I", "output": "__Q"}[direction] edouard@3366: for row in data: edouard@3366: dname, ua_nsidx, ua_nodeid_type, _ua_node_id, ua_type, iec_number = row edouard@3366: iec_type, C_type, iec_size_prefix, ua_type_enum, ua_type = UA_IEC_types[ua_type] edouard@3366: c_loc_name = iec_direction_prefix + iec_size_prefix + locstr + "_" + str(iec_number) edouard@3366: entries.append({ edouard@3366: "name": dname, edouard@3366: "type": {"input": LOCATION_VAR_INPUT, "output": LOCATION_VAR_OUTPUT}[direction], edouard@3366: "size": {"X":1, "B":8, "W":16, "D":32, "L":64}[iec_size_prefix], edouard@3366: "IEC_type": iec_type, edouard@3366: "var_name": c_loc_name, edouard@3366: "location": iec_size_prefix + ".".join([str(i) for i in current_location]) + "." + str(iec_number), edouard@3366: "description": "", edouard@3366: "children": []}) edouard@3366: return {"name": name, edouard@3366: "type": LOCATION_CONFNODE, edouard@3366: "location": ".".join([str(i) for i in current_location]) + ".x", edouard@3366: "children": entries} edouard@3366: