00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 import cPickle
00025 from types import *
00026 import re
00027
00028 """
00029 Dictionary of translation between access symbol and their signification
00030 """
00031 AccessType = {"ro" : "Read Only", "wo" : "Write Only", "rw" : "Read/Write"}
00032
00033 BoolType = {True : "True", False : "False"}
00034 OptionType = {True : "Yes", False : "No"}
00035
00036 CustomisableTypes = [(0x02, 0), (0x03, 0), (0x04, 0), (0x05, 0), (0x06, 0), (0x07, 0),
00037 (0x08, 0), (0x09, 1), (0x0A, 1), (0x0B, 1), (0x10, 0), (0x11, 0), (0x12, 0),
00038 (0x13, 0), (0x14, 0), (0x15, 0), (0x16, 0), (0x18, 0), (0x19, 0), (0x1A, 0),
00039 (0x1B, 0)]
00040
00041 DefaultParams = {"comment" : "", "save" : False}
00042
00043
00044
00045
00046
00047 """
00048 Properties of entry structure in the Object Dictionary
00049 """
00050 OD_Subindex = 1
00051 OD_MultipleSubindexes = 2
00052 OD_IdenticalSubindexes = 4
00053 OD_IdenticalIndexes = 8
00054
00055 """
00056 Structures of entry in the Object Dictionary, sum of the properties described above
00057 for all sorts of entries use in CAN Open specification
00058 """
00059 nosub = 0
00060 var = 1
00061 array = 3
00062 rec = 7
00063
00064 plurivar = 9
00065 pluriarray = 11
00066 plurirec = 15
00067
00068 """
00069 MappingDictionary is the structure used for writing a good organised Object
00070 Dictionary. It follows the specifications of the CANOpen standard.
00071 Change the informations within it if there is a mistake. But don't modify the
00072 organisation of this object, it will involve in a malfunction of the application.
00073 """
00074
00075 MappingDictionary = {
00076 0x0001 : {"name" : "BOOLEAN", "struct" : nosub, "size" : 1, "default" : False, "values" : []},
00077 0x0002 : {"name" : "INTEGER8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []},
00078 0x0003 : {"name" : "INTEGER16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []},
00079 0x0004 : {"name" : "INTEGER32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []},
00080 0x0005 : {"name" : "UNSIGNED8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []},
00081 0x0006 : {"name" : "UNSIGNED16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []},
00082 0x0007 : {"name" : "UNSIGNED32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []},
00083 0x0008 : {"name" : "REAL32", "struct" : nosub, "size" : 32, "default" : 0.0, "values" : []},
00084 0x0009 : {"name" : "VISIBLE_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []},
00085 0x000A : {"name" : "OCTET_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []},
00086 0x000B : {"name" : "UNICODE_STRING", "struct" : nosub, "size" : 16, "default" : "", "values" : []},
00087
00088
00089 0x000F : {"name" : "DOMAIN", "struct" : nosub, "size" : 0, "default" : "", "values" : []},
00090 0x0010 : {"name" : "INTEGER24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []},
00091 0x0011 : {"name" : "REAL64", "struct" : nosub, "size" : 64, "default" : 0.0, "values" : []},
00092 0x0012 : {"name" : "INTEGER40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []},
00093 0x0013 : {"name" : "INTEGER48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
00094 0x0014 : {"name" : "INTEGER56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []},
00095 0x0015 : {"name" : "INTEGER64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []},
00096 0x0016 : {"name" : "UNSIGNED24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []},
00097 0x0018 : {"name" : "UNSIGNED40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []},
00098 0x0019 : {"name" : "UNSIGNED48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
00099 0x001A : {"name" : "UNSIGNED56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []},
00100 0x001B : {"name" : "UNSIGNED64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []},
00101 0x1000 : {"name" : "Device Type", "struct" : var, "need" : True, "values" :
00102 [{"name" : "Device Type", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
00103 0x1001 : {"name" : "Error Register", "struct" : var, "need" : True, "values" :
00104 [{"name" : "Error Register", "type" : 0x05, "access": 'ro', "pdo" : True}]},
00105 0x1002 : {"name" : "Manufacturer Status Register", "struct" : var, "need" : False, "values" :
00106 [{"name" : "Manufacturer Status Register", "type" : 0x07, "access" : 'ro', "pdo" : True}]},
00107 0x1003 : {"name" : "Pre-defined Error Field", "struct" : rec, "need" : False, "values" :
00108 [{"name" : "Number of Errors", "type" : 0x05, "access" : 'rw', "pdo" : False},
00109 {"name" : "Standard Error Field", "type" : 0x07, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
00110 0x1005 : {"name" : "SYNC COB ID", "struct" : var, "need" : True, "callback" : True, "values" :
00111 [{"name" : "SYNC COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
00112 0x1006 : {"name" : "Communication / Cycle Period", "struct" : var, "need" : False, "callback" : True, "values" :
00113 [{"name" : "Communication Cycle Period", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
00114 0x1007 : {"name" : "Synchronous Window Length", "struct" : var, "need" : False, "values" :
00115 [{"name" : "Synchronous Window Length", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
00116 0x1008 : {"name" : "Manufacturer Device Name", "struct" : var, "need" : False, "values" :
00117 [{"name" : "Manufacturer Device Name", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
00118 0x1009 : {"name" : "Manufacturer Hardware Version", "struct" : var, "need" : False, "values" :
00119 [{"name" : "Manufacturer Hardware Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
00120 0x100A : {"name" : "Manufacturer Software Version", "struct" : var, "need" : False, "values" :
00121 [{"name" : "Manufacturer Software Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
00122 0x100C : {"name" : "Guard Time", "struct" : var, "need" : False, "values" :
00123 [{"name" : "Guard Time", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
00124 0x100D : {"name" : "Life Time Factor", "struct" : var, "need" : False, "values" :
00125 [{"name" : "Life Time Factor", "type" : 0x05, "access" : 'rw', "pdo" : False}]},
00126 0x1010 : {"name" : "Store parameters", "struct" : array, "need" : False, "values" :
00127 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00128 {"name" : "Save All Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
00129 {"name" : "Save Communication Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
00130 {"name" : "Save Application Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
00131 {"name" : "Save Manufacturer Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
00132 0x1011 : {"name" : "Restore Default Parameters", "struct" : array, "need" : False, "values" :
00133 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00134 {"name" : "Restore All Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
00135 {"name" : "Restore Communication Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
00136 {"name" : "Restore Application Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
00137 {"name" : "Restore Manufacturer Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
00138 0x1012 : {"name" : "TIME COB ID", "struct" : var, "need" : False, "values" :
00139 [{"name" : "TIME COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
00140 0x1013 : {"name" : "High Resolution Timestamp", "struct" : var, "need" : False, "values" :
00141 [{"name" : "High Resolution Time Stamp", "type" : 0x07, "access" : 'rw', "pdo" : True}]},
00142 0x1014 : {"name" : "Emergency COB ID", "struct" : var, "need" : False, "values" :
00143 [{"name" : "Emergency COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
00144 0x1015 : {"name" : "Inhibit Time Emergency", "struct" : var, "need" : False, "values" :
00145 [{"name" : "Inhibit Time Emergency", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
00146 0x1016 : {"name" : "Consumer Heartbeat Time", "struct" : rec, "need" : False, "values" :
00147 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00148 {"name" : "Consumer Heartbeat Time", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7F}]},
00149 0x1017 : {"name" : "Producer Heartbeat Time", "struct" : var, "need" : False, "callback" : True, "values" :
00150 [{"name" : "Producer Heartbeat Time", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
00151 0x1018 : {"name" : "Identity", "struct" : array, "need" : True, "values" :
00152 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00153 {"name" : "Vendor ID", "type" : 0x07, "access" : 'ro', "pdo" : False},
00154 {"name" : "Product Code", "type" : 0x07, "access" : 'ro', "pdo" : False},
00155 {"name" : "Revision Number", "type" : 0x07, "access" : 'ro', "pdo" : False},
00156 {"name" : "Serial Number", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
00157 0x1020 : {"name" : "Verify Configuration", "struct" : array, "need" : False, "values" :
00158 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00159 {"name" : "Configuration Date", "type" : 0x07, "access" : 'ro', "pdo" : False},
00160 {"name" : "Configuration Time", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
00161
00162
00163
00164
00165 0x1023 : {"name" : "OS Command", "struct" : array, "need" : False, "values" :
00166 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00167 {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
00168 {"name" : "Status", "type" : 0x05, "access" : 'ro', "pdo" : False},
00169 {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]},
00170 0x1024 : {"name" : "OS Command Mode", "struct" : var, "need" : False, "values" :
00171 [{"name" : "OS Command Mode", "type" : 0x05, "access" : 'wo', "pdo" : False}]},
00172 0x1025 : {"name" : "OS Debugger Interface", "struct" : array, "need" : False, "values" :
00173 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00174 {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
00175 {"name" : "Status", "type" : 0x07, "access" : 'ro', "pdo" : False},
00176 {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]},
00177 0x1026 : {"name" : "OS Prompt", "struct" : array, "need" : False, "values" :
00178 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00179 {"name" : "StdIn", "type" : 0x05, "access" : 'wo', "pdo" : True},
00180 {"name" : "StdOut", "type" : 0x05, "access" : 'ro', "pdo" : True},
00181 {"name" : "StdErr", "type" : 0x05, "access" : 'ro', "pdo" : True}]},
00182 0x1027 : {"name" : "Module List", "struct" : rec, "need" : False, "values" :
00183 [{"name" : "Number of Connected Modules", "type" : 0x05, "access" : 'ro', "pdo" : False},
00184 {"name" : "Module %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
00185 0x1028 : {"name" : "Emergency Consumer", "struct" : rec, "need" : False, "values" :
00186 [{"name" : "Number of Consumed Emergency Objects", "type" : 0x05, "access" : 'ro', "pdo" : False},
00187 {"name" : "Emergency Consumer", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7E}]},
00188 0x1029 : {"name" : "Error Behavior", "struct" : array, "need" : False, "values" :
00189 [{"name" : "Number of Error Classes", "type" : 0x05, "access" : 'ro', "pdo" : False},
00190 {"name" : "Communication Error", "type" : 0x05, "access" : 'rw', "pdo" : False},
00191 {"name" : "Device Profile", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]},
00192 0x1200 : {"name" : "Server SDO Parameter", "struct" : array, "need" : False, "values" :
00193 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00194 {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
00195 {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
00196 0x1201 : {"name" : "Additional Server SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x7F, "need" : False, "values" :
00197 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00198 {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
00199 {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
00200 {"name" : "Node ID of the SDO Client", "type" : 0x05, "access" : 'ro', "pdo" : False}]},
00201 0x1280 : {"name" : "Client SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x100, "need" : False, "values" :
00202 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
00203 {"name" : "COB ID Client to Server (Transmit SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
00204 {"name" : "COB ID Server to Client (Receive SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
00205 {"name" : "Node ID of the SDO Server", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
00206 0x1400 : {"name" : "Receive PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
00207 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
00208 {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:self.ID+(base+2)*0x100,False:0}[base<4]"},
00209 {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
00210 {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
00211 {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
00212 {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
00213 0x1600 : {"name" : "Receive PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
00214 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
00215 {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
00216 0x1800 : {"name" : "Transmit PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
00217 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
00218 {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:self.ID+(base+1)*0x100+0x80,False:0}[base<4]"},
00219 {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
00220 {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
00221 {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
00222 {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
00223 0x1A00 : {"name" : "Transmit PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
00224 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
00225 {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
00226 }
00227
00228
00229
00230
00231
00232 """
00233 Return the index of the typename given by searching in mappingdictionary
00234 """
00235 def FindTypeIndex(typename, mappingdictionary):
00236 testdic = {}
00237 for index, values in mappingdictionary.iteritems():
00238 if index < 0x1000:
00239 testdic[values["name"]] = index
00240 if typename in testdic:
00241 return testdic[typename]
00242 return None
00243
00244 """
00245 Return the name of the type by searching in mappingdictionary
00246 """
00247 def FindTypeName(typeindex, mappingdictionary):
00248 if typeindex < 0x1000 and typeindex in mappingdictionary:
00249 return mappingdictionary[typeindex]["name"]
00250 return None
00251
00252 """
00253 Return the default value of the type by searching in mappingdictionary
00254 """
00255 def FindTypeDefaultValue(typeindex, mappingdictionary):
00256 if typeindex < 0x1000 and typeindex in mappingdictionary:
00257 return mappingdictionary[typeindex]["default"]
00258 return None
00259
00260 """
00261 Return the list of types defined in mappingdictionary
00262 """
00263 def FindTypeList(mappingdictionary):
00264 list = []
00265 for index in mappingdictionary.keys():
00266 if index < 0x1000:
00267 list.append(mappingdictionary[index]["name"])
00268 return list
00269
00270 """
00271 Return the name of an entry by searching in mappingdictionary
00272 """
00273 def FindEntryName(index, mappingdictionary):
00274 base_index = FindIndex(index, mappingdictionary)
00275 if base_index:
00276 infos = mappingdictionary[base_index]
00277 if infos["struct"] & OD_IdenticalIndexes:
00278 return StringFormat(infos["name"], (index - base_index) / infos["incr"] + 1, 0)
00279 else:
00280 return infos["name"]
00281 return None
00282
00283 """
00284 Return the informations of one entry by searching in mappingdictionary
00285 """
00286 def FindEntryInfos(index, mappingdictionary):
00287 base_index = FindIndex(index, mappingdictionary)
00288 if base_index:
00289 copy = mappingdictionary[base_index].copy()
00290 if copy["struct"] & OD_IdenticalIndexes:
00291 copy["name"] = StringFormat(copy["name"], (index - base_index) / copy["incr"] + 1, 0)
00292 copy.pop("values")
00293 return copy
00294 return None
00295
00296 """
00297 Return the informations of one subentry of an entry by searching in mappingdictionary
00298 """
00299 def FindSubentryInfos(index, subIndex, mappingdictionary):
00300 base_index = FindIndex(index, mappingdictionary)
00301 if base_index:
00302 struct = mappingdictionary[base_index]["struct"]
00303 if struct & OD_Subindex:
00304 if struct & OD_IdenticalSubindexes:
00305 if struct & OD_IdenticalIndexes:
00306 incr = mappingdictionary[base_index]["incr"]
00307 else:
00308 incr = 1
00309 if subIndex == 0:
00310 return mappingdictionary[base_index]["values"][0].copy()
00311 elif 0 < subIndex <= mappingdictionary[base_index]["values"][1]["nbmax"]:
00312 copy = mappingdictionary[base_index]["values"][1].copy()
00313 copy["name"] = StringFormat(copy["name"], (index - base_index) / incr + 1, subIndex)
00314 return copy
00315 elif struct & OD_MultipleSubindexes and 0 <= subIndex < len(mappingdictionary[base_index]["values"]):
00316 return mappingdictionary[base_index]["values"][subIndex].copy()
00317 elif subIndex == 0:
00318 return mappingdictionary[base_index]["values"][0].copy()
00319 return None
00320
00321 """
00322 Return the list of variables that can be mapped defined in mappingdictionary
00323 """
00324 def FindMapVariableList(mappingdictionary, Node):
00325 list = []
00326 for index in mappingdictionary.iterkeys():
00327 if Node.IsEntry(index):
00328 for subIndex, values in enumerate(mappingdictionary[index]["values"]):
00329 if mappingdictionary[index]["values"][subIndex]["pdo"]:
00330 infos = Node.GetEntryInfos(mappingdictionary[index]["values"][subIndex]["type"])
00331 if mappingdictionary[index]["struct"] & OD_IdenticalSubindexes:
00332 values = Node.GetEntry(index)
00333 for i in xrange(len(values) - 1):
00334 list.append((index, i + 1, infos["size"], StringFormat(mappingdictionary[index]["values"][subIndex]["name"],1,i+1)))
00335 else:
00336 list.append((index, subIndex, infos["size"], mappingdictionary[index]["values"][subIndex]["name"]))
00337 return list
00338
00339 """
00340 Return the list of mandatory indexes defined in mappingdictionary
00341 """
00342 def FindMandatoryIndexes(mappingdictionary):
00343 list = []
00344 for index in mappingdictionary.iterkeys():
00345 if index >= 0x1000 and mappingdictionary[index]["need"]:
00346 list.append(index)
00347 return list
00348
00349 """
00350 Return the index of the informations in the Object Dictionary in case of identical
00351 indexes
00352 """
00353 def FindIndex(index, mappingdictionary):
00354 if index in mappingdictionary:
00355 return index
00356 else:
00357 listpluri = [idx for idx in mappingdictionary.keys() if mappingdictionary[idx]["struct"] & OD_IdenticalIndexes]
00358 listpluri.sort()
00359 for idx in listpluri:
00360 nb_max = mappingdictionary[idx]["nbmax"]
00361 incr = mappingdictionary[idx]["incr"]
00362 if idx < index < idx + incr * nb_max and (index - idx)%incr == 0:
00363 return idx
00364 return None
00365
00366
00367
00368
00369
00370 name_model = re.compile('(.*)\[(.*)\]')
00371
00372 """
00373 Format the text given with the index and subindex defined
00374 """
00375 def StringFormat(text, idx, sub):
00376 result = name_model.match(text)
00377 if result:
00378 format = result.groups()
00379 return format[0]%eval(format[1])
00380 else:
00381 return text
00382
00383
00384
00385
00386
00387 """
00388 Class recording the Object Dictionary entries. It checks at each modification
00389 that the structure of the Object Dictionary stay coherent
00390 """
00391
00392 class Node:
00393
00394 def __init__(self, name = "", type = "slave", id = 0, description = "", profilename = "DS-301", profile = {}, specificmenu = []):
00395 self.NameName = name
00396 self.TypeType = type
00397 self.IDID = id
00398 self.DescriptionDescription = description
00399 self.ProfileNameProfileName = profilename
00400 self.ProfileProfile = profile
00401 self.SpecificMenuSpecificMenu = specificmenu
00402 self.DictionaryDictionary = {}
00403 self.ParamsDictionaryParamsDictionary = {}
00404 self.DS302DS302 = {}
00405 self.UserMappingUserMapping = {}
00406
00407 """
00408 Return the node name
00409 """
00410 def GetNodeName(self):
00411 return self.NameName
00412
00413 """
00414 Define the node name
00415 """
00416 def SetNodeName(self, name):
00417 self.NameName = name
00418
00419 """
00420 Return the node type ("master" or "slave")
00421 """
00422 def GetNodeType(self):
00423 return self.TypeType
00424
00425 """
00426 Define the node type ("master" or "slave")
00427 """
00428 def SetNodeType(self, type):
00429 self.TypeType = type
00430
00431 """
00432 Return the node ID
00433 """
00434 def GetNodeID(self):
00435 return self.IDID
00436
00437 """
00438 Define the node ID
00439 """
00440 def SetNodeID(self, id):
00441 self.IDID = id
00442
00443 """
00444 Return the node description
00445 """
00446 def GetNodeDescription(self):
00447 if getattr(self, "Description", False):
00448 return self.DescriptionDescription
00449 else:
00450 return ""
00451
00452 """
00453 Define the node description
00454 """
00455 def SetNodeDescription(self, description):
00456 self.DescriptionDescription = description
00457
00458 """
00459 Return the Specific Profile Name
00460 """
00461 def GetProfileName(self):
00462 return self.ProfileNameProfileName
00463
00464 """
00465 Define the Specific Profile Name
00466 """
00467 def SetProfileName(self, profilename):
00468 self.ProfileNameProfileName = profilename
00469
00470 """
00471 Return the Specific Profile
00472 """
00473 def GetProfile(self):
00474 return self.ProfileProfile
00475
00476 """
00477 Define the Specific Profile
00478 """
00479 def SetProfile(self, profile):
00480 self.ProfileProfile = profile
00481
00482 """
00483 Define the DS-302 Profile
00484 """
00485 def SetDS302Profile(self, profile):
00486 self.DS302DS302 = profile
00487
00488 """
00489 Define the DS-302 Profile
00490 """
00491 def GetDS302Profile(self):
00492 return self.DS302DS302
00493
00494 """
00495 Return the Specific Menu Entries
00496 """
00497 def GetSpecificMenu(self):
00498 return self.SpecificMenuSpecificMenu
00499
00500 """
00501 Define the Specific Menu Entries
00502 """
00503 def SetSpecificMenu(self, specificmenu):
00504 self.SpecificMenuSpecificMenu = specificmenu
00505
00506 """
00507 Extend the Specific Menu Entries
00508 """
00509
00510 def ExtendSpecificMenu(self, specificmenu):
00511 self.SpecificMenuSpecificMenu.extend(specificmenu)
00512
00513 """
00514 Function which return the different Mappings available for this node
00515 """
00516 def GetMappings(self, userdefinedtoo = True):
00517 if userdefinedtoo:
00518 return [self.ProfileProfile, self.DS302DS302, self.UserMappingUserMapping]
00519 else:
00520 return [self.ProfileProfile, self.DS302DS302]
00521
00522 """
00523 Add a new entry in the Object Dictionary
00524 """
00525 def AddEntry(self, index, subIndex = None, value = None):
00526 if index not in self.DictionaryDictionary:
00527 if not subIndex:
00528 self.DictionaryDictionary[index] = value
00529 return True
00530 elif subIndex == 1:
00531 self.DictionaryDictionary[index] = [value]
00532 return True
00533 elif subIndex > 1 and type(self.DictionaryDictionary[index]) == ListType and subIndex == len(self.DictionaryDictionary[index]) + 1:
00534 self.DictionaryDictionary[index].append(value)
00535 return True
00536 return False
00537
00538 """
00539 Warning ! Modifies an existing entry in the Object Dictionary. Can't add a new one.
00540 """
00541 def SetEntry(self, index, subIndex = None, value = None):
00542 if index in self.DictionaryDictionary:
00543 if not subIndex:
00544 if value != None:
00545 self.DictionaryDictionary[index] = value
00546 return True
00547 elif type(self.DictionaryDictionary[index]) == ListType and 0 < subIndex <= len(self.DictionaryDictionary[index]):
00548 if value != None:
00549 self.DictionaryDictionary[index][subIndex - 1] = value
00550 return True
00551 return False
00552
00553 def SetParamsEntry(self, index, subIndex = None, comment = None, save = None, callback = None):
00554 if not getattr(self, "ParamsDictionary", False):
00555 self.ParamsDictionaryParamsDictionary = {}
00556 if index in self.DictionaryDictionary:
00557 if (comment != None or save != None or callback != None) and index not in self.ParamsDictionaryParamsDictionary:
00558 self.ParamsDictionaryParamsDictionary[index] = {}
00559 if subIndex == None or type(self.DictionaryDictionary[index]) != ListType and subIndex == 0:
00560 if comment != None:
00561 self.ParamsDictionaryParamsDictionary[index]["comment"] = comment
00562 if save != None:
00563 self.ParamsDictionaryParamsDictionary[index]["save"] = save
00564 if callback != None:
00565 self.ParamsDictionaryParamsDictionary[index]["callback"] = callback
00566 return True
00567 elif type(self.DictionaryDictionary[index]) == ListType and 0 <= subIndex <= len(self.DictionaryDictionary[index]):
00568 if (comment != None or save != None or callback != None) and subIndex not in self.ParamsDictionaryParamsDictionary[index]:
00569 self.ParamsDictionaryParamsDictionary[index][subIndex] = {}
00570 if comment != None:
00571 self.ParamsDictionaryParamsDictionary[index][subIndex]["comment"] = comment
00572 if save != None:
00573 self.ParamsDictionaryParamsDictionary[index][subIndex]["save"] = save
00574 return True
00575 return False
00576
00577 """
00578 Removes an existing entry in the Object Dictionary. If a subIndex is specified
00579 it will remove this subIndex only if it's the last of the index. If no subIndex
00580 is specified it removes the whole index and subIndexes from the Object Dictionary.
00581 """
00582 def RemoveEntry(self, index, subIndex = None):
00583 if not getattr(self, "ParamsDictionary", False):
00584 self.ParamsDictionaryParamsDictionary = {}
00585 if index in self.DictionaryDictionary:
00586 if not subIndex:
00587 self.DictionaryDictionary.pop(index)
00588 if index in self.ParamsDictionaryParamsDictionary:
00589 self.ParamsDictionaryParamsDictionary.pop(index)
00590 return True
00591 elif type(self.DictionaryDictionary[index]) == ListType and subIndex == len(self.DictionaryDictionary[index]):
00592 self.DictionaryDictionary[index].pop(subIndex - 1)
00593 if index in self.ParamsDictionaryParamsDictionary:
00594 if subIndex in self.ParamsDictionaryParamsDictionary[index]:
00595 self.ParamsDictionaryParamsDictionary[index].pop(subIndex)
00596 if len(self.ParamsDictionaryParamsDictionary[index]) == 0:
00597 self.ParamsDictionaryParamsDictionary.pop(index)
00598 if len(self.DictionaryDictionary[index]) == 0:
00599 self.DictionaryDictionary.pop(index)
00600 if index in self.ParamsDictionaryParamsDictionary:
00601 self.ParamsDictionaryParamsDictionary.pop(index)
00602 return True
00603 return False
00604
00605 """
00606 Check if an entry exists in the Object Dictionary and returns the answer.
00607 """
00608 def IsEntry(self, index, subIndex = None):
00609 if index in self.DictionaryDictionary:
00610 if not subIndex:
00611 return True
00612 return subIndex <= len(self.DictionaryDictionary[index])
00613 return False
00614
00615 """
00616 Returns the value of the entry asked. If the entry has the value "count", it
00617 returns the number of subIndex in the entry except the first.
00618 """
00619 def GetEntry(self, index, subIndex = None):
00620 if index in self.DictionaryDictionary:
00621 if subIndex == None:
00622 if type(self.DictionaryDictionary[index]) == ListType:
00623 values = [len(self.DictionaryDictionary[index])]
00624 for value in self.DictionaryDictionary[index]:
00625 values.append(self.CompileValueCompileValue(value, index))
00626 return values
00627 else:
00628 return self.DictionaryDictionary[index]
00629 elif subIndex == 0:
00630 if type(self.DictionaryDictionary[index]) == ListType:
00631 return len(self.DictionaryDictionary[index])
00632 else:
00633 return self.CompileValueCompileValue(self.DictionaryDictionary[index], index)
00634 elif type(self.DictionaryDictionary[index]) == ListType and 0 < subIndex <= len(self.DictionaryDictionary[index]):
00635 return self.CompileValueCompileValue(self.DictionaryDictionary[index][subIndex - 1], index)
00636 return None
00637
00638 """
00639 Returns the value of the entry asked. If the entry has the value "count", it
00640 returns the number of subIndex in the entry except the first.
00641 """
00642 def GetParamsEntry(self, index, subIndex = None):
00643 if not getattr(self, "ParamsDictionary", False):
00644 self.ParamsDictionaryParamsDictionary = {}
00645 if index in self.DictionaryDictionary:
00646 if subIndex == None:
00647 if type(self.DictionaryDictionary[index]) == ListType:
00648 if index in self.ParamsDictionaryParamsDictionary:
00649 result = []
00650 for i in xrange(len(self.DictionaryDictionary[index]) + 1):
00651 line = DefaultParams.copy()
00652 if i in self.ParamsDictionaryParamsDictionary[index]:
00653 line.update(self.ParamsDictionaryParamsDictionary[index][i])
00654 result.append(line)
00655 return result
00656 else:
00657 return [DefaultParams.copy() for i in xrange(len(self.DictionaryDictionary[index]) + 1)]
00658 else:
00659 result = DefaultParams.copy()
00660 if index in self.ParamsDictionaryParamsDictionary:
00661 result.update(self.ParamsDictionaryParamsDictionary[index])
00662 return result
00663 elif subIndex == 0 and type(self.DictionaryDictionary[index]) != ListType:
00664 result = DefaultParams.copy()
00665 if index in self.ParamsDictionaryParamsDictionary:
00666 result.update(self.ParamsDictionaryParamsDictionary[index])
00667 return result
00668 elif type(self.DictionaryDictionary[index]) == ListType and 0 <= subIndex <= len(self.DictionaryDictionary[index]):
00669 result = DefaultParams.copy()
00670 if index in self.ParamsDictionaryParamsDictionary and subIndex in self.ParamsDictionaryParamsDictionary[index]:
00671 result.update(self.ParamsDictionaryParamsDictionary[index][subIndex])
00672 return result
00673 return None
00674
00675 def HasEntryCallbacks(self, index):
00676 if not getattr(self, "ParamsDictionary", False):
00677 self.ParamsDictionaryParamsDictionary = {}
00678 if index in self.DictionaryDictionary and index in self.ParamsDictionaryParamsDictionary and "callback" in self.ParamsDictionaryParamsDictionary[index]:
00679 return self.ParamsDictionaryParamsDictionary[index]["callback"]
00680 return False
00681
00682 """
00683 Check if an entry exists in the User Mapping Dictionary and returns the answer.
00684 """
00685 def IsMappingEntry(self, index):
00686 if index in self.UserMappingUserMapping:
00687 return True
00688 return False
00689
00690 """
00691 Add a new entry in the User Mapping Dictionary
00692 """
00693 def AddMappingEntry(self, index, subIndex = None, name = "Undefined", struct = 0, size = None, nbmax = None, default = None, values = None):
00694 if index not in self.UserMappingUserMapping:
00695 if values == None:
00696 values = []
00697 if subIndex == None:
00698 self.UserMappingUserMapping[index] = {"name" : name, "struct" : struct, "need" : False, "values" : values}
00699 if size != None:
00700 self.UserMappingUserMapping[index]["size"] = size
00701 if nbmax != None:
00702 self.UserMappingUserMapping[index]["nbmax"] = nbmax
00703 if default != None:
00704 self.UserMappingUserMapping[index]["default"] = default
00705 return True
00706 elif subIndex != None and subIndex == len(self.UserMappingUserMapping[index]["values"]):
00707 if values == None:
00708 values = {}
00709 self.UserMappingUserMapping[index]["values"].append(values)
00710 return True
00711 return False
00712
00713 """
00714 Warning ! Modifies an existing entry in the User Mapping Dictionary. Can't add a new one.
00715 """
00716 def SetMappingEntry(self, index, subIndex = None, name = None, struct = None, size = None, nbmax = None, default = None, values = None):
00717 if index in self.UserMappingUserMapping:
00718 if subIndex == None:
00719 if name != None:
00720 self.UserMappingUserMapping[index]["name"] = name
00721 if self.UserMappingUserMapping[index]["struct"] & OD_IdenticalSubindexes:
00722 self.UserMappingUserMapping[index]["values"][1]["name"] = name + " %d[(sub)]"
00723 elif not self.UserMappingUserMapping[index]["struct"] & OD_MultipleSubindexes:
00724 self.UserMappingUserMapping[index]["values"][0]["name"] = name
00725 if struct != None:
00726 self.UserMappingUserMapping[index]["struct"] = struct
00727 if size != None:
00728 self.UserMappingUserMapping[index]["size"] = size
00729 if nbmax != None:
00730 self.UserMappingUserMapping[index]["nbmax"] = nbmax
00731 if default != None:
00732 self.UserMappingUserMapping[index]["default"] = default
00733 if values != None:
00734 self.UserMappingUserMapping[index]["values"] = values
00735 return True
00736 elif 0 <= subIndex < len(self.UserMappingUserMapping[index]["values"]) and values != None:
00737 self.UserMappingUserMapping[index]["values"][subIndex].update(values)
00738 return True
00739 return False
00740
00741 """
00742 Removes an existing entry in the User Mapping Dictionary. If a subIndex is specified
00743 it will remove this subIndex only if it's the last of the index. If no subIndex
00744 is specified it removes the whole index and subIndexes from the User Mapping Dictionary.
00745 """
00746 def RemoveMappingEntry(self, index, subIndex = None):
00747 if index in self.UserMappingUserMapping:
00748 if subIndex == None:
00749 self.UserMappingUserMapping.pop(index)
00750 return True
00751 elif subIndex == len(self.UserMappingUserMapping[index]["values"]) - 1:
00752 self.UserMappingUserMapping[index]["values"].pop(subIndex)
00753 return True
00754 return False
00755
00756 def RemoveMapVariable(self, index, subIndex = None):
00757 model = index << 16
00758 mask = 0xFFFF << 16
00759 if subIndex:
00760 model += subIndex << 8
00761 mask = 0xFF << 8
00762 for i in self.DictionaryDictionary.iterkeys():
00763 if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
00764 for j,value in enumerate(self.DictionaryDictionary[i]):
00765 if (value & mask) == model:
00766 self.DictionaryDictionary[i][j] = 0
00767
00768 def UpdateMapVariable(self, index, subIndex, size):
00769 model = index << 16
00770 mask = 0xFFFF << 16
00771 if subIndex:
00772 model += subIndex << 8
00773 mask = 0xFF << 8
00774 for i in self.DictionaryDictionary.iterkeys():
00775 if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
00776 for j,value in enumerate(self.DictionaryDictionary[i]):
00777 if (value & mask) == model:
00778 self.DictionaryDictionary[i][j] = model + size
00779
00780 def RemoveLine(self, index, max, incr = 1):
00781 i = index
00782 while i < max and self.IsEntryIsEntry(i + incr):
00783 self.DictionaryDictionary[i] = self.DictionaryDictionary[i + incr]
00784 i += incr
00785 self.DictionaryDictionary.pop(i)
00786
00787 def RemoveUserType(self, index):
00788 type = self.GetEntryGetEntry(index, 1)
00789 for i in self.UserMappingUserMapping:
00790 for value in self.UserMappingUserMapping[i]["values"]:
00791 if value["type"] == index:
00792 value["type"] = type
00793 self.RemoveMappingEntryRemoveMappingEntry(index)
00794 self.RemoveEntryRemoveEntry(index)
00795
00796 """
00797 Return a copy of the node
00798 """
00799 def Copy(self):
00800 return cPickle.loads(cPickle.dumps(self))
00801
00802 """
00803 Return a sorted list of indexes in Object Dictionary
00804 """
00805 def GetIndexes(self):
00806 listindex = self.DictionaryDictionary.keys()
00807 listindex.sort()
00808 return listindex
00809
00810 """
00811 Print the Dictionary values
00812 """
00813 def Print(self):
00814 listindex = self.DictionaryDictionary.keys()
00815 listindex.sort()
00816 for index in listindex:
00817 print "%04X : %s"%(index, self.DictionaryDictionary[index])
00818
00819 def CompileValue(self, value, index):
00820 if type(value) == StringType and value.find("self.ID") != -1:
00821 base = self.GetBaseIndexGetBaseIndex(index)
00822 try:
00823 return eval(value)
00824 except:
00825 return 0
00826 else:
00827 return value
00828
00829
00830
00831
00832
00833 def GetBaseIndex(self, index):
00834 for mapping in self.GetMappingsGetMappings():
00835 result = FindIndex(index, mapping)
00836 if result != None:
00837 return (index - result) / mapping[result]["incr"]
00838 result = FindIndex(index, MappingDictionary)
00839 if result != None:
00840 return (index - result) / MappingDictionary[result]["incr"]
00841 return 0
00842
00843 def GetCustomisedTypeValues(self, index):
00844 values = self.GetEntryGetEntry(index)
00845 customisabletypes = self.GetCustomisableTypesGetCustomisableTypes()
00846 return values, customisabletypes[values[1]][1]
00847
00848 def GetEntryName(self, index):
00849 result = None
00850 mappings = self.GetMappingsGetMappings()
00851 i = 0
00852 while not result and i < len(mappings):
00853 result = FindEntryName(index, mappings[i])
00854 i += 1
00855 if result == None:
00856 result = FindEntryName(index, MappingDictionary)
00857 return result
00858
00859 def GetEntryInfos(self, index):
00860 result = None
00861 mappings = self.GetMappingsGetMappings()
00862 i = 0
00863 while not result and i < len(mappings):
00864 result = FindEntryInfos(index, mappings[i])
00865 i += 1
00866 if result == None:
00867 result = FindEntryInfos(index, MappingDictionary)
00868 return result
00869
00870 def GetSubentryInfos(self, index, subIndex):
00871 result = None
00872 mappings = self.GetMappingsGetMappings()
00873 i = 0
00874 while not result and i < len(mappings):
00875 result = FindSubentryInfos(index, subIndex, mappings[i])
00876 if result:
00877 result["user_defined"] = i == len(mappings) - 1 and index >= 0x1000
00878 i += 1
00879 if result == None:
00880 result = FindSubentryInfos(index, subIndex, MappingDictionary)
00881 if result:
00882 result["user_defined"] = False
00883 return result
00884
00885 def GetTypeIndex(self, typename):
00886 result = None
00887 mappings = self.GetMappingsGetMappings()
00888 i = 0
00889 while not result and i < len(mappings):
00890 result = FindTypeIndex(typename, mappings[i])
00891 i += 1
00892 if result == None:
00893 result = FindTypeIndex(typename, MappingDictionary)
00894 return result
00895
00896 def GetTypeName(self, typeindex):
00897 result = None
00898 mappings = self.GetMappingsGetMappings()
00899 i = 0
00900 while not result and i < len(mappings):
00901 result = FindTypeName(typeindex, mappings[i])
00902 i += 1
00903 if result == None:
00904 result = FindTypeName(typeindex, MappingDictionary)
00905 return result
00906
00907 def GetTypeDefaultValue(self, typeindex):
00908 result = None
00909 mappings = self.GetMappingsGetMappings()
00910 i = 0
00911 while not result and i < len(mappings):
00912 result = FindTypeDefaultValue(typeindex, mappings[i])
00913 i += 1
00914 if result == None:
00915 result = FindTypeDefaultValue(typeindex, MappingDictionary)
00916 return result
00917
00918 def GetMapVariableList(self):
00919 list = FindMapVariableList(MappingDictionary, self)
00920 for mapping in self.GetMappingsGetMappings():
00921 list.extend(FindMapVariableList(mapping, self))
00922 list.sort()
00923 return list
00924
00925 def GetMandatoryIndexes(self, node = None):
00926 list = FindMandatoryIndexes(MappingDictionary)
00927 for mapping in self.GetMappingsGetMappings():
00928 list.extend(FindMandatoryIndexes(mapping))
00929 return list
00930
00931 def GetCustomisableTypes(self):
00932 dic = {}
00933 for index, valuetype in CustomisableTypes:
00934 name = self.GetTypeNameGetTypeName(index)
00935 dic[index] = [name, valuetype]
00936 return dic
00937
00938
00939
00940
00941
00942 def GetTypeList(self):
00943 list = FindTypeList(MappingDictionary)
00944 for mapping in self.GetMappingsGetMappings():
00945 list.extend(FindTypeList(mapping))
00946 list.sort()
00947 return ",".join(list)
00948
00949 """
00950 Generate the list of variables that can be mapped for the current node
00951 """
00952 def GenerateMapList(self):
00953 self.MapListMapList = "None"
00954 self.NameTranslationNameTranslation = {"None" : "00000000"}
00955 self.MapTranslationMapTranslation = {"00000000" : "None"}
00956 list = self.GetMapVariableListGetMapVariableList()
00957 for index, subIndex, size, name in list:
00958 self.MapListMapList += ",%s"%name
00959 map = "%04X%02X%02X"%(index,subIndex,size)
00960 self.NameTranslationNameTranslation[name] = map
00961 self.MapTranslationMapTranslation[map] = name
00962
00963 def GetMapValue(self, mapname):
00964 if mapname == "None":
00965 return 0
00966 else:
00967 list = self.GetMapVariableListGetMapVariableList()
00968 for index, subIndex, size, name in list:
00969 if mapname == name:
00970 return (index << 16) + (subIndex << 8) + size
00971 return None
00972
00973 def GetMapName(self, value):
00974 if value != 0:
00975 index = value >> 16
00976 subindex = (value >> 8) % (1 << 8)
00977 result = self.GetSubentryInfosGetSubentryInfos(index, subindex)
00978 if result:
00979 return result["name"]
00980 return "None"
00981
00982 """
00983 Return the list of variables that can be mapped for the current node
00984 """
00985 def GetMapList(self):
00986 list = ["None"] + [name for index, subIndex, size, name in self.GetMapVariableListGetMapVariableList()]
00987 return ",".join(list)