2111
|
1 |
import wx
|
|
2 |
|
|
3 |
from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
|
|
4 |
from ConfigTreeNode import ConfigTreeNode
|
|
5 |
|
|
6 |
from ConfigEditor import NodeEditor
|
|
7 |
|
|
8 |
TYPECONVERSION = {"BOOL" : "X", "SINT" : "B", "INT" : "W", "DINT" : "D", "LINT" : "L",
|
|
9 |
"USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L",
|
|
10 |
"BYTE" : "B", "WORD" : "W", "DWORD" : "D", "LWORD" : "L"}
|
|
11 |
|
|
12 |
DATATYPECONVERSION = {"BOOL" : "BIT", "SINT" : "S8", "INT" : "S16", "DINT" : "S32", "LINT" : "S64",
|
|
13 |
"USINT" : "U8", "UINT" : "U16", "UDINT" : "U32", "ULINT" : "U64",
|
|
14 |
"BYTE" : "U8", "WORD" : "U16", "DWORD" : "U32", "LWORD" : "U64"}
|
|
15 |
|
|
16 |
VARCLASSCONVERSION = {"T": LOCATION_VAR_INPUT, "R": LOCATION_VAR_OUTPUT, "RT": LOCATION_VAR_MEMORY}
|
|
17 |
|
|
18 |
def ExtractHexDecValue(value):
|
|
19 |
try:
|
|
20 |
return int(value)
|
|
21 |
except:
|
|
22 |
pass
|
|
23 |
try:
|
|
24 |
return int(value.replace("#", "0"), 16)
|
|
25 |
except:
|
|
26 |
raise ValueError, "Invalid value for HexDecValue \"%s\"" % value
|
|
27 |
|
|
28 |
def GenerateHexDecValue(value, base=10):
|
|
29 |
if base == 10:
|
|
30 |
return str(value)
|
|
31 |
elif base == 16:
|
|
32 |
return "#x%.8x" % value
|
|
33 |
else:
|
|
34 |
raise ValueError, "Not supported base"
|
|
35 |
|
|
36 |
def ExtractName(names, default=None):
|
|
37 |
if len(names) == 1:
|
|
38 |
return names[0].getcontent()
|
|
39 |
else:
|
|
40 |
for name in names:
|
|
41 |
if name.getLcId() == 1033:
|
|
42 |
return name.getcontent()
|
|
43 |
return default
|
|
44 |
|
|
45 |
#--------------------------------------------------
|
|
46 |
# Ethercat Node
|
|
47 |
#--------------------------------------------------
|
|
48 |
|
|
49 |
class _EthercatSlaveCTN:
|
|
50 |
|
|
51 |
NODE_PROFILE = None
|
|
52 |
EditorType = NodeEditor
|
|
53 |
|
|
54 |
def GetIconName(self):
|
|
55 |
return "Slave"
|
|
56 |
|
|
57 |
def ExtractHexDecValue(self, value):
|
|
58 |
return ExtractHexDecValue(value)
|
|
59 |
|
|
60 |
def GetSizeOfType(self, type):
|
|
61 |
return TYPECONVERSION.get(self.GetCTRoot().GetBaseType(type), None)
|
|
62 |
|
|
63 |
def GetSlavePos(self):
|
|
64 |
return self.BaseParams.getIEC_Channel()
|
|
65 |
|
|
66 |
def GetParamsAttributes(self, path = None):
|
|
67 |
if path:
|
|
68 |
parts = path.split(".", 1)
|
|
69 |
if self.MandatoryParams and parts[0] == self.MandatoryParams[0]:
|
|
70 |
return self.MandatoryParams[1].getElementInfos(parts[0], parts[1])
|
|
71 |
elif self.CTNParams and parts[0] == self.CTNParams[0]:
|
|
72 |
return self.CTNParams[1].getElementInfos(parts[0], parts[1])
|
|
73 |
else:
|
|
74 |
params = []
|
|
75 |
if self.CTNParams:
|
|
76 |
params.append(self.CTNParams[1].getElementInfos(self.CTNParams[0]))
|
|
77 |
else:
|
|
78 |
params.append({
|
|
79 |
'use': 'required',
|
|
80 |
'type': 'element',
|
|
81 |
'name': 'SlaveParams',
|
|
82 |
'value': None,
|
|
83 |
'children': []
|
|
84 |
})
|
|
85 |
|
|
86 |
slave_type = self.CTNParent.GetSlaveType(self.GetSlavePos())
|
|
87 |
params[0]['children'].insert(0,
|
|
88 |
{'use': 'optional',
|
|
89 |
'type': self.CTNParent.GetSlaveTypesLibrary(self.NODE_PROFILE),
|
|
90 |
'name': 'Type',
|
|
91 |
'value': (slave_type["device_type"], slave_type)})
|
|
92 |
params[0]['children'].insert(1,
|
|
93 |
{'use': 'optional',
|
|
94 |
'type': 'unsignedLong',
|
|
95 |
'name': 'Alias',
|
|
96 |
'value': self.CTNParent.GetSlaveAlias(self.GetSlavePos())})
|
|
97 |
return params
|
|
98 |
|
|
99 |
def SetParamsAttribute(self, path, value):
|
|
100 |
position = self.BaseParams.getIEC_Channel()
|
|
101 |
|
|
102 |
if path == "SlaveParams.Type":
|
|
103 |
self.CTNParent.SetSlaveType(position, value)
|
|
104 |
slave_type = self.CTNParent.GetSlaveType(self.GetSlavePos())
|
|
105 |
value = (slave_type["device_type"], slave_type)
|
|
106 |
if self._View is not None:
|
|
107 |
wx.CallAfter(self._View.RefreshSlaveInfos)
|
|
108 |
return value, True
|
|
109 |
elif path == "SlaveParams.Alias":
|
|
110 |
self.CTNParent.SetSlaveAlias(position, value)
|
|
111 |
return value, True
|
|
112 |
|
|
113 |
value, refresh = ConfigTreeNode.SetParamsAttribute(self, path, value)
|
|
114 |
|
|
115 |
# Filter IEC_Channel, Slave_Type and Alias that have specific behavior
|
|
116 |
if path == "BaseParams.IEC_Channel" and value != position:
|
|
117 |
self.CTNParent.SetSlavePosition(position, value)
|
|
118 |
|
|
119 |
return value, refresh
|
|
120 |
|
|
121 |
def GetSlaveInfos(self):
|
|
122 |
return self.CTNParent.GetSlaveInfos(self.GetSlavePos())
|
|
123 |
|
|
124 |
def GetSlaveVariables(self, limits):
|
|
125 |
return self.CTNParent.GetSlaveVariables(self.GetSlavePos(), limits)
|
|
126 |
|
|
127 |
def GetVariableLocationTree(self):
|
|
128 |
return {"name": self.BaseParams.getName(),
|
|
129 |
"type": LOCATION_CONFNODE,
|
|
130 |
"location": self.GetFullIEC_Channel(),
|
|
131 |
"children": self.CTNParent.GetDeviceLocationTree(self.GetSlavePos(), self.GetCurrentLocation(), self.BaseParams.getName())
|
|
132 |
}
|
|
133 |
|
|
134 |
def CTNGenerate_C(self, buildpath, locations):
|
|
135 |
return [],"",False
|