2 # -*- coding: utf-8 -*-
4 #This file is part of CanFestival, a library implementing CanOpen Stack.
6 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
8 #See COPYING file for copyrights details.
10 #This library is free software; you can redistribute it and/or
11 #modify it under the terms of the GNU Lesser General Public
12 #License as published by the Free Software Foundation; either
13 #version 2.1 of the License, or (at your option) any later version.
15 #This library is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 #Lesser General Public License for more details.
20 #You should have received a copy of the GNU Lesser General Public
21 #License along with this library; if not, write to the Free Software
22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 Dictionary of translation between access symbol and their signification
31 AccessType = {"ro" : "Read Only", "wo" : "Write Only", "rw" : "Read/Write"}
33 BoolType = {True : "True", False : "False"}
34 OptionType = {True : "Yes", False : "No"}
36 CustomisableTypes = [(0x02, 0), (0x03, 0), (0x04, 0), (0x05, 0), (0x06, 0), (0x07, 0),
37 (0x08, 0), (0x09, 1), (0x0A, 1), (0x0B, 1), (0x10, 0), (0x11, 0), (0x12, 0),
38 (0x13, 0), (0x14, 0), (0x15, 0), (0x16, 0), (0x18, 0), (0x19, 0), (0x1A, 0),
41 DefaultParams = {"comment" : "", "save" : False}
43 #-------------------------------------------------------------------------------
44 # Dictionary Mapping and Organisation
45 #-------------------------------------------------------------------------------
48 Properties of entry structure in the Object Dictionary
50 OD_Subindex = 1 # Entry has at least one subindex
51 OD_MultipleSubindexes = 2 # Entry has more than one subindex
52 OD_IdenticalSubindexes = 4 # Subindexes of entry have the same description
53 OD_IdenticalIndexes = 8 # Entry has the same description on multiple indexes
56 Structures of entry in the Object Dictionary, sum of the properties described above
57 for all sorts of entries use in CAN Open specification
59 nosub = 0 # Entry without subindex (only for type declaration)
61 array = OD_Subindex | OD_MultipleSubindexes
62 rec = OD_Subindex | OD_MultipleSubindexes | OD_IdenticalSubindexes
63 # Entries identical on multiple indexes
64 plurivar = OD_Subindex | OD_IdenticalIndexes
65 pluriarray = OD_Subindex | OD_MultipleSubindexes | OD_IdenticalIndexes # Example : PDO Parameters
66 plurirec = OD_Subindex | OD_MultipleSubindexes | OD_IdenticalSubindexes |OD_IdenticalIndexes # Example : PDO Mapping
69 MappingDictionary is the structure used for writing a good organised Object
70 Dictionary. It follows the specifications of the CANOpen standard.
71 Change the informations within it if there is a mistake. But don't modify the
72 organisation of this object, it will involve in a malfunction of the application.
76 0x0001 : {"name" : "BOOLEAN", "struct" : nosub, "size" : 1, "default" : False, "values" : []},
77 0x0002 : {"name" : "INTEGER8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []},
78 0x0003 : {"name" : "INTEGER16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []},
79 0x0004 : {"name" : "INTEGER32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []},
80 0x0005 : {"name" : "UNSIGNED8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []},
81 0x0006 : {"name" : "UNSIGNED16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []},
82 0x0007 : {"name" : "UNSIGNED32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []},
83 0x0008 : {"name" : "REAL32", "struct" : nosub, "size" : 32, "default" : 0.0, "values" : []},
84 0x0009 : {"name" : "VISIBLE_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []},
85 0x000A : {"name" : "OCTET_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []},
86 0x000B : {"name" : "UNICODE_STRING", "struct" : nosub, "size" : 16, "default" : "", "values" : []},
87 # 0x000C : {"name" : "TIME_OF_DAY", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
88 # 0x000D : {"name" : "TIME_DIFFERENCE", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
89 0x000F : {"name" : "DOMAIN", "struct" : nosub, "size" : 0, "default" : "", "values" : []},
90 0x0010 : {"name" : "INTEGER24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []},
91 0x0011 : {"name" : "REAL64", "struct" : nosub, "size" : 64, "default" : 0.0, "values" : []},
92 0x0012 : {"name" : "INTEGER40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []},
93 0x0013 : {"name" : "INTEGER48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
94 0x0014 : {"name" : "INTEGER56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []},
95 0x0015 : {"name" : "INTEGER64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []},
96 0x0016 : {"name" : "UNSIGNED24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []},
97 0x0018 : {"name" : "UNSIGNED40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []},
98 0x0019 : {"name" : "UNSIGNED48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
99 0x001A : {"name" : "UNSIGNED56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []},
100 0x001B : {"name" : "UNSIGNED64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []},
101 0x1000 : {"name" : "Device Type", "struct" : var, "need" : True, "values" :
102 [{"name" : "Device Type", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
103 0x1001 : {"name" : "Error Register", "struct" : var, "need" : True, "values" :
104 [{"name" : "Error Register", "type" : 0x05, "access": 'ro', "pdo" : True}]},
105 0x1002 : {"name" : "Manufacturer Status Register", "struct" : var, "need" : False, "values" :
106 [{"name" : "Manufacturer Status Register", "type" : 0x07, "access" : 'ro', "pdo" : True}]},
107 0x1003 : {"name" : "Pre-defined Error Field", "struct" : rec, "need" : False, "values" :
108 [{"name" : "Number of Errors", "type" : 0x05, "access" : 'rw', "pdo" : False},
109 {"name" : "Standard Error Field", "type" : 0x07, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
110 0x1005 : {"name" : "SYNC COB ID", "struct" : var, "need" : False, "callback" : True, "values" :
111 [{"name" : "SYNC COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
112 0x1006 : {"name" : "Communication / Cycle Period", "struct" : var, "need" : False, "callback" : True, "values" :
113 [{"name" : "Communication Cycle Period", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
114 0x1007 : {"name" : "Synchronous Window Length", "struct" : var, "need" : False, "values" :
115 [{"name" : "Synchronous Window Length", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
116 0x1008 : {"name" : "Manufacturer Device Name", "struct" : var, "need" : False, "values" :
117 [{"name" : "Manufacturer Device Name", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
118 0x1009 : {"name" : "Manufacturer Hardware Version", "struct" : var, "need" : False, "values" :
119 [{"name" : "Manufacturer Hardware Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
120 0x100A : {"name" : "Manufacturer Software Version", "struct" : var, "need" : False, "values" :
121 [{"name" : "Manufacturer Software Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
122 0x100C : {"name" : "Guard Time", "struct" : var, "need" : False, "values" :
123 [{"name" : "Guard Time", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
124 0x100D : {"name" : "Life Time Factor", "struct" : var, "need" : False, "values" :
125 [{"name" : "Life Time Factor", "type" : 0x05, "access" : 'rw', "pdo" : False}]},
126 0x1010 : {"name" : "Store parameters", "struct" : array, "need" : False, "values" :
127 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
128 {"name" : "Save All Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
129 {"name" : "Save Communication Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
130 {"name" : "Save Application Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
131 {"name" : "Save Manufacturer Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
132 0x1011 : {"name" : "Restore Default Parameters", "struct" : array, "need" : False, "values" :
133 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
134 {"name" : "Restore All Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
135 {"name" : "Restore Communication Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
136 {"name" : "Restore Application Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
137 {"name" : "Restore Manufacturer Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
138 0x1012 : {"name" : "TIME COB ID", "struct" : var, "need" : False, "values" :
139 [{"name" : "TIME COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
140 0x1013 : {"name" : "High Resolution Timestamp", "struct" : var, "need" : False, "values" :
141 [{"name" : "High Resolution Time Stamp", "type" : 0x07, "access" : 'rw', "pdo" : True}]},
142 0x1014 : {"name" : "Emergency COB ID", "struct" : var, "need" : False, "values" :
143 [{"name" : "Emergency COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
144 0x1015 : {"name" : "Inhibit Time Emergency", "struct" : var, "need" : False, "values" :
145 [{"name" : "Inhibit Time Emergency", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
146 0x1016 : {"name" : "Consumer Heartbeat Time", "struct" : rec, "need" : False, "values" :
147 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
148 {"name" : "Consumer Heartbeat Time", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7F}]},
149 0x1017 : {"name" : "Producer Heartbeat Time", "struct" : var, "need" : False, "callback" : True, "values" :
150 [{"name" : "Producer Heartbeat Time", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
151 0x1018 : {"name" : "Identity", "struct" : array, "need" : True, "values" :
152 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
153 {"name" : "Vendor ID", "type" : 0x07, "access" : 'ro', "pdo" : False},
154 {"name" : "Product Code", "type" : 0x07, "access" : 'ro', "pdo" : False},
155 {"name" : "Revision Number", "type" : 0x07, "access" : 'ro', "pdo" : False},
156 {"name" : "Serial Number", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
157 0x1020 : {"name" : "Verify Configuration", "struct" : array, "need" : False, "values" :
158 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
159 {"name" : "Configuration Date", "type" : 0x07, "access" : 'ro', "pdo" : False},
160 {"name" : "Configuration Time", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
161 # 0x1021 : {"name" : "Store EDS", "struct" : var, "need" : False, "values" :
162 # [{"name" : "Store EDS", "type" : 0x0F, "access" : 'rw', "pdo" : False}]},
163 # 0x1022 : {"name" : "Storage Format", "struct" : var, "need" : False, "values" :
164 # [{"name" : "Storage Format", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
165 0x1023 : {"name" : "OS Command", "struct" : array, "need" : False, "values" :
166 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
167 {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
168 {"name" : "Status", "type" : 0x05, "access" : 'ro', "pdo" : False},
169 {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]},
170 0x1024 : {"name" : "OS Command Mode", "struct" : var, "need" : False, "values" :
171 [{"name" : "OS Command Mode", "type" : 0x05, "access" : 'wo', "pdo" : False}]},
172 0x1025 : {"name" : "OS Debugger Interface", "struct" : array, "need" : False, "values" :
173 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
174 {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
175 {"name" : "Status", "type" : 0x07, "access" : 'ro', "pdo" : False},
176 {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]},
177 0x1026 : {"name" : "OS Prompt", "struct" : array, "need" : False, "values" :
178 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
179 {"name" : "StdIn", "type" : 0x05, "access" : 'wo', "pdo" : True},
180 {"name" : "StdOut", "type" : 0x05, "access" : 'ro', "pdo" : True},
181 {"name" : "StdErr", "type" : 0x05, "access" : 'ro', "pdo" : True}]},
182 0x1027 : {"name" : "Module List", "struct" : rec, "need" : False, "values" :
183 [{"name" : "Number of Connected Modules", "type" : 0x05, "access" : 'ro', "pdo" : False},
184 {"name" : "Module %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
185 0x1028 : {"name" : "Emergency Consumer", "struct" : rec, "need" : False, "values" :
186 [{"name" : "Number of Consumed Emergency Objects", "type" : 0x05, "access" : 'ro', "pdo" : False},
187 {"name" : "Emergency Consumer", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7E}]},
188 0x1029 : {"name" : "Error Behavior", "struct" : array, "need" : False, "values" :
189 [{"name" : "Number of Error Classes", "type" : 0x05, "access" : 'ro', "pdo" : False},
190 {"name" : "Communication Error", "type" : 0x05, "access" : 'rw', "pdo" : False},
191 {"name" : "Device Profile", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]},
192 0x1200 : {"name" : "Server SDO Parameter", "struct" : array, "need" : False, "values" :
193 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
194 {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
195 {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
196 0x1201 : {"name" : "Additional Server SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x7F, "need" : False, "values" :
197 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
198 {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
199 {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
200 {"name" : "Node ID of the SDO Client", "type" : 0x05, "access" : 'ro', "pdo" : False}]},
201 0x1280 : {"name" : "Client SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x100, "need" : False, "values" :
202 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
203 {"name" : "COB ID Client to Server (Transmit SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
204 {"name" : "COB ID Server to Client (Receive SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
205 {"name" : "Node ID of the SDO Server", "type" : 0x05, "access" : 'rw', "pdo" : False}]},
206 0x1400 : {"name" : "Receive PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
207 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
208 {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:self.ID+(base+2)*0x100,False:0}[base<4]"},
209 {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
210 {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
211 {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
212 {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
213 0x1600 : {"name" : "Receive PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
214 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
215 {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
216 0x1800 : {"name" : "Transmit PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "callback" : True, "values" :
217 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
218 {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:self.ID+(base+1)*0x100+0x80,False:0}[base<4]"},
219 {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
220 {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
221 {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
222 {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
223 0x1A00 : {"name" : "Transmit PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
224 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
225 {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
228 #-------------------------------------------------------------------------------
229 # Search in a Mapping Dictionary
230 #-------------------------------------------------------------------------------
233 Return the index of the typename given by searching in mappingdictionary
235 def FindTypeIndex(typename, mappingdictionary):
237 for index, values in mappingdictionary.iteritems():
239 testdic[values["name"]] = index
240 if typename in testdic:
241 return testdic[typename]
245 Return the name of the type by searching in mappingdictionary
247 def FindTypeName(typeindex, mappingdictionary):
248 if typeindex < 0x1000 and typeindex in mappingdictionary:
249 return mappingdictionary[typeindex]["name"]
253 Return the default value of the type by searching in mappingdictionary
255 def FindTypeDefaultValue(typeindex, mappingdictionary):
256 if typeindex < 0x1000 and typeindex in mappingdictionary:
257 return mappingdictionary[typeindex]["default"]
261 Return the list of types defined in mappingdictionary
263 def FindTypeList(mappingdictionary):
265 for index in mappingdictionary.keys():
267 list.append(mappingdictionary[index]["name"])
271 Return the name of an entry by searching in mappingdictionary
273 def FindEntryName(index, mappingdictionary):
274 base_index = FindIndex(index, mappingdictionary)
276 infos = mappingdictionary[base_index]
277 if infos["struct"] & OD_IdenticalIndexes:
278 return StringFormat(infos["name"], (index - base_index) / infos["incr"] + 1, 0)
284 Return the informations of one entry by searching in mappingdictionary
286 def FindEntryInfos(index, mappingdictionary):
287 base_index = FindIndex(index, mappingdictionary)
289 copy = mappingdictionary[base_index].copy()
290 if copy["struct"] & OD_IdenticalIndexes:
291 copy["name"] = StringFormat(copy["name"], (index - base_index) / copy["incr"] + 1, 0)
297 Return the informations of one subentry of an entry by searching in mappingdictionary
299 def FindSubentryInfos(index, subIndex, mappingdictionary):
300 base_index = FindIndex(index, mappingdictionary)
302 struct = mappingdictionary[base_index]["struct"]
303 if struct & OD_Subindex:
304 if struct & OD_IdenticalSubindexes:
305 if struct & OD_IdenticalIndexes:
306 incr = mappingdictionary[base_index]["incr"]
310 return mappingdictionary[base_index]["values"][0].copy()
311 elif 0 < subIndex <= mappingdictionary[base_index]["values"][1]["nbmax"]:
312 copy = mappingdictionary[base_index]["values"][1].copy()
313 copy["name"] = StringFormat(copy["name"], (index - base_index) / incr + 1, subIndex)
315 elif struct & OD_MultipleSubindexes and 0 <= subIndex < len(mappingdictionary[base_index]["values"]):
316 return mappingdictionary[base_index]["values"][subIndex].copy()
318 return mappingdictionary[base_index]["values"][0].copy()
322 Return the list of variables that can be mapped defined in mappingdictionary
324 def FindMapVariableList(mappingdictionary, Node):
326 for index in mappingdictionary.iterkeys():
327 if Node.IsEntry(index):
328 for subIndex, values in enumerate(mappingdictionary[index]["values"]):
329 if mappingdictionary[index]["values"][subIndex]["pdo"]:
330 infos = Node.GetEntryInfos(mappingdictionary[index]["values"][subIndex]["type"])
331 if mappingdictionary[index]["struct"] & OD_IdenticalSubindexes:
332 values = Node.GetEntry(index)
333 for i in xrange(len(values) - 1):
334 list.append((index, i + 1, infos["size"], StringFormat(mappingdictionary[index]["values"][subIndex]["name"],1,i+1)))
336 list.append((index, subIndex, infos["size"], mappingdictionary[index]["values"][subIndex]["name"]))
340 Return the list of mandatory indexes defined in mappingdictionary
342 def FindMandatoryIndexes(mappingdictionary):
344 for index in mappingdictionary.iterkeys():
345 if index >= 0x1000 and mappingdictionary[index]["need"]:
350 Return the index of the informations in the Object Dictionary in case of identical
353 def FindIndex(index, mappingdictionary):
354 if index in mappingdictionary:
357 listpluri = [idx for idx in mappingdictionary.keys() if mappingdictionary[idx]["struct"] & OD_IdenticalIndexes]
359 for idx in listpluri:
360 nb_max = mappingdictionary[idx]["nbmax"]
361 incr = mappingdictionary[idx]["incr"]
362 if idx < index < idx + incr * nb_max and (index - idx)%incr == 0:
366 #-------------------------------------------------------------------------------
367 # Formating Name of an Entry
368 #-------------------------------------------------------------------------------
370 name_model = re.compile('(.*)\[(.*)\]')
373 Format the text given with the index and subindex defined
375 def StringFormat(text, idx, sub):
376 result = name_model.match(text)
378 format = result.groups()
379 return format[0]%eval(format[1])
383 #-------------------------------------------------------------------------------
384 # Definition of Node Object
385 #-------------------------------------------------------------------------------
388 Class recording the Object Dictionary entries. It checks at each modification
389 that the structure of the Object Dictionary stay coherent
394 def __init__(self, name = "", type = "slave", id = 0, description = "", profilename = "DS-301", profile = {}, specificmenu = []):
398 self.Description = description
399 self.ProfileName = profilename
400 self.Profile = profile
401 self.SpecificMenu = specificmenu
403 self.ParamsDictionary = {}
405 self.UserMapping = {}
410 def GetNodeName(self):
416 def SetNodeName(self, name):
420 Return the node type ("master" or "slave")
422 def GetNodeType(self):
426 Define the node type ("master" or "slave")
428 def SetNodeType(self, type):
440 def SetNodeID(self, id):
444 Return the node description
446 def GetNodeDescription(self):
447 if getattr(self, "Description", False):
448 return self.Description
453 Define the node description
455 def SetNodeDescription(self, description):
456 self.Description = description
459 Return the Specific Profile Name
461 def GetProfileName(self):
462 return self.ProfileName
465 Define the Specific Profile Name
467 def SetProfileName(self, profilename):
468 self.ProfileName = profilename
471 Return the Specific Profile
473 def GetProfile(self):
477 Define the Specific Profile
479 def SetProfile(self, profile):
480 self.Profile = profile
483 Define the DS-302 Profile
485 def SetDS302Profile(self, profile):
489 Define the DS-302 Profile
491 def GetDS302Profile(self):
495 Return the Specific Menu Entries
497 def GetSpecificMenu(self):
498 return self.SpecificMenu
501 Define the Specific Menu Entries
503 def SetSpecificMenu(self, specificmenu):
504 self.SpecificMenu = specificmenu
507 Extend the Specific Menu Entries
510 def ExtendSpecificMenu(self, specificmenu):
511 self.SpecificMenu.extend(specificmenu)
514 Function which return the different Mappings available for this node
516 def GetMappings(self, userdefinedtoo = True):
518 return [self.Profile, self.DS302, self.UserMapping]
520 return [self.Profile, self.DS302]
523 Add a new entry in the Object Dictionary
525 def AddEntry(self, index, subIndex = None, value = None):
526 if index not in self.Dictionary:
528 self.Dictionary[index] = value
531 self.Dictionary[index] = [value]
533 elif subIndex > 1 and type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]) + 1:
534 self.Dictionary[index].append(value)
539 Warning ! Modifies an existing entry in the Object Dictionary. Can't add a new one.
541 def SetEntry(self, index, subIndex = None, value = None):
542 if index in self.Dictionary:
545 self.Dictionary[index] = value
547 elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
549 self.Dictionary[index][subIndex - 1] = value
553 def SetParamsEntry(self, index, subIndex = None, comment = None, save = None, callback = None):
554 if not getattr(self, "ParamsDictionary", False):
555 self.ParamsDictionary = {}
556 if index in self.Dictionary:
557 if (comment != None or save != None or callback != None) and index not in self.ParamsDictionary:
558 self.ParamsDictionary[index] = {}
559 if subIndex == None or type(self.Dictionary[index]) != ListType and subIndex == 0:
561 self.ParamsDictionary[index]["comment"] = comment
563 self.ParamsDictionary[index]["save"] = save
565 self.ParamsDictionary[index]["callback"] = callback
567 elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
568 if (comment != None or save != None or callback != None) and subIndex not in self.ParamsDictionary[index]:
569 self.ParamsDictionary[index][subIndex] = {}
571 self.ParamsDictionary[index][subIndex]["comment"] = comment
573 self.ParamsDictionary[index][subIndex]["save"] = save
578 Removes an existing entry in the Object Dictionary. If a subIndex is specified
579 it will remove this subIndex only if it's the last of the index. If no subIndex
580 is specified it removes the whole index and subIndexes from the Object Dictionary.
582 def RemoveEntry(self, index, subIndex = None):
583 if not getattr(self, "ParamsDictionary", False):
584 self.ParamsDictionary = {}
585 if index in self.Dictionary:
587 self.Dictionary.pop(index)
588 if index in self.ParamsDictionary:
589 self.ParamsDictionary.pop(index)
591 elif type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]):
592 self.Dictionary[index].pop(subIndex - 1)
593 if index in self.ParamsDictionary:
594 if subIndex in self.ParamsDictionary[index]:
595 self.ParamsDictionary[index].pop(subIndex)
596 if len(self.ParamsDictionary[index]) == 0:
597 self.ParamsDictionary.pop(index)
598 if len(self.Dictionary[index]) == 0:
599 self.Dictionary.pop(index)
600 if index in self.ParamsDictionary:
601 self.ParamsDictionary.pop(index)
606 Check if an entry exists in the Object Dictionary and returns the answer.
608 def IsEntry(self, index, subIndex = None):
609 if index in self.Dictionary:
612 return subIndex <= len(self.Dictionary[index])
616 Returns the value of the entry asked. If the entry has the value "count", it
617 returns the number of subIndex in the entry except the first.
619 def GetEntry(self, index, subIndex = None):
620 if index in self.Dictionary:
622 if type(self.Dictionary[index]) == ListType:
623 values = [len(self.Dictionary[index])]
624 for value in self.Dictionary[index]:
625 values.append(self.CompileValue(value, index))
628 return self.CompileValue(self.Dictionary[index], index)
630 if type(self.Dictionary[index]) == ListType:
631 return len(self.Dictionary[index])
633 return self.CompileValue(self.Dictionary[index], index)
634 elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
635 return self.CompileValue(self.Dictionary[index][subIndex - 1], index)
639 Returns the value of the entry asked. If the entry has the value "count", it
640 returns the number of subIndex in the entry except the first.
642 def GetParamsEntry(self, index, subIndex = None):
643 if not getattr(self, "ParamsDictionary", False):
644 self.ParamsDictionary = {}
645 if index in self.Dictionary:
647 if type(self.Dictionary[index]) == ListType:
648 if index in self.ParamsDictionary:
650 for i in xrange(len(self.Dictionary[index]) + 1):
651 line = DefaultParams.copy()
652 if i in self.ParamsDictionary[index]:
653 line.update(self.ParamsDictionary[index][i])
657 return [DefaultParams.copy() for i in xrange(len(self.Dictionary[index]) + 1)]
659 result = DefaultParams.copy()
660 if index in self.ParamsDictionary:
661 result.update(self.ParamsDictionary[index])
663 elif subIndex == 0 and type(self.Dictionary[index]) != ListType:
664 result = DefaultParams.copy()
665 if index in self.ParamsDictionary:
666 result.update(self.ParamsDictionary[index])
668 elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
669 result = DefaultParams.copy()
670 if index in self.ParamsDictionary and subIndex in self.ParamsDictionary[index]:
671 result.update(self.ParamsDictionary[index][subIndex])
675 def HasEntryCallbacks(self, index):
676 entry_infos = self.GetEntryInfos(index)
677 if entry_infos and "callback" in entry_infos:
678 return entry_infos["callback"]
680 if not getattr(self, "ParamsDictionary", False):
681 self.ParamsDictionary = {}
682 if index in self.Dictionary and index in self.ParamsDictionary and "callback" in self.ParamsDictionary[index]:
683 return self.ParamsDictionary[index]["callback"]
687 Check if an entry exists in the User Mapping Dictionary and returns the answer.
689 def IsMappingEntry(self, index):
690 if index in self.UserMapping:
695 Add a new entry in the User Mapping Dictionary
697 def AddMappingEntry(self, index, subIndex = None, name = "Undefined", struct = 0, size = None, nbmax = None, default = None, values = None):
698 if index not in self.UserMapping:
702 self.UserMapping[index] = {"name" : name, "struct" : struct, "need" : False, "values" : values}
704 self.UserMapping[index]["size"] = size
706 self.UserMapping[index]["nbmax"] = nbmax
708 self.UserMapping[index]["default"] = default
710 elif subIndex != None and subIndex == len(self.UserMapping[index]["values"]):
713 self.UserMapping[index]["values"].append(values)
718 Warning ! Modifies an existing entry in the User Mapping Dictionary. Can't add a new one.
720 def SetMappingEntry(self, index, subIndex = None, name = None, struct = None, size = None, nbmax = None, default = None, values = None):
721 if index in self.UserMapping:
724 self.UserMapping[index]["name"] = name
725 if self.UserMapping[index]["struct"] & OD_IdenticalSubindexes:
726 self.UserMapping[index]["values"][1]["name"] = name + " %d[(sub)]"
727 elif not self.UserMapping[index]["struct"] & OD_MultipleSubindexes:
728 self.UserMapping[index]["values"][0]["name"] = name
730 self.UserMapping[index]["struct"] = struct
732 self.UserMapping[index]["size"] = size
734 self.UserMapping[index]["nbmax"] = nbmax
736 self.UserMapping[index]["default"] = default
738 self.UserMapping[index]["values"] = values
740 elif 0 <= subIndex < len(self.UserMapping[index]["values"]) and values != None:
741 self.UserMapping[index]["values"][subIndex].update(values)
746 Removes an existing entry in the User Mapping Dictionary. If a subIndex is specified
747 it will remove this subIndex only if it's the last of the index. If no subIndex
748 is specified it removes the whole index and subIndexes from the User Mapping Dictionary.
750 def RemoveMappingEntry(self, index, subIndex = None):
751 if index in self.UserMapping:
753 self.UserMapping.pop(index)
755 elif subIndex == len(self.UserMapping[index]["values"]) - 1:
756 self.UserMapping[index]["values"].pop(subIndex)
760 def RemoveMapVariable(self, index, subIndex = None):
764 model += subIndex << 8
766 for i in self.Dictionary.iterkeys():
767 if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
768 for j,value in enumerate(self.Dictionary[i]):
769 if (value & mask) == model:
770 self.Dictionary[i][j] = 0
772 def UpdateMapVariable(self, index, subIndex, size):
776 model += subIndex << 8
778 for i in self.Dictionary.iterkeys():
779 if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
780 for j,value in enumerate(self.Dictionary[i]):
781 if (value & mask) == model:
782 self.Dictionary[i][j] = model + size
784 def RemoveLine(self, index, max, incr = 1):
786 while i < max and self.IsEntry(i + incr):
787 self.Dictionary[i] = self.Dictionary[i + incr]
789 self.Dictionary.pop(i)
791 def RemoveUserType(self, index):
792 type = self.GetEntry(index, 1)
793 for i in self.UserMapping:
794 for value in self.UserMapping[i]["values"]:
795 if value["type"] == index:
797 self.RemoveMappingEntry(index)
798 self.RemoveEntry(index)
801 Return a copy of the node
804 return cPickle.loads(cPickle.dumps(self))
807 Return a sorted list of indexes in Object Dictionary
809 def GetIndexes(self):
810 listindex = self.Dictionary.keys()
815 Print the Dictionary values
818 print self.PrintString()
820 def PrintString(self):
822 listindex = self.Dictionary.keys()
824 for index in listindex:
825 name = self.GetEntryName(index)
826 values = self.Dictionary[index]
827 if isinstance(values, ListType):
828 result += "%04X (%s):\n"%(index, name)
829 for subidx, value in enumerate(values):
830 subentry_infos = self.GetSubentryInfos(index, subidx + 1)
831 if index == 0x1F22 and value:
832 nb_params = BE_to_LE(value[:4])
834 value = "%d arg defined"%nb_params
838 value += "\n%04X %02X, arg %d: "%(index, subidx+1, count)
839 value += "%04X"%BE_to_LE(data[i:i+2])
840 value += " %02X"%BE_to_LE(data[i+2:i+3])
841 size = BE_to_LE(data[i+3:i+7])
842 value += " %08X"%size
843 value += (" %0"+"%d"%(size * 2)+"X")%BE_to_LE(data[i+7:i+7+size])
846 elif isinstance(value, IntType):
848 result += "%04X %02X (%s): %s\n"%(index, subidx+1, subentry_infos["name"], value)
850 if isinstance(values, IntType):
852 result += "%04X (%s): %s\n"%(index, name, values)
855 def CompileValue(self, value, index):
856 if type(value) == StringType and value.find("self.ID") != -1:
857 base = self.GetBaseIndex(index)
865 #-------------------------------------------------------------------------------
866 # Node Informations Functions
867 #-------------------------------------------------------------------------------
869 def GetBaseIndex(self, index):
870 for mapping in self.GetMappings():
871 result = FindIndex(index, mapping)
873 return (index - result) / mapping[result].get("incr", 1)
874 result = FindIndex(index, MappingDictionary)
876 return (index - result) / MappingDictionary[result].get("incr", 1)
879 def GetCustomisedTypeValues(self, index):
880 values = self.GetEntry(index)
881 customisabletypes = self.GetCustomisableTypes()
882 return values, customisabletypes[values[1]][1]
884 def GetEntryName(self, index):
886 mappings = self.GetMappings()
888 while not result and i < len(mappings):
889 result = FindEntryName(index, mappings[i])
892 result = FindEntryName(index, MappingDictionary)
895 def GetEntryInfos(self, index):
897 mappings = self.GetMappings()
899 while not result and i < len(mappings):
900 result = FindEntryInfos(index, mappings[i])
903 result = FindEntryInfos(index, MappingDictionary)
906 def GetSubentryInfos(self, index, subIndex):
908 mappings = self.GetMappings()
910 while not result and i < len(mappings):
911 result = FindSubentryInfos(index, subIndex, mappings[i])
913 result["user_defined"] = i == len(mappings) - 1 and index >= 0x1000
916 result = FindSubentryInfos(index, subIndex, MappingDictionary)
918 result["user_defined"] = False
921 def GetTypeIndex(self, typename):
923 mappings = self.GetMappings()
925 while not result and i < len(mappings):
926 result = FindTypeIndex(typename, mappings[i])
929 result = FindTypeIndex(typename, MappingDictionary)
932 def GetTypeName(self, typeindex):
934 mappings = self.GetMappings()
936 while not result and i < len(mappings):
937 result = FindTypeName(typeindex, mappings[i])
940 result = FindTypeName(typeindex, MappingDictionary)
943 def GetTypeDefaultValue(self, typeindex):
945 mappings = self.GetMappings()
947 while not result and i < len(mappings):
948 result = FindTypeDefaultValue(typeindex, mappings[i])
951 result = FindTypeDefaultValue(typeindex, MappingDictionary)
954 def GetMapVariableList(self):
955 list = FindMapVariableList(MappingDictionary, self)
956 for mapping in self.GetMappings():
957 list.extend(FindMapVariableList(mapping, self))
961 def GetMandatoryIndexes(self, node = None):
962 list = FindMandatoryIndexes(MappingDictionary)
963 for mapping in self.GetMappings():
964 list.extend(FindMandatoryIndexes(mapping))
967 def GetCustomisableTypes(self):
969 for index, valuetype in CustomisableTypes:
970 name = self.GetTypeName(index)
971 dic[index] = [name, valuetype]
974 #-------------------------------------------------------------------------------
975 # Type and Map Variable Lists
976 #-------------------------------------------------------------------------------
978 def GetTypeList(self):
979 list = FindTypeList(MappingDictionary)
980 for mapping in self.GetMappings():
981 list.extend(FindTypeList(mapping))
983 return ",".join(list)
986 Generate the list of variables that can be mapped for the current node
988 def GenerateMapList(self):
989 self.MapList = "None"
990 self.NameTranslation = {"None" : "00000000"}
991 self.MapTranslation = {"00000000" : "None"}
992 list = self.GetMapVariableList()
993 for index, subIndex, size, name in list:
994 self.MapList += ",%s"%name
995 map = "%04X%02X%02X"%(index,subIndex,size)
996 self.NameTranslation[name] = map
997 self.MapTranslation[map] = name
999 def GetMapValue(self, mapname):
1000 if mapname == "None":
1003 list = self.GetMapVariableList()
1004 for index, subIndex, size, name in list:
1006 return (index << 16) + (subIndex << 8) + size
1009 def GetMapName(self, value):
1012 subindex = (value >> 8) % (1 << 8)
1013 result = self.GetSubentryInfos(index, subindex)
1015 return result["name"]
1019 Return the list of variables that can be mapped for the current node
1021 def GetMapList(self):
1022 list = ["None"] + [name for index, subIndex, size, name in self.GetMapVariableList()]
1023 return ",".join(list)
1025 def BE_to_LE(value):
1027 Convert Big Endian to Little Endian
1028 @param value: value expressed in Big Endian
1029 @param size: number of bytes generated
1030 @return: a string containing the value converted
1033 data = [char for char in value]
1035 return int("".join(["%2.2X"%ord(char) for char in data]), 16)