etherlab/etherlab.py
changeset 2099 ea5384ab152c
parent 2098 392791b5cc04
child 2101 da450992572e
equal deleted inserted replaced
2098:392791b5cc04 2099:ea5384ab152c
   648         return os.path.join(self.CTNPath(), "config.xml")
   648         return os.path.join(self.CTNPath(), "config.xml")
   649     
   649     
   650     def ProcessVariablesFileName(self):
   650     def ProcessVariablesFileName(self):
   651         return os.path.join(self.CTNPath(), "process_variables.xml")
   651         return os.path.join(self.CTNPath(), "process_variables.xml")
   652     
   652     
   653     def GetSlaves(self):
       
   654         slaves = []
       
   655         for slave in self.Config.getConfig().getSlave():
       
   656             slaves.append(slave.getInfo().getPhysAddr())
       
   657         slaves.sort()
       
   658         return slaves
       
   659 
       
   660     def GetSlave(self, slave_pos):
       
   661         for slave in self.Config.getConfig().getSlave():
       
   662             slave_info = slave.getInfo()
       
   663             if slave_info.getPhysAddr() == slave_pos:
       
   664                 return slave
       
   665         return None
       
   666 
       
   667     def FilterSlave(self, slave, vendor=None, slave_pos=None, slave_profile=None):
   653     def FilterSlave(self, slave, vendor=None, slave_pos=None, slave_profile=None):
   668         if slave_pos is not None and slave.getInfo().getPhysAddr() != slave_pos:
   654         if slave_pos is not None and slave.getInfo().getPhysAddr() != slave_pos:
   669             return False
   655             return False
   670         type_infos = slave.getType()
   656         type_infos = slave.getType()
   671         if vendor is not None and ExtractHexDecValue(type_infos["vendor"]) != vendor:
   657         if vendor is not None and ExtractHexDecValue(type_infos["vendor"]) != vendor:
   672             return False
   658             return False
   673         device, alignment = self.GetModuleInfos(type_infos)
   659         device, alignment = self.GetModuleInfos(type_infos)
   674         if slave_profile is not None and slave_profile not in device.GetProfileNumbers():
   660         if slave_profile is not None and slave_profile not in device.GetProfileNumbers():
   675             return False
   661             return False
   676         return True
   662         return True
       
   663 
       
   664     def GetSlaves(self, vendor=None, slave_pos=None, slave_profile=None):
       
   665         slaves = []
       
   666         for slave in self.Config.getConfig().getSlave():
       
   667             if self.FilterSlave(slave, vendor, slave_pos, slave_profile):
       
   668                 slaves.append(slave.getInfo().getPhysAddr())
       
   669         slaves.sort()
       
   670         return slaves
       
   671 
       
   672     def GetSlave(self, slave_pos):
       
   673         for slave in self.Config.getConfig().getSlave():
       
   674             slave_info = slave.getInfo()
       
   675             if slave_info.getPhysAddr() == slave_pos:
       
   676                 return slave
       
   677         return None
   677 
   678 
   678     def GetStartupCommands(self, vendor=None, slave_pos=None, slave_profile=None):
   679     def GetStartupCommands(self, vendor=None, slave_pos=None, slave_profile=None):
   679         commands = []
   680         commands = []
   680         for slave in self.Config.getConfig().getSlave():
   681         for slave in self.Config.getConfig().getSlave():
   681             if self.FilterSlave(slave, vendor, slave_pos, slave_profile):
   682             if self.FilterSlave(slave, vendor, slave_pos, slave_profile):
   733         self.ProcessVariables.setvariable(vars)
   734         self.ProcessVariables.setvariable(vars)
   734         self.BufferModel()
   735         self.BufferModel()
   735         
   736         
   736     def GetProcessVariables(self):
   737     def GetProcessVariables(self):
   737         variables = []
   738         variables = []
       
   739         idx = 0
   738         for variable in self.ProcessVariables.getvariable():
   740         for variable in self.ProcessVariables.getvariable():
   739             var = {"Name": variable.getName(),
   741             var = {"Name": variable.getName(),
       
   742                    "Number": idx,
   740                    "Description": variable.getComment()}
   743                    "Description": variable.getComment()}
   741             read_from = variable.getReadFrom()
   744             read_from = variable.getReadFrom()
   742             if read_from is not None:
   745             if read_from is not None:
   743                 var["ReadFrom"] = (read_from.getPosition(),
   746                 var["ReadFrom"] = (read_from.getPosition(),
   744                                    read_from.getIndex(),
   747                                    read_from.getIndex(),
   751                                    write_to.getIndex(),
   754                                    write_to.getIndex(),
   752                                    write_to.getSubIndex())
   755                                    write_to.getSubIndex())
   753             else:
   756             else:
   754                 var["WriteTo"] = ""
   757                 var["WriteTo"] = ""
   755             variables.append(var)
   758             variables.append(var)
       
   759             idx += 1
   756         return variables
   760         return variables
   757     
   761     
   758     def _ScanNetwork(self):
   762     def _ScanNetwork(self):
   759         app_frame = self.GetCTRoot().AppFrame
   763         app_frame = self.GetCTRoot().AppFrame
   760         
   764         
   829     def SetSlavePosition(self, slave_pos, new_pos):
   833     def SetSlavePosition(self, slave_pos, new_pos):
   830         slave = self.GetSlave(slave_pos)
   834         slave = self.GetSlave(slave_pos)
   831         if slave is not None:
   835         if slave is not None:
   832             slave_info = slave.getInfo()
   836             slave_info = slave.getInfo()
   833             slave_info.setPhysAddr(new_pos)
   837             slave_info.setPhysAddr(new_pos)
   834             self.BufferModel()
   838             for variable in self.ProcessVariables.getvariable():
       
   839                 read_from = variable.getReadFrom()
       
   840                 if read_from is not None and read_from.getPosition() == slave_pos:
       
   841                     read_from.setPosition(new_pos)
       
   842                 write_to = variable.getWriteTo()
       
   843                 if write_to is not None and write_to.getPosition() == slave_pos:
       
   844                     write_to.setPosition(new_pos)
       
   845             self.CreateBuffer(True)
       
   846             self.OnCTNSave()
       
   847             if self._View is not None:
       
   848                 self._View.RefreshView()
       
   849                 self._View.RefreshBuffer()
   835     
   850     
   836     def GetSlaveAlias(self, slave_pos):
   851     def GetSlaveAlias(self, slave_pos):
   837         slave = self.GetSlave(slave_pos)
   852         slave = self.GetSlave(slave_pos)
   838         if slave is not None:
   853         if slave is not None:
   839             slave_info = slave.getInfo()
   854             slave_info = slave.getInfo()
   898                     current_entry["children"].append(entry)
   913                     current_entry["children"].append(entry)
   899                 else:
   914                 else:
   900                     entries.append(entry)
   915                     entries.append(entry)
   901             return entries
   916             return entries
   902         return []
   917         return []
       
   918     
       
   919     def GetSlaveVariableDataType(self, slave_pos, index, subindex):
       
   920         slave = self.GetSlave(slave_pos)
       
   921         if slave is not None:
       
   922             device, alignment = self.GetModuleInfos(slave.getType())
       
   923             if device is not None:
       
   924                 entries = device.GetEntriesList()
       
   925                 entry_infos = entries.get((index, subindex))
       
   926                 if entry_infos is not None:
       
   927                     return entry_infos["Type"]
       
   928         return None
   903     
   929     
   904     def GetNodesVariables(self, vendor=None, slave_pos=None, slave_profile=None, limits=None):
   930     def GetNodesVariables(self, vendor=None, slave_pos=None, slave_profile=None, limits=None):
   905         entries = []
   931         entries = []
   906         for slave_position in self.GetSlaves():
   932         for slave_position in self.GetSlaves():
   907             if slave_pos is not None and slave_position != slave_pos:
   933             if slave_pos is not None and slave_position != slave_pos:
  1003         
  1029         
  1004         self.FileGenerator = _EthercatCFileGenerator(self)
  1030         self.FileGenerator = _EthercatCFileGenerator(self)
  1005         
  1031         
  1006         LocationCFilesAndCFLAGS, LDFLAGS, extra_files = ConfigTreeNode._Generate_C(self, buildpath, locations)
  1032         LocationCFilesAndCFLAGS, LDFLAGS, extra_files = ConfigTreeNode._Generate_C(self, buildpath, locations)
  1007         
  1033         
  1008         self.FileGenerator.GenerateCFile(Gen_Ethercatfile_path, location_str, self.EtherlabNode)
  1034         self.FileGenerator.GenerateCFile(Gen_Ethercatfile_path, location_str, self.BaseParams.getIEC_Channel())
  1009         
  1035         
  1010         LocationCFilesAndCFLAGS.append(
  1036         LocationCFilesAndCFLAGS.append(
  1011             (current_location, 
  1037             (current_location, 
  1012              [(Gen_Ethercatfile_path, '"-I%s"'%os.path.abspath(self.GetCTRoot().GetIECLibPath()))], 
  1038              [(Gen_Ethercatfile_path, '"-I%s"'%os.path.abspath(self.GetCTRoot().GetIECLibPath()))], 
  1013              True))
  1039              True))
  1039         
  1065         
  1040         slaves = self.GetSlaves()
  1066         slaves = self.GetSlaves()
  1041         for slave_pos in slaves:
  1067         for slave_pos in slaves:
  1042             slave = self.GetSlave(slave_pos)
  1068             slave = self.GetSlave(slave_pos)
  1043             if slave is not None:
  1069             if slave is not None:
  1044                 self.FileGenerator.DeclareSlave(slave_pos, slave.getInfo().getAutoIncAddr(), slave.getType())
  1070                 self.FileGenerator.DeclareSlave(slave_pos, slave)
  1045         
  1071         
  1046         for location in locations:
  1072         for location in locations:
  1047             loc = location["LOC"][len(current_location):]
  1073             loc = location["LOC"][len(current_location):]
  1048             slave_pos = loc[0]
  1074             slave_pos = loc[0]
  1049             if slave_pos in slaves and len(loc) == 3:
  1075             if slave_pos in slaves and len(loc) == 3:
  1208         self.UsedVariables = {}
  1234         self.UsedVariables = {}
  1209 
  1235 
  1210     def __del__(self):
  1236     def __del__(self):
  1211         self.Controler = None            
  1237         self.Controler = None            
  1212     
  1238     
  1213     def DeclareSlave(self, slave_index, slave_alias, slave):
  1239     def DeclareSlave(self, slave_index, slave):
  1214         self.Slaves.append((slave_index, slave_alias, slave))
  1240         self.Slaves.append((slave_index, slave.getInfo().getAutoIncAddr(), slave))
  1215 
  1241 
  1216     def DeclareVariable(self, slave_index, index, subindex, iec_type, dir, name):
  1242     def DeclareVariable(self, slave_index, index, subindex, iec_type, dir, name):
  1217         slave_variables = self.UsedVariables.setdefault(slave_index, {})
  1243         slave_variables = self.UsedVariables.setdefault(slave_index, {})
  1218         
  1244         
  1219         entry_infos = slave_variables.get((index, subindex), None)
  1245         entry_infos = slave_variables.get((index, subindex), None)
  1222                 "infos": (iec_type, dir, name),
  1248                 "infos": (iec_type, dir, name),
  1223                 "mapped": False}
  1249                 "mapped": False}
  1224         elif entry_infos["infos"] != (iec_type, dir, name):
  1250         elif entry_infos["infos"] != (iec_type, dir, name):
  1225             raise ValueError, _("Definition conflict for location \"%s\"") % name 
  1251             raise ValueError, _("Definition conflict for location \"%s\"") % name 
  1226         
  1252         
  1227     def GenerateCFile(self, filepath, location_str, etherlab_node_infos):
  1253     def GenerateCFile(self, filepath, location_str, master_number):
  1228         
  1254         
  1229         # Extract etherlab master code template
  1255         # Extract etherlab master code template
  1230         plc_etherlab_filepath = os.path.join(os.path.split(__file__)[0], "plc_etherlab.c")
  1256         plc_etherlab_filepath = os.path.join(os.path.split(__file__)[0], "plc_etherlab.c")
  1231         plc_etherlab_file = open(plc_etherlab_filepath, 'r')
  1257         plc_etherlab_file = open(plc_etherlab_filepath, 'r')
  1232         plc_etherlab_code = plc_etherlab_file.read()
  1258         plc_etherlab_code = plc_etherlab_file.read()
  1233         plc_etherlab_file.close()
  1259         plc_etherlab_file.close()
  1234         
  1260         
  1235         # Initialize strings for formatting master code template
  1261         # Initialize strings for formatting master code template
  1236         str_completion = {
  1262         str_completion = {
  1237             "location": location_str,
  1263             "location": location_str,
  1238             "master_number": self.BaseParams.getIEC_Channel(),
  1264             "master_number": master_number,
  1239             "located_variables_declaration": [],
  1265             "located_variables_declaration": [],
  1240             "used_pdo_entry_offset_variables_declaration": [],
  1266             "used_pdo_entry_offset_variables_declaration": [],
  1241             "used_pdo_entry_configuration": [],
  1267             "used_pdo_entry_configuration": [],
  1242             "pdos_configuration_declaration": "",
  1268             "pdos_configuration_declaration": "",
  1243             "slaves_declaration": "",
  1269             "slaves_declaration": "",
  1257         self.Slaves.sort()
  1283         self.Slaves.sort()
  1258         # Initialize dictionary storing alias auto-increment position values
  1284         # Initialize dictionary storing alias auto-increment position values
  1259         alias = {}
  1285         alias = {}
  1260         
  1286         
  1261         # Generating code for each slave
  1287         # Generating code for each slave
  1262         for (slave_idx, slave_alias, type_infos) in self.Slaves:
  1288         for (slave_idx, slave_alias, slave) in self.Slaves:
       
  1289             type_infos = slave.getType()
  1263             
  1290             
  1264             # Defining slave alias and auto-increment position
  1291             # Defining slave alias and auto-increment position
  1265             if alias.get(slave_alias) is not None:
  1292             if alias.get(slave_alias) is not None:
  1266                 alias[slave_alias] += 1
  1293                 alias[slave_alias] += 1
  1267             else:
  1294             else:
  1287                 device_coe = device.getCoE()
  1314                 device_coe = device.getCoE()
  1288                 if device_coe is not None:
  1315                 if device_coe is not None:
  1289                     
  1316                     
  1290                     # If device support CanOpen over Ethernet, adding code for calling 
  1317                     # If device support CanOpen over Ethernet, adding code for calling 
  1291                     # init commands when initializing slave in master code template strings
  1318                     # init commands when initializing slave in master code template strings
       
  1319                     initCmds = []
  1292                     for initCmd in device_coe.getInitCmd():
  1320                     for initCmd in device_coe.getInitCmd():
  1293                         index = ExtractHexDecValue(initCmd.getIndex())
  1321                         initCmds.append({
  1294                         subindex = ExtractHexDecValue(initCmd.getSubIndex())
  1322                             "Index": ExtractHexDecValue(initCmd.getIndex()),
       
  1323                             "Subindex": ExtractHexDecValue(initCmd.getSubIndex()),
       
  1324                             "Value": initCmd.getData().getcontent()})
       
  1325                     initCmds.extend(slave.getStartupCommands())
       
  1326                     for initCmd in initCmds:
       
  1327                         index = initCmd["Index"]
       
  1328                         subindex = initCmd["Subindex"]
  1295                         entry = device_entries.get((index, subindex), None)
  1329                         entry = device_entries.get((index, subindex), None)
  1296                         if entry is not None:
  1330                         if entry is not None:
  1297                             data_size = entry["BitSize"] / 8
  1331                             data_size = entry["BitSize"] / 8
  1298                             data_str = ("0x%%.%dx" % (data_size * 2)) % initCmd.getData().getcontent()
  1332                             data_str = ("0x%%.%dx" % (data_size * 2)) % initCmd["Value"]
  1299                             init_cmd_infos = {
  1333                             init_cmd_infos = {
  1300                                 "index": index,
  1334                                 "index": index,
  1301                                 "subindex": subindex,
  1335                                 "subindex": subindex,
  1302                                 "data": data_str,
  1336                                 "data": data_str,
  1303                                 "data_type": DATATYPECONVERSION.get(entry["Type"]),
  1337                                 "data_type": DATATYPECONVERSION.get(entry["Type"]),
  1552                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos_number"] += 1
  1586                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos_number"] += 1
  1553                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos"].append(pdo)
  1587                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos"].append(pdo)
  1554                                     dynamic_pdos[pdo_type]["pdos"].append(pdo)
  1588                                     dynamic_pdos[pdo_type]["pdos"].append(pdo)
  1555                                 
  1589                                 
  1556                                 pdo["entries"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
  1590                                 pdo["entries"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
       
  1591                                 if entry_infos["bitlen"] < alignment:
       
  1592                                     pdo["entries"].append("    {0x0000, 0x00, %d}, /* None */" % (alignment - entry_infos["bitlen"]))
  1557                                 pdo["entries_number"] += 1
  1593                                 pdo["entries_number"] += 1
  1558                                 
  1594                                 
  1559                                 if pdo["entries_number"] == 255:
  1595                                 if pdo["entries_number"] == 255:
  1560                                     dynamic_pdos[pdo_type]["pdos"].pop(0)
  1596                                     dynamic_pdos[pdo_type]["pdos"].pop(0)
  1561                     
  1597