opc_ua/client.py
author Edouard Tisserant
Thu, 09 Dec 2021 10:21:45 +0100
branchRuntimeLists
changeset 3395 93ad018fb602
parent 3378 e655ec8162e1
child 3589 a0b645a934c9
permissions -rw-r--r--
RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
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