230 "Name": ExtractName(pdo_entry.getName()), |
230 "Name": ExtractName(pdo_entry.getName()), |
231 "Type": entry_type.getcontent(), |
231 "Type": entry_type.getcontent(), |
232 "Access": access, |
232 "Access": access, |
233 "PDOMapping": pdomapping} |
233 "PDOMapping": pdomapping} |
234 |
234 |
235 DEFAULT_ALIGNMENT = 8 |
|
236 |
|
237 class ModulesLibrary: |
235 class ModulesLibrary: |
|
236 |
|
237 MODULES_EXTRA_PARAMS = [ |
|
238 ("pdo_alignment", { |
|
239 "column_label": _("PDO alignment (bits)"), |
|
240 "default": 8}), |
|
241 ("max_pdo_size", { |
|
242 "column_label": _("Max entries by PDO (-1=unbounded)"), |
|
243 "default": -1}), |
|
244 ("add_pdo", { |
|
245 "column_label": _("Creating new PDO (1=possible)"), |
|
246 "default": 0}) |
|
247 ] |
238 |
248 |
239 def __init__(self, path, parent_library=None): |
249 def __init__(self, path, parent_library=None): |
240 self.Path = path |
250 self.Path = path |
241 if not os.path.exists(self.Path): |
251 if not os.path.exists(self.Path): |
242 os.makedirs(self.Path) |
252 os.makedirs(self.Path) |
308 device_dict = {} |
318 device_dict = {} |
309 for device_type, device in group["devices"]: |
319 for device_type, device in group["devices"]: |
310 if profile_filter is None or profile_filter in device.GetProfileNumbers(): |
320 if profile_filter is None or profile_filter in device.GetProfileNumbers(): |
311 product_code = device.getType().getProductCode() |
321 product_code = device.getType().getProductCode() |
312 revision_number = device.getType().getRevisionNo() |
322 revision_number = device.getType().getRevisionNo() |
313 alignment = self.GetAlignment(vendor_id, product_code, revision_number) |
323 module_infos = {"device_type": device_type, |
|
324 "vendor": vendor_id, |
|
325 "product_code": product_code, |
|
326 "revision_number": revision_number} |
|
327 module_infos.update(self.GetModuleExtraParams(vendor_id, product_code, revision_number)) |
314 device_infos = {"name": ExtractName(device.getName()), |
328 device_infos = {"name": ExtractName(device.getName()), |
315 "type": ETHERCAT_DEVICE, |
329 "type": ETHERCAT_DEVICE, |
316 "infos": {"device_type": device_type, |
330 "infos": module_infos, |
317 "vendor": vendor_id, |
|
318 "product_code": product_code, |
|
319 "revision_number": revision_number, |
|
320 "alignment": alignment}, |
|
321 "children": []} |
331 "children": []} |
322 group_infos["children"].append(device_infos) |
332 group_infos["children"].append(device_infos) |
323 device_type_occurrences = device_dict.setdefault(device_type, []) |
333 device_type_occurrences = device_dict.setdefault(device_type, []) |
324 device_type_occurrences.append(device_infos) |
334 device_type_occurrences.append(device_infos) |
325 for device_type_occurrences in device_dict.itervalues(): |
335 for device_type_occurrences in device_dict.itervalues(): |
351 for device_type, device_infos in group_infos["devices"]: |
361 for device_type, device_infos in group_infos["devices"]: |
352 product_code = ExtractHexDecValue(device_infos.getType().getProductCode()) |
362 product_code = ExtractHexDecValue(device_infos.getType().getProductCode()) |
353 revision_number = ExtractHexDecValue(device_infos.getType().getRevisionNo()) |
363 revision_number = ExtractHexDecValue(device_infos.getType().getRevisionNo()) |
354 if (product_code == ExtractHexDecValue(module_infos["product_code"]) and |
364 if (product_code == ExtractHexDecValue(module_infos["product_code"]) and |
355 revision_number == ExtractHexDecValue(module_infos["revision_number"])): |
365 revision_number == ExtractHexDecValue(module_infos["revision_number"])): |
356 return device_infos, self.GetAlignment(vendor, product_code, revision_number) |
366 return device_infos, self.GetModuleExtraParams(vendor, product_code, revision_number) |
357 return None, None |
367 return None, None |
358 |
368 |
359 def ImportModuleLibrary(self, filepath): |
369 def ImportModuleLibrary(self, filepath): |
360 if os.path.isfile(filepath): |
370 if os.path.isfile(filepath): |
361 shutil.copy(filepath, self.Path) |
371 shutil.copy(filepath, self.Path) |
362 self.LoadModules() |
372 self.LoadModules() |
363 return True |
373 return True |
364 return False |
374 return False |
365 |
375 |
366 def LoadAlignments(self): |
376 def LoadModulesExtraParams(self): |
367 self.Alignments = {} |
377 self.ModulesExtraParams = {} |
368 |
378 |
369 csvfile_path = self.GetAlignmentFilePath() |
379 csvfile_path = self.GetModulesExtraParamsFilePath() |
370 if os.path.exists(csvfile_path): |
380 if os.path.exists(csvfile_path): |
371 csvfile = open(csvfile_path, "rb") |
381 csvfile = open(csvfile_path, "rb") |
372 sample = csvfile.read(1024) |
382 sample = csvfile.read(1024) |
373 csvfile.seek(0) |
383 csvfile.seek(0) |
374 dialect = csv.Sniffer().sniff(sample) |
384 dialect = csv.Sniffer().sniff(sample) |
377 for row in reader: |
387 for row in reader: |
378 if has_header: |
388 if has_header: |
379 has_header = False |
389 has_header = False |
380 else: |
390 else: |
381 try: |
391 try: |
382 self.Alignments[tuple(map(int, row[:3]))] = int(row[3]) |
392 self.ModulesExtraParams[tuple(map(int, row[:3]))] = dict( |
|
393 zip([param for param, params_infos in self.MODULES_EXTRA_PARAMS], |
|
394 int(row[3]))) |
383 except: |
395 except: |
384 pass |
396 pass |
385 csvfile.close() |
397 csvfile.close() |
386 |
398 |
387 def SaveAlignments(self): |
399 def SaveModulesExtraParams(self): |
388 csvfile = open(self.GetAlignmentFilePath(), "wb") |
400 csvfile = open(self.GetModulesExtraParamsFilePath(), "wb") |
|
401 extra_params = [param for param, params_infos in self.MODULES_EXTRA_PARAMS] |
389 writer = csv.writer(csvfile, delimiter=';') |
402 writer = csv.writer(csvfile, delimiter=';') |
390 writer.writerow(['Vendor', 'product_code', 'revision_number', 'alignment']) |
403 writer.writerow(['Vendor', 'product_code', 'revision_number'] + extra_params) |
391 for (vendor, product_code, revision_number), alignment in self.Alignments.iteritems(): |
404 for (vendor, product_code, revision_number), module_extra_params in self.ModulesExtraParams.iteritems(): |
392 writer.writerow([vendor, product_code, revision_number, alignment]) |
405 writer.writerow([vendor, product_code, revision_number] + |
|
406 [module_extra_params.get(param, '') |
|
407 for param in extra_params]) |
393 csvfile.close() |
408 csvfile.close() |
394 |
409 |
395 def SetAlignment(self, vendor, product_code, revision_number, alignment): |
410 def SetModuleExtraParam(self, vendor, product_code, revision_number, param, value): |
396 vendor = ExtractHexDecValue(vendor) |
411 vendor = ExtractHexDecValue(vendor) |
397 product_code = ExtractHexDecValue(product_code) |
412 product_code = ExtractHexDecValue(product_code) |
398 revision_number = ExtractHexDecValue(revision_number) |
413 revision_number = ExtractHexDecValue(revision_number) |
399 |
414 |
400 self.Alignments[tuple([vendor, product_code, revision_number])] = alignment |
415 self.ModulesExtraParams[tuple([vendor, product_code, revision_number])][param] = value |
401 self.SaveAlignments() |
416 self.SaveModulesExtraParams() |
402 |
417 |
403 def GetAlignment(self, vendor, product_code, revision_number): |
418 def GetModuleExtraParams(self, vendor, product_code, revision_number): |
404 vendor = ExtractHexDecValue(vendor) |
419 vendor = ExtractHexDecValue(vendor) |
405 product_code = ExtractHexDecValue(product_code) |
420 product_code = ExtractHexDecValue(product_code) |
406 revision_number = ExtractHexDecValue(revision_number) |
421 revision_number = ExtractHexDecValue(revision_number) |
407 |
422 |
408 alignment = self.Alignments.get(tuple([vendor, product_code, revision_number])) |
|
409 if alignment is not None: |
|
410 return alignment |
|
411 |
|
412 if self.ParentLibrary is not None: |
423 if self.ParentLibrary is not None: |
413 return self.ParentLibrary.GetAlignment(vendor, product_code, revision_number) |
424 extra_params = self.ParentLibrary.GetModuleExtraParams(vendor, product_code, revision_number) |
414 return DEFAULT_ALIGNMENT |
425 else: |
|
426 extra_params = {} |
|
427 |
|
428 extra_params.update(self.ModulesExtraParams.get(tuple([vendor, product_code, revision_number]), {})) |
|
429 |
|
430 for param, param_infos in self.MODULES_EXTRA_PARAMS: |
|
431 extra_params.setdefault(param, param_infos["default"]) |
|
432 |
|
433 return extra_params |
415 |
434 |
416 USERDATA_DIR = wx.StandardPaths.Get().GetUserDataDir() |
435 USERDATA_DIR = wx.StandardPaths.Get().GetUserDataDir() |
417 if wx.Platform != '__WXMSW__': |
436 if wx.Platform != '__WXMSW__': |
418 USERDATA_DIR += '_files' |
437 USERDATA_DIR += '_files' |
419 |
438 |