etherlab/etherlab.py
changeset 2137 b65abacdbdf9
parent 2133 ba0b2ca7db26
child 2138 79dc2d15c580
equal deleted inserted replaced
2136:71fdfd4a12a3 2137:b65abacdbdf9
   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)
   244         
   254         
   245         if parent_library is not None:
   255         if parent_library is not None:
   246             self.LoadModules()
   256             self.LoadModules()
   247         else:
   257         else:
   248             self.Library = None
   258             self.Library = None
   249         self.LoadAlignments()
   259         self.LoadModulesExtraParams()
   250     
   260     
   251     def GetPath(self):
   261     def GetPath(self):
   252         return self.Path
   262         return self.Path
   253     
   263     
   254     def GetAlignmentFilePath(self):
   264     def GetModulesExtraParamsFilePath(self):
   255         return os.path.join(self.Path, "alignments.cfg")
   265         return os.path.join(self.Path, "modules_extra_params.cfg")
   256     
   266     
   257     def LoadModules(self):
   267     def LoadModules(self):
   258         self.Library = {}
   268         self.Library = {}
   259         
   269         
   260         files = os.listdir(self.Path)
   270         files = os.listdir(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