opc_ua/opcua_client_maker.py
branchwxPython4
changeset 3589 a0b645a934c9
parent 3422 700b39cb4525
child 3591 50600b946ea7
equal deleted inserted replaced
3588:412090a6b3a7 3589:a0b645a934c9
    36 lstcolwidths = [     100,      50,      100,  100,    100,    50]
    36 lstcolwidths = [     100,      50,      100,  100,    100,    50]
    37 lstcoltypess = [     str,     int,      str,  str,    str,   int]
    37 lstcoltypess = [     str,     int,      str,  str,    str,   int]
    38 
    38 
    39 directions = ["input", "output"]
    39 directions = ["input", "output"]
    40 
    40 
       
    41 authParams = {
       
    42     "x509":[
       
    43         ("Certificate", "certificate.der"),
       
    44         ("PrivateKey", "private_key.pem"),
       
    45         ("Policy", "Basic256Sha256"),
       
    46         ("Mode", "SignAndEncrypt")],
       
    47     "UserPassword":[
       
    48         ("User", None),
       
    49         ("Password", None)]}
       
    50 
    41 class OPCUASubListModel(dv.DataViewIndexListModel):
    51 class OPCUASubListModel(dv.DataViewIndexListModel):
    42     def __init__(self, data, log):
    52     def __init__(self, data, log):
    43         dv.DataViewIndexListModel.__init__(self, len(data))
    53         dv.DataViewIndexListModel.__init__(self, len(data))
    44         self.data = data
    54         self.data = data
    45         self.log = log
    55         self.log = log
   228     fileidx     = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz))
   238     fileidx     = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz))
   229     smileidx    = il.Add(wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_OTHER, isz))
   239     smileidx    = il.Add(wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_OTHER, isz))
   230 
   240 
   231 
   241 
   232 class OPCUAClientPanel(wx.SplitterWindow):
   242 class OPCUAClientPanel(wx.SplitterWindow):
   233     def __init__(self, parent, modeldata, log, uri_getter):
   243     def __init__(self, parent, modeldata, log, config_getter):
   234         self.log = log
   244         self.log = log
   235         wx.SplitterWindow.__init__(self, parent, -1)
   245         wx.SplitterWindow.__init__(self, parent, -1)
   236 
   246 
   237         self.ordered_nodes = []
   247         self.ordered_nodes = []
   238 
   248 
   240         self.inout_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
   250         self.inout_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
   241         self.inout_sizer.AddGrowableCol(0)
   251         self.inout_sizer.AddGrowableCol(0)
   242         self.inout_sizer.AddGrowableRow(1)
   252         self.inout_sizer.AddGrowableRow(1)
   243 
   253 
   244         self.client = None
   254         self.client = None
   245         self.uri_getter = uri_getter
   255         self.config_getter = config_getter
   246 
   256 
   247         self.connect_button = wx.ToggleButton(self.inout_panel, -1, "Browse Server")
   257         self.connect_button = wx.ToggleButton(self.inout_panel, -1, "Browse Server")
   248 
   258 
   249         self.selected_splitter = wx.SplitterWindow(self.inout_panel, style=wx.SUNKEN_BORDER | wx.SP_3D)
   259         self.selected_splitter = wx.SplitterWindow(self.inout_panel, style=wx.SUNKEN_BORDER | wx.SP_3D)
   250 
   260 
   296                 self.tree.AddColumn(colname)
   306                 self.tree.AddColumn(colname)
   297                 self.tree.SetColumnWidth(idx, width)
   307                 self.tree.SetColumnWidth(idx, width)
   298 
   308 
   299             self.tree.SetMainColumn(0)
   309             self.tree.SetMainColumn(0)
   300 
   310 
   301             self.client = Client(self.uri_getter())
   311             config = self.config_getter()
       
   312             self.client = Client(config["URI"])
       
   313             
       
   314             # TODO: crypto stuff
       
   315             # client.set_security_string("Basic256Sha256,SignAndEncrypt,certificate-example.der,private-key-example.pem")
       
   316 
   302             self.client.connect()
   317             self.client.connect()
   303             self.client.load_type_definitions()  # load definition of server specific structures/extension objects
   318             self.client.load_type_definitions()  # load definition of server specific structures/extension objects
   304             rootnode = self.client.get_root_node()
   319             rootnode = self.client.get_root_node()
   305 
   320 
   306             rootitem = self.AddNodeItem(self.tree.AddRoot, rootnode)
   321             rootitem = self.AddNodeItem(self.tree.AddRoot, rootnode)
   476                 writer = csv.writer(csvfile, delimiter=',',
   491                 writer = csv.writer(csvfile, delimiter=',',
   477                                 quotechar='"', quoting=csv.QUOTE_MINIMAL)
   492                                 quotechar='"', quoting=csv.QUOTE_MINIMAL)
   478                 for row in data:
   493                 for row in data:
   479                     writer.writerow([direction] + row)
   494                     writer.writerow([direction] + row)
   480 
   495 
   481     def GenerateC(self, path, locstr, server_uri):
   496     def GenerateC(self, path, locstr, config):
   482         template = """/* code generated by beremiz OPC-UA extension */
   497         template = """/* code generated by beremiz OPC-UA extension */
   483 
   498 
   484 #include <open62541/client_config_default.h>
   499 #include <open62541/client_config_default.h>
   485 #include <open62541/client_highlevel.h>
   500 #include <open62541/client_highlevel.h>
   486 #include <open62541/plugin/log_stdout.h>
   501 #include <open62541/plugin/log_stdout.h>
   490 #define DECL_VAR(ua_type, C_type, c_loc_name)                                                       \\
   505 #define DECL_VAR(ua_type, C_type, c_loc_name)                                                       \\
   491 static UA_Variant c_loc_name##_variant;                                                             \\
   506 static UA_Variant c_loc_name##_variant;                                                             \\
   492 static C_type c_loc_name##_buf = 0;                                                                 \\
   507 static C_type c_loc_name##_buf = 0;                                                                 \\
   493 C_type *c_loc_name = &c_loc_name##_buf;
   508 C_type *c_loc_name = &c_loc_name##_buf;
   494 
   509 
   495 %(decl)s
   510 {decl}
   496 
   511 
   497 void __cleanup_%(locstr)s(void)
   512 void __cleanup_{locstr}(void)
   498 {
   513 {{
   499     UA_Client_disconnect(client);
   514     UA_Client_disconnect(client);
   500     UA_Client_delete(client);
   515     UA_Client_delete(client);
   501 }
   516 }}
   502 
   517 
   503 
   518 
   504 #define INIT_READ_VARIANT(ua_type, c_loc_name)                                                     \\
   519 #define INIT_READ_VARIANT(ua_type, c_loc_name)                                                     \\
   505     UA_Variant_init(&c_loc_name##_variant);
   520     UA_Variant_init(&c_loc_name##_variant);
   506 
   521 
   507 #define INIT_WRITE_VARIANT(ua_type, ua_type_enum, c_loc_name)       \\
   522 #define INIT_WRITE_VARIANT(ua_type, ua_type_enum, c_loc_name)                                      \\
   508     UA_Variant_setScalar(&c_loc_name##_variant, (ua_type*)c_loc_name, &UA_TYPES[ua_type_enum]);
   523     UA_Variant_setScalar(&c_loc_name##_variant, (ua_type*)c_loc_name, &UA_TYPES[ua_type_enum]);
   509 
   524 
   510 int __init_%(locstr)s(int argc,char **argv)
   525 int __init_{locstr}(int argc,char **argv)
   511 {
   526 {{
   512     UA_StatusCode retval;
   527     UA_StatusCode retval;
   513     client = UA_Client_new();
   528     client = UA_Client_new();
   514     UA_ClientConfig_setDefault(UA_Client_getConfig(client));
   529     UA_ClientConfig_setDefault(UA_Client_getConfig(client));
   515 %(init)s
   530 {init}
   516 
   531 
   517     /* Connect to server */
   532     /* Connect to server */
   518     retval = UA_Client_connect(client, "%(uri)s");
   533     retval = UA_Client_connect(client, "{uri}");
   519     if(retval != UA_STATUSCODE_GOOD) {
   534     if(retval != UA_STATUSCODE_GOOD) {{
   520         UA_Client_delete(client);
   535         UA_Client_delete(client);
   521         return EXIT_FAILURE;
   536         return EXIT_FAILURE;
   522     }
   537     }}
   523 }
   538 }}
   524 
   539 
   525 #define READ_VALUE(ua_type, ua_type_enum, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id)        \\
   540 #define READ_VALUE(ua_type, ua_type_enum, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id)        \\
   526     retval = UA_Client_readValueAttribute(                                                         \\
   541     retval = UA_Client_readValueAttribute(                                                         \\
   527         client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant);                      \\
   542         client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant);                      \\
   528     if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(&c_loc_name##_variant) &&               \\
   543     if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(&c_loc_name##_variant) &&               \\
   529        c_loc_name##_variant.type == &UA_TYPES[ua_type_enum]) {                                     \\
   544        c_loc_name##_variant.type == &UA_TYPES[ua_type_enum]) {{                                    \\
   530             c_loc_name##_buf = *(ua_type*)c_loc_name##_variant.data;                               \\
   545             c_loc_name##_buf = *(ua_type*)c_loc_name##_variant.data;                               \\
   531             UA_Variant_clear(&c_loc_name##_variant);  /* Unalloc requiered on each read ! */       \\
   546             UA_Variant_clear(&c_loc_name##_variant);  /* Unalloc requiered on each read ! */       \\
   532     }
   547     }}
   533 
   548 
   534 void __retrieve_%(locstr)s(void)
   549 void __retrieve_{locstr}(void)
   535 {
   550 {{
   536     UA_StatusCode retval;
   551     UA_StatusCode retval;
   537 %(retrieve)s
   552 {retrieve}
   538 }
   553 }}
   539 
   554 
   540 #define WRITE_VALUE(ua_type, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id)       \\
   555 #define WRITE_VALUE(ua_type, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id)                     \\
   541     UA_Client_writeValueAttribute(                                                                 \\
   556     UA_Client_writeValueAttribute(                                                                 \\
   542         client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant);
   557         client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant);
   543 
   558 
   544 void __publish_%(locstr)s(void)
   559 void __publish_{locstr}(void)
   545 {
   560 {{
   546 %(publish)s
   561 {publish}
   547 }
   562 }}
   548 
   563 
   549 """
   564 """
   550         
   565         
   551         formatdict = dict(
   566         formatdict = dict(
   552             locstr   = locstr,
   567             locstr   = locstr,
   553             uri      = server_uri,
   568             uri      = config["URI"],
       
   569             # TODO: pass authentication code.
   554             decl     = "",
   570             decl     = "",
   555             cleanup  = "",
   571             cleanup  = "",
   556             init     = "",
   572             init     = "",
   557             retrieve = "",
   573             retrieve = "",
   558             publish  = "" 
   574             publish  = "" 
   579                     formatdict["init"] +="""
   595                     formatdict["init"] +="""
   580     INIT_WRITE_VARIANT({ua_type}, {ua_type_enum}, {c_loc_name})""".format(**locals())
   596     INIT_WRITE_VARIANT({ua_type}, {ua_type_enum}, {c_loc_name})""".format(**locals())
   581                     formatdict["publish"] += """
   597                     formatdict["publish"] += """
   582     WRITE_VALUE({ua_type}, {c_loc_name}, {ua_nodeid_type}, {ua_nsidx}, {ua_node_id})""".format(**locals())
   598     WRITE_VALUE({ua_type}, {c_loc_name}, {ua_nodeid_type}, {ua_nsidx}, {ua_node_id})""".format(**locals())
   583 
   599 
   584         Ccode = template%formatdict
   600         Ccode = template.format(**formatdict)
   585         
   601         
   586         return Ccode
   602         return Ccode
   587 
   603 
   588 if __name__ == "__main__":
   604 if __name__ == "__main__":
   589 
   605 
   592 
   608 
   593     app = wit.InspectableApp()
   609     app = wit.InspectableApp()
   594 
   610 
   595     frame = wx.Frame(None, -1, "OPCUA Client Test App", size=(800,600))
   611     frame = wx.Frame(None, -1, "OPCUA Client Test App", size=(800,600))
   596 
   612 
   597     uri = sys.argv[1] if len(sys.argv)>1 else "opc.tcp://localhost:4840"
   613     argc = len(sys.argv)
       
   614 
       
   615     config={}
       
   616     config["URI"] = sys.argv[1] if argc>1 else "opc.tcp://localhost:4840"
       
   617 
       
   618     if argc > 2:
       
   619         AuthType = sys.argv[2]
       
   620         config["AuthType"] = AuthType
       
   621         for (name, default), value in izip_longest(authParams[AuthType], sys.argv[3:]):
       
   622             if value is None:
       
   623                 if default is None:
       
   624                     raise Exception(name+" param expected")
       
   625                 value = default
       
   626             config[name] = value
   598 
   627 
   599     test_panel = wx.Panel(frame)
   628     test_panel = wx.Panel(frame)
   600     test_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
   629     test_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
   601     test_sizer.AddGrowableCol(0)
   630     test_sizer.AddGrowableCol(0)
   602     test_sizer.AddGrowableRow(0)
   631     test_sizer.AddGrowableRow(0)
   603 
   632 
   604     modeldata = OPCUAClientModel(print)
   633     modeldata = OPCUAClientModel(print)
   605 
   634 
   606     opcuatestpanel = OPCUAClientPanel(test_panel, modeldata, print, lambda:uri)
   635     opcuatestpanel = OPCUAClientPanel(test_panel, modeldata, print, lambda:config)
   607 
   636 
   608     def OnGenerate(evt):
   637     def OnGenerate(evt):
   609         dlg = wx.FileDialog(
   638         dlg = wx.FileDialog(
   610             frame, message="Generate file as ...", defaultDir=os.getcwd(),
   639             frame, message="Generate file as ...", defaultDir=os.getcwd(),
   611             defaultFile="", 
   640             defaultFile="", 
   622     -I ../../open62541/build/src_generated/ \\
   651     -I ../../open62541/build/src_generated/ \\
   623     -I ../../open62541/include/ \\
   652     -I ../../open62541/include/ \\
   624     -I ../../open62541/arch/ ../../open62541/build/bin/libopen62541.a
   653     -I ../../open62541/arch/ ../../open62541/build/bin/libopen62541.a
   625 */
   654 */
   626 
   655 
   627 """%(path, path[:-2]) + modeldata.GenerateC(path, "test", uri) + """
   656 """%(path, path[:-2]) + modeldata.GenerateC(path, "test", config) + """
   628 
   657 
   629 int main(int argc, char *argv[]) {
   658 int main(int argc, char *argv[]) {
   630 
   659 
   631     __init_test(arc,argv);
   660     __init_test(arc,argv);
   632    
   661