54 |
54 |
55 class EntryListFactory: |
55 class EntryListFactory: |
56 |
56 |
57 def __init__(self, entries): |
57 def __init__(self, entries): |
58 self.Entries = entries |
58 self.Entries = entries |
59 |
59 |
60 def AddEntry(self, context, *args): |
60 def AddEntry(self, context, *args): |
61 index, subindex = map(lambda x: int(x[0]), args[:2]) |
61 index, subindex = map(lambda x: int(x[0]), args[:2]) |
62 new_entry_infos = { |
62 new_entry_infos = { |
63 key: translate(arg[0]) if len(arg) > 0 else default |
63 key: translate(arg[0]) if len(arg) > 0 else default |
64 for (key, translate, default), arg |
64 for (key, translate, default), arg |
65 in zip(ENTRY_INFOS_KEYS, args)} |
65 in zip(ENTRY_INFOS_KEYS, args)} |
66 |
66 |
67 if (index, subindex) != (0, 0): |
67 if (index, subindex) != (0, 0): |
68 entry_infos = self.Entries.get((index, subindex)) |
68 entry_infos = self.Entries.get((index, subindex)) |
69 if entry_infos is not None: |
69 if entry_infos is not None: |
70 for param in ["PDO index", "PDO name", "PDO type"]: |
70 for param in ["PDO index", "PDO name", "PDO type"]: |
71 value = new_entry_infos.get(param) |
71 value = new_entry_infos.get(param) |
77 entries_list_xslt = etree.parse( |
77 entries_list_xslt = etree.parse( |
78 os.path.join(ScriptDirectory, "entries_list.xslt")) |
78 os.path.join(ScriptDirectory, "entries_list.xslt")) |
79 |
79 |
80 cls = EtherCATInfoParser.GetElementClass("DeviceType") |
80 cls = EtherCATInfoParser.GetElementClass("DeviceType") |
81 if cls: |
81 if cls: |
82 |
82 |
83 profile_numbers_xpath = EtherCATInfo_XPath("Profile/ProfileNo") |
83 profile_numbers_xpath = EtherCATInfo_XPath("Profile/ProfileNo") |
84 def GetProfileNumbers(self): |
84 def GetProfileNumbers(self): |
85 return [number.text for number in profile_numbers_xpath(self)] |
85 return [number.text for number in profile_numbers_xpath(self)] |
86 setattr(cls, "GetProfileNumbers", GetProfileNumbers) |
86 setattr(cls, "GetProfileNumbers", GetProfileNumbers) |
87 |
87 |
88 def getCoE(self): |
88 def getCoE(self): |
89 mailbox = self.getMailbox() |
89 mailbox = self.getMailbox() |
90 if mailbox is not None: |
90 if mailbox is not None: |
91 return mailbox.getCoE() |
91 return mailbox.getCoE() |
92 return None |
92 return None |
93 setattr(cls, "getCoE", getCoE) |
93 setattr(cls, "getCoE", getCoE) |
94 |
94 |
95 def GetEntriesList(self, limits=None): |
95 def GetEntriesList(self, limits=None): |
96 entries = {} |
96 entries = {} |
97 |
97 |
98 factory = EntryListFactory(entries) |
98 factory = EntryListFactory(entries) |
99 |
99 |
100 entries_list_xslt_tree = etree.XSLT( |
100 entries_list_xslt_tree = etree.XSLT( |
101 entries_list_xslt, extensions = { |
101 entries_list_xslt, extensions = { |
102 ("entries_list_ns", "AddEntry"): factory.AddEntry, |
102 ("entries_list_ns", "AddEntry"): factory.AddEntry, |
103 ("entries_list_ns", "HexDecValue"): HexDecValue, |
103 ("entries_list_ns", "HexDecValue"): HexDecValue, |
104 ("entries_list_ns", "EntryName"): EntryName}) |
104 ("entries_list_ns", "EntryName"): EntryName}) |
105 entries_list_xslt_tree(self, **dict(zip( |
105 entries_list_xslt_tree(self, **dict(zip( |
106 ["min_index", "max_index"], |
106 ["min_index", "max_index"], |
107 map(lambda x: etree.XSLT.strparam(str(x)), |
107 map(lambda x: etree.XSLT.strparam(str(x)), |
108 limits if limits is not None else [0x0000, 0xFFFF]) |
108 limits if limits is not None else [0x0000, 0xFFFF]) |
109 ))) |
109 ))) |
110 |
110 |
111 return entries |
111 return entries |
112 setattr(cls, "GetEntriesList", GetEntriesList) |
112 setattr(cls, "GetEntriesList", GetEntriesList) |
113 |
113 |
114 def GetSyncManagers(self): |
114 def GetSyncManagers(self): |
115 sync_managers = [] |
115 sync_managers = [] |
158 "default": 255, |
158 "default": 255, |
159 "description": _( |
159 "description": _( |
160 """Maximal number of entries mapped in a PDO |
160 """Maximal number of entries mapped in a PDO |
161 including empty entries used for PDO alignment""")}), |
161 including empty entries used for PDO alignment""")}), |
162 ("add_pdo", { |
162 ("add_pdo", { |
163 "column_label": _("Creating new PDO"), |
163 "column_label": _("Creating new PDO"), |
164 "column_size": 150, |
164 "column_size": 150, |
165 "default": 0, |
165 "default": 0, |
166 "description": _( |
166 "description": _( |
167 """Adding a PDO not defined in default configuration |
167 """Adding a PDO not defined in default configuration |
168 for mapping needed location variables |
168 for mapping needed location variables |
169 (1 if possible)""")}) |
169 (1 if possible)""")}) |
170 ] |
170 ] |
171 |
171 |
172 def __init__(self, path, parent_library=None): |
172 def __init__(self, path, parent_library=None): |
173 self.Path = path |
173 self.Path = path |
174 if not os.path.exists(self.Path): |
174 if not os.path.exists(self.Path): |
175 os.makedirs(self.Path) |
175 os.makedirs(self.Path) |
176 self.ParentLibrary = parent_library |
176 self.ParentLibrary = parent_library |
177 |
177 |
178 if parent_library is not None: |
178 if parent_library is not None: |
179 self.LoadModules() |
179 self.LoadModules() |
180 else: |
180 else: |
181 self.Library = None |
181 self.Library = None |
182 self.LoadModulesExtraParams() |
182 self.LoadModulesExtraParams() |
183 |
183 |
184 def GetPath(self): |
184 def GetPath(self): |
185 return self.Path |
185 return self.Path |
186 |
186 |
187 def GetModulesExtraParamsFilePath(self): |
187 def GetModulesExtraParamsFilePath(self): |
188 return os.path.join(self.Path, "modules_extra_params.cfg") |
188 return os.path.join(self.Path, "modules_extra_params.cfg") |
189 |
189 |
190 groups_xpath = EtherCATInfo_XPath("Descriptions/Groups/Group") |
190 groups_xpath = EtherCATInfo_XPath("Descriptions/Groups/Group") |
191 devices_xpath = EtherCATInfo_XPath("Descriptions/Devices/Device") |
191 devices_xpath = EtherCATInfo_XPath("Descriptions/Devices/Device") |
192 def LoadModules(self): |
192 def LoadModules(self): |
193 self.Library = {} |
193 self.Library = {} |
194 |
194 |
195 files = os.listdir(self.Path) |
195 files = os.listdir(self.Path) |
196 for file in files: |
196 for file in files: |
197 filepath = os.path.join(self.Path, file) |
197 filepath = os.path.join(self.Path, file) |
198 if os.path.isfile(filepath) and os.path.splitext(filepath)[-1] == ".xml": |
198 if os.path.isfile(filepath) and os.path.splitext(filepath)[-1] == ".xml": |
199 self.modules_infos = None |
199 self.modules_infos = None |
200 |
200 |
201 xmlfile = open(filepath, 'r') |
201 xmlfile = open(filepath, 'r') |
202 try: |
202 try: |
203 self.modules_infos, error = EtherCATInfoParser.LoadXMLString(xmlfile.read()) |
203 self.modules_infos, error = EtherCATInfoParser.LoadXMLString(xmlfile.read()) |
204 if error is not None: |
204 if error is not None: |
205 self.GetCTRoot().logger.write_warning( |
205 self.GetCTRoot().logger.write_warning( |
206 XSDSchemaErrorMessage % (filepath + error)) |
206 XSDSchemaErrorMessage % (filepath + error)) |
207 except Exception, exc: |
207 except Exception, exc: |
208 self.modules_infos, error = None, unicode(exc) |
208 self.modules_infos, error = None, unicode(exc) |
209 xmlfile.close() |
209 xmlfile.close() |
210 |
210 |
211 if self.modules_infos is not None: |
211 if self.modules_infos is not None: |
212 vendor = self.modules_infos.getVendor() |
212 vendor = self.modules_infos.getVendor() |
213 |
213 |
214 vendor_category = self.Library.setdefault( |
214 vendor_category = self.Library.setdefault( |
215 ExtractHexDecValue(vendor.getId()), |
215 ExtractHexDecValue(vendor.getId()), |
216 {"name": ExtractName(vendor.getName(), _("Miscellaneous")), |
216 {"name": ExtractName(vendor.getName(), _("Miscellaneous")), |
217 "groups": {}}) |
217 "groups": {}}) |
218 |
218 |
219 for group in self.groups_xpath(self.modules_infos): |
219 for group in self.groups_xpath(self.modules_infos): |
220 group_type = group.getType() |
220 group_type = group.getType() |
221 |
221 |
222 vendor_category["groups"].setdefault(group_type, |
222 vendor_category["groups"].setdefault(group_type, |
223 {"name": ExtractName(group.getName(), group_type), |
223 {"name": ExtractName(group.getName(), group_type), |
224 "parent": group.getParentGroup(), |
224 "parent": group.getParentGroup(), |
225 "order": group.getSortOrder(), |
225 "order": group.getSortOrder(), |
226 #"value": group.getcontent()["value"], |
226 #"value": group.getcontent()["value"], |
227 "devices": []}) |
227 "devices": []}) |
228 |
228 |
229 for device in self.devices_xpath(self.modules_infos): |
229 for device in self.devices_xpath(self.modules_infos): |
230 device_group = device.getGroupType() |
230 device_group = device.getGroupType() |
231 if not vendor_category["groups"].has_key(device_group): |
231 if not vendor_category["groups"].has_key(device_group): |
232 raise ValueError, "Not such group \"%\"" % device_group |
232 raise ValueError, "Not such group \"%\"" % device_group |
233 vendor_category["groups"][device_group]["devices"].append( |
233 vendor_category["groups"][device_group]["devices"].append( |
234 (device.getType().getcontent(), device)) |
234 (device.getType().getcontent(), device)) |
235 |
235 |
236 else: |
236 else: |
237 |
237 |
238 self.GetCTRoot().logger.write_error( |
238 self.GetCTRoot().logger.write_error( |
239 _("Couldn't load %s XML file:\n%s") % (filepath, error)) |
239 _("Couldn't load %s XML file:\n%s") % (filepath, error)) |
240 |
240 |
241 return self.Library |
241 return self.Library |
242 |
242 |
243 def GetModulesLibrary(self, profile_filter=None): |
243 def GetModulesLibrary(self, profile_filter=None): |
244 if self.Library is None: |
244 if self.Library is None: |
245 self.LoadModules() |
245 self.LoadModules() |
288 library.sort(lambda x, y: cmp(x["name"], y["name"])) |
288 library.sort(lambda x, y: cmp(x["name"], y["name"])) |
289 return library |
289 return library |
290 |
290 |
291 def GetVendors(self): |
291 def GetVendors(self): |
292 return [(vendor_id, vendor["name"]) for vendor_id, vendor in self.Library.items()] |
292 return [(vendor_id, vendor["name"]) for vendor_id, vendor in self.Library.items()] |
293 |
293 |
294 def GetModuleInfos(self, module_infos): |
294 def GetModuleInfos(self, module_infos): |
295 vendor = ExtractHexDecValue(module_infos["vendor"]) |
295 vendor = ExtractHexDecValue(module_infos["vendor"]) |
296 vendor_infos = self.Library.get(vendor) |
296 vendor_infos = self.Library.get(vendor) |
297 if vendor_infos is not None: |
297 if vendor_infos is not None: |
298 for group_name, group_infos in vendor_infos["groups"].iteritems(): |
298 for group_name, group_infos in vendor_infos["groups"].iteritems(): |
299 for device_type, device_infos in group_infos["devices"]: |
299 for device_type, device_infos in group_infos["devices"]: |
300 product_code = ExtractHexDecValue(device_infos.getType().getProductCode()) |
300 product_code = ExtractHexDecValue(device_infos.getType().getProductCode()) |
301 revision_number = ExtractHexDecValue(device_infos.getType().getRevisionNo()) |
301 revision_number = ExtractHexDecValue(device_infos.getType().getRevisionNo()) |
302 if (product_code == ExtractHexDecValue(module_infos["product_code"]) and |
302 if (product_code == ExtractHexDecValue(module_infos["product_code"]) and |
303 revision_number == ExtractHexDecValue(module_infos["revision_number"])): |
303 revision_number == ExtractHexDecValue(module_infos["revision_number"])): |
304 self.cntdevice = device_infos |
304 self.cntdevice = device_infos |
305 self.cntdeviceType = device_type |
305 self.cntdeviceType = device_type |
306 return device_infos, self.GetModuleExtraParams(vendor, product_code, revision_number) |
306 return device_infos, self.GetModuleExtraParams(vendor, product_code, revision_number) |
307 return None, None |
307 return None, None |
308 |
308 |
309 def ImportModuleLibrary(self, filepath): |
309 def ImportModuleLibrary(self, filepath): |
310 if os.path.isfile(filepath): |
310 if os.path.isfile(filepath): |
311 shutil.copy(filepath, self.Path) |
311 shutil.copy(filepath, self.Path) |
312 self.LoadModules() |
312 self.LoadModules() |
313 return True |
313 return True |
314 return False |
314 return False |
315 |
315 |
316 def LoadModulesExtraParams(self): |
316 def LoadModulesExtraParams(self): |
317 self.ModulesExtraParams = {} |
317 self.ModulesExtraParams = {} |
318 |
318 |
319 csvfile_path = self.GetModulesExtraParamsFilePath() |
319 csvfile_path = self.GetModulesExtraParamsFilePath() |
320 if os.path.exists(csvfile_path): |
320 if os.path.exists(csvfile_path): |
321 csvfile = open(csvfile_path, "rb") |
321 csvfile = open(csvfile_path, "rb") |
322 sample = csvfile.read(1024) |
322 sample = csvfile.read(1024) |
323 csvfile.seek(0) |
323 csvfile.seek(0) |
334 if value != "": |
334 if value != "": |
335 params_values[param] = int(value) |
335 params_values[param] = int(value) |
336 self.ModulesExtraParams[ |
336 self.ModulesExtraParams[ |
337 tuple(map(int, row[:3]))] = params_values |
337 tuple(map(int, row[:3]))] = params_values |
338 csvfile.close() |
338 csvfile.close() |
339 |
339 |
340 def SaveModulesExtraParams(self): |
340 def SaveModulesExtraParams(self): |
341 csvfile = open(self.GetModulesExtraParamsFilePath(), "wb") |
341 csvfile = open(self.GetModulesExtraParamsFilePath(), "wb") |
342 extra_params = [param for param, params_infos in self.MODULES_EXTRA_PARAMS] |
342 extra_params = [param for param, params_infos in self.MODULES_EXTRA_PARAMS] |
343 writer = csv.writer(csvfile, delimiter=';') |
343 writer = csv.writer(csvfile, delimiter=';') |
344 writer.writerow(['Vendor', 'product_code', 'revision_number'] + extra_params) |
344 writer.writerow(['Vendor', 'product_code', 'revision_number'] + extra_params) |
345 for (vendor, product_code, revision_number), module_extra_params in self.ModulesExtraParams.iteritems(): |
345 for (vendor, product_code, revision_number), module_extra_params in self.ModulesExtraParams.iteritems(): |
346 writer.writerow([vendor, product_code, revision_number] + |
346 writer.writerow([vendor, product_code, revision_number] + |
347 [module_extra_params.get(param, '') |
347 [module_extra_params.get(param, '') |
348 for param in extra_params]) |
348 for param in extra_params]) |
349 csvfile.close() |
349 csvfile.close() |
350 |
350 |
351 def SetModuleExtraParam(self, vendor, product_code, revision_number, param, value): |
351 def SetModuleExtraParam(self, vendor, product_code, revision_number, param, value): |
352 vendor = ExtractHexDecValue(vendor) |
352 vendor = ExtractHexDecValue(vendor) |
353 product_code = ExtractHexDecValue(product_code) |
353 product_code = ExtractHexDecValue(product_code) |
354 revision_number = ExtractHexDecValue(revision_number) |
354 revision_number = ExtractHexDecValue(revision_number) |
355 |
355 |
356 module_infos = (vendor, product_code, revision_number) |
356 module_infos = (vendor, product_code, revision_number) |
357 self.ModulesExtraParams.setdefault(module_infos, {}) |
357 self.ModulesExtraParams.setdefault(module_infos, {}) |
358 self.ModulesExtraParams[module_infos][param] = value |
358 self.ModulesExtraParams[module_infos][param] = value |
359 |
359 |
360 self.SaveModulesExtraParams() |
360 self.SaveModulesExtraParams() |
361 |
361 |
362 def GetModuleExtraParams(self, vendor, product_code, revision_number): |
362 def GetModuleExtraParams(self, vendor, product_code, revision_number): |
363 vendor = ExtractHexDecValue(vendor) |
363 vendor = ExtractHexDecValue(vendor) |
364 product_code = ExtractHexDecValue(product_code) |
364 product_code = ExtractHexDecValue(product_code) |
365 revision_number = ExtractHexDecValue(revision_number) |
365 revision_number = ExtractHexDecValue(revision_number) |
366 |
366 |
367 if self.ParentLibrary is not None: |
367 if self.ParentLibrary is not None: |
368 extra_params = self.ParentLibrary.GetModuleExtraParams(vendor, product_code, revision_number) |
368 extra_params = self.ParentLibrary.GetModuleExtraParams(vendor, product_code, revision_number) |
369 else: |
369 else: |
370 extra_params = {} |
370 extra_params = {} |
371 |
371 |
372 extra_params.update(self.ModulesExtraParams.get((vendor, product_code, revision_number), {})) |
372 extra_params.update(self.ModulesExtraParams.get((vendor, product_code, revision_number), {})) |
373 |
373 |
374 for param, param_infos in self.MODULES_EXTRA_PARAMS: |
374 for param, param_infos in self.MODULES_EXTRA_PARAMS: |
375 extra_params.setdefault(param, param_infos["default"]) |
375 extra_params.setdefault(param, param_infos["default"]) |
376 |
376 |
377 return extra_params |
377 return extra_params |
378 |
378 |
379 USERDATA_DIR = wx.StandardPaths.Get().GetUserDataDir() |
379 USERDATA_DIR = wx.StandardPaths.Get().GetUserDataDir() |
380 if wx.Platform != '__WXMSW__': |
380 if wx.Platform != '__WXMSW__': |
381 USERDATA_DIR += '_files' |
381 USERDATA_DIR += '_files' |
382 |
382 |
383 ModulesDatabase = ModulesLibrary( |
383 ModulesDatabase = ModulesLibrary( |
384 os.path.join(USERDATA_DIR, "ethercat_modules")) |
384 os.path.join(USERDATA_DIR, "ethercat_modules")) |
385 |
385 |
386 class RootClass: |
386 class RootClass: |
387 |
387 |
388 CTNChildrenTypes = [("EthercatNode",_EthercatCTN,"Ethercat Master")] |
388 CTNChildrenTypes = [("EthercatNode",_EthercatCTN,"Ethercat Master")] |
389 EditorType = LibraryEditor |
389 EditorType = LibraryEditor |
390 |
390 |
391 |
391 |
392 def __init__(self): |
392 def __init__(self): |
393 self.ModulesLibrary = None |
393 self.ModulesLibrary = None |
394 self.LoadModulesLibrary() |
394 self.LoadModulesLibrary() |
395 |
395 |
396 def GetIconName(self): |
396 def GetIconName(self): |
397 return "Ethercat" |
397 return "Ethercat" |
398 |
398 |
399 def GetModulesLibraryPath(self, project_path=None): |
399 def GetModulesLibraryPath(self, project_path=None): |
400 if project_path is None: |
400 if project_path is None: |
401 project_path = self.CTNPath() |
401 project_path = self.CTNPath() |
402 return os.path.join(project_path, "modules") |
402 return os.path.join(project_path, "modules") |
403 |
403 |
404 def OnCTNSave(self, from_project_path=None): |
404 def OnCTNSave(self, from_project_path=None): |
405 if from_project_path is not None: |
405 if from_project_path is not None: |
406 shutil.copytree(self.GetModulesLibraryPath(from_project_path), |
406 shutil.copytree(self.GetModulesLibraryPath(from_project_path), |
407 self.GetModulesLibraryPath()) |
407 self.GetModulesLibraryPath()) |
408 return True |
408 return True |
409 |
409 |
410 def CTNGenerate_C(self, buildpath, locations): |
410 def CTNGenerate_C(self, buildpath, locations): |
411 return [],"",False |
411 return [],"",False |
412 |
412 |
413 def LoadModulesLibrary(self): |
413 def LoadModulesLibrary(self): |
414 if self.ModulesLibrary is None: |
414 if self.ModulesLibrary is None: |
415 self.ModulesLibrary = ModulesLibrary(self.GetModulesLibraryPath(), ModulesDatabase) |
415 self.ModulesLibrary = ModulesLibrary(self.GetModulesLibraryPath(), ModulesDatabase) |
416 else: |
416 else: |
417 self.ModulesLibrary.LoadModulesLibrary() |
417 self.ModulesLibrary.LoadModulesLibrary() |
418 |
418 |
419 def GetModulesDatabaseInstance(self): |
419 def GetModulesDatabaseInstance(self): |
420 return ModulesDatabase |
420 return ModulesDatabase |
421 |
421 |
422 def GetModulesLibraryInstance(self): |
422 def GetModulesLibraryInstance(self): |
423 return self.ModulesLibrary |
423 return self.ModulesLibrary |
424 |
424 |
425 def GetModulesLibrary(self, profile_filter=None): |
425 def GetModulesLibrary(self, profile_filter=None): |
426 return self.ModulesLibrary.GetModulesLibrary(profile_filter) |
426 return self.ModulesLibrary.GetModulesLibrary(profile_filter) |
427 |
427 |
428 def GetVendors(self): |
428 def GetVendors(self): |
429 return self.ModulesLibrary.GetVendors() |
429 return self.ModulesLibrary.GetVendors() |
430 |
430 |
431 def GetModuleInfos(self, module_infos): |
431 def GetModuleInfos(self, module_infos): |
432 return self.ModulesLibrary.GetModuleInfos(module_infos) |
432 return self.ModulesLibrary.GetModuleInfos(module_infos) |
433 |
|