Added support for multiple module extra params in ModulesLibrary
authorLaurent Bessard
Fri, 26 Apr 2013 13:57:10 +0200
changeset 2137 b65abacdbdf9
parent 2136 71fdfd4a12a3
child 2138 79dc2d15c580
Added support for multiple module extra params in ModulesLibrary
etherlab/ConfigEditor.py
etherlab/EthercatCFileGenerator.py
etherlab/EthercatMaster.py
etherlab/etherlab.py
--- a/etherlab/ConfigEditor.py	Thu Apr 25 23:01:06 2013 +0200
+++ b/etherlab/ConfigEditor.py	Fri Apr 26 13:57:10 2013 +0200
@@ -984,10 +984,6 @@
                 maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
         event.Skip()
     
-def GetModulesTableColnames():
-    _ = lambda x : x
-    return [_("Name"), _("PDO alignment (bits)")]
-
 class LibraryEditorSizer(wx.FlexGridSizer):
     
     def __init__(self, parent, module_library, buttons):
@@ -1051,9 +1047,12 @@
         self.AddWindow(self.ModulesGrid, border=10, 
             flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
         
-        for colname, colsize, colalign in zip(GetModulesTableColnames(),
-                                              [400, 150],
-                                              [wx.ALIGN_LEFT, wx.ALIGN_RIGHT]):
+        for colname, colsize, colalign in zip(
+                [_("Name")] + [param_infos["column_label"] 
+                               for param, param_infos in 
+                               self.ModuleLibrary.MODULES_EXTRA_PARAMS],
+                [400] + [150] * len(self.ModuleLibrary.MODULES_EXTRA_PARAMS),
+                [wx.ALIGN_LEFT] + [wx.ALIGN_RIGHT] * len(self.ModuleLibrary.MODULES_EXTRA_PARAMS)):
             self.ModulesGrid.AddColumn(_(colname), colsize, colalign)
         self.ModulesGrid.SetMainColumn(0)
     
@@ -1089,7 +1088,10 @@
                 item = self.ModulesGrid.AppendItem(root, "")
             self.ModulesGrid.SetItemText(item, module["name"], 0)
             if module["infos"] is not None:
-                self.ModulesGrid.SetItemText(item, str(module["infos"]["alignment"]), 1)
+                for param_idx, (param, params_infos) in enumerate(self.ModuleLibrary.MODULES_EXTRA_PARAMS):
+                    self.ModulesGrid.SetItemText(item, 
+                                                 str(module["infos"][param]), 
+                                                 param_idx + 1)
             else:
                 self.ModulesGrid.SetItemBackgroundColour(item, wx.LIGHT_GREY)
             self.ModulesGrid.SetItemPyData(item, module["infos"])
@@ -1147,23 +1149,27 @@
         item, flags, col = self.ModulesGrid.HitTest(event.GetPosition())
         if item.IsOk():
             entry_infos = self.ModulesGrid.GetItemPyData(item)
-            if entry_infos is not None and col == 1:
+            if entry_infos is not None and col > 0:
+                param, param_infos = self.ModuleLibrary.MODULES_EXTRA_PARAMS[col - 1]
+                column_label = param_infos["column_label"]
+                stripped_column_label = column_label.split('(')[0].strip()
                 dialog = wx.TextEntryDialog(self.ParentWindow, 
-                    _("Set PDO alignment (bits):"),
-                    _("%s PDO alignment") % self.ModulesGrid.GetItemText(item), 
-                    str(entry_infos["alignment"]))
+                    _("Set %s:") % column_label,
+                    self.ModulesGrid.GetItemText(item) + " " + stripped_column_label, 
+                    str(entry_infos[param]))
                 
                 if dialog.ShowModal() == wx.ID_OK:
                     try:
