]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/node.py
6d7cf544dca3f6797b761a29513e8c41e3f3f9d3
[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" : 0x07, "access" : 'ro', "pdo" : False}]},
102     0x1001 : {"name" : "Error Register", "struct" : var,  "need" : True, "values" : 
103                 [{"name" : "Error Register", "type" : 0x05, "access": 'ro', "pdo" : True}]},
104     0x1002 : {"name" : "Manufacturer Status Register", "struct" : var, "need" : False,  "values" :
105                 [{"name" : "Manufacturer Status Register", "type" : 0x07, "access" : 'ro', "pdo" : True}]},
106     0x1003 : {"name" : "Pre-defined Error Field", "struct" : rec, "need" : False,  "values" :
107                 [{"name" : "Number of Errors", "type" : 0x05, "access" : 'rw', "pdo" : False},
108                  {"name" : "Standard Error Field", "type" : 0x07, "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" : 0x07, "access" : 'rw', "pdo" : False}]},
111     0x1006 : {"name" : "Communication / Cycle Period", "struct" : var, "need" : False, "callback" : True, "values" :
112                 [{"name" : "Communication Cycle Period", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
113     0x1007 : {"name" : "Synchronous Window Length", "struct" : var, "need" : False, "values" :
114                 [{"name" : "Synchronous Window Length", "type" : 0x07, "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" : 0x06, "access" : 'rw', "pdo" : False}]},
123     0x100D : {"name" : "Life Time Factor", "struct" : var, "need" : False, "values" :
124                 [{"name" : "Life Time Factor", "type" : 0x05, "access" : 'rw', "pdo" : False}]},
125     0x1010 : {"name" : "Store parameters", "struct" : array, "need" : False, "values" :
126                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
127                  {"name" : "Save All Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
128                  {"name" : "Save Communication Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
129                  {"name" : "Save Application Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
130                  {"name" : "Save Manufacturer Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
131     0x1011 : {"name" : "Restore Default Parameters", "struct" : array, "need" : False, "values" :
132                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
133                  {"name" : "Restore All Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
134                  {"name" : "Restore Communication Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
135                  {"name" : "Restore Application Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
136                  {"name" : "Restore Manufacturer Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
137     0x1012 : {"name" : "TIME COB ID", "struct" : var, "need" : False, "values" :
138                 [{"name" : "TIME COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
139     0x1013 : {"name" : "High Resolution Timestamp", "struct" : var, "need" : False, "values" :
140                 [{"name" : "High Resolution Time Stamp", "type" : 0x07, "access" : 'rw', "pdo" : True}]},
141     0x1014 : {"name" : "Emergency COB ID", "struct" : var, "need" : False, "values" :
142                 [{"name" : "Emergency COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
143     0x1015 : {"name" : "Inhibit Time Emergency", "struct" : var, "need" : False, "values" :
144                 [{"name" : "Inhibit Time Emergency", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
145     0x1016 : {"name" : "Consumer Heartbeat Time", "struct" : rec, "need" : False, "values" :
146                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
147                  {"name" : "Consumer Heartbeat Time", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7F}]},
148     0x1017 : {"name" : "Producer Heartbeat Time", "struct" : var, "need" : False, "callback" : True, "values" :
149                 [{"name" : "Producer Heartbeat Time", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
150     0x1018 : {"name" : "Identity", "struct" : array, "need" : True, "values" :
151                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
152                  {"name" : "Vendor ID", "type" : 0x07, "access" : 'ro', "pdo" : False},
153                  {"name" : "Product Code", "type" : 0x07, "access" : 'ro', "pdo" : False},
154                  {"name" : "Revision Number", "type" : 0x07, "access" : 'ro', "pdo" : False},
155                  {"name" : "Serial Number", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
156     0x1020 : {"name" : "Verify Configuration", "struct" : array, "need" : False, "values" :
157                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
158                  {"name" : "Configuration Date", "type" : 0x07, "access" : 'ro', "pdo" : False},
159                  {"name" : "Configuration Time", "type" : 0x07, "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" : 0x06, "access" : 'rw', "pdo" : False}]},
164     0x1023 : {"name" : "OS Command", "struct" : array, "need" : False, "values" :
165                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
166                  {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
167                  {"name" : "Status", "type" : 0x05, "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" : 0x05, "access" : 'wo', "pdo" : False}]},
171     0x1025 : {"name" : "OS Debugger Interface", "struct" : array, "need" : False, "values" :
172                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
173                  {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
174                  {"name" : "Status", "type" : 0x07, "access" : 'ro', "pdo" : False},
175                  {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]},
176     0x1026 : {"name" : "OS Prompt", "struct" : array, "need" : False, "values" :
177                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
178                  {"name" : "StdIn", "type" : 0x05, "access" : 'wo', "pdo" : True},
179                  {"name" : "StdOut", "type" : 0x05, "access" : 'ro', "pdo" : True},
180                  {"name" : "StdErr", "type" : 0x05, "access" : 'ro', "pdo" : True}]},
181     0x1027 : {"name" : "Module List", "struct" : rec, "need" : False, "values" :
182                 [{"name" : "Number of Connected Modules", "type" : 0x05, "access" : 'ro', "pdo" : False},
183                  {"name" : "Module %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
184     0x1028 : {"name" : "Emergency Consumer", "struct" : rec, "need" : False, "values" :
185                 [{"name" : "Number of Consumed Emergency Objects", "type" : 0x05, "access" : 'ro', "pdo" : False},
186                  {"name" : "Emergency Consumer", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7E}]},
187     0x1029 : {"name" : "Error Behavior", "struct" : array, "need" : False, "values" :
188                 [{"name" : "Number of Error Classes", "type" : 0x05, "access" : 'ro', "pdo" : False},
189                  {"name" : "Communication Error", "type" : 0x05, "access" : 'rw', "pdo" : False},
190                  {"name" : "Device Profile", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]},
191     0x1200 : {"name" : "Server SDO Parameter", "struct" : array, "need" : False, "values" :
192                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
193                  {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
194                  {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "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" : 0x05, "access" : 'ro', "pdo" : False},
197                  {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
198                  {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
199                  {"name" : "Node ID of the SDO Client", "type" : 0x05, "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" : 0x05, "access" : 'ro', "pdo" : False},
202                  {"name" : "COB ID Client to Server (Transmit SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
203                  {"name" : "COB ID Server to Client (Receive SDO)", "type" : 0x07, "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" : 0x05, "access" : 'ro', "pdo" : False},
207                  {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False},
208                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
209                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
210                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
211                  {"name" : "Event Timer", "type" : 0x06, "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" : 0x05, "access" : 'rw', "pdo" : False},
214                  {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x07, "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" : 0x05, "access" : 'ro', "pdo" : False},
217                  {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False},
218                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
219                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
220                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
221                  {"name" : "Event Timer", "type" : 0x06, "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" : 0x05, "access" : 'rw', "pdo" : False},
224                  {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x07, "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, description = "", profilename = "DS-301", profile = {}, specificmenu = []):
239         self.Name = name
240         self.Type = type
241         self.ID = id
242         self.Description = description
243         self.ProfileName = profilename
244         self.Profile = profile
245         self.SpecificMenu = specificmenu
246         self.Dictionary = {}
247         self.ParamsDictionary = {}
248         self.DS302 = {}
249         self.UserMapping = {}
250     
251     """
252     Return the node name
253     """
254     def GetNodeName(self):
255         return self.Name
256     
257     """
258     Define the node name
259     """
260     def SetNodeName(self, name):
261         self.Name = name
262
263     """
264     Return the node type ("master" or "slave")
265     """
266     def GetNodeType(self):
267         return self.Type
268     
269     """
270     Define the node type ("master" or "slave")
271     """
272     def SetNodeType(self, type):
273         self.Type = type
274
275     """
276     Return the node ID
277     """
278     def GetNodeID(self):
279         return self.ID
280     
281     """
282     Define the node ID
283     """
284     def SetNodeID(self, id):
285         self.ID = id
286
287     """
288     Return the node description
289     """
290     def GetNodeDescription(self):
291         if getattr(self, "Description", False):
292             return self.Description
293         else:
294             return ""
295     
296     """
297     Define the node description
298     """
299     def SetNodeDescription(self, description):
300         self.Description = description
301
302     """
303     Return the Specific Profile Name
304     """
305     def GetProfileName(self):
306         return self.ProfileName
307     
308     """
309     Define the Specific Profile Name
310     """
311     def SetProfileName(self, profilename):
312         self.ProfileName = profilename
313
314     """
315     Return the Specific Profile
316     """
317     def GetProfile(self):
318         return self.Profile
319     
320     """
321     Define the Specific Profile
322     """
323     def SetProfile(self, profile):
324         self.Profile = profile
325     
326     """
327     Define the DS-302 Profile
328     """
329     def SetDS302Profile(self, profile):
330         self.DS302 = profile
331     
332     """
333     Define the DS-302 Profile
334     """
335     def GetDS302Profile(self):
336         return self.DS302
337     
338     """
339     Return the Specific Menu Entries
340     """
341     def GetSpecificMenu(self):
342         return self.SpecificMenu
343     
344     """
345     Define the Specific Menu Entries
346     """
347     def SetSpecificMenu(self, specificmenu):
348         self.SpecificMenu = specificmenu
349     
350     """
351     Extend the Specific Menu Entries
352     """
353     
354     def ExtendSpecificMenu(self, specificmenu):
355         self.SpecificMenu.extend(specificmenu)
356     
357     """
358     Function which return the different Mappings available for this node
359     """
360     def GetMappings(self, userdefinedtoo = True):
361         if userdefinedtoo:
362             return [self.Profile, self.DS302, self.UserMapping]
363         else:
364             return [self.Profile, self.DS302]
365     
366     """
367     Add a new entry in the Object Dictionary
368     """
369     def AddEntry(self, index, subIndex = None, value = None):
370         if index not in self.Dictionary:
371             if not subIndex:
372                 self.Dictionary[index] = value
373                 return True
374             elif subIndex == 1:
375                 self.Dictionary[index] = [value]
376                 return True
377         elif subIndex > 1 and type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]) + 1:
378             self.Dictionary[index].append(value)
379             return True
380         return False
381
382     """
383     Warning ! Modifies an existing entry in the Object Dictionary. Can't add a new one.
384     """
385     def SetEntry(self, index, subIndex = None, value = None):
386         if index in self.Dictionary:
387             if not subIndex:
388                 if value != None:
389                     self.Dictionary[index] = value
390                 return True
391             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
392                 if value != None:
393                     self.Dictionary[index][subIndex - 1] = value
394                 return True
395         return False
396     
397     def SetParamsEntry(self, index, subIndex = None, comment = None, save = None, callback = None):
398         if not getattr(self, "ParamsDictionary", False):
399             self.ParamsDictionary = {}
400         if index in self.Dictionary:
401             if (comment != None or save != None or callback != None) and index not in self.ParamsDictionary:
402                 self.ParamsDictionary[index] = {}
403             if subIndex == None or type(self.Dictionary[index]) != ListType and subIndex == 0:
404                 if comment != None:
405                     self.ParamsDictionary[index]["comment"] = comment
406                 if save != None:
407                     self.ParamsDictionary[index]["save"] = save
408                 if callback != None:
409                     self.ParamsDictionary[index]["callback"] = callback
410                 return True
411             elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
412                 if (comment != None or save != None or callback != None) and subIndex not in self.ParamsDictionary[index]:
413                     self.ParamsDictionary[index][subIndex] = {}
414                 if comment != None:
415                     self.ParamsDictionary[index][subIndex]["comment"] = comment
416                 if save != None:
417                     self.ParamsDictionary[index][subIndex]["save"] = save
418                 return True
419         return False
420     
421     """
422     Removes an existing entry in the Object Dictionary. If a subIndex is specified
423     it will remove this subIndex only if it's the last of the index. If no subIndex
424     is specified it removes the whole index and subIndexes from the Object Dictionary.
425     """
426     def RemoveEntry(self, index, subIndex = None):
427         if not getattr(self, "ParamsDictionary", False):
428             self.ParamsDictionary = {}
429         if index in self.Dictionary:
430             if not subIndex:
431                 self.Dictionary.pop(index)
432                 if index in self.ParamsDictionary:
433                     self.ParamsDictionary.pop(index)
434                 return True
435             elif type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]):
436                 self.Dictionary[index].pop(subIndex - 1)
437                 if index in self.ParamsDictionary:
438                     if subIndex in self.ParamsDictionary[index]:
439                         self.ParamsDictionary[index].pop(subIndex)
440                     if len(self.ParamsDictionary[index]) == 0:
441                         self.ParamsDictionary.pop(index)
442                 if len(self.Dictionary[index]) == 0:
443                     self.Dictionary.pop(index)
444                     if index in self.ParamsDictionary:
445                         self.ParamsDictionary.pop(index)
446                 return True
447         return False
448     
449     """
450     Check if an entry exists in the Object Dictionary and returns the answer.
451     """
452     def IsEntry(self, index):
453         if index in self.Dictionary:
454             return True
455         return False
456     
457     """
458     Returns the value of the entry asked. If the entry has the value "count", it
459     returns the number of subIndex in the entry except the first.
460     """
461     def GetEntry(self, index, subIndex = None):
462         if index in self.Dictionary:
463             if subIndex == None:
464                 if type(self.Dictionary[index]) == ListType:
465                     values = [len(self.Dictionary[index])]
466                     values.extend(self.Dictionary[index])
467                     return values
468                 else:
469                     return self.Dictionary[index]
470             elif subIndex == 0:
471                 if type(self.Dictionary[index]) == ListType:
472                     return len(self.Dictionary[index])
473                 else:
474                     return self.Dictionary[index]
475             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
476                 return self.Dictionary[index][subIndex - 1]
477         return None
478
479     """
480     Returns the value of the entry asked. If the entry has the value "count", it
481     returns the number of subIndex in the entry except the first.
482     """
483     def GetParamsEntry(self, index, subIndex = None):
484         if not getattr(self, "ParamsDictionary", False):
485             self.ParamsDictionary = {}
486         if index in self.Dictionary:
487             if subIndex == None:
488                 if type(self.Dictionary[index]) == ListType:
489                     if index in self.ParamsDictionary:
490                         result = []
491                         for i in xrange(len(self.Dictionary[index]) + 1):
492                             line = DefaultParams.copy()
493                             if i in self.ParamsDictionary[index]:
494                                 line.update(self.ParamsDictionary[index][i])
495                             result.append(line)
496                         return result
497                     else:
498                         return [DefaultParams.copy() for i in xrange(len(self.Dictionary[index]) + 1)]
499                 else:
500                     result = DefaultParams.copy()
501                     if index in self.ParamsDictionary:
502                         result.update(self.ParamsDictionary[index])
503                     return result
504             elif subIndex == 0 and type(self.Dictionary[index]) != ListType:
505                 result = DefaultParams.copy()
506                 if index in self.ParamsDictionary:
507                     result.update(self.ParamsDictionary[index])
508                 return result
509             elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
510                 result = DefaultParams.copy()
511                 if index in self.ParamsDictionary and subIndex in self.ParamsDictionary[index]:
512                     result.update(self.ParamsDictionary[index][subIndex])
513                 return result
514         return None
515
516     def HasEntryCallbacks(self, index):
517         if not getattr(self, "ParamsDictionary", False):
518             self.ParamsDictionary = {}
519         if index in self.Dictionary and index in self.ParamsDictionary and "callback" in self.ParamsDictionary[index]:
520             return self.ParamsDictionary[index]["callback"]
521         return False
522
523     """
524     Check if an entry exists in the User Mapping Dictionary and returns the answer.
525     """
526     def IsMappingEntry(self, index):
527         if index in self.UserMapping:
528             return True
529         return False
530
531     """
532     Add a new entry in the User Mapping Dictionary
533     """
534     def AddMappingEntry(self, index, subIndex = None, name = "Undefined", struct = 0, size = None, nbmax = None, default = None, values = None):
535         if index not in self.UserMapping:
536             if values == None:
537                 values = []
538             if subIndex == None:
539                 self.UserMapping[index] = {"name" : name, "struct" : struct, "need" : False, "values" : values}
540                 if size != None:
541                     self.UserMapping[index]["size"] = size
542                 if nbmax != None:
543                     self.UserMapping[index]["nbmax"] = nbmax
544                 if default != None:
545                     self.UserMapping[index]["default"] = default
546                 return True
547         elif subIndex != None and subIndex == len(self.UserMapping[index]["values"]):
548             if values == None:
549                 values = {}
550             self.UserMapping[index]["values"].append(values)
551             return True
552         return False
553
554     """
555     Warning ! Modifies an existing entry in the User Mapping Dictionary. Can't add a new one.
556     """
557     def SetMappingEntry(self, index, subIndex = None, name = None, struct = None, size = None, nbmax = None, default = None, values = None):
558         if index in self.UserMapping:
559             if subIndex == None:
560                 if name != None:
561                     self.UserMapping[index]["name"] = name
562                     if self.UserMapping[index]["struct"] & OD_IdenticalSubindexes:
563                         self.UserMapping[index]["values"][1]["name"] = name + " %d[(sub)]"
564                     elif not self.UserMapping[index]["struct"] & OD_MultipleSubindexes:
565                         self.UserMapping[index]["values"][0]["name"] = name
566                 if struct != None:
567                     self.UserMapping[index]["struct"] = struct
568                 if size != None:
569                     self.UserMapping[index]["size"] = size
570                 if nbmax != None:
571                     self.UserMapping[index]["nbmax"] = nbmax
572                 if default != None:
573                     self.UserMapping[index]["default"] = default
574                 if values != None:
575                     self.UserMapping[index]["values"] = values
576                 return True
577             elif 0 <= subIndex < len(self.UserMapping[index]["values"]) and values != None:
578                 self.UserMapping[index]["values"][subIndex].update(values)
579                 return True
580         return False
581     
582     """
583     Removes an existing entry in the User Mapping Dictionary. If a subIndex is specified
584     it will remove this subIndex only if it's the last of the index. If no subIndex
585     is specified it removes the whole index and subIndexes from the User Mapping Dictionary.
586     """
587     def RemoveMappingEntry(self, index, subIndex = None):
588         if index in self.UserMapping:
589             if subIndex == None:
590                 self.UserMapping.pop(index)
591                 return True
592             elif subIndex == len(self.UserMapping[index]["values"]) - 1:
593                 self.UserMapping[index]["values"].pop(subIndex)
594                 return True
595         return False
596
597     def RemoveMapVariable(self, index, subIndex):
598         model = index << 16
599         mask = 0xFFFF << 16
600         if subIndex:
601             model += subIndex << 8
602             mask = 0xFF << 8
603         for i in self.Dictionary.iterkeys():
604             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
605                 for j,value in enumerate(self.Dictionary[i]):
606                     if (value & mask) == model:
607                         self.Dictionary[i][j] = 0
608     
609     def UpdateMapVariable(self, index, subIndex, size):
610         model = index << 16
611         mask = 0xFFFF << 16
612         if subIndex:
613             model += subIndex << 8
614             mask = 0xFF << 8
615         for i in self.Dictionary.iterkeys():
616             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
617                 for j,value in enumerate(self.Dictionary[i]):
618                     if (value & mask) == model:
619                         self.Dictionary[i][j] = model + size
620     
621     def RemoveLine(self, index, max, incr = 1):
622         i = index
623         while i < max and self.IsEntry(i + incr):
624             self.Dictionary[i] = self.Dictionary[i + incr]
625             i += incr
626         self.Dictionary.pop(i)
627
628     def RemoveUserType(self, index):
629         type = self.GetEntry(index, 1)
630         for i in self.UserMapping:
631             for value in self.UserMapping[i]["values"]:
632                 if value["type"] == index:
633                     value["type"] = type
634         self.RemoveMappingEntry(index)
635         self.RemoveEntry(index)
636
637     """
638     Return a copy of the node
639     """
640     def Copy(self):
641         return cPickle.loads(cPickle.dumps(self))
642
643     """
644     Return a sorted list of indexes in Object Dictionary
645     """
646     def GetIndexes(self):
647         listindex = self.Dictionary.keys()
648         listindex.sort()
649         return listindex
650
651     """
652     Print the Dictionary values
653     """
654     def Print(self):
655         listindex = self.Dictionary.keys()
656         listindex.sort()
657         for index in listindex:
658             print "%04X : %s"%(index, self.Dictionary[index])