]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/node.py
PDO mapping parameters : number of mapped app must be in RW access
[CanFestival-3.git] / objdictgen / node.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 #This file is part of CanFestival, a library implementing CanOpen Stack. 
5 #
6 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
7 #
8 #See COPYING file for copyrights details.
9 #
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.
14 #
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.
19 #
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
23
24 import cPickle
25 from types import *
26
27 """
28 Dictionary of translation between access symbol and their signification
29 """
30 AccessType = {"ro" : "Read Only", "wo" : "Write Only", "rw" : "Read/Write"}
31
32 BoolType = {True : "True", False : "False"} 
33 OptionType = {True : "Yes", False : "No"}
34
35 CustomisableTypes = [(0x02, 0), (0x03, 0), (0x04, 0), (0x05, 0), (0x06, 0), (0x07, 0),
36     (0x08, 0), (0x09, 1), (0x0A, 1), (0x0B, 1), (0x10, 0), (0x11, 0), (0x12, 0),
37     (0x13, 0), (0x14, 0), (0x15, 0), (0x16, 0), (0x18, 0), (0x19, 0), (0x1A, 0),
38     (0x1B, 0)]
39
40 DefaultParams = {"comment" : "", "save" : False}
41
42 #-------------------------------------------------------------------------------
43 #                      Dictionary Mapping and Organisation
44 #-------------------------------------------------------------------------------
45
46 """
47 Properties of entry structure in the Object Dictionary
48 """
49 OD_Subindex = 1             # Entry has at least one subindex
50 OD_MultipleSubindexes = 2   # Entry has more than one subindex
51 OD_IdenticalSubindexes = 4  # Subindexes of entry have the same description
52 OD_IdenticalIndexes = 8     # Entry has the same description on multiple indexes
53
54 """
55 Structures of entry in the Object Dictionary, sum of the properties described above
56 for all sorts of entries use in CAN Open specification
57 """
58 nosub = 0 # Entry without subindex (only for type declaration)
59 var = 1
60 array = 3
61 rec = 7
62 # Entries identical on multiple indexes
63 plurivar = 9
64 pluriarray = 11 # Example : PDO Parameters
65 plurirec = 15   # Example : PDO Mapping
66
67 """
68 MappingDictionary is the structure used for writing a good organised Object
69 Dictionary. It follows the specifications of the CANOpen standard.
70 Change the informations within it if there is a mistake. But don't modify the
71 organisation of this object, it will involve in a malfunction of the application.
72 """
73
74 MappingDictionary = {
75     0x0001 : {"name" : "BOOLEAN", "struct" : nosub, "size" : 1, "default" : False, "values" : []},
76     0x0002 : {"name" : "INTEGER8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []},
77     0x0003 : {"name" : "INTEGER16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []},
78     0x0004 : {"name" : "INTEGER32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []},
79     0x0005 : {"name" : "UNSIGNED8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []},
80     0x0006 : {"name" : "UNSIGNED16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []},
81     0x0007 : {"name" : "UNSIGNED32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []},
82     0x0008 : {"name" : "REAL32", "struct" : nosub, "size" : 32, "default" : 0.0, "values" : []},
83     0x0009 : {"name" : "VISIBLE_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []},
84     0x000A : {"name" : "OCTET_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []},
85     0x000B : {"name" : "UNICODE_STRING", "struct" : nosub, "size" : 16, "default" : "", "values" : []},
86     0x000C : {"name" : "TIME_OF_DAY", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
87     0x000D : {"name" : "TIME_DIFFERENCE", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
88 #    0x000F : {"name" : "DOMAIN", "struct" : nosub, "size" : 0, "default" : "", "values" : []},
89     0x0010 : {"name" : "INTEGER24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []},
90     0x0011 : {"name" : "REAL64", "struct" : nosub, "size" : 64, "default" : 0.0, "values" : []},
91     0x0012 : {"name" : "INTEGER40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []},
92     0x0013 : {"name" : "INTEGER48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
93     0x0014 : {"name" : "INTEGER56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []},
94     0x0015 : {"name" : "INTEGER64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []},
95     0x0016 : {"name" : "UNSIGNED24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []},
96     0x0018 : {"name" : "UNSIGNED40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []},
97     0x0019 : {"name" : "UNSIGNED48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
98     0x001A : {"name" : "UNSIGNED56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []},
99     0x001B : {"name" : "UNSIGNED64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []},
100     0x1000 : {"name" : "Device Type", "struct" : var, "need" : True, "values" : 
101                 [{"name" : "Device Type", "type" : 0x04, "access" : 'ro', "pdo" : False}]},
102     0x1001 : {"name" : "Error Register", "struct" : var,  "need" : True, "values" : 
103                 [{"name" : "Error Register", "type" : 0x02, "access": 'ro', "pdo" : True}]},
104     0x1002 : {"name" : "Manufacturer Status Register", "struct" : var, "need" : False,  "values" :
105                 [{"name" : "Manufacturer Status Register", "type" : 0x04, "access" : 'ro', "pdo" : True}]},
106     0x1003 : {"name" : "Pre-defined Error Field", "struct" : rec, "need" : False,  "values" :
107                 [{"name" : "Number of Errors", "type" : 0x04, "access" : 'rw', "pdo" : False},
108                  {"name" : "Standard Error Field", "type" : 0x04, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
109     0x1005 : {"name" : "SYNC COB ID", "struct" : var, "need" : True, "callback" : True, "values" :
110                 [{"name" : "SYNC COB ID", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
111     0x1006 : {"name" : "Communication / Cycle Period", "struct" : var, "need" : False, "callback" : True, "values" :
112                 [{"name" : "Communication Cycle Period", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
113     0x1007 : {"name" : "Synchronous Window Length", "struct" : var, "need" : False, "values" :
114                 [{"name" : "Synchronous Window Length", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
115     0x1008 : {"name" : "Manufacturer Device Name", "struct" : var, "need" : False, "values" :
116                 [{"name" : "Manufacturer Device Name", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
117     0x1009 : {"name" : "Manufacturer Hardware Version", "struct" : var, "need" : False, "values" :
118                 [{"name" : "Manufacturer Hardware Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
119     0x100A : {"name" : "Manufacturer Software Version", "struct" : var, "need" : False, "values" :
120                 [{"name" : "Manufacturer Software Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
121     0x100C : {"name" : "Guard Time", "struct" : var, "need" : False, "values" :
122                 [{"name" : "Guard Time", "type" : 0x03, "access" : 'rw', "pdo" : False}]},
123     0x100D : {"name" : "Life Time Factor", "struct" : var, "need" : False, "values" :
124                 [{"name" : "Life Time Factor", "type" : 0x02, "access" : 'rw', "pdo" : False}]},
125     0x1010 : {"name" : "Store parameters", "struct" : array, "need" : False, "values" :
126                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
127                  {"name" : "Save All Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False},
128                  {"name" : "Save Communication Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False},
129                  {"name" : "Save Application Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False},
130                  {"name" : "Save Manufacturer Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
131     0x1011 : {"name" : "Restore Default Parameters", "struct" : array, "need" : False, "values" :
132                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
133                  {"name" : "Restore All Default Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False},
134                  {"name" : "Restore Communication Default Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False},
135                  {"name" : "Restore Application Default Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False},
136                  {"name" : "Restore Manufacturer Default Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
137     0x1012 : {"name" : "TIME COB ID", "struct" : var, "need" : False, "values" :
138                 [{"name" : "TIME COB ID", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
139     0x1013 : {"name" : "High Resolution Timestamp", "struct" : var, "need" : False, "values" :
140                 [{"name" : "High Resolution Time Stamp", "type" : 0x04, "access" : 'rw', "pdo" : True}]},
141     0x1014 : {"name" : "Emergency COB ID", "struct" : var, "need" : False, "values" :
142                 [{"name" : "Emergency COB ID", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
143     0x1015 : {"name" : "Inhibit Time Emergency", "struct" : var, "need" : False, "values" :
144                 [{"name" : "Inhibit Time Emergency", "type" : 0x03, "access" : 'rw', "pdo" : False}]},
145     0x1016 : {"name" : "Consumer Heartbeat Time", "struct" : rec, "need" : False, "values" :
146                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
147                  {"name" : "Consumer Heartbeat Time", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x7F}]},
148     0x1017 : {"name" : "Producer Heartbeat Time", "struct" : var, "need" : False, "values" :
149                 [{"name" : "Producer Heartbeat Time", "type" : 0x03, "access" : 'rw', "pdo" : False}]},
150     0x1018 : {"name" : "Identity", "struct" : array, "need" : True, "values" :
151                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
152                  {"name" : "Vendor ID", "type" : 0x04, "access" : 'ro', "pdo" : False},
153                  {"name" : "Product Code", "type" : 0x04, "access" : 'ro', "pdo" : False},
154                  {"name" : "Revision Number", "type" : 0x04, "access" : 'ro', "pdo" : False},
155                  {"name" : "Serial Number", "type" : 0x04, "access" : 'ro', "pdo" : False}]},
156     0x1020 : {"name" : "Verify Configuration", "struct" : array, "need" : False, "values" :
157                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
158                  {"name" : "Configuration Date", "type" : 0x04, "access" : 'ro', "pdo" : False},
159                  {"name" : "Configuration Time", "type" : 0x04, "access" : 'ro', "pdo" : False}]},
160 #    0x1021 : {"name" : "Store EDS", "struct" : var, "need" : False, "values" :
161 #                [{"name" : "Store EDS", "type" : 0x0F, "access" : 'rw', "pdo" : False}]},
162 #    0x1022 : {"name" : "Storage Format", "struct" : var, "need" : False, "values" :
163 #                [{"name" : "Storage Format", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
164     0x1023 : {"name" : "OS Command", "struct" : array, "need" : False, "values" :
165                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
166                  {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
167                  {"name" : "Status", "type" : 0x02, "access" : 'ro', "pdo" : False},
168                  {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]},
169     0x1024 : {"name" : "OS Command Mode", "struct" : var, "need" : False, "values" :
170                 [{"name" : "OS Command Mode", "type" : 0x02, "access" : 'wo', "pdo" : False}]},
171     0x1025 : {"name" : "OS Debugger Interface", "struct" : array, "need" : False, "values" :
172                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
173                  {"name" : "Command", "type" : 0x04, "access" : 'rw', "pdo" : False},
174                  {"name" : "Status", "type" : 0x04, "access" : 'ro', "pdo" : False},
175                  {"name" : "Reply", "type" : 0x04, "access" : 'ro', "pdo" : False}]},
176     0x1026 : {"name" : "OS Prompt", "struct" : array, "need" : False, "values" :
177                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
178                  {"name" : "StdIn", "type" : 0x02, "access" : 'wo', "pdo" : True},
179                  {"name" : "StdOut", "type" : 0x02, "access" : 'ro', "pdo" : True},
180                  {"name" : "StdErr", "type" : 0x02, "access" : 'ro', "pdo" : True}]},
181     0x1027 : {"name" : "Module List", "struct" : rec, "need" : False, "values" :
182                 [{"name" : "Number of Connected Modules", "type" : 0x02, "access" : 'ro', "pdo" : False},
183                  {"name" : "Module %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
184     0x1028 : {"name" : "Emergency Consumer", "struct" : rec, "need" : False, "values" :
185                 [{"name" : "Number of Consumed Emergency Objects", "type" : 0x02, "access" : 'ro', "pdo" : False},
186                  {"name" : "Emergency Consumer", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x7E}]},
187     0x1029 : {"name" : "Error Behavior", "struct" : array, "need" : False, "values" :
188                 [{"name" : "Number of Error Classes", "type" : 0x02, "access" : 'ro', "pdo" : False},
189                  {"name" : "Communication Error", "type" : 0x02, "access" : 'rw', "pdo" : False},
190                  {"name" : "Device Profile", "type" : 0x02, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]},
191     0x1200 : {"name" : "Server SDO Parameter", "struct" : array, "need" : False, "values" :
192                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
193                  {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x04, "access" : 'ro', "pdo" : False},
194                  {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x04, "access" : 'ro', "pdo" : False}]},
195     0x1201 : {"name" : "Additional Server SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x7F, "need" : False, "values" :
196                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
197                  {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x04, "access" : 'ro', "pdo" : False},
198                  {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x04, "access" : 'ro', "pdo" : False},
199                  {"name" : "Node ID of the SDO Client", "type" : 0x04, "access" : 'ro', "pdo" : False}]},
200     0x1280 : {"name" : "Client SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x100, "need" : False, "values" :
201                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False},
202                  {"name" : "COB ID Client to Server (Transmit SDO)", "type" : 0x04, "access" : 'rw', "pdo" : False},
203                  {"name" : "COB ID Server to Client (Receive SDO)", "type" : 0x04, "access" : 'rw', "pdo" : False},
204                  {"name" : "Node ID of the SDO Server", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
205     0x1400 : {"name" : "Receive PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
206                 [{"name" : "Highest SubIndex Supported", "type" : 0x02, "access" : 'ro', "pdo" : False},
207                  {"name" : "COB ID used by PDO", "type" : 0x04, "access" : 'rw', "pdo" : False},
208                  {"name" : "Transmission Type", "type" : 0x02, "access" : 'rw', "pdo" : False},
209                  {"name" : "Inhibit Time", "type" : 0x03, "access" : 'rw', "pdo" : False},
210                  {"name" : "Compatibility Entry", "type" : 0x03, "access" : 'rw', "pdo" : False},
211                  {"name" : "Event Timer", "type" : 0x03, "access" : 'rw', "pdo" : False}]},
212     0x1600 : {"name" : "Receive PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
213                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'rw', "pdo" : False},
214                  {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
215     0x1800 : {"name" : "Transmit PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
216                 [{"name" : "Highest SubIndex Supported", "type" : 0x02, "access" : 'ro', "pdo" : False},
217                  {"name" : "COB ID used by PDO", "type" : 0x04, "access" : 'rw', "pdo" : False},
218                  {"name" : "Transmission Type", "type" : 0x02, "access" : 'rw', "pdo" : False},
219                  {"name" : "Inhibit Time", "type" : 0x03, "access" : 'rw', "pdo" : False},
220                  {"name" : "Compatibility Entry", "type" : 0x03, "access" : 'rw', "pdo" : False},
221                  {"name" : "Event Timer", "type" : 0x03, "access" : 'rw', "pdo" : False}]},
222     0x1A00 : {"name" : "Transmit PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
223                 [{"name" : "Number of Entries", "type" : 0x02, "access" : 'rw', "pdo" : False},
224                  {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
225 }
226
227 #-------------------------------------------------------------------------------
228 #                          Definition of Node Object
229 #-------------------------------------------------------------------------------
230
231 """
232 Class recording the Object Dictionary entries. It checks at each modification
233 that the structure of the Object Dictionary stay coherent
234 """
235
236 class Node:
237     
238     def __init__(self, name = "", type = "slave", id = 0, profilename = "DS-301", profile = {}, specificmenu = []):
239         self.Name = name
240         self.Type = type
241         self.ID = id
242         self.ProfileName = profilename
243         self.Profile = profile
244         self.SpecificMenu = specificmenu
245         self.Dictionary = {}
246         self.ParamsDictionary = {}
247         self.DS302 = {}
248         self.UserMapping = {}
249     
250     """
251     Return the node name
252     """
253     def GetNodeName(self):
254         return self.Name
255     
256     """
257     Define the node name
258     """
259     def SetNodeName(self, name):
260         self.Name = name
261
262     """
263     Return the node type ("master" or "slave")
264     """
265     def GetNodeType(self):
266         return self.Type
267     
268     """
269     Define the node type ("master" or "slave")
270     """
271     def SetNodeType(self, type):
272         self.Type = type
273
274     """
275     Return the node ID
276     """
277     def GetNodeID(self):
278         return self.ID
279     
280     """
281     Define the node ID
282     """
283     def SetNodeID(self, id):
284         self.ID = id
285
286     """
287     Return the Specific Profile Name
288     """
289     def GetProfileName(self):
290         return self.ProfileName
291     
292     """
293     Define the Specific Profile Name
294     """
295     def SetProfileName(self, profilename):
296         self.ProfileName = profilename
297
298     """
299     Return the Specific Profile
300     """
301     def GetProfile(self):
302         return self.Profile
303     
304     """
305     Define the Specific Profile
306     """
307     def SetProfile(self, profile):
308         self.Profile = profile
309     
310     """
311     Define the DS-302 Profile
312     """
313     def SetDS302Profile(self, profile):
314         self.DS302 = profile
315     
316     """
317     Define the DS-302 Profile
318     """
319     def GetDS302Profile(self):
320         return self.DS302
321     
322     """
323     Return the Specific Menu Entries
324     """
325     def GetSpecificMenu(self):
326         return self.SpecificMenu
327     
328     """
329     Define the Specific Menu Entries
330     """
331     def SetSpecificMenu(self, specificmenu):
332         self.SpecificMenu = specificmenu
333     
334     """
335     Extend the Specific Menu Entries
336     """
337     
338     def ExtendSpecificMenu(self, specificmenu):
339         self.SpecificMenu.extend(AddMenuEntries)
340     
341     """
342     Function which return the different Mappings available for this node
343     """
344     def GetMappings(self, userdefinedtoo = True):
345         if userdefinedtoo:
346             return [self.Profile, self.DS302, self.UserMapping]
347         else:
348             return [self.Profile, self.DS302]
349     
350     """
351     Add a new entry in the Object Dictionary
352     """
353     def AddEntry(self, index, subIndex = None, value = None):
354         if index not in self.Dictionary:
355             if not subIndex:
356                 self.Dictionary[index] = value
357                 return True
358             elif subIndex == 1:
359                 self.Dictionary[index] = [value]
360                 return True
361         elif subIndex > 1 and type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]) + 1:
362             self.Dictionary[index].append(value)
363             return True
364         return False
365
366     """
367     Warning ! Modifies an existing entry in the Object Dictionary. Can't add a new one.
368     """
369     def SetEntry(self, index, subIndex = None, value = None):
370         if index in self.Dictionary:
371             if not subIndex:
372                 if value != None:
373                     self.Dictionary[index] = value
374                 return True
375             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
376                 if value != None:
377                     self.Dictionary[index][subIndex - 1] = value
378                 return True
379         return False
380     
381     def SetParamsEntry(self, index, subIndex = None, comment = None, save = None, callback = None):
382         if not getattr(self, "ParamsDictionary", False):
383             self.ParamsDictionary = {}
384         if index in self.Dictionary:
385             if (comment != None or save != None or callback != None) and index not in self.ParamsDictionary:
386                 self.ParamsDictionary[index] = {}
387             if subIndex == None or type(self.Dictionary[index]) != ListType and subIndex == 0:
388                 if comment != None:
389                     self.ParamsDictionary[index]["comment"] = comment
390                 if save != None:
391                     self.ParamsDictionary[index]["save"] = save
392                 if callback != None:
393                     self.ParamsDictionary[index]["callback"] = callback
394                 return True
395             elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
396                 if (comment != None or save != None or callback != None) and subIndex not in self.ParamsDictionary[index]:
397                     self.ParamsDictionary[index][subIndex] = {}
398                 if comment != None:
399                     self.ParamsDictionary[index][subIndex]["comment"] = comment
400                 if save != None:
401                     self.ParamsDictionary[index][subIndex]["save"] = save
402                 return True
403         return False
404     
405     """
406     Removes an existing entry in the Object Dictionary. If a subIndex is specified
407     it will remove this subIndex only if it's the last of the index. If no subIndex
408     is specified it removes the whole index and subIndexes from the Object Dictionary.
409     """
410     def RemoveEntry(self, index, subIndex = None):
411         if not getattr(self, "ParamsDictionary", False):
412             self.ParamsDictionary = {}
413         if index in self.Dictionary:
414             if not subIndex:
415                 self.Dictionary.pop(index)
416                 if index in self.ParamsDictionary:
417                     self.ParamsDictionary.pop(index)
418                 return True
419             elif type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]):
420                 self.Dictionary[index].pop(subIndex - 1)
421                 if index in self.ParamsDictionary:
422                     if subIndex in self.ParamsDictionary[index]:
423                         self.ParamsDictionary[index].pop(subIndex)
424                     if len(self.ParamsDictionary[index]) == 0:
425                         self.ParamsDictionary.pop(index)
426                 if len(self.Dictionary[index]) == 0:
427                     self.Dictionary.pop(index)
428                     if index in self.ParamsDictionary:
429                         self.ParamsDictionary.pop(index)
430                 return True
431         return False
432     
433     """
434     Check if an entry exists in the Object Dictionary and returns the answer.
435     """
436     def IsEntry(self, index):
437         if index in self.Dictionary:
438             return True
439         return False
440     
441     """
442     Returns the value of the entry asked. If the entry has the value "count", it
443     returns the number of subIndex in the entry except the first.
444     """
445     def GetEntry(self, index, subIndex = None):
446         if index in self.Dictionary:
447             if subIndex == None:
448                 if type(self.Dictionary[index]) == ListType:
449                     values = [len(self.Dictionary[index])]
450                     values.extend(self.Dictionary[index])
451                     return values
452                 else:
453                     return self.Dictionary[index]
454             elif subIndex == 0:
455                 if type(self.Dictionary[index]) == ListType:
456                     return len(self.Dictionary[index])
457                 else:
458                     return self.Dictionary[index]
459             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
460                 return self.Dictionary[index][subIndex - 1]
461         return None
462
463     """
464     Returns the value of the entry asked. If the entry has the value "count", it
465     returns the number of subIndex in the entry except the first.
466     """
467     def GetParamsEntry(self, index, subIndex = None):
468         if not getattr(self, "ParamsDictionary", False):
469             self.ParamsDictionary = {}
470         if index in self.Dictionary:
471             if subIndex == None:
472                 if type(self.Dictionary[index]) == ListType:
473                     if index in self.ParamsDictionary:
474                         result = []
475                         for i in xrange(len(self.Dictionary[index]) + 1):
476                             line = DefaultParams.copy()
477                             if i in self.ParamsDictionary[index]:
478                                 line.update(self.ParamsDictionary[index][i])
479                             result.append(line)
480                         return result
481                     else:
482                         return [DefaultParams.copy() for i in xrange(len(self.Dictionary[index]) + 1)]
483                 else:
484                     result = DefaultParams.copy()
485                     if index in self.ParamsDictionary:
486                         result.update(self.ParamsDictionary[index])
487                     return result
488             elif subIndex == 0 and type(self.Dictionary[index]) != ListType:
489                 result = DefaultParams.copy()
490                 if index in self.ParamsDictionary:
491                     result.update(self.ParamsDictionary[index])
492                 return result
493             elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
494                 result = DefaultParams.copy()
495                 if index in self.ParamsDictionary and subIndex in self.ParamsDictionary[index]:
496                     result.update(self.ParamsDictionary[index][subIndex])
497                 return result
498         return None
499
500     def HasEntryCallbacks(self, index):
501         if not getattr(self, "ParamsDictionary", False):
502             self.ParamsDictionary = {}
503         if index in self.Dictionary and index in self.ParamsDictionary and "callback" in self.ParamsDictionary[index]:
504             return self.ParamsDictionary[index]["callback"]
505         return False
506
507     """
508     Add a new entry in the User Mapping Dictionary
509     """
510     def AddMappingEntry(self, index, subIndex = None, name = "Undefined", struct = 0, size = None, nbmax = None, default = None, values = None):
511         if index not in self.UserMapping:
512             if values == None:
513                 values = []
514             if subIndex == None:
515                 self.UserMapping[index] = {"name" : name, "struct" : struct, "need" : False, "values" : values}
516                 if size != None:
517                     self.UserMapping[index]["size"] = size
518                 if nbmax != None:
519                     self.UserMapping[index]["nbmax"] = nbmax
520                 if default != None:
521                     self.UserMapping[index]["default"] = default
522                 return True
523         elif subIndex != None and subIndex == len(self.UserMapping[index]["values"]):
524             if values == None:
525                 values = {}
526             self.UserMapping[index]["values"].append(values)
527             return True
528         return False
529
530     """
531     Warning ! Modifies an existing entry in the User Mapping Dictionary. Can't add a new one.
532     """
533     def SetMappingEntry(self, index, subIndex = None, name = None, struct = None, size = None, nbmax = None, default = None, values = None):
534         if index in self.UserMapping:
535             if subIndex == None:
536                 if name != None:
537                     self.UserMapping[index]["name"] = name
538                     if self.UserMapping[index]["struct"] & OD_IdenticalSubindexes:
539                         self.UserMapping[index]["values"][1]["name"] = name + " %d[(sub)]"
540                     elif not self.UserMapping[index]["struct"] & OD_MultipleSubindexes:
541                         self.UserMapping[index]["values"][0]["name"] = name
542                 if struct != None:
543                     self.UserMapping[index]["struct"] = struct
544                 if size != None:
545                     self.UserMapping[index]["size"] = size
546                 if nbmax != None:
547                     self.UserMapping[index]["nbmax"] = nbmax
548                 if default != None:
549                     self.UserMapping[index]["default"] = default
550                 if values != None:
551                     self.UserMapping[index]["values"] = values
552                 return True
553             elif 0 <= subIndex < len(self.UserMapping[index]["values"]) and values != None:
554                 self.UserMapping[index]["values"][subIndex].update(values)
555                 return True
556         return False
557     
558     """
559     Removes an existing entry in the User Mapping Dictionary. If a subIndex is specified
560     it will remove this subIndex only if it's the last of the index. If no subIndex
561     is specified it removes the whole index and subIndexes from the User Mapping Dictionary.
562     """
563     def RemoveMappingEntry(self, index, subIndex = None):
564         if index in self.UserMapping:
565             if subIndex == None:
566                 self.UserMapping.pop(index)
567                 return True
568             elif subIndex == len(self.UserMapping[index]["values"]) - 1:
569                 self.UserMapping[index]["values"].pop(subIndex)
570                 return True
571         return False
572
573     def RemoveMapVariable(self, index, subIndex):
574         model = index << 16
575         mask = 0xFFFF << 16
576         if subIndex:
577             model += subIndex << 8
578             mask = 0xFF << 8
579         for i in self.Dictionary.iterkeys():
580             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
581                 for j,value in enumerate(self.Dictionary[i]):
582                     if (value & mask) == model:
583                         self.Dictionary[i][j] = 0
584     
585     def UpdateMapVariable(self, index, subIndex, size):
586         model = index << 16
587         mask = 0xFFFF << 16
588         if subIndex:
589             model += subIndex << 8
590             mask = 0xFF << 8
591         for i in self.Dictionary.iterkeys():
592             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
593                 for j,value in enumerate(self.Dictionary[i]):
594                     if (value & mask) == model:
595                         self.Dictionary[i][j] = model + size
596     
597     def RemoveLine(self, index, max, incr = 1):
598         i = index
599         while i < max and self.IsEntry(i + incr):
600             self.Dictionary[i] = self.Dictionary[i + incr]
601             i += incr
602         self.Dictionary.pop(i)
603
604     def RemoveUserType(self, index):
605         type = self.GetEntry(index, 1)
606         for i in self.UserMapping:
607             for value in self.UserMapping[i]["values"]:
608                 if value["type"] == index:
609                     value["type"] = type
610         self.RemoveMappingEntry(index)
611         self.RemoveEntry(index)
612
613     """
614     Return a copy of the node
615     """
616     def Copy(self):
617         return cPickle.loads(cPickle.dumps(self))
618
619     """
620     Return a sorted list of indexes in Object Dictionary
621     """
622     def GetIndexes(self):
623         listindex = self.Dictionary.keys()
624         listindex.sort()
625         return listindex
626
627     """
628     Print the Dictionary values
629     """
630     def Print(self):
631         listindex = self.Dictionary.keys()
632         listindex.sort()
633         for index in listindex:
634             print "%04X : %s"%(index, self.Dictionary[index])