-                        self.ModuleLibrary.SetAlignment(
+                        self.ModuleLibrary.SetModuleExtraParam(
                             entry_infos["vendor"],
                             entry_infos["product_code"],
                             entry_infos["revision_number"],
+                            param,
                             int(dialog.GetValue()))
                         wx.CallAfter(self.RefreshModulesGrid)
                     except ValueError:
                         message = wx.MessageDialog(self, 
-                            _("Module PDO alignment must be an integer!"), 
+                            _("Module %s must be an integer!") % stripped_column_label, 
                             _("Error"), wx.OK|wx.ICON_ERROR)
                         message.ShowModal()
                         message.Destroy()
--- a/etherlab/EthercatCFileGenerator.py	Thu Apr 25 23:01:06 2013 +0200
+++ b/etherlab/EthercatCFileGenerator.py	Fri Apr 26 13:57:10 2013 +0200
@@ -201,7 +201,7 @@
             slave_pos = (slave_alias, alias[slave_alias])
             
             # Extract slave device informations
-            device, alignment = self.Controler.GetModuleInfos(type_infos)
+            device, module_extra_params = self.Controler.GetModuleInfos(type_infos)
             if device is not None:
                 
                 # Extract slaves variables to be mapped
@@ -495,9 +495,9 @@
                                     dynamic_pdos[pdo_type]["pdos"].append(pdo)
                                 
                                 pdo["entries"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
-                                if entry_infos["bitlen"] < alignment:
-                                    print (alignment, entry_infos["bitlen"])
-                                    pdo["entries"].append("    {0x0000, 0x00, %d}, /* None */" % (alignment - entry_infos["bitlen"]))
+                                if entry_infos["bitlen"] < module_extra_params["pdo_alignment"]:
+                                    pdo["entries"].append("    {0x0000, 0x00, %d}, /* None */" % (
+                                            module_extra_params["pdo_alignment"] - entry_infos["bitlen"]))
                                 pdo["entries_number"] += 1
                                 
                                 if pdo["entries_number"] == 255:
--- a/etherlab/EthercatMaster.py	Thu Apr 25 23:01:06 2013 +0200
+++ b/etherlab/EthercatMaster.py	Fri Apr 26 13:57:10 2013 +0200
@@ -256,7 +256,7 @@
             "Ethercat Slave Type", self.GetSlaveTypesLibrary())
         if dialog.ShowModal() == wx.ID_OK:
             type_infos = dialog.GetValueInfos()
-            device, alignment = self.GetModuleInfos(type_infos)
+            device, module_extra_params = self.GetModuleInfos(type_infos)
             if device is not None:
                 if HAS_MCL and _EthercatCIA402SlaveCTN.NODE_PROFILE in device.GetProfileNumbers():
                     ConfNodeType = "EthercatCIA402Slave"
@@ -287,7 +287,7 @@
         type_infos = slave.getType()
         if vendor is not None and ExtractHexDecValue(type_infos["vendor"]) != vendor:
             return False
-        device, alignment = self.GetModuleInfos(type_infos)
+        device, module_extra_params = self.GetModuleInfos(type_infos)
         if slave_profile is not None and slave_profile not in device.GetProfileNumbers():
             return False
         return True
@@ -425,7 +425,7 @@
                         "product_code": slave["product_code"],
                         "revision_number":slave["revision_number"],
                     }
-                    device, alignment = self.GetModuleInfos(type_infos)
+                    device, module_extra_params = self.GetModuleInfos(type_infos)
                     if device is not None:
                         if HAS_MCL and _EthercatCIA402SlaveCTN.NODE_PROFILE in device.GetProfileNumbers():
                             CTNType = "EthercatCIA402Slave"
@@ -519,7 +519,7 @@
         slave = self.GetSlave(slave_pos)
         if slave is not None:
             type_infos = slave.getType()
