etherlab/etherlab.py
changeset 2023 f9f884cf3033
parent 2022 c2295d311402
child 2026 65ecbfe9a6f9
equal deleted inserted replaced
2022:c2295d311402 2023:f9f884cf3033
     3 from xml.dom import minidom
     3 from xml.dom import minidom
     4 
     4 
     5 import wx
     5 import wx
     6 
     6 
     7 from xmlclass import *
     7 from xmlclass import *
     8 from PLCControler import UndoBuffer
     8 from PLCControler import UndoBuffer, LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
     9 from ConfigEditor import ConfigEditor, ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE
     9 from ConfigEditor import ConfigEditor, ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE
    10 
    10 
    11 TYPECONVERSION = {"BOOL" : "X", "SINT" : "B", "INT" : "W", "DINT" : "D", "LINT" : "L",
    11 TYPECONVERSION = {"BOOL" : "X", "SINT" : "B", "INT" : "W", "DINT" : "D", "LINT" : "L",
    12     "USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L", 
    12     "USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L", 
    13     "BYTE" : "B", "WORD" : "W", "DWORD" : "D", "LWORD" : "L"}
    13     "BYTE" : "B", "WORD" : "W", "DWORD" : "D", "LWORD" : "L"}
    80           <xsd:attribute name="ConfigurePDOs" type="xsd:boolean" use="optional" default="true"/>
    80           <xsd:attribute name="ConfigurePDOs" type="xsd:boolean" use="optional" default="true"/>
    81         </xsd:complexType>
    81         </xsd:complexType>
    82       </xsd:element>
    82       </xsd:element>
    83     </xsd:schema>
    83     </xsd:schema>
    84     """
    84     """
       
    85     EditorType = ConfigEditor
    85     
    86     
    86     def __init__(self):
    87     def __init__(self):
    87         filepath = self.ConfigFileName()
    88         filepath = self.ConfigFileName()
    88         
    89         
    89         self.Config = EtherCATConfigClasses["EtherCATConfig"]()
    90         self.Config = EtherCATConfigClasses["EtherCATConfig"]()
   184             type_infos = slave.getType()
   185             type_infos = slave.getType()
   185             device = self.GetModuleInfos(type_infos)
   186             device = self.GetModuleInfos(type_infos)
   186             if device is not None:
   187             if device is not None:
   187                 infos = type_infos.copy()
   188                 infos = type_infos.copy()
   188                 infos.update({"physics": device.getPhysics(),
   189                 infos.update({"physics": device.getPhysics(),
   189                               "pdos": [],
       
   190                               "variables": []})
   190                               "variables": []})
   191                 for TxPdo in device.getTxPdo():
   191                 for TxPdo in device.getTxPdo():
   192                     ExtractPdoInfos(TxPdo, "Transmit", infos)
   192                     ExtractPdoInfos(TxPdo, "Transmit", infos)
   193                 for RxPdo in device.getRxPdo():
   193                 for RxPdo in device.getRxPdo():
   194                     ExtractPdoInfos(RxPdo, "Receive", infos)
   194                     ExtractPdoInfos(RxPdo, "Receive", infos)
   199         return self.PlugParent.GetModuleInfos(type_infos)
   199         return self.PlugParent.GetModuleInfos(type_infos)
   200     
   200     
   201     def GetSlaveTypesLibrary(self):
   201     def GetSlaveTypesLibrary(self):
   202         return self.PlugParent.GetModulesLibrary()
   202         return self.PlugParent.GetModulesLibrary()
   203     
   203     
   204     def _OpenView(self):
   204     def GetVariableLocationTree(self):
   205         app_frame = self.GetPlugRoot().AppFrame
   205         '''See PlugTemplate.GetVariableLocationTree() for a description.'''
   206         
   206 
   207         configeditor = ConfigEditor(app_frame.TabsOpened, self, app_frame)
   207         current_location = self.GetCurrentLocation()
   208         
   208         
   209         app_frame.EditProjectElement(configeditor, self.GetFilename())
   209         groups = []
       
   210         for slave_pos in self.GetSlaves():
       
   211             
       
   212             slave = self.GetSlave(slave_pos)
       
   213             if slave is not None:
       
   214                 type_infos = slave.getType()
   210                 
   215                 
       
   216                 device = self.GetModuleInfos(type_infos)
       
   217                 if device is not None:
       
   218                     vars = []
       
   219                     
       
   220                     sync_managers = []
       
   221                     for sync_manager in device.getSm():
       
   222                         sync_manager_control_byte = ExtractHexDecValue(sync_manager.getControlByte())
       
   223                         sync_manager_direction = sync_manager_control_byte & 0x0c
       
   224                         if sync_manager_direction:
       
   225                             sync_managers.append(LOCATION_VAR_OUTPUT)
       
   226                         else:
       
   227                             sync_managers.append(LOCATION_VAR_INPUT)
       
   228                     
       
   229                     for pdo in device.getTxPdo() + device.getRxPdo():
       
   230                         var_class = sync_managers[pdo.getSm()]
       
   231                         
       
   232                         for entry in pdo.getEntry():
       
   233                             index = ExtractHexDecValue(entry.getIndex().getcontent())
       
   234                             subindex = ExtractHexDecValue(entry.getSubIndex())
       
   235                             var_type = entry.getDataType().getcontent()
       
   236                             var_size = self.GetSizeOfType(var_type)
       
   237                             if var_class == LOCATION_VAR_INPUT:
       
   238                                 var_dir = "%I"
       
   239                             else:
       
   240                                 var_dir = "%Q"    
       
   241                             
       
   242                             vars.append({"name": "%s - %s" % (ExtractName(pdo.getName()), ExtractName(entry.getName())),
       
   243                                          "type": var_class,
       
   244                                          "size": var_size,
       
   245                                          "IEC_type": var_type,
       
   246                                          "location": "%s%s%s"%(var_dir, var_size, ".".join(map(str, current_location + 
       
   247                                                                                                     slave_pos + 
       
   248                                                                                                     (index, subindex)))),
       
   249                                          "description": "",
       
   250                                          "children": []})
       
   251                     
       
   252                     groups.append({"name": "%s (%d,%d)" % ((type_infos["device_type"],) + slave_pos),
       
   253                                    "type": LOCATION_GROUP,
       
   254                                    "location": ".".join(map(str, current_location + slave_pos)) + ".x",
       
   255                                    "children": vars})
       
   256                 
       
   257         return  {"name": self.BaseParams.getName(),
       
   258                  "type": LOCATION_PLUGIN,
       
   259                  "location": self.GetFullIEC_Channel(),
       
   260                  "children": groups}
       
   261     
   211     PluginMethods = [
   262     PluginMethods = [
   212         {"bitmap" : os.path.join("images", "EditCfile"),
   263         {"bitmap" : os.path.join("images", "EditCfile"),
   213          "name" : _("Edit Config"), 
   264          "name" : _("Edit Config"), 
   214          "tooltip" : _("Edit Config"),
   265          "tooltip" : _("Edit Config"),
   215          "method" : "_OpenView"},
   266          "method" : "_OpenView"},
   379             slave = self.Controler.GetSlave(slave_pos)
   430             slave = self.Controler.GetSlave(slave_pos)
   380             if slave is not None:
   431             if slave is not None:
   381                 type_infos = slave.getType()
   432                 type_infos = slave.getType()
   382                 
   433                 
   383                 device = self.Controler.GetModuleInfos(type_infos)
   434                 device = self.Controler.GetModuleInfos(type_infos)
   384                 if device is not None:                
   435                 if device is not None:
   385                     
   436                     
   386                     pdos = device.getTxPdo() + device.getRxPdo()
   437                     pdos = device.getTxPdo() + device.getRxPdo()
   387                     if len(pdos) > 0:
   438                     if len(pdos) > 0:
   388                         slave_variables = self.UsedVariables.get(slave_pos, {})
   439                         slave_variables = self.UsedVariables.get(slave_pos, {})
   389                         
   440                         
   423                             
   474                             
   424                             sync_managers.append(sync_manager_infos)
   475                             sync_managers.append(sync_manager_infos)
   425                         
   476                         
   426                         entry_offset = 0
   477                         entry_offset = 0
   427                         for pdo in pdos:
   478                         for pdo in pdos:
   428                             sync_managers[pdo.getSm()]["pdos_number"] += 1
       
   429                             entries = pdo.getEntry()
   479                             entries = pdo.getEntry()
   430                             
   480                             
   431                             pdo_infos = {
   481                             pdo_needed = pdo.getMandatory()
   432                                 "slave": slave_idx,
   482                             entries_infos = []
   433                                 "index": ExtractHexDecValue(pdo.getIndex().getcontent()),
       
   434                                 "name": ExtractName(pdo.getName()),
       
   435                                 "offset": entry_offset,
       
   436                                 "entries_number": len(entries)
       
   437                             }
       
   438                             pdos_infos["pdos_infos"].append("    {0x%(index).4x, %(entries_number)d, slave_%(slave)d_pdo_entries + %(offset)d}, /* %(name)s */" % pdo_infos)
       
   439                             entry_offset += len(entries)
       
   440                             
   483                             
   441                             for entry in pdo.getEntry():
   484                             for entry in entries:
   442                                 index = ExtractHexDecValue(entry.getIndex().getcontent())
   485                                 index = ExtractHexDecValue(entry.getIndex().getcontent())
   443                                 subindex = ExtractHexDecValue(entry.getSubIndex())
   486                                 subindex = ExtractHexDecValue(entry.getSubIndex())
   444                                 entry_infos = {
   487                                 entry_infos = {
   445                                     "index": index,
   488                                     "index": index,
   446                                     "subindex": subindex,
   489                                     "subindex": subindex,
   447                                     "name": ExtractName(entry.getName()),
   490                                     "name": ExtractName(entry.getName()),
   448                                     "bitlen": entry.getBitLen(),
   491                                     "bitlen": entry.getBitLen(),
   449                                 }
   492                                 }
   450                                 entry_infos.update(type_infos)
   493                                 entry_infos.update(type_infos)
   451                                 pdos_infos["pdos_entries_infos"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
   494                                 entries_infos.append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
   452                                 
   495                                 
   453                                 entry_declaration = slave_variables.get((index, subindex), None)
   496                                 entry_declaration = slave_variables.get((index, subindex), None)
   454                                 if entry_declaration is not None:
   497                                 if entry_declaration is not None:
       
   498                                     pdo_needed = True
   455                                     entry_infos.update(dict(zip(["var_type", "dir", "var_name"], entry_declaration)))
   499                                     entry_infos.update(dict(zip(["var_type", "dir", "var_name"], entry_declaration)))
   456                                     
   500                                     
   457                                     if entry_infos["var_type"] != entry.getDataType().getcontent():
   501                                     if entry_infos["var_type"] != entry.getDataType().getcontent():
   458                                         raise ValueError, _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
   502                                         raise ValueError, _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
   459                                     
   503                                     
   463                                     
   507                                     
   464                                     if (entry_infos["dir"] == "I" and sync_managers[pdo.getSm()]["sync_manager_type"] != "EC_DIR_INPUT" or 
   508                                     if (entry_infos["dir"] == "I" and sync_managers[pdo.getSm()]["sync_manager_type"] != "EC_DIR_INPUT" or 
   465                                         entry_infos["dir"] == "Q" and sync_managers[pdo.getSm()]["sync_manager_type"] != "EC_DIR_OUTPUT"):
   509                                         entry_infos["dir"] == "Q" and sync_managers[pdo.getSm()]["sync_manager_type"] != "EC_DIR_OUTPUT"):
   466                                         raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
   510                                         raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
   467                                     
   511                                     
   468                                     str_completion["located_variables_declaration"].extend(["IEC_%(var_type)s beremiz%(var_name)s;" % entry_infos,
   512                                     str_completion["located_variables_declaration"].extend(
   469                                                                                             "IEC_%(var_type)s *%(var_name)s = &beremiz%(var_name)s;" % entry_infos])
   513                                         ["IEC_%(var_type)s beremiz%(var_name)s;" % entry_infos,
       
   514                                          "IEC_%(var_type)s *%(var_name)s = &beremiz%(var_name)s;" % entry_infos])
       
   515                                     
   470                                     if data_type == "BIT":
   516                                     if data_type == "BIT":
   471                                         str_completion["used_pdo_entry_offset_variables_declaration"].extend(["static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos,
   517                                         str_completion["used_pdo_entry_offset_variables_declaration"].extend(
   472                                                                                                               "static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x_bit;" % entry_infos])
   518                                             ["static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos,
       
   519                                              "static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x_bit;" % entry_infos])
   473                                         
   520                                         
   474                                         str_completion["used_pdo_entry_configuration"].append("    {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x, &slave%(slave)d_%(index).4x_%(subindex).2x_bit}," % entry_infos)
   521                                         str_completion["used_pdo_entry_configuration"].append(
       
   522                                              ("    {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, " + 
       
   523                                               "0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x, " + 
       
   524                                               "&slave%(slave)d_%(index).4x_%(subindex).2x_bit},") % entry_infos)
   475                                         
   525                                         
   476                                         if entry_infos["dir"] == "I":
   526                                         if entry_infos["dir"] == "I":
   477                                             str_completion["retrieve_variables"].append("    beremiz%(name)s = EC_READ_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, slave%(slave)d_%(index).4x_%(subindex).2x_bit);" % entry_infos)
   527                                             str_completion["retrieve_variables"].append(
       
   528                                               ("    beremiz%(name)s = EC_READ_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " + 
       
   529                                                "slave%(slave)d_%(index).4x_%(subindex).2x_bit);") % entry_infos)
   478                                         elif entry_infos["dir"] == "Q":
   530                                         elif entry_infos["dir"] == "Q":
   479                                             str_completion["publish_variables"].append("    EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, slave%(slave)d_%(index).4x_%(subindex).2x_bit, beremiz%(var_name)s);" % entry_infos)
   531                                             str_completion["publish_variables"].append(
       
   532                                               ("    EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " + 
       
   533                                                "slave%(slave)d_%(index).4x_%(subindex).2x_bit, beremiz%(var_name)s);") % entry_infos)
   480                                     
   534                                     
   481                                     else:
   535                                     else:
   482                                         entry_infos["data_type"] = data_type
   536                                         entry_infos["data_type"] = data_type
   483                                         
   537                                         
   484                                         str_completion["used_pdo_entry_offset_variables_declaration"].append("static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos)
   538                                         str_completion["used_pdo_entry_offset_variables_declaration"].append(
       
   539                                             "static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos)
   485                                         
   540                                         
   486                                         str_completion["used_pdo_entry_configuration"].append("    {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x}," % entry_infos)
   541                                         str_completion["used_pdo_entry_configuration"].append(
       
   542                                             ("    {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, " + 
       
   543                                              "%(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x},") % entry_infos)
   487                                         
   544                                         
   488                                         if entry_infos["dir"] == "I":
   545                                         if entry_infos["dir"] == "I":
   489                                             str_completion["retrieve_variables"].append("    beremiz%(name)s = EC_READ_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x);" % entry_infos)
   546                                             str_completion["retrieve_variables"].append(
       
   547                                                 ("    beremiz%(name)s = EC_READ_BIT(domain1_pd + " + 
       
   548                                                  "slave%(slave)d_%(index).4x_%(subindex).2x);") % entry_infos)
   490                                         elif entry_infos["dir"] == "Q":
   549                                         elif entry_infos["dir"] == "Q":
   491                                             str_completion["publish_variables"].append("    EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, beremiz%(var_name)s);" % entry_infos)
   550                                             str_completion["publish_variables"].append(
   492                         
   551                                                 ("    EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " + 
       
   552                                                  "beremiz%(var_name)s);") % entry_infos)
       
   553                             
       
   554                             if pdo_needed:
       
   555                                 sync_managers[pdo.getSm()]["pdos_number"] += 1
       
   556                                 pdo_infos = {
       
   557                                     "slave": slave_idx,
       
   558                                     "index": ExtractHexDecValue(pdo.getIndex().getcontent()),
       
   559                                     "name": ExtractName(pdo.getName()),
       
   560                                     "offset": entry_offset,
       
   561                                     "entries_number": len(entries)
       
   562                                 }
       
   563                                 pdos_infos["pdos_infos"].append(
       
   564                                     ("    {0x%(index).4x, %(entries_number)d, " + 
       
   565                                      "slave_%(slave)d_pdo_entries + %(offset)d}, /* %(name)s */") % pdo_infos)
       
   566                                 entry_offset += len(entries)
       
   567                                 pdos_infos["pdos_entries_infos"].extend(entries_infos)
       
   568                                 
       
   569                                 
   493                         pdo_offset = 0
   570                         pdo_offset = 0
   494                         for sync_manager_infos in sync_managers:
   571                         for sync_manager_infos in sync_managers:
   495                             sync_manager_infos["offset"] = pdo_offset
   572                             sync_manager_infos["offset"] = pdo_offset
   496                             pdos_infos["pdos_sync_infos"].append("    {%(index)d, %(sync_manager_type)s, %(pdos_number)d, slave_%(slave)d_pdos + %(offset)d, %(watchdog)s}," % sync_manager_infos)
   573                             pdos_infos["pdos_sync_infos"].append(
       
   574                                 ("    {%(index)d, %(sync_manager_type)s, %(pdos_number)d, " + 
       
   575                                  "slave_%(slave)d_pdos + %(offset)d, %(watchdog)s},") % sync_manager_infos)
   497                             pdo_offset += sync_manager_infos["pdos_number"]
   576                             pdo_offset += sync_manager_infos["pdos_number"]
   498                         
   577                         
   499                         for element in ["pdos_entries_infos", "pdos_infos", "pdos_sync_infos"]:
   578                         for element in ["pdos_entries_infos", "pdos_infos", "pdos_sync_infos"]:
   500                             pdos_infos[element] = "\n".join(pdos_infos[element])
   579                             pdos_infos[element] = "\n".join(pdos_infos[element])
   501                         
   580                         
   502                         str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos
   581                         str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos
   503         
   582         
   504         for element in ["used_pdo_entry_offset_variables_declaration", "used_pdo_entry_configuration", "located_variables_declaration", "retrieve_variables", "publish_variables"]:
   583         for element in ["used_pdo_entry_offset_variables_declaration", 
       
   584                         "used_pdo_entry_configuration", 
       
   585                         "located_variables_declaration", 
       
   586                         "retrieve_variables", 
       
   587                         "publish_variables"]:
   505             str_completion[element] = "\n".join(str_completion[element])
   588             str_completion[element] = "\n".join(str_completion[element])
   506         
   589         
   507         etherlabfile = open(self.FilePath,'w')
   590         etherlabfile = open(self.FilePath,'w')
   508         etherlabfile.write(plc_etherlab_code % str_completion)
   591         etherlabfile.write(plc_etherlab_code % str_completion)
   509         etherlabfile.close()
   592         etherlabfile.close()
   539                 return name.getcontent()
   622                 return name.getcontent()
   540     return default
   623     return default
   541 
   624 
   542 def ExtractPdoInfos(pdo, pdo_type, infos):
   625 def ExtractPdoInfos(pdo, pdo_type, infos):
   543     pdo_index = pdo.getIndex().getcontent()
   626     pdo_index = pdo.getIndex().getcontent()
   544     infos["pdos"].append({"Index": pdo_index,
       
   545                           "Name": ExtractName(pdo.getName()),
       
   546                           "Type": pdo_type})
       
   547     for entry in pdo.getEntry():
   627     for entry in pdo.getEntry():
   548         infos["variables"].append({"Index": entry.getIndex().getcontent(),
   628         infos["variables"].append({"Index": entry.getIndex().getcontent(),
   549                                    "SubIndex": entry.getSubIndex(),
   629                                    "SubIndex": entry.getSubIndex(),
   550                                    "Name": ExtractName(entry.getName()),
   630                                    "Name": ExtractName(entry.getName()),
   551                                    "Type": entry.getDataType().getcontent(),
   631                                    "Type": entry.getDataType().getcontent(),
   552                                    "PDO": pdo_index})
   632                                    "PDO index": pdo_index, 
       
   633                                    "PDO name": ExtractName(pdo.getName()), 
       
   634                                    "PDO type": pdo_type})
   553 
   635 
   554 class RootClass:
   636 class RootClass:
   555     
   637     
   556     PlugChildsTypes = [("EthercatNode",_EthercatPlug,"Ethercat Master")]
   638     PlugChildsTypes = [("EthercatNode",_EthercatPlug,"Ethercat Master")]
   557     
   639     
   579         {"bitmap" : os.path.join("images", "ImportDEF"),
   661         {"bitmap" : os.path.join("images", "ImportDEF"),
   580          "name" : _("Import module library"), 
   662          "name" : _("Import module library"), 
   581          "tooltip" : _("Import module library"),
   663          "tooltip" : _("Import module library"),
   582          "method" : "_ImportModuleLibrary"},
   664          "method" : "_ImportModuleLibrary"},
   583     ]
   665     ]
       
   666     
       
   667     def PlugGenerate_C(self, buildpath, locations):
       
   668         return [],"",False
   584     
   669     
   585     def LoadModulesLibrary(self):
   670     def LoadModulesLibrary(self):
   586         self.ModulesLibrary = {}
   671         self.ModulesLibrary = {}
   587         
   672         
   588         library_path = self.GetModulesLibraryPath()
   673         library_path = self.GetModulesLibraryPath()