57 ("PDOMapping", str, ""), |
64 ("PDOMapping", str, ""), |
58 ("PDO index", str, ""), |
65 ("PDO index", str, ""), |
59 ("PDO name", str, ""), |
66 ("PDO name", str, ""), |
60 ("PDO type", str, "")] |
67 ("PDO type", str, "")] |
61 |
68 |
|
69 # Read DefaultValue from ESI file |
|
70 # Add by jblee 151229 |
|
71 ENTRY_INFOS_KEYS_FOR_DV = [ |
|
72 ("Index", lambda x: "#x%4.4X" % int(x), "#x0000"), |
|
73 ("SubIndex", str, "0"), |
|
74 ("Name", str, ""), |
|
75 ("Type", str, ""), |
|
76 ("BitSize", int, 0), |
|
77 ("Access", str, ""), |
|
78 ("PDOMapping", str, ""), |
|
79 ("DefaultValue", str, ""), |
|
80 ("Sub_entry_flag", str, "0")] |
62 |
81 |
63 class EntryListFactory(object): |
82 class EntryListFactory(object): |
64 |
83 |
65 def __init__(self, entries): |
84 def __init__(self, entries): |
66 self.Entries = entries |
85 self.Entries = entries |
67 |
86 |
68 def AddEntry(self, context, *args): |
87 def AddEntry(self, context, *args): |
69 index, subindex = map(lambda x: int(x[0]), args[:2]) |
88 index, subindex = map(lambda x: int(x[0]), args[:2]) |
70 new_entry_infos = { |
89 if len(args) > 9: |
|
90 new_entry_infos = { |
71 key: translate(arg[0]) if len(arg) > 0 else default |
91 key: translate(arg[0]) if len(arg) > 0 else default |
72 for (key, translate, default), arg |
92 for (key, translate, default), arg |
73 in zip(ENTRY_INFOS_KEYS, args)} |
93 in zip(ENTRY_INFOS_KEYS, args)} |
74 |
94 else: |
|
95 new_entry_infos = { |
|
96 key: translate(arg[0]) if len(arg) > 0 else default |
|
97 for (key, translate, default), arg |
|
98 in zip(ENTRY_INFOS_KEYS_FOR_DV, args)} |
|
99 |
75 if (index, subindex) != (0, 0): |
100 if (index, subindex) != (0, 0): |
76 entry_infos = self.Entries.get((index, subindex)) |
101 entry_infos = self.Entries.get((index, subindex)) |
77 if entry_infos is not None: |
102 if entry_infos is not None: |
78 for param in ["PDO index", "PDO name", "PDO type"]: |
103 for param in ["PDO index", "PDO name", "PDO type"]: |
79 value = new_entry_infos.get(param) |
104 value = new_entry_infos.get(param) |
100 if mailbox is not None: |
126 if mailbox is not None: |
101 return mailbox.getCoE() |
127 return mailbox.getCoE() |
102 return None |
128 return None |
103 setattr(cls, "getCoE", getCoE) |
129 setattr(cls, "getCoE", getCoE) |
104 |
130 |
|
131 # Modify by jblee |
|
132 def ExtractDataTypes(self): |
|
133 #self.DataTypes = {} |
|
134 #self.DT = {} |
|
135 DT = {} |
|
136 objects = [] |
|
137 |
|
138 # get Profile Field |
|
139 for profile in self.getProfile(): |
|
140 # get each (ProfileNo, Dictionary) Field as child |
|
141 for child in profile.getchildren(): |
|
142 # child.text is not None -> ProfileNo, is None -> Dictionary |
|
143 if child.text is None: |
|
144 # get each (DataTypes, Objects) Field |
|
145 dataTypes = child.getDataTypes() |
|
146 objects = child.getObjects() |
|
147 |
|
148 for dataType in dataTypes.getDataType(): |
|
149 #if dataType.getName() is not None: |
|
150 # print dataType.getName(), dataType |
|
151 DT[dataType.getName()] = dataType |
|
152 |
|
153 return DT, objects |
|
154 setattr(cls, "ExtractDataTypes", ExtractDataTypes) |
|
155 |
105 def GetEntriesList(self, limits=None): |
156 def GetEntriesList(self, limits=None): |
|
157 DataTypes, objects = self.ExtractDataTypes() |
|
158 |
106 entries = {} |
159 entries = {} |
107 |
160 |
108 factory = EntryListFactory(entries) |
161 # get each Object Field |
109 |
162 for object in objects: |
110 entries_list_xslt_tree = etree.XSLT( |
163 # Object Field mendatory : Index, Name, Type, BitSize |
111 entries_list_xslt, extensions={ |
164 # Frequently Use : Info, Flags |
112 ("entries_list_ns", "AddEntry"): factory.AddEntry, |
165 # Info Field -> DefaultData, SubItem |
113 ("entries_list_ns", "HexDecValue"): HexDecValue, |
166 # Flags Field -> Access, Category, PdoMapping |
114 ("entries_list_ns", "EntryName"): EntryName}) |
167 object_index = object.getIndex().getcontent() |
115 entries_list_xslt_tree(self, **dict(zip( |
168 index = ExtractHexDecValue(object_index) |
116 ["min_index", "max_index"], |
169 if limits is None or limits[0] <= index <= limits[1]: |
117 map(lambda x: etree.XSLT.strparam(str(x)), |
170 object_type = object.getType() |
118 limits if limits is not None else [0x0000, 0xFFFF]) |
171 object_name = ExtractName(object.getName()) |
119 ))) |
172 object_size = object.getBitSize() |
120 |
173 defaultData = "" |
|
174 object_access = "" |
|
175 object_PDOMapping_data = "" |
|
176 |
|
177 object_type_infos = DataTypes.get(object_type, None) |
|
178 subItem_infos = object_type_infos.getchildren() |
|
179 countSubIndex = 0 |
|
180 if len(subItem_infos) > 2: |
|
181 for subItem_info in subItem_infos: |
|
182 if subItem_info.tag == "SubItem" : |
|
183 subItemName = subItem_info.getName() |
|
184 subIdx = subItem_info.getSubIdx() |
|
185 if subIdx is not None: |
|
186 object_subidx = ExtractHexDecValue(subIdx) |
|
187 else: |
|
188 object_subidx = ExtractHexDecValue(countSubIndex) |
|
189 subType = subItem_info.getType() |
|
190 subBitSize = subItem_info.getBitSize() |
|
191 subFlags = subItem_info.getFlags() |
|
192 subAccess = "" |
|
193 subPDOMapping_data = "" |
|
194 if subFlags is not None: |
|
195 subAccess = subFlags.getAccess().getcontent() |
|
196 subPDOMapping = subFlags.getPdoMapping() |
|
197 if subPDOMapping is not None: |
|
198 subPDOMapping_data = subFlags.getPdoMapping().upper() |
|
199 |
|
200 entries[(index, object_subidx)] = { |
|
201 "Index": object_index, |
|
202 "SubIndex": subIdx, |
|
203 "Name": "%s - %s" % |
|
204 (object_name.decode("utf-8"), |
|
205 subItemName.decode("utf-8")), |
|
206 "Type": subType, |
|
207 "BitSize": subBitSize, |
|
208 "Access": subAccess, |
|
209 "PDOMapping": subPDOMapping_data} |
|
210 |
|
211 countSubIndex += 1 |
|
212 |
|
213 info = object.getInfo() |
|
214 # subItemTest : check subItem |
|
215 countSubIndex = 0 |
|
216 if info is not None: |
|
217 subItems = info.getchildren() |
|
218 if len(subItems) > 1: |
|
219 for subItem in subItems: |
|
220 defaultdata_subidx = ExtractHexDecValue(countSubIndex) |
|
221 defaultData = subItem.getchildren()[1].findtext("DefaultData") |
|
222 entry = entries.get((index, defaultdata_subidx), None) |
|
223 if entry is not None: |
|
224 entry["DefaultData"] = defaultData |
|
225 countSubIndex += 1 |
|
226 |
|
227 else : |
|
228 info = object.getInfo() |
|
229 if info is not None: |
|
230 subItems = info.getchildren() |
|
231 if len(subItems) <= 1: |
|
232 defaultData = subItems[0].text |
|
233 |
|
234 object_flag = object.getFlags() |
|
235 object_access = object_flag.getAccess().getcontent() |
|
236 object_PDOMapping = object_flag.getPdoMapping() |
|
237 if object_PDOMapping is not None: |
|
238 object_PDOMapping_data = object_flag.getPdoMapping().upper() |
|
239 entries[(index, 0)] = { |
|
240 "Index": object_index, |
|
241 "SubIndex": "0", |
|
242 "Name": object_name, |
|
243 "Type": object_type, |
|
244 "BitSize": object_size, |
|
245 "DefaultData" : defaultData, |
|
246 "Access": object_access, |
|
247 "PDOMapping": object_PDOMapping_data} |
|
248 |
|
249 for TxPdo in self.getTxPdo(): |
|
250 ExtractPdoInfos(TxPdo, "Transmit", entries, limits) |
|
251 for RxPdo in self.getRxPdo(): |
|
252 ExtractPdoInfos(RxPdo, "Receive", entries, limits) |
|
253 |
121 return entries |
254 return entries |
122 setattr(cls, "GetEntriesList", GetEntriesList) |
255 setattr(cls, "GetEntriesList", GetEntriesList) |
|
256 |
|
257 # def GetEntriesList(self, limits=None): |
|
258 # entries = {} |
|
259 |
|
260 # factory = EntryListFactory(entries) |
|
261 |
|
262 # entries_list_xslt_tree = etree.XSLT( |
|
263 # entries_list_xslt, extensions = { |
|
264 # ("entries_list_ns", "AddEntry"): factory.AddEntry, |
|
265 # ("entries_list_ns", "HexDecValue"): HexDecValue, |
|
266 # ("entries_list_ns", "EntryName"): EntryName}) |
|
267 # entries_list_xslt_tree(self, **dict(zip( |
|
268 # ["min_index", "max_index"], |
|
269 # map(lambda x: etree.XSLT.strparam(str(x)), |
|
270 # limits if limits is not None else [0x0000, 0xFFFF]) |
|
271 # ))) |
|
272 # |
|
273 # return entries |
|
274 # setattr(cls, "GetEntriesList", GetEntriesList) |
123 |
275 |
124 def GetSyncManagers(self): |
276 def GetSyncManagers(self): |
125 sync_managers = [] |
277 sync_managers = [] |
126 for sync_manager in self.getSm(): |
278 for sync_manager in self.getSm(): |
127 sync_manager_infos = {} |
279 sync_manager_infos = {} |
153 for item in group["children"]: |
305 for item in group["children"]: |
154 if item["type"] == ETHERCAT_GROUP: |
306 if item["type"] == ETHERCAT_GROUP: |
155 SortGroupItems(item) |
307 SortGroupItems(item) |
156 group["children"].sort(GroupItemCompare) |
308 group["children"].sort(GroupItemCompare) |
157 |
309 |
|
310 def ExtractPdoInfos(pdo, pdo_type, entries, limits=None): |
|
311 pdo_index = pdo.getIndex().getcontent() |
|
312 pdo_name = ExtractName(pdo.getName()) |
|
313 exclude = pdo.getExclude() |
|
314 for pdo_entry in pdo.getEntry(): |
|
315 entry_index = pdo_entry.getIndex().getcontent() |
|
316 entry_subindex = pdo_entry.getSubIndex() |
|
317 index = ExtractHexDecValue(entry_index) |
|
318 subindex = ExtractHexDecValue(entry_subindex) |
|
319 object_size = pdo_entry.getBitLen() |
|
320 |
|
321 if limits is None or limits[0] <= index <= limits[1]: |
|
322 entry = entries.get((index, subindex), None) |
|
323 if entry is not None: |
|
324 entry["PDO index"] = pdo_index |
|
325 entry["PDO name"] = pdo_name |
|
326 entry["PDO type"] = pdo_type |
|
327 else: |
|
328 entry_type = pdo_entry.getDataType() |
|
329 if entry_type is not None: |
|
330 if pdo_type == "Transmit": |
|
331 access = "ro" |
|
332 pdomapping = "T" |
|
333 else: |
|
334 access = "wo" |
|
335 pdomapping = "R" |
|
336 entries[(index, subindex)] = { |
|
337 "Index": entry_index, |
|
338 "SubIndex": entry_subindex, |
|
339 "Name": ExtractName(pdo_entry.getName()), |
|
340 "Type": entry_type.getcontent(), |
|
341 "BitSize": object_size, |
|
342 "Access": access, |
|
343 "PDOMapping": pdomapping} |
158 |
344 |
159 class ModulesLibrary(object): |
345 class ModulesLibrary(object): |
160 |
346 |
161 MODULES_EXTRA_PARAMS = [ |
347 MODULES_EXTRA_PARAMS = [ |
162 ( |
348 ( |
209 def GetModulesExtraParamsFilePath(self): |
395 def GetModulesExtraParamsFilePath(self): |
210 return os.path.join(self.Path, "modules_extra_params.cfg") |
396 return os.path.join(self.Path, "modules_extra_params.cfg") |
211 |
397 |
212 groups_xpath = EtherCATInfo_XPath("Descriptions/Groups/Group") |
398 groups_xpath = EtherCATInfo_XPath("Descriptions/Groups/Group") |
213 devices_xpath = EtherCATInfo_XPath("Descriptions/Devices/Device") |
399 devices_xpath = EtherCATInfo_XPath("Descriptions/Devices/Device") |
|
400 module_xpath = EtherCATBase_XPath("Descriptions/Modules/Module") |
214 |
401 |
215 def LoadModules(self): |
402 def LoadModules(self): |
216 self.Library = {} |
403 self.Library = {} |
217 |
404 # add by jblee for Modular Device Profile |
|
405 self.MDPList = [] |
|
406 self.ModuleList = [] |
|
407 self.MDPEntryList = {} |
|
408 dtDic = {} |
|
409 self.idxIncrement = 0 |
|
410 self.slotIncrement = 0 |
|
411 # add by jblee for PDO Mapping |
|
412 self.DataTypes = {} |
|
413 self.ObjectDictionary = {} |
|
414 |
218 files = os.listdir(self.Path) |
415 files = os.listdir(self.Path) |
219 for file in files: |
416 for file in files: |
220 filepath = os.path.join(self.Path, file) |
417 filepath = os.path.join(self.Path, file) |
221 if os.path.isfile(filepath) and os.path.splitext(filepath)[-1] == ".xml": |
418 if os.path.isfile(filepath) and os.path.splitext(filepath)[-1] == ".xml": |
222 self.modules_infos = None |
419 self.modules_infos = None |
223 |
420 |
224 xmlfile = open(filepath, 'r') |
421 xmlfile = open(filepath, 'r') |
225 try: |
422 try: |
226 self.modules_infos, error = EtherCATInfoParser.LoadXMLString(xmlfile.read()) |
423 self.modules_infos, error = EtherCATInfoParser.LoadXMLString(xmlfile.read()) |
227 if error is not None: |
424 # if error is not None: |
228 self.GetCTRoot().logger.write_warning( |
425 # self.GetCTRoot().logger.write_warning( |
229 XSDSchemaErrorMessage % (filepath + error)) |
426 # XSDSchemaErrorMessage % (filepath + error)) |
230 except Exception as exc: |
427 except Exception as exc: |
231 self.modules_infos, error = None, text(exc) |
428 self.modules_infos, error = None, text(exc) |
232 xmlfile.close() |
429 xmlfile.close() |
233 |
430 |
234 if self.modules_infos is not None: |
431 if self.modules_infos is not None: |
239 {"name": ExtractName(vendor.getName(), _("Miscellaneous")), |
436 {"name": ExtractName(vendor.getName(), _("Miscellaneous")), |
240 "groups": {}}) |
437 "groups": {}}) |
241 |
438 |
242 for group in self.groups_xpath(self.modules_infos): |
439 for group in self.groups_xpath(self.modules_infos): |
243 group_type = group.getType() |
440 group_type = group.getType() |
|
441 # add for XmlToEeprom Func by jblee. |
|
442 self.LcId_data = group.getchildren()[1] |
|
443 self.Image16x14_data = group.getchildren()[2] |
244 |
444 |
245 vendor_category["groups"].setdefault( |
445 vendor_category["groups"].setdefault( |
246 group_type, |
446 group_type, |
247 { |
447 { |
248 "name": ExtractName(group.getName(), group_type), |
448 "name": ExtractName(group.getName(), group_type), |
249 "parent": group.getParentGroup(), |
449 "parent": group.getParentGroup(), |
250 "order": group.getSortOrder(), |
450 "order": group.getSortOrder(), |
251 # "value": group.getcontent()["value"], |
|
252 "devices": [], |
451 "devices": [], |
|
452 # add jblee for support Moduler Device Profile (MDP) |
|
453 "modules": []}) |
253 }) |
454 }) |
254 |
455 |
255 for device in self.devices_xpath(self.modules_infos): |
456 for device in self.devices_xpath(self.modules_infos): |
256 device_group = device.getGroupType() |
457 device_group = device.getGroupType() |
257 if device_group not in vendor_category["groups"]: |
458 if device_group not in vendor_category["groups"]: |
258 raise ValueError("Not such group \"%s\"" % device_group) |
459 raise ValueError("Not such group \"%s\"" % device_group) |
259 vendor_category["groups"][device_group]["devices"].append( |
460 vendor_category["groups"][device_group]["devices"].append( |
260 (device.getType().getcontent(), device)) |
461 (device.getType().getcontent(), device)) |
261 |
462 |
262 else: |
463 # ------------------ Test Section --------------------# |
263 |
464 slots = device.getSlots() |
264 self.GetCTRoot().logger.write_error( |
465 if slots is not None: |
265 _("Couldn't load {a1} XML file:\n{a2}").format(a1=filepath, a2=error)) |
466 for slot in slots.getSlot(): |
|
467 self.idxIncrement = slot.getSlotIndexIncrement() |
|
468 self.slotIncrement = slot.getSlotPdoIncrement() |
|
469 for child in slot.getchildren(): |
|
470 if child.tag == "ModuleClass": |
|
471 child_class = child.getClass() |
|
472 child_name = child.getName() |
|
473 |
|
474 # -------------------- Test Section ----------------------------------# |
|
475 LocalMDPList = [] |
|
476 for module in self.module_xpath(self.modules_infos): |
|
477 module_type = module.getType().getModuleClass() |
|
478 module_name = module.getName() |
|
479 LocalMDPData = ExtractName(module_name) + " (" + module_type + ")" |
|
480 |
|
481 self.ModuleList.append(module) |
|
482 try : |
|
483 module_pdos = module.getTxPdo() |
|
484 module_pdos += module.getRxPdo() |
|
485 for module_pdo in module_pdos: |
|
486 device_name = ExtractName(module_name) |
|
487 pdo_index = module_pdo.getIndex().getcontent() |
|
488 pdo_name = ExtractName(module_pdo.getName()) |
|
489 pdo_entry = module_pdo.getEntry() |
|
490 if module_pdo.tag == "TxPdo": |
|
491 mapping_type = "T" |
|
492 else : |
|
493 mapping_type = "R" |
|
494 |
|
495 LocalMDPEntry = [] |
|
496 for entry in pdo_entry: |
|
497 entry_index = entry.getIndex().getcontent() |
|
498 entry_subidx = entry.getSubIndex() |
|
499 entry_name = ExtractName(entry.getName()) |
|
500 entry_bitsize = entry.getBitLen() |
|
501 try : |
|
502 entry_type = entry.getDataType().getcontent() |
|
503 except : |
|
504 entry_type = "" |
|
505 |
|
506 LocalMDPEntry.append({ |
|
507 "Index": entry_index, |
|
508 "SubIndex": entry_subidx, |
|
509 "Name": "%s - %s" % (pdo_name, entry_name), |
|
510 "Type": entry_type, |
|
511 "BitSize": entry_bitsize, |
|
512 "Access": "", |
|
513 "PDOMapping": mapping_type}) |
|
514 |
|
515 self.MDPEntryList[device_name] = LocalMDPEntry |
|
516 |
|
517 LocalMDPList.append([LocalMDPData, module, LocalMDPEntry]) |
|
518 except : |
|
519 LocalMDPList.append([LocalMDPData, module, []]) |
|
520 |
|
521 if LocalMDPList: |
|
522 vendor_category["groups"][device_group]["modules"].append( |
|
523 (device.getType().getcontent(), LocalMDPList, self.idxIncrement, self.slotIncrement)) |
|
524 #self.MDPList.append([device.getType().getcontent(), LocalMDPList, |
|
525 # self.idxIncrement, self.slotIncrement]) |
|
526 |
|
527 # --------------------------------------------------------------------- # |
|
528 |
|
529 # else: |
|
530 # self.GetCTRoot().logger.write_error( |
|
531 # _("Couldn't load {a1} XML file:\n{a2}").format(a1=filepath, a2=error)) |
266 |
532 |
267 return self.Library |
533 return self.Library |
268 |
534 |
|
535 # add jblee |
|
536 def GetMDPList(self): |
|
537 return self.MDPList |
|
538 |
|
539 # add jblee |
|
540 def GetSelectModule(self, idx): |
|
541 return self.ModuleList[idx] |
|
542 |
|
543 # add jblee |
|
544 def GetModuleEntryList(self): |
|
545 return self.MDPEntryList |
|
546 |
|
547 # add jblee |
|
548 def GetModuleIncrement(self): |
|
549 return (self.idxIncrement, self.slotIncrement) |
|
550 |
|
551 # add jblee |
|
552 #def GetEntriesList(self): |
|
553 # return self.ObjectDictionary |
|
554 |
269 def GetModulesLibrary(self, profile_filter=None): |
555 def GetModulesLibrary(self, profile_filter=None): |
270 if self.Library is None: |
556 if self.Library is None: |
271 self.LoadModules() |
557 self.LoadModules() |
272 library = [] |
558 library = [] |
273 for vendor_id, vendor in self.Library.iteritems(): |
559 for vendor_id, vendor in self.Library.iteritems(): |
330 self.cntdevice = device_infos |
616 self.cntdevice = device_infos |
331 self.cntdeviceType = device_type |
617 self.cntdeviceType = device_type |
332 return device_infos, self.GetModuleExtraParams(vendor, product_code, revision_number) |
618 return device_infos, self.GetModuleExtraParams(vendor, product_code, revision_number) |
333 return None, None |
619 return None, None |
334 |
620 |
|
621 # add jblee for MDP |
|
622 def GetMDPInfos(self, module_infos): |
|
623 vendor = ExtractHexDecValue(module_infos["vendor"]) |
|
624 vendor_infos = self.Library.get(vendor) |
|
625 if vendor_infos is not None: |
|
626 for group_name, group_infos in vendor_infos["groups"].iteritems(): |
|
627 return group_infos["modules"] |
|
628 #for device_type, module_list, idx_inc, slot_inc in group_infos["modules"]: |
|
629 # return module_list, idx_inc, slot_inc |
|
630 |
|
631 #return None, None, None |
|
632 |
335 def ImportModuleLibrary(self, filepath): |
633 def ImportModuleLibrary(self, filepath): |
336 if os.path.isfile(filepath): |
634 if os.path.isfile(filepath): |
337 shutil.copy(filepath, self.Path) |
635 shutil.copy(filepath, self.Path) |
338 self.LoadModules() |
636 self.LoadModules() |
339 return True |
637 return True |