opc_ua/client.py
author Edouard Tisserant
Thu, 08 Dec 2022 11:17:15 +0100
changeset 3704 c17fac18c663
parent 3378 e655ec8162e1
child 3589 a0b645a934c9
permissions -rw-r--r--
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
3364
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     1
# opcua/client.py
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     2
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     3
from __future__ import absolute_import
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     4
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     5
import os
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     6
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     7
from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
3366
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
     8
from PLCControler import LOCATION_CONFNODE, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
     9
from .opcua_client_maker import OPCUAClientPanel, OPCUAClientModel, UA_IEC_types
3364
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    10
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    11
import util.paths as paths
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    12
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    13
# Paths to open62541 assume that 
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    14
# - open62541 directory is aside beremiz directory
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    15
# - open62541 was just built (not installed)
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    16
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    17
Open62541Path = paths.ThirdPartyPath("open62541")
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    18
Open62541LibraryPath = os.path.join(Open62541Path,"build","bin") 
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    19
Open62541IncludePaths = [os.path.join(Open62541Path, *dirs) for dirs in [
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    20
    ("plugins","include"),
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    21
    ("build","src_generated"),
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    22
    ("include",),
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    23
    ("arch",)]]
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    24
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    25
class OPCUAClientEditor(ConfTreeNodeEditor):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    26
    CONFNODEEDITOR_TABS = [
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    27
        (_("OPC-UA Client"), "CreateOPCUAClient_UI")]
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    28
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    29
    def Log(self, msg):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    30
        self.Controler.GetCTRoot().logger.write(msg)
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    31
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    32
    def UriGetter(self):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    33
        return self.Controler.GetServerURI() 
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    34
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    35
    def CreateOPCUAClient_UI(self, parent):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    36
        return OPCUAClientPanel(parent, self.Controler.GetModelData(), self.Log, self.UriGetter)
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    37
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    38
class OPCUAClient(object):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    39
    XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    40
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    41
      <xsd:element name="OPCUAClient">
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    42
        <xsd:complexType>
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    43
          <xsd:attribute name="Server_URI" type="xsd:string" use="optional" default="opc.tcp://localhost:4840"/>
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    44
        </xsd:complexType>
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    45
      </xsd:element>
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    46
    </xsd:schema>
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    47
    """
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    48
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    49
    EditorType = OPCUAClientEditor
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    50
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    51
    def __init__(self):
3378
e655ec8162e1 OPC-UA: fix types in model not being preserved after reload of CSV file, leading to exception when changing selection lists content.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3366
diff changeset
    52
        self.modeldata = OPCUAClientModel(self.Log)
3364
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    53
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    54
        filepath = self.GetFileName()
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    55
        if os.path.isfile(filepath):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    56
            self.modeldata.LoadCSV(filepath)
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    57
3378
e655ec8162e1 OPC-UA: fix types in model not being preserved after reload of CSV file, leading to exception when changing selection lists content.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3366
diff changeset
    58
    def Log(self, msg):
e655ec8162e1 OPC-UA: fix types in model not being preserved after reload of CSV file, leading to exception when changing selection lists content.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3366
diff changeset
    59
        self.GetCTRoot().logger.write(msg)
e655ec8162e1 OPC-UA: fix types in model not being preserved after reload of CSV file, leading to exception when changing selection lists content.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3366
diff changeset
    60
3364
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    61
    def GetModelData(self):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    62
        return self.modeldata
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    63
    
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    64
    def GetServerURI(self):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    65
        return self.GetParamsAttributes("OPCUAClient.Server_URI")["value"]
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    66
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    67
    def GetFileName(self):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    68
        return os.path.join(self.CTNPath(), 'selected.csv')
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    69
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    70
    def OnCTNSave(self, from_project_path=None):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    71
        self.modeldata.SaveCSV(self.GetFileName())
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    72
        return True
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    73
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    74
    def CTNGenerate_C(self, buildpath, locations):
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    75
        current_location = self.GetCurrentLocation()
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    76
        locstr = "_".join(map(str, current_location))
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    77
        c_path = os.path.join(buildpath, "opcua_client__%s.c" % locstr)
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    78
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    79
        c_code = self.modeldata.GenerateC(c_path, locstr, 
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    80
            self.GetParamsAttributes("OPCUAClient.Server_URI")["value"])
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    81
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    82
        with open(c_path, 'wb') as c_file:
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    83
            c_file.write(c_code)
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    84
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    85
        LDFLAGS = [' "' + os.path.join(Open62541LibraryPath, "libopen62541.a") + '"']
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    86
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    87
        CFLAGS = ' '.join(['-I"' + path + '"' for path in Open62541IncludePaths])
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    88
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    89
        return [(c_path, CFLAGS)], LDFLAGS, True
fa2365fa6154 Add OPC-UA simple synchronous client extension.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    90
3366
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    91
    def GetVariableLocationTree(self):
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    92
        current_location = self.GetCurrentLocation()
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    93
        locstr = "_".join(map(str, current_location))
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    94
        name = self.BaseParams.getName()
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    95
        entries = []
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    96
        for direction, data in self.modeldata.iteritems():
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    97
            iec_direction_prefix = {"input": "__I", "output": "__Q"}[direction]
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    98
            for row in data:
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
    99
                dname, ua_nsidx, ua_nodeid_type, _ua_node_id, ua_type, iec_number = row
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   100
                iec_type, C_type, iec_size_prefix, ua_type_enum, ua_type = UA_IEC_types[ua_type]
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   101
                c_loc_name = iec_direction_prefix + iec_size_prefix + locstr + "_" + str(iec_number)
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   102
                entries.append({
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   103
                    "name": dname,
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   104
                    "type": {"input": LOCATION_VAR_INPUT, "output": LOCATION_VAR_OUTPUT}[direction],
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   105
                    "size": {"X":1, "B":8, "W":16, "D":32, "L":64}[iec_size_prefix],
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   106
                    "IEC_type": iec_type,
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   107
                    "var_name": c_loc_name,
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   108
                    "location": iec_size_prefix + ".".join([str(i) for i in current_location]) + "." + str(iec_number),
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   109
                    "description": "",
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   110
                    "children": []})
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   111
        return {"name": name,
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   112
                "type": LOCATION_CONFNODE,
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   113
                "location": ".".join([str(i) for i in current_location]) + ".x",
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   114
                "children": entries}
1ca385429bba OPCUA: Add browsing of variables exposed by client when selecting location from variable panel.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3364
diff changeset
   115