-            device, alignment = self.GetModuleInfos(type_infos)
+            device, module_extra_params = self.GetModuleInfos(type_infos)
             if device is not None:
                 infos = type_infos.copy()
                 infos.update({"physics": device.getPhysics(),
@@ -533,7 +533,7 @@
             slave = self.GetSlave(slave_pos)
             if slave is not None:
                 type_infos = slave.getType()
-                device, alignment = self.GetModuleInfos(type_infos)
+                device, module_extra_params = self.GetModuleInfos(type_infos)
         if device is not None:
             entries = device.GetEntriesList(limits)
             entries_list = entries.items()
@@ -560,7 +560,7 @@
     def GetSlaveVariableDataType(self, slave_pos, index, subindex):
         slave = self.GetSlave(slave_pos)
         if slave is not None:
-            device, alignment = self.GetModuleInfos(slave.getType())
+            device, module_extra_params = self.GetModuleInfos(slave.getType())
             if device is not None:
                 entries = device.GetEntriesList()
                 entry_infos = entries.get((index, subindex))
@@ -577,7 +577,7 @@
             type_infos = slave.getType()
             if vendor is not None and ExtractHexDecValue(type_infos["vendor"]) != vendor:
                 continue
-            device, alignment = self.GetModuleInfos(type_infos)
+            device, module_extra_params = self.GetModuleInfos(type_infos)
             if slave_profile is not None and slave_profile not in device.GetProfileNumbers():
                 continue
             entries.extend(self.GetSlaveVariables(slave_position, limits, device))
@@ -598,7 +598,7 @@
         if slave is not None:
             type_infos = slave.getType()
         
-            device, alignment = self.GetModuleInfos(type_infos)
+            device, module_extra_params = self.GetModuleInfos(type_infos)
             if device is not None:
                 sync_managers = []
                 for sync_manager in device.getSm():
--- a/etherlab/etherlab.py	Thu Apr 25 23:01:06 2013 +0200
+++ b/etherlab/etherlab.py	Fri Apr 26 13:57:10 2013 +0200
@@ -232,9 +232,19 @@
                         "Access": access,
                         "PDOMapping": pdomapping}
 
-DEFAULT_ALIGNMENT = 8
-
 class ModulesLibrary:
+
+    MODULES_EXTRA_PARAMS = [
+        ("pdo_alignment", {
+            "column_label": _("PDO alignment (bits)"), 
+            "default": 8}),
+        ("max_pdo_size", {
+            "column_label": _("Max entries by PDO (-1=unbounded)"), 
+            "default": -1}),
+        ("add_pdo", {
+            "column_label": _("Creating new PDO (1=possible)"), 
+            "default": 0})
+    ]
     
     def __init__(self, path, parent_library=None):
         self.Path = path
@@ -246,13 +256,13 @@
             self.LoadModules()
         else:
             self.Library = None
-        self.LoadAlignments()
+        self.LoadModulesExtraParams()
     
     def GetPath(self):
         return self.Path
     
-    def GetAlignmentFilePath(self):
-        return os.path.join(self.Path, "alignments.cfg")
+    def GetModulesExtraParamsFilePath(self):
+        return os.path.join(self.Path, "modules_extra_params.cfg")
     
     def LoadModules(self):
         self.Library = {}
@@ -310,14 +320,14 @@
                     if profile_filter is None or profile_filter in device.GetProfileNumbers():
                         product_code = device.getType().getProductCode()
                         revision_number = device.getType().getRevisionNo()
-                        alignment = self.GetAlignment(vendor_id, product_code, revision_number)
+                        module_infos = {"device_type": device_type,
+                                        "vendor": vendor_id,
+                                        "product_code": product_code,
+                                        "revision_number": revision_number}
+                        module_infos.update(self.GetModuleExtraParams(vendor_id, product_code, revision_number))
                         device_infos = {"name": ExtractName(device.getName()),
                                         "type": ETHERCAT_DEVICE,
-                                        "infos": {"device_type": device_type,
-                                                  "vendor": vendor_id,
-                                                  "product_code": product_code,
-                                                  "revision_number": revision_number,
-                                                  "alignment": alignment},
+                                        "infos": module_infos,
                                         "children": []}
                         group_infos["children"].append(device_infos)
                         device_type_occurrences = device_dict.setdefault(device_type, [])
@@ -353,7 +363,7 @@
                     revision_number = ExtractHexDecValue(device_infos.getType().getRevisionNo())
                     if (product_code == ExtractHexDecValue(module_infos["product_code"]) and
                         revision_number == ExtractHexDecValue(module_infos["revision_number"])):
-                        return device_infos, self.GetAlignment(vendor, product_code, revision_number)
+                        return device_infos, self.GetModuleExtraParams(vendor, product_code, revision_number)
         return None, None
     
     def ImportModuleLibrary(self, filepath):
@@ -363,10 +373,10 @@
             return True
         return False
     
-    def LoadAlignments(self):
-        self.Alignments = {}
-        
-        csvfile_path = self.GetAlignmentFilePath()
+    def LoadModulesExtraParams(self):
+        self.ModulesExtraParams = {}
+        
+        csvfile_path = self.GetModulesExtraParamsFilePath()
         if os.path.exists(csvfile_path):
             csvfile = open(csvfile_path, "rb")
             sample = csvfile.read(1024)
@@ -379,39 +389,48 @@
                     has_header = False
                 else:
                     try:
-                        self.Alignments[tuple(map(int, row[:3]))] = int(row[3])
+                        self.ModulesExtraParams[tuple(map(int, row[:3]))] = dict(
+                            zip([param for param, params_infos in self.MODULES_EXTRA_PARAMS], 
+                                int(row[3])))
                     except:
                         pass
             csvfile.close()
-        
-    def SaveAlignments(self):
-        csvfile = open(self.GetAlignmentFilePath(), "wb")
+    
+    def SaveModulesExtraParams(self):
+        csvfile = open(self.GetModulesExtraParamsFilePath(), "wb")
+        extra_params = [param for param, params_infos in self.MODULES_EXTRA_PARAMS]
         writer = csv.writer(csvfile, delimiter=';')
-        writer.writerow(['Vendor', 'product_code', 'revision_number', 'alignment'])
-        for (vendor, product_code, revision_number), alignment in self.Alignments.iteritems():
-            writer.writerow([vendor, product_code, revision_number, alignment])
+        writer.writerow(['Vendor', 'product_code', 'revision_number'] + extra_params)
+        for (vendor, product_code, revision_number), module_extra_params in self.ModulesExtraParams.iteritems():
+            writer.writerow([vendor, product_code, revision_number] + 
+                            [module_extra_params.get(param, '') 
+                             for param in extra_params])
         csvfile.close()
     
-    def SetAlignment(self, vendor, product_code, revision_number, alignment):
+    def SetModuleExtraParam(self, vendor, product_code, revision_number, param, value):
         vendor = ExtractHexDecValue(vendor)
         product_code = ExtractHexDecValue(product_code)
         revision_number = ExtractHexDecValue(revision_number)
         
-        self.Alignments[tuple([vendor, product_code, revision_number])] = alignment
-        self.SaveAlignments()
-    
-    def GetAlignment(self, vendor, product_code, revision_number):
+        self.ModulesExtraParams[tuple([vendor, product_code, revision_number])][param] = value
+        self.SaveModulesExtraParams()
+    
+    def GetModuleExtraParams(self, vendor, product_code, revision_number):
         vendor = ExtractHexDecValue(vendor)
         product_code = ExtractHexDecValue(product_code)
         revision_number = ExtractHexDecValue(revision_number)
         
-        alignment = self.Alignments.get(tuple([vendor, product_code, revision_number]))
-        if alignment is not None:
-            return alignment
-        
         if self.ParentLibrary is not None:
-            return self.ParentLibrary.GetAlignment(vendor, product_code, revision_number)
-        return DEFAULT_ALIGNMENT
+            extra_params = self.ParentLibrary.GetModuleExtraParams(vendor, product_code, revision_number)
+        else:
+            extra_params = {}
+        
+        extra_params.update(self.ModulesExtraParams.get(tuple([vendor, product_code, revision_number]), {}))
+        
+        for param, param_infos in self.MODULES_EXTRA_PARAMS:
+            extra_params.setdefault(param, param_infos["default"])
+        
+        return extra_params
 
 USERDATA_DIR = wx.StandardPaths.Get().GetUserDataDir()
 if wx.Platform != '__WXMSW__':