etherlab/CommonEtherCATFunction.py
changeset 2165 02a2b5dee5e3
parent 2163 6ea6d83e7280
child 2353 8f1a2846b2f5
child 2641 c9deff128c37
equal deleted inserted replaced
2021:bcf346f558bd 2165:02a2b5dee5e3
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 
       
     5 # This file is part of Beremiz
       
     6 #
       
     7 # Copyright (C) 2013: Real-Time & Embedded Systems (RTES) Lab. University of Seoul, Korea
       
     8 #
       
     9 # See COPYING file for copyrights details.
       
    10 
       
    11 import os
       
    12 import wx
       
    13 
       
    14 mailbox_protocols =  ["AoE", "EoE", "CoE", "FoE", "SoE", "VoE"]
       
    15 
       
    16 def ExtractHexDecValue(value):
       
    17     """
       
    18      convert numerical value in string format into decimal or hex format.
       
    19      @param value : hex or decimal data
       
    20      @return integer data
       
    21     """
       
    22     try:
       
    23         return int(value)
       
    24     except:
       
    25         pass
       
    26     try:
       
    27         return int(value.replace("#", "0"), 16)
       
    28         
       
    29     except:
       
    30         raise ValueError, "Invalid value for HexDecValue \"%s\"" % value
       
    31 
       
    32 def ExtractName(names, default=None):
       
    33     """
       
    34      Extract "name" field from XML entries.
       
    35      @param names : XML entry
       
    36      @default : if it fails to extract from the designated XML entry, return the default value ("None").
       
    37      @return default or the name extracted
       
    38     """
       
    39     if len(names) == 1:
       
    40         return names[0].getcontent()
       
    41     else:
       
    42         for name in names:
       
    43             if name.getLcId() == 1033:
       
    44                 return name.getcontent()
       
    45     return default
       
    46 
       
    47 #--------------------------------------------------
       
    48 #         Remote Exec Etherlab Commands
       
    49 #--------------------------------------------------
       
    50 
       
    51 # --------------------- for master ---------------------------
       
    52 MASTER_STATE = """
       
    53 import commands
       
    54 result = commands.getoutput("ethercat master")
       
    55 returnVal =result 
       
    56 """
       
    57 
       
    58 # --------------------- for slave ----------------------------
       
    59 # ethercat state -p (slave position) (state (INIT, PREOP, SAFEOP, OP))
       
    60 SLAVE_STATE = """
       
    61 import commands
       
    62 result = commands.getoutput("ethercat state -p %d %s")
       
    63 returnVal = result 
       
    64 """
       
    65 
       
    66 # ethercat slave
       
    67 GET_SLAVE = """
       
    68 import commands
       
    69 result = commands.getoutput("ethercat slaves")
       
    70 returnVal =result 
       
    71 """
       
    72 
       
    73 # ethercat xml -p (slave position)
       
    74 SLAVE_XML = """
       
    75 import commands
       
    76 result = commands.getoutput("ethercat xml -p %d")
       
    77 returnVal = result 
       
    78 """
       
    79 
       
    80 # ethercat sdos -p (slave position)
       
    81 SLAVE_SDO = """
       
    82 import commands
       
    83 result = commands.getoutput("ethercat sdos -p %d")
       
    84 returnVal =result 
       
    85 """
       
    86 
       
    87 # ethercat upload -p (slave position) (main index) (sub index)
       
    88 GET_SLOW_SDO = """
       
    89 import commands
       
    90 result = commands.getoutput("ethercat upload -p %d %s %s")
       
    91 returnVal =result 
       
    92 """
       
    93 
       
    94 # ethercat download -p (slave position) (main index) (sub index) (value)
       
    95 SDO_DOWNLOAD = """
       
    96 import commands
       
    97 result = commands.getoutput("ethercat download --type %s -p %d %s %s %s")
       
    98 returnVal =result 
       
    99 """
       
   100 
       
   101 # ethercat sii_read -p (slave position)
       
   102 SII_READ = """
       
   103 import commands
       
   104 result = commands.getoutput("ethercat sii_read -p %d")
       
   105 returnVal =result 
       
   106 """
       
   107 
       
   108 # ethercat reg_read -p (slave position) (address) (size)
       
   109 REG_READ = """
       
   110 import commands
       
   111 result = commands.getoutput("ethercat reg_read -p %d %s %s")
       
   112 returnVal =result 
       
   113 """
       
   114 
       
   115 # ethercat sii_write -p (slave position) - (contents)
       
   116 SII_WRITE = """ 
       
   117 import subprocess 
       
   118 process = subprocess.Popen(
       
   119     ["ethercat", "-f", "sii_write", "-p", "%d", "-"],
       
   120     stdin=subprocess.PIPE)
       
   121 process.communicate(sii_data)
       
   122 returnVal = process.returncode 
       
   123 """
       
   124 
       
   125 # ethercat reg_write -p (slave position) -t (uinit16) (address) (data)
       
   126 REG_WRITE = """ 
       
   127 import commands
       
   128 result = commands.getoutput("ethercat reg_write -p %d -t uint16 %s %s")
       
   129 returnVal =result 
       
   130 """ 
       
   131 
       
   132 # ethercat rescan -p (slave position)
       
   133 RESCAN = """ 
       
   134 import commands
       
   135 result = commands.getoutput("ethercat rescan -p %d")
       
   136 returnVal =result 
       
   137 """
       
   138 
       
   139 #--------------------------------------------------
       
   140 #    Common Method For EtherCAT Management 
       
   141 #--------------------------------------------------
       
   142 class _CommonSlave:
       
   143 
       
   144     # ----- Data Structure for ethercat management ----
       
   145     SlaveState = ""
       
   146 
       
   147     # category of SDO data
       
   148     DatatypeDescription, CommunicationObject, ManufacturerSpecific, \
       
   149     ProfileSpecific, Reserved, AllSDOData = range(6)
       
   150     
       
   151     # store the execution result of "ethercat sdos" command into SaveSDOData.
       
   152     SaveSDOData = []
       
   153     
       
   154     # Flags for checking "write" permission of OD entries 
       
   155     CheckPREOP = False
       
   156     CheckSAFEOP = False
       
   157     CheckOP = False
       
   158 
       
   159     # Save PDO Data
       
   160     TxPDOInfo = []
       
   161     TxPDOCategory = []
       
   162     RxPDOInfo = []
       
   163     RxPDOCategory = []
       
   164     
       
   165     # Save EEPROM Data
       
   166     SiiData = ""
       
   167 
       
   168     # Save Register Data
       
   169     RegData = ""
       
   170     CrtRegSpec = {"ESCType": "",
       
   171                   "FMMUNumber": "",
       
   172                   "SMNumber": "",
       
   173                   "PDIType": ""}
       
   174     
       
   175     def __init__(self, controler):
       
   176         """
       
   177         Constructor
       
   178         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
       
   179         """
       
   180         self.Controler = controler
       
   181          
       
   182         self.ClearSDODataSet()
       
   183     
       
   184     #-------------------------------------------------------------------------------
       
   185     #                        Used Master State
       
   186     #-------------------------------------------------------------------------------
       
   187     def GetMasterState(self):
       
   188         """
       
   189         Execute "ethercat master" command and parse the execution result
       
   190         @return MasterState 
       
   191         """
       
   192 
       
   193         # exectute "ethercat master" command 
       
   194         error, return_val = self.Controler.RemoteExec(MASTER_STATE, return_val = None)
       
   195         master_state = {}
       
   196         # parse the reslut
       
   197         for each_line in return_val.splitlines():
       
   198             if len(each_line) > 0 :
       
   199                 chunks = each_line.strip().split(':', 1)
       
   200                 key = chunks[0]
       
   201                 value = []
       
   202                 if len(chunks) > 1 :
       
   203                     value = chunks[1].split()
       
   204                 if '(attached)' in value:
       
   205                     value.remove('(attached)')
       
   206                 master_state[key] = value
       
   207          
       
   208         return master_state     
       
   209     
       
   210     #-------------------------------------------------------------------------------
       
   211     #                        Used Slave State
       
   212     #-------------------------------------------------------------------------------
       
   213     def RequestSlaveState(self, command):
       
   214         """
       
   215         Set slave state to the specified one using "ethercat states -p %d %s" command.
       
   216         Command example : "ethercat states -p 0 PREOP" (target slave position and target state are given.)
       
   217         @param command : target slave state 
       
   218         """
       
   219         error, return_val = self.Controler.RemoteExec(SLAVE_STATE%(self.Controler.GetSlavePos(), command), return_val = None)
       
   220     
       
   221     def GetSlaveStateFromSlave(self):  
       
   222         """
       
   223         Get slave information using "ethercat slaves" command and store the information into internal data structure 
       
   224         (self.SlaveState) for "Slave State" 
       
   225         return_val example : 0  0:0  PREOP  +  EL9800 (V4.30) (PIC24, SPI, ET1100)
       
   226         """ 
       
   227         error, return_val = self.Controler.RemoteExec(GET_SLAVE, return_val = None)
       
   228         self.SlaveState = return_val
       
   229         return return_val 
       
   230 
       
   231     #-------------------------------------------------------------------------------
       
   232     #                        Used SDO Management
       
   233     #-------------------------------------------------------------------------------
       
   234     def GetSlaveSDOFromSlave(self):
       
   235         """
       
   236         Get SDO objects information of current slave using "ethercat sdos -p %d" command.
       
   237         Command example : "ethercat sdos -p 0"
       
   238         @return return_val : execution results of "ethercat sdos" command (need to be parsed later)
       
   239         """  
       
   240         error, return_val = self.Controler.RemoteExec(SLAVE_SDO%(self.Controler.GetSlavePos()), return_val = None)
       
   241         return return_val   
       
   242         
       
   243     def SDODownload(self, data_type, idx, sub_idx, value):
       
   244         """
       
   245         Set an SDO object value to user-specified value using "ethercat download" command.
       
   246         Command example : "ethercat download --type int32 -p 0 0x8020 0x12 0x00000000"
       
   247         @param data_type : data type of SDO entry
       
   248         @param idx : index of the SDO entry
       
   249         @param sub_idx : subindex of the SDO entry
       
   250         @param value : value of SDO entry
       
   251         """  
       
   252         error, return_val = self.Controler.RemoteExec(SDO_DOWNLOAD%(data_type, self.Controler.GetSlavePos(), idx, sub_idx, value), return_val = None)
       
   253     
       
   254     def BackupSDODataSet(self):
       
   255         """
       
   256         Back-up current SDO entry information to restore the SDO data 
       
   257          in case that the user cancels SDO update operation.
       
   258     	"""  
       
   259         self.BackupDatatypeDescription = self.SaveDatatypeDescription
       
   260         self.BackupCommunicationObject = self.SaveCommunicationObject
       
   261         self.BackupManufacturerSpecific = self.SaveManufacturerSpecific
       
   262         self.BackupProfileSpecific = self.SaveProfileSpecific
       
   263         self.BackupReserved = self.SaveReserved
       
   264         self.BackupAllSDOData = self.SaveAllSDOData
       
   265     
       
   266     def ClearSDODataSet(self):
       
   267         """
       
   268         Clear the specified SDO entry information.
       
   269         """ 
       
   270         for count in range(6):
       
   271             self.SaveSDOData.append([])
       
   272     
       
   273     #-------------------------------------------------------------------------------
       
   274     #                        Used PDO Monitoring
       
   275     #-------------------------------------------------------------------------------
       
   276     def RequestPDOInfo(self):
       
   277         """
       
   278         Load slave information from RootClass (XML data) and parse the information (calling SlavePDOData() method).
       
   279         """ 
       
   280         # Load slave information from ESI XML file (def EthercatMaster.py)
       
   281         slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
       
   282         
       
   283         type_infos = slave.getType()
       
   284         device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
       
   285         # Initialize PDO data set
       
   286         self.ClearDataSet()
       
   287         
       
   288         # if 'device' object is valid, call SavePDOData() to parse PDO data 
       
   289         if device is not None :
       
   290             self.SavePDOData(device)
       
   291     
       
   292     def SavePDOData(self, device):
       
   293         """
       
   294         Parse PDO data and store the results in TXPDOCategory and RXPDOCategory
       
   295         Tx(Rx)PDOCategory : index, name, entry number
       
   296         Tx(Rx)Info : entry index, sub index, name, length, type
       
   297         @param device : Slave information extracted from ESI XML file
       
   298         """ 
       
   299         # Parsing TXPDO entries
       
   300         for pdo, pdo_info in ([(pdo, "Inputs") for pdo in device.getTxPdo()]):
       
   301             # Save pdo_index, entry, and name of each entry
       
   302             pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   303             entries = pdo.getEntry()
       
   304             pdo_name = ExtractName(pdo.getName())
       
   305             
       
   306             # Initialize entry number count
       
   307             count = 0
       
   308             
       
   309             # Parse entries
       
   310             for entry in entries:
       
   311                 # Save index and subindex
       
   312                 index = ExtractHexDecValue(entry.getIndex().getcontent())
       
   313                 subindex = ExtractHexDecValue(entry.getSubIndex())
       
   314                 # if entry name exists, save entry data
       
   315                 if ExtractName(entry.getName()) is not None :
       
   316                     entry_infos = {
       
   317                                 "entry_index" : index,
       
   318                                 "subindex" : subindex,
       
   319                                 "name" : ExtractName(entry.getName()),
       
   320                                 "bitlen" : entry.getBitLen(),
       
   321                                 "type" : entry.getDataType().getcontent()
       
   322                                     }
       
   323                     self.TxPDOInfo.append(entry_infos)
       
   324                     count += 1
       
   325               
       
   326             categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count}  
       
   327             self.TxPDOCategory.append(categorys)
       
   328 
       
   329         # Parsing RxPDO entries
       
   330         for pdo, pdo_info in ([(pdo, "Outputs") for pdo in device.getRxPdo()]):
       
   331             # Save pdo_index, entry, and name of each entry
       
   332             pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   333             entries = pdo.getEntry()
       
   334             pdo_name = ExtractName(pdo.getName())
       
   335             
       
   336             # Initialize entry number count
       
   337             count = 0          
       
   338 
       
   339             # Parse entries          
       
   340             for entry in entries:
       
   341                 # Save index and subindex
       
   342                 index = ExtractHexDecValue(entry.getIndex().getcontent())
       
   343                 subindex = ExtractHexDecValue(entry.getSubIndex())
       
   344                 # if entry name exists, save entry data
       
   345                 if ExtractName(entry.getName()) is not None :
       
   346                     entry_infos = {
       
   347                                 "entry_index" : index,
       
   348                                 "subindex" : subindex,
       
   349                                 "name" : ExtractName(entry.getName()),
       
   350                                 "bitlen" : str(entry.getBitLen()),
       
   351                                 "type" : entry.getDataType().getcontent()
       
   352                                     }
       
   353                     self.RxPDOInfo.append(entry_infos)
       
   354                     count += 1
       
   355     
       
   356             categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count}  
       
   357             self.RxPDOCategory.append(categorys) 
       
   358 
       
   359     def GetTxPDOCategory(self):
       
   360         """
       
   361         Get TxPDOCategory data structure (Meta informaton of TxPDO).
       
   362         TxPDOCategorys : index, name, number of entries
       
   363         @return TxPDOCategorys
       
   364         """ 
       
   365         return self.TxPDOCategory
       
   366         
       
   367     def GetRxPDOCategory(self):
       
   368         """
       
   369         Get RxPDOCategory data structure (Meta information of RxPDO).
       
   370         RxPDOCategorys : index, name, number of entries
       
   371         @return RxPDOCategorys
       
   372         """ 
       
   373         return self.RxPDOCategory
       
   374         
       
   375     def GetTxPDOInfo(self):
       
   376         """
       
   377         Get TxPDOInfo data structure (Detailed information on TxPDO entries). 
       
   378         TxPDOInfos : entry index, sub index, name, length, type
       
   379         @return TxPDOInfos
       
   380         """ 
       
   381         return self.TxPDOInfo
       
   382         
       
   383     def GetRxPDOInfo(self):
       
   384         """
       
   385         Get RxPDOInfo data structure (Detailed information on RxPDO entries). 
       
   386         RxPDOInfos : entry index, sub index, name, length, type
       
   387         @return RxPDOInfos
       
   388         """ 
       
   389         return self.RxPDOInfo
       
   390         
       
   391     def ClearDataSet(self):
       
   392         """
       
   393         Initialize PDO management data structure.
       
   394         """ 
       
   395         self.TxPDOInfos = []
       
   396         self.TxPDOCategorys = []
       
   397         self.RxPDOInfos = []
       
   398         self.RxPDOCategorys = []
       
   399                
       
   400     #-------------------------------------------------------------------------------
       
   401     #                        Used EEPROM Management
       
   402     #-------------------------------------------------------------------------------
       
   403     # Base data types in ETG2000; format = {"Name": "BitSize"}
       
   404     BaseDataTypeDict = {"BOOL": "01",
       
   405                         "SINT": "02",
       
   406                         "INT": "03",
       
   407                         "DINT": "04",
       
   408                         "USINT": "05",
       
   409                         "UINT": "06",
       
   410                         "UDINT": "07",
       
   411                         "REAL": "08",
       
   412                         "INT24": "10",
       
   413                         "LREAL": "11",
       
   414                         "INT40": "12",
       
   415                         "INT48": "13",
       
   416                         "INT56": "14",
       
   417                         "LINT": "15",
       
   418                         "UINT24": "16",
       
   419                         "UINT40": "18",
       
   420                         "UINT48": "19",
       
   421                         "UINT56": "1a",
       
   422                         "ULINT": "1b",
       
   423                         "USINT": "1e",
       
   424                         "BITARR8": "2d",
       
   425                         "BITARR16": "2e",
       
   426                         "BITARR32": "2f",
       
   427                         "BIT1": "30",
       
   428                         "BIT2": "31",
       
   429                         "BIT3": "32",
       
   430                         "BIT4": "33",
       
   431                         "BIT5": "34",
       
   432                         "BIT6": "35",
       
   433                         "BIT7": "36",
       
   434                         "BIT8": "37"}        
       
   435         
       
   436     def GetSmartViewInfos(self):
       
   437         """
       
   438         Parse XML data for "Smart View" of EEPROM contents.
       
   439         @return smartview_infos : EEPROM contents dictionary
       
   440         """ 
       
   441 
       
   442         smartview_infos = {"eeprom_size": 128,
       
   443                            "pdi_type": 0,
       
   444                            "device_emulation": "False",
       
   445                            "vendor_id": '0x00000000',
       
   446                            "product_code": '0x00000000',
       
   447                            "revision_no": '0x00000000',
       
   448                            "serial_no": '0x00000000',
       
   449                            "supported_mailbox": "",
       
   450                            "mailbox_bootstrapconf_outstart": '0',
       
   451                            "mailbox_bootstrapconf_outlength": '0',
       
   452                            "mailbox_bootstrapconf_instart": '0',
       
   453                            "mailbox_bootstrapconf_inlength": '0',
       
   454                            "mailbox_standardconf_outstart": '0',
       
   455                            "mailbox_standardconf_outlength": '0',
       
   456                            "mailbox_standardconf_instart": '0',
       
   457                            "mailbox_standardconf_inlength": '0'}
       
   458         
       
   459         slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
       
   460         type_infos = slave.getType()
       
   461         device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
       
   462 
       
   463         # 'device' represents current slave device selected by user
       
   464         if device is not None:
       
   465             for eeprom_element in device.getEeprom().getcontent():
       
   466                 # get EEPROM size; <Device>-<Eeprom>-<ByteSize>
       
   467                 if eeprom_element["name"] == "ByteSize":
       
   468                     smartview_infos["eeprom_size"] = eeprom_element
       
   469                         
       
   470                 elif eeprom_element["name"] == "ConfigData":
       
   471                     configData_data = self.DecimalToHex(eeprom_element)
       
   472                     # get PDI type; <Device>-<Eeprom>-<ConfigData> address 0x00
       
   473                     smartview_infos["pdi_type"] = int(configData_data[0:2], 16)
       
   474                     # get state of device emulation; <Device>-<Eeprom>-<ConfigData> address 0x01
       
   475                     if "{:0>8b}".format(int(configData_data[2:4], 16))[7] == '1':
       
   476                         smartview_infos["device_emulation"] = "True"
       
   477 
       
   478                 elif eeprom_element["name"] == "BootStrap":
       
   479                     bootstrap_data = "{:0>16x}".format(eeprom_element)
       
   480                     # get bootstrap configuration; <Device>-<Eeprom>-<BootStrap>
       
   481                     for cfg, iter in [("mailbox_bootstrapconf_outstart", 0), 
       
   482                                       ("mailbox_bootstrapconf_outlength", 1),
       
   483                                       ("mailbox_bootstrapconf_instart", 2),
       
   484                                       ("mailbox_bootstrapconf_inlength", 3)]:
       
   485                         smartview_infos[cfg] = str(int(bootstrap_data[4*iter+2:4*(iter+1)]+bootstrap_data[4*iter:4*iter+2], 16))
       
   486             
       
   487             # get protocol (profile) types supported by mailbox; <Device>-<Mailbox>
       
   488             mb = device.getMailbox()
       
   489             if mb is not None:
       
   490                 for mailbox_protocol in mailbox_protocols:
       
   491                     if getattr(mb,"get%s"%mailbox_protocol)() is not None:
       
   492                         smartview_infos["supported_mailbox"] += "%s,  "%mailbox_protocol
       
   493             smartview_infos["supported_mailbox"] = smartview_infos["supported_mailbox"].strip(",  ")
       
   494                 
       
   495             # get standard configuration of mailbox; <Device>-<Sm>
       
   496             for sm_element in device.getSm():
       
   497                 if sm_element.getcontent() == "MBoxOut":
       
   498                     smartview_infos["mailbox_standardconf_outstart"] = str(ExtractHexDecValue(sm_element.getStartAddress()))
       
   499                     smartview_infos["mailbox_standardconf_outlength"] = str(ExtractHexDecValue(sm_element.getDefaultSize()))
       
   500                 elif sm_element.getcontent() == "MBoxIn":
       
   501                     smartview_infos["mailbox_standardconf_instart"] = str(ExtractHexDecValue(sm_element.getStartAddress()))
       
   502                     smartview_infos["mailbox_standardconf_inlength"] = str(ExtractHexDecValue(sm_element.getDefaultSize()))
       
   503                 else:
       
   504                     pass
       
   505 
       
   506             # get device identity from <Device>-<Type>
       
   507             #  vendor ID; by default, pre-defined value in self.ModulesLibrary
       
   508             #             if device type in 'vendor' item equals to actual slave device type, set 'vendor_id' to vendor ID.
       
   509             for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
   510                 for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]:
       
   511                     if available_device[0] == type_infos["device_type"]:
       
   512                         smartview_infos["vendor_id"] = "0x" + "{:0>8x}".format(vendor_id)
       
   513                         
       
   514             #  product code; 
       
   515             if device.getType().getProductCode() is not None:
       
   516                 product_code = device.getType().getProductCode()
       
   517                 smartview_infos["product_code"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(product_code))
       
   518                 
       
   519             #  revision number; 
       
   520             if device.getType().getRevisionNo() is not None:
       
   521                 revision_no = device.getType().getRevisionNo()
       
   522                 smartview_infos["revision_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(revision_no))
       
   523                 
       
   524             #  serial number;
       
   525             if device.getType().getSerialNo() is not None:
       
   526                 serial_no = device.getType().getSerialNo()
       
   527                 smartview_infos["serial_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(serial_no))
       
   528                                             
       
   529             return smartview_infos
       
   530         
       
   531         else:
       
   532             return None
       
   533         
       
   534     def DecimalToHex(self, decnum):
       
   535         """
       
   536         Convert decimal value into hexadecimal representation. 
       
   537         @param decnum : decimal value
       
   538         @return hex_data : hexadecimal representation of input value in decimal
       
   539         """ 
       
   540         value = "%x" % decnum
       
   541         value_len = len(value)
       
   542         if (value_len % 2) == 0:
       
   543             hex_len = value_len
       
   544         else:
       
   545             hex_len = (value_len / 2) * 2 + 2
       
   546         
       
   547         hex_data = ("{:0>"+str(hex_len)+"x}").format(decnum)
       
   548         
       
   549         return hex_data
       
   550 
       
   551     def SiiRead(self):
       
   552         """
       
   553         Get slave EEPROM contents maintained by master device using "ethercat sii_read -p %d" command.
       
   554         Command example : "ethercat sii_read -p 0"
       
   555         @return return_val : result of "ethercat sii_read" (binary data)
       
   556         """ 
       
   557         error, return_val = self.Controler.RemoteExec(SII_READ%(self.Controler.GetSlavePos()), return_val = None)
       
   558         self.SiiData = return_val
       
   559         return return_val
       
   560 
       
   561     def SiiWrite(self, binary):
       
   562         """
       
   563         Overwrite slave EEPROM contents using "ethercat sii_write -p %d" command.
       
   564         Command example : "ethercat sii_write -p 0 - (binary contents)"
       
   565         @param binary : EEPROM contents in binary data format
       
   566         @return return_val : result of "ethercat sii_write" (If it succeeds, the return value is NULL.)
       
   567         """ 
       
   568         error, return_val = self.Controler.RemoteExec(SII_WRITE%(self.Controler.GetSlavePos()), return_val = None, sii_data = binary)
       
   569         return return_val 
       
   570 
       
   571     def LoadData(self):
       
   572         """
       
   573         Loading data from EEPROM use Sii_Read Method
       
   574         @return self.BinaryCode : slave EEPROM data in binary format (zero-padded)
       
   575         """ 
       
   576         return_val = self.Controler.CommonMethod.SiiRead()
       
   577         self.BinaryCode = return_val
       
   578         self.Controler.SiiData = self.BinaryCode
       
   579 
       
   580         # append zero-filled padding data up to EEPROM size
       
   581         for index in range(self.SmartViewInfosFromXML["eeprom_size"] - len(self.BinaryCode)):
       
   582             self.BinaryCode = self.BinaryCode +'ff'.decode('hex')
       
   583               
       
   584         return self.BinaryCode
       
   585 
       
   586     def HexRead(self, binary):
       
   587         """
       
   588         Convert binary digit representation into hexadecimal representation for "Hex View" menu.
       
   589         @param binary : binary digits
       
   590         @return hexCode : hexadecimal digits
       
   591         @return hexview_table_row, hexview_table_col : Grid size for "Hex View" UI
       
   592         """ 
       
   593         row_code = []
       
   594         row_text = ""
       
   595         row = 0
       
   596         hex_code = []
       
   597 
       
   598         hexview_table_col = 17
       
   599         
       
   600         for index in range(0, len(binary)) :
       
   601             if len(binary[index]) != 1:
       
   602                 break
       
   603             else:
       
   604                 digithexstr = hex(ord(binary[index])) 
       
   605 
       
   606                 tempvar2 = digithexstr[2:4]
       
   607                 if len(tempvar2) == 1:
       
   608                     tempvar2 = "0" + tempvar2
       
   609                 row_code.append(tempvar2) 
       
   610                 
       
   611                 if int(digithexstr, 16)>=32 and int(digithexstr, 16)<=126:
       
   612                     row_text = row_text + chr(int(digithexstr, 16))
       
   613                 else:
       
   614                     row_text = row_text + "."
       
   615                 
       
   616                 if index != 0 : 
       
   617                     if len(row_code) == (hexview_table_col - 1):
       
   618                         row_code.append(row_text)
       
   619                         hex_code.append(row_code)
       
   620                         row_text = ""
       
   621                         row_code = []
       
   622                         row = row + 1        
       
   623                                         
       
   624         hexview_table_row = row
       
   625         
       
   626         return hex_code, hexview_table_row, hexview_table_col
       
   627     
       
   628     def GenerateEEPROMList(self, data, direction, length):
       
   629         """
       
   630         Generate EEPROM data list by reconstructing 'data' string.
       
   631         example : data="12345678", direction=0, length=8 -> eeprom_list=['12', '34', '56', '78']
       
   632                   data="12345678", direction=1, length=8 -> eeprom_list=['78', '56', '34', '12']
       
   633         @param data : string to be reconstructed
       
   634         @param direction : endianness
       
   635         @param length : data length
       
   636         @return eeprom_list : reconstructed list data structure
       
   637         """ 
       
   638         eeprom_list = []
       
   639 
       
   640         if direction is 0 or 1:
       
   641             for i in range(length/2):
       
   642                 if data == "":
       
   643                     eeprom_list.append("00")
       
   644                 else:
       
   645                     eeprom_list.append(data[direction*(length-2):direction*(length-2)+2])
       
   646                 data = data[(1-direction)*2:length-direction*2]
       
   647                 length -= 2
       
   648         return eeprom_list
       
   649     
       
   650     def XmlToEeprom(self):
       
   651         """
       
   652         Extract slave EEPROM contents using slave ESI XML file.
       
   653           - Mandatory parts
       
   654           - String category : ExtractEEPROMStringCategory()
       
   655           - General category : ExtractEEPROMGeneralCategory()
       
   656           - FMMU category : ExtractEEPROMFMMUCategory
       
   657           - SyncM category : ExtractEEPROMSyncMCategory()
       
   658           - Tx/RxPDO category : ExtractEEPROMPDOCategory()
       
   659           - DC category : ExtractEEPROMDCCategory()
       
   660         @return eeprom_binary 
       
   661         """ 
       
   662         eeprom = []
       
   663         data = ""
       
   664         eeprom_size = 0
       
   665         eeprom_binary = ""
       
   666 
       
   667         # 'device' is the slave device of the current EtherCAT slave plugin
       
   668         slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
       
   669         type_infos = slave.getType()
       
   670         device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
       
   671         
       
   672         if device is not None:
       
   673             # get ConfigData for EEPROM offset 0x0000-0x000d; <Device>-<Eeprom>-<ConfigData>
       
   674             for eeprom_element in device.getEeprom().getcontent():
       
   675                 if eeprom_element["name"] == "ConfigData":
       
   676                     data = self.DecimalToHex(eeprom_element)
       
   677             eeprom += self.GenerateEEPROMList(data, 0, 28)
       
   678             
       
   679             # calculate CRC for EEPROM offset 0x000e-0x000f
       
   680             crc = 0x48
       
   681             for segment in eeprom:
       
   682                 for i in range(8):
       
   683                     bit = crc & 0x80
       
   684                     crc = (crc << 1) | ((int(segment, 16) >> (7 - i)) & 0x01)
       
   685                     if bit:
       
   686                         crc ^= 0x07   
       
   687             for k in range(8):
       
   688                 bit = crc & 0x80
       
   689                 crc <<= 1
       
   690                 if bit:
       
   691                     crc ^= 0x07      
       
   692             eeprom.append(hex(crc)[len(hex(crc))-3:len(hex(crc))-1])
       
   693             eeprom.append("00")
       
   694             
       
   695             # get VendorID for EEPROM offset 0x0010-0x0013;
       
   696             data = ""
       
   697             for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
   698                 for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]:
       
   699                     if available_device[0] == type_infos["device_type"]:
       
   700                         data = "{:0>8x}".format(vendor_id)
       
   701             eeprom += self.GenerateEEPROMList(data, 1, 8)
       
   702             
       
   703             # get Product Code for EEPROM offset 0x0014-0x0017;
       
   704             data = ""
       
   705             if device.getType().getProductCode() is not None:
       
   706                 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getProductCode()))
       
   707             eeprom += self.GenerateEEPROMList(data, 1, 8)
       
   708             
       
   709             # get Revision Number for EEPROM offset 0x0018-0x001b;
       
   710             data = ""
       
   711             if device.getType().getRevisionNo() is not None:
       
   712                 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getRevisionNo()))
       
   713             eeprom += self.GenerateEEPROMList(data, 1, 8)  
       
   714             
       
   715             # get Serial Number for EEPROM 0x001c-0x001f;
       
   716             data = ""
       
   717             if device.getType().getSerialNo() is not None:
       
   718                 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getSerialNo()))
       
   719             eeprom += self.GenerateEEPROMList(data, 1, 8)
       
   720                 
       
   721             # get Execution Delay for EEPROM 0x0020-0x0021; not analyzed yet
       
   722             eeprom.append("00")
       
   723             eeprom.append("00")
       
   724             
       
   725             # get Port0/1 Delay for EEPROM offset 0x0022-0x0025; not analyzed yet
       
   726             eeprom.append("00")
       
   727             eeprom.append("00")
       
   728             eeprom.append("00")
       
   729             eeprom.append("00")
       
   730             
       
   731             # reserved for EEPROM offset 0x0026-0x0027;
       
   732             eeprom.append("00")
       
   733             eeprom.append("00")
       
   734 
       
   735             # get BootStrap for EEPROM offset 0x0028-0x002e; <Device>-<Eeprom>-<BootStrap>
       
   736             data = ""
       
   737             for eeprom_element in device.getEeprom().getcontent():
       
   738                 if eeprom_element["name"] == "BootStrap":
       
   739                     data = "{:0>16x}".format(eeprom_element)
       
   740             eeprom += self.GenerateEEPROMList(data, 0, 16)
       
   741             
       
   742             # get Standard Mailbox for EEPROM offset 0x0030-0x0037; <Device>-<sm>
       
   743             data = ""
       
   744             standard_send_mailbox_offset = None
       
   745             standard_send_mailbox_size = None
       
   746             standard_receive_mailbox_offset = None
       
   747             standard_receive_mailbox_size = None
       
   748             for sm_element in device.getSm():
       
   749                 if sm_element.getcontent() == "MBoxOut":
       
   750                     standard_receive_mailbox_offset = "{:0>4x}".format(ExtractHexDecValue(sm_element.getStartAddress()))
       
   751                     standard_receive_mailbox_size = "{:0>4x}".format(ExtractHexDecValue(sm_element.getDefaultSize()))
       
   752                 elif sm_element.getcontent() == "MBoxIn":
       
   753                     standard_send_mailbox_offset = "{:0>4x}".format(ExtractHexDecValue(sm_element.getStartAddress()))
       
   754                     standard_send_mailbox_size = "{:0>4x}".format(ExtractHexDecValue(sm_element.getDefaultSize()))
       
   755                     
       
   756             if standard_receive_mailbox_offset is None:
       
   757                 eeprom.append("00")
       
   758                 eeprom.append("00")
       
   759             else:
       
   760                 eeprom.append(standard_receive_mailbox_offset[2:4])
       
   761                 eeprom.append(standard_receive_mailbox_offset[0:2])
       
   762             if standard_receive_mailbox_size is None:
       
   763                 eeprom.append("00")
       
   764                 eeprom.append("00")
       
   765             else:
       
   766                 eeprom.append(standard_receive_mailbox_size[2:4])
       
   767                 eeprom.append(standard_receive_mailbox_size[0:2])
       
   768             if standard_send_mailbox_offset is None:
       
   769                 eeprom.append("00")
       
   770                 eeprom.append("00")
       
   771             else:
       
   772                 eeprom.append(standard_send_mailbox_offset[2:4])
       
   773                 eeprom.append(standard_send_mailbox_offset[0:2])
       
   774             if standard_send_mailbox_size is None:
       
   775                 eeprom.append("00")
       
   776                 eeprom.append("00")
       
   777             else:
       
   778                 eeprom.append(standard_send_mailbox_size[2:4])
       
   779                 eeprom.append(standard_send_mailbox_size[0:2])
       
   780             
       
   781             # get supported mailbox protocols for EEPROM offset 0x0038-0x0039;
       
   782             data = 0
       
   783             mb = device.getMailbox()
       
   784             if mb is not None :
       
   785                 for bit,mbprot in enumerate(mailbox_protocols):
       
   786                     if getattr(mb,"get%s"%mbprot)() is not None:
       
   787                         data += 1<<bit
       
   788             data = "{:0>4x}".format(data)
       
   789             eeprom.append(data[2:4])
       
   790             eeprom.append(data[0:2])
       
   791             
       
   792             # resereved for EEPROM offset 0x003a-0x007b;
       
   793             for i in range(0x007b-0x003a+0x0001):
       
   794                 eeprom.append("00")
       
   795             
       
   796             # get EEPROM size for EEPROM offset 0x007c-0x007d;
       
   797             data = ""
       
   798             for eeprom_element in device.getEeprom().getcontent():
       
   799                 if eeprom_element["name"] == "ByteSize":
       
   800                     eeprom_size = int(str(eeprom_element))
       
   801                     data = "{:0>4x}".format(int(eeprom_element)/1024*8-1)
       
   802 
       
   803             if data == "":
       
   804                 eeprom.append("00")
       
   805                 eeprom.append("00")
       
   806             else:
       
   807                 eeprom.append(data[2:4])
       
   808                 eeprom.append(data[0:2])
       
   809                 
       
   810             # Version for EEPROM 0x007e-0x007f; 
       
   811             #  According to "EtherCAT Slave Device Description(V0.3.0)"
       
   812             eeprom.append("01")
       
   813             eeprom.append("00")
       
   814             
       
   815             # append String Category data
       
   816             for data in self.ExtractEEPROMStringCategory(device):
       
   817                 eeprom.append(data)
       
   818                 
       
   819             # append General Category data
       
   820             for data in self.ExtractEEPROMGeneralCategory(device):
       
   821                 eeprom.append(data)
       
   822                 
       
   823             # append FMMU Category data
       
   824             for data in self.ExtractEEPROMFMMUCategory(device):
       
   825                 eeprom.append(data)
       
   826             
       
   827             # append SyncM Category data
       
   828             for data in self.ExtractEEPROMSyncMCategory(device):
       
   829                 eeprom.append(data)
       
   830                 
       
   831             # append TxPDO Category data
       
   832             for data in self.ExtractEEPROMPDOCategory(device, "TxPdo"):
       
   833                 eeprom.append(data)
       
   834                 
       
   835             # append RxPDO Category data
       
   836             for data in self.ExtractEEPROMPDOCategory(device, "RxPdo"):
       
   837                 eeprom.append(data)
       
   838                 
       
   839             # append DC Category data
       
   840             for data in self.ExtractEEPROMDCCategory(device):
       
   841                 eeprom.append(data)
       
   842             
       
   843             # append padding
       
   844             padding = eeprom_size-len(eeprom)
       
   845             for i in range(padding):
       
   846                 eeprom.append("ff")
       
   847             
       
   848             # convert binary code
       
   849             for index in range(eeprom_size):
       
   850                 eeprom_binary = eeprom_binary + eeprom[index].decode('hex')
       
   851             
       
   852             return eeprom_binary
       
   853     
       
   854     def ExtractEEPROMStringCategory(self, device):
       
   855         """
       
   856         Extract "Strings" category data from slave ESI XML and generate EEPROM image data.
       
   857         @param device : 'device' object in the slave ESI XML
       
   858         @return eeprom : "Strings" category EEPROM image data
       
   859         """ 
       
   860         eeprom = []
       
   861         self.Strings = []
       
   862         data = "" 
       
   863         count = 0 # string counter
       
   864         padflag = False # padding flag if category length is odd
       
   865         
       
   866         # index information for General Category in EEPROM
       
   867         self.GroupIdx = 0
       
   868         self.ImgIdx = 0
       
   869         self.OrderIdx = 0
       
   870         self.NameIdx = 0
       
   871         
       
   872         # flag for preventing duplicated vendor specific data 
       
   873         typeflag = False
       
   874         grouptypeflag = False
       
   875         groupnameflag = False
       
   876         devnameflag = False
       
   877         imageflag = False
       
   878         
       
   879         # vendor specific data
       
   880         #   element1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Type>
       
   881         #   vendor_specific_data : vendor specific data (binary type)
       
   882         vendor_specific_data = ""
       
   883         #   vendor_spec_strings : list of vendor specific "strings" for preventing duplicated strings
       
   884         vendor_spec_strings = []
       
   885         for element in device.getType().getcontent():
       
   886             data += element
       
   887         if data is not "" and type(data) == unicode:
       
   888             for vendor_spec_string in vendor_spec_strings: 
       
   889                 if data == vendor_spec_string:
       
   890                     self.OrderIdx = vendor_spec_strings.index(data)+1
       
   891                     typeflag = True
       
   892                     break
       
   893             if typeflag is False:
       
   894                 count += 1
       
   895                 self.Strings.append(data)
       
   896                 vendor_spec_strings.append(data)
       
   897                 typeflag = True
       
   898                 self.OrderIdx = count
       
   899                 vendor_specific_data += "{:0>2x}".format(len(data))
       
   900                 for character in range(len(data)):
       
   901                     vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   902         data = ""
       
   903         
       
   904         #  element2-1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<GroupType>
       
   905         data = device.getGroupType()
       
   906         if data is not None and type(data) == unicode:
       
   907             for vendor_spec_string in vendor_spec_strings:
       
   908                 if data == vendor_spec_string:
       
   909                     self.GroupIdx = vendor_spec_strings.index(data)+1
       
   910                     grouptypeflag = True
       
   911                     break
       
   912             if grouptypeflag is False:
       
   913                 grouptype = data
       
   914                 count += 1
       
   915                 self.Strings.append(data)
       
   916                 vendor_spec_strings.append(data)
       
   917                 grouptypeflag = True
       
   918                 self.GroupIdx = count
       
   919                 vendor_specific_data += "{:0>2x}".format(len(data))
       
   920                 for character in range(len(data)):
       
   921                     vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   922         
       
   923         #  element2-2; <EtherCATInfo>-<Groups>-<Group>-<Type>            
       
   924         if grouptypeflag is False: 
       
   925             if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
       
   926                 for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
   927                     for group_type, group_etc in vendor["groups"].iteritems():
       
   928                         for device_item in group_etc["devices"]:
       
   929                             if device == device_item[1]: 
       
   930                                 data = group_type
       
   931                 if data is not None and type(data) == unicode:
       
   932                     for vendor_spec_string in vendor_spec_strings:
       
   933                         if data == vendor_spec_string:
       
   934                             self.GroupIdx = vendor_spec_strings.index(data)+1
       
   935                             grouptypeflag = True
       
   936                             break
       
   937                     if grouptypeflag is False:
       
   938                         grouptype = data
       
   939                         count += 1
       
   940                         self.Strings.append(data)
       
   941                         vendor_spec_strings.append(data)
       
   942                         grouptypeflag = True
       
   943                         self.GroupIdx = count
       
   944                         vendor_specific_data += "{:0>2x}".format(len(data))
       
   945                         for character in range(len(data)):
       
   946                             vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   947         data = ""
       
   948         
       
   949         #  element3; <EtherCATInfo>-<Descriptions>-<Groups>-<Group>-<Name(LcId is "1033")>
       
   950         if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
       
   951             for vendorId, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
   952                 for group_type, group_etc in vendor["groups"].iteritems():
       
   953                     for device_item in group_etc["devices"]:
       
   954                         if device == device_item[1]:
       
   955                             data = group_etc["name"]
       
   956         if data is not "" and type(data) == unicode:
       
   957             for vendor_spec_string in vendor_spec_strings:
       
   958                 if data == vendor_spec_string:
       
   959                     groupnameflag = True
       
   960                     break
       
   961             if groupnameflag is False:
       
   962                 count += 1
       
   963                 self.Strings.append(data)
       
   964                 vendor_spec_strings.append(data)
       
   965                 groupnameflag = True
       
   966                 vendor_specific_data += "{:0>2x}".format(len(data))
       
   967                 for character in range(len(data)):
       
   968                     vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   969         data = ""
       
   970         
       
   971         #  element4; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Name(LcId is "1033" or "1"?)>
       
   972         for element in device.getName():
       
   973             if element.getLcId() == 1 or element.getLcId()==1033:
       
   974                 data = element.getcontent()
       
   975         if data is not "" and type(data) == unicode:
       
   976             for vendor_spec_string in vendor_spec_strings:
       
   977                 if data == vendor_spec_string:
       
   978                     self.NameIdx = vendor_spec_strings.index(data)+1
       
   979                     devnameflag = True
       
   980                     break
       
   981             if devnameflag is False:
       
   982                 count += 1
       
   983                 self.Strings.append(data)
       
   984                 vendor_spec_strings.append(data)
       
   985                 devnameflag = True
       
   986                 self.NameIdx = count
       
   987                 vendor_specific_data += "{:0>2x}".format(len(data))
       
   988                 for character in range(len(data)):
       
   989                     vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   990         data = ""
       
   991         
       
   992         #  element5-1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Image16x14>
       
   993         if device.getcontent() is not None:
       
   994             data = device.getcontent()
       
   995             if data is not None and type(data) == unicode:
       
   996                 for vendor_spec_string in vendor_spec_strings:
       
   997                     if data == vendor_spec_string:
       
   998                         self.ImgIdx = vendor_spec_strings.index(data)+1
       
   999                         imageflag = True
       
  1000                         break
       
  1001                 if imageflag is False:
       
  1002                     count += 1
       
  1003                     self.Strings.append(data)
       
  1004                     vendor_spec_strings.append(data)
       
  1005                     imageflag = True
       
  1006                     self.ImgIdx = count
       
  1007                     vendor_specific_data += "{:0>2x}".format(len(data))
       
  1008                     for character in range(len(data)):
       
  1009                         vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
  1010                         
       
  1011         #  element5-2; <EtherCATInfo>-<Descriptions>-<Groups>-<Group>-<Image16x14>
       
  1012         if imageflag is False:
       
  1013             if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
       
  1014                 for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
  1015                     for group_type, group_etc in vendor["groups"].iteritems():
       
  1016                         for device_item in group_etc["devices"]:
       
  1017                             if device == device_item[1]:
       
  1018                                 data = group_etc
       
  1019                 if data is not None and type(data) == unicode:
       
  1020                     for vendor_spec_string in vendor_spec_strings:
       
  1021                         if data == vendor_spec_string:
       
  1022                             self.ImgIdx = vendor_spec_strings.index(data)+1
       
  1023                             imageflag = True
       
  1024                             break
       
  1025                     if imageflag is False:
       
  1026                         count += 1
       
  1027                         self.Strings.append(data)
       
  1028                         vendor_spec_strings.append(data)
       
  1029                         imageflag = True
       
  1030                         self.ImgIdx = count
       
  1031                         vendor_specific_data += "{:0>2x}".format(len(data))
       
  1032                         for character in range(len(data)):
       
  1033                             vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
  1034         data = ""
       
  1035         
       
  1036         # DC related elements
       
  1037         #  <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Dc>-<OpMode>-<Name>
       
  1038         dc_related_elements = ""
       
  1039         if device.getDc() is not None:
       
  1040             for element in device.getDc().getOpMode():
       
  1041                 data = element.getName()
       
  1042                 if data is not "":
       
  1043                     count += 1
       
  1044                     self.Strings.append(data)
       
  1045                     dc_related_elements += "{:0>2x}".format(len(data))
       
  1046                     for character in range(len(data)):
       
  1047                         dc_related_elements += "{:0>2x}".format(ord(data[character]))
       
  1048                     data = ""
       
  1049         
       
  1050         # Input elements(TxPDO)
       
  1051         #  <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<TxPdo>; Name
       
  1052         input_elements = ""
       
  1053         inputs = []
       
  1054         for element in device.getTxPdo():
       
  1055             for name in element.getName():
       
  1056                 data = name.getcontent()
       
  1057             for input in inputs:
       
  1058                 if data == input: 
       
  1059                     data = ""
       
  1060             if data is not "":
       
  1061                 count += 1
       
  1062                 self.Strings.append(data)
       
  1063                 inputs.append(data)
       
  1064                 input_elements += "{:0>2x}".format(len(data))
       
  1065                 for character in range(len(data)):
       
  1066                     input_elements += "{:0>2x}".format(ord(data[character]))
       
  1067                 data = ""            
       
  1068             for entry in element.getEntry():
       
  1069                 for name in entry.getName():
       
  1070                     data = name.getcontent()
       
  1071                 for input in inputs:
       
  1072                     if data == input: 
       
  1073                         data = ""
       
  1074                 if data is not "":
       
  1075                     count += 1
       
  1076                     self.Strings.append(data)
       
  1077                     inputs.append(data)
       
  1078                     input_elements += "{:0>2x}".format(len(data))
       
  1079                     for character in range(len(data)):
       
  1080                         input_elements += "{:0>2x}".format(ord(data[character]))
       
  1081                     data = ""
       
  1082         
       
  1083         # Output elements(RxPDO)
       
  1084         #  <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<RxPdo>; Name
       
  1085         output_elements = ""
       
  1086         outputs = []
       
  1087         for element in device.getRxPdo():
       
  1088             for name in element.getName():
       
  1089                 data = name.getcontent()
       
  1090             for output in outputs:
       
  1091                 if data == output: 
       
  1092                     data = ""
       
  1093             if data is not "":
       
  1094                 count += 1
       
  1095                 self.Strings.append(data)
       
  1096                 outputs.append(data)
       
  1097                 output_elements += "{:0>2x}".format(len(data))
       
  1098                 for character in range(len(data)):
       
  1099                     output_elements += "{:0>2x}".format(ord(data[character]))
       
  1100                 data = ""            
       
  1101             for entry in element.getEntry():
       
  1102                 for name in entry.getName():
       
  1103                     data = name.getcontent()
       
  1104                 for output in outputs:
       
  1105                     if data == output: 
       
  1106                         data = ""
       
  1107                 if data is not "":
       
  1108                     count += 1
       
  1109                     self.Strings.append(data)
       
  1110                     outputs.append(data)
       
  1111                     output_elements += "{:0>2x}".format(len(data))
       
  1112                     for character in range(len(data)):
       
  1113                         output_elements += "{:0>2x}".format(ord(data[character]))
       
  1114                     data = ""     
       
  1115         
       
  1116         # form eeprom data
       
  1117         #  category header
       
  1118         eeprom.append("0a")
       
  1119         eeprom.append("00")
       
  1120         #  category length (word); 1 word is 4 bytes. "+2" is the length of string's total number
       
  1121         length = len(vendor_specific_data + dc_related_elements + input_elements + output_elements) + 2
       
  1122         if length%4 == 0:
       
  1123             pass
       
  1124         else:
       
  1125             length +=length%4
       
  1126             padflag = True
       
  1127         eeprom.append("{:0>4x}".format(length/4)[2:4])
       
  1128         eeprom.append("{:0>4x}".format(length/4)[0:2])
       
  1129         #  total numbers of strings
       
  1130         eeprom.append("{:0>2x}".format(count))
       
  1131         for element in [vendor_specific_data,
       
  1132                         dc_related_elements,
       
  1133                         input_elements,
       
  1134                         output_elements]:
       
  1135             for iter in range(len(element)/2):
       
  1136                 if element == "":
       
  1137                     eeprom.append("00")
       
  1138                 else:
       
  1139                     eeprom.append(element[0:2])
       
  1140                 element = element[2:len(element)]     
       
  1141         # padding if length is odd bytes 
       
  1142         if padflag is True:
       
  1143             eeprom.append("ff")
       
  1144         
       
  1145         return eeprom
       
  1146     
       
  1147     def ExtractEEPROMGeneralCategory(self, device):
       
  1148         """
       
  1149         Extract "General" category data from slave ESI XML and generate EEPROM image data.
       
  1150         @param device : 'device' object in the slave ESI XML
       
  1151         @return eeprom : "Strings" category EEPROM image data
       
  1152         """ 
       
  1153         eeprom = []
       
  1154         data = ""
       
  1155         
       
  1156         # category header
       
  1157         eeprom.append("1e")
       
  1158         eeprom.append("00")
       
  1159         
       
  1160         # category length
       
  1161         eeprom.append("10")
       
  1162         eeprom.append("00")
       
  1163         
       
  1164         # word 1 : Group Type index and Image index in STRINGS Category
       
  1165         eeprom.append("{:0>2x}".format(self.GroupIdx))
       
  1166         eeprom.append("{:0>2x}".format(self.ImgIdx))
       
  1167         
       
  1168         # word 2 : Device Type index and Device Name index in STRINGS Category
       
  1169         eeprom.append("{:0>2x}".format(self.OrderIdx))
       
  1170         eeprom.append("{:0>2x}".format(self.NameIdx))
       
  1171         
       
  1172         # word 3 : Physical Layer Port info. and CoE Details
       
  1173         eeprom.append("01") # Physical Layer Port info - assume 01
       
  1174         #  CoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<CoE>
       
  1175         coe_details = 0
       
  1176         mb = device.getMailbox()
       
  1177         coe_details = 1 # sdo enabled
       
  1178         if mb is not None :
       
  1179             coe = mb.getCoE()
       
  1180             if coe is not None:
       
  1181                 for bit,flag in enumerate(["SdoInfo", "PdoAssign", "PdoConfig", 
       
  1182                                            "PdoUpload", "CompleteAccess"]):
       
  1183                     if getattr(coe,"get%s"%flag)() is not None:
       
  1184                         coe_details += 1<<bit        
       
  1185         eeprom.append("{:0>2x}".format(coe_details))
       
  1186         
       
  1187         # word 4 : FoE Details and EoE Details
       
  1188         #  FoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<FoE>
       
  1189         if mb is not None and mb.getFoE() is not None:
       
  1190             eeprom.append("01")
       
  1191         else:
       
  1192             eeprom.append("00")
       
  1193         #  EoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<EoE>
       
  1194         if mb is not None and mb.getEoE() is not None:
       
  1195             eeprom.append("01")
       
  1196         else:
       
  1197             eeprom.append("00")
       
  1198             
       
  1199         # word 5 : SoE Channels(reserved) and DS402 Channels
       
  1200         #  SoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<SoE>
       
  1201         if mb is not None and mb.getSoE() is not None:
       
  1202             eeprom.append("01")
       
  1203         else:
       
  1204             eeprom.append("00")
       
  1205         #  DS402Channels; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<CoE>: DS402Channels
       
  1206         ds402ch = False
       
  1207         if mb is not None :
       
  1208             coe = mb.getCoE()
       
  1209             if coe is not None :
       
  1210                 ds402ch = coe.getDS402Channels()
       
  1211         eeprom.append("01" if ds402ch in [True,1] else "00")
       
  1212             
       
  1213         # word 6 : SysmanClass(reserved) and Flags
       
  1214         eeprom.append("00") # reserved
       
  1215         #  Flags 
       
  1216         en_safeop = False
       
  1217         en_lrw = False
       
  1218         if device.getType().getTcCfgModeSafeOp() == True \
       
  1219         or device.getType().getTcCfgModeSafeOp() == 1:
       
  1220             en_safeop = True
       
  1221         if device.getType().getUseLrdLwr() == True \
       
  1222         or device.getType().getUseLrdLwr() == 1:
       
  1223             en_lrw = True
       
  1224         
       
  1225         flags = "0b"+"000000"+str(int(en_lrw))+str(int(en_safeop))
       
  1226         eeprom.append("{:0>2x}".format(int(flags, 2)))
       
  1227             
       
  1228         # word 7 : Current On EBus (assume 0x0000)
       
  1229         eeprom.append("00")
       
  1230         eeprom.append("00")
       
  1231         # after word 7; couldn't analyze yet
       
  1232         eeprom.append("03")
       
  1233         eeprom.append("00")
       
  1234         eeprom.append("11")
       
  1235         eeprom.append("00")
       
  1236         eeprom.append("00")
       
  1237         eeprom.append("00")
       
  1238         eeprom.append("00")
       
  1239         eeprom.append("00")
       
  1240         eeprom.append("00")
       
  1241         eeprom.append("00")
       
  1242         eeprom.append("00")
       
  1243         eeprom.append("00")
       
  1244         eeprom.append("00")
       
  1245         eeprom.append("00")
       
  1246         eeprom.append("00")
       
  1247         eeprom.append("00")
       
  1248         eeprom.append("00")
       
  1249         eeprom.append("00")
       
  1250         
       
  1251         return eeprom
       
  1252     
       
  1253     def ExtractEEPROMFMMUCategory(self, device):
       
  1254         """
       
  1255         Extract "FMMU" category data from slave ESI XML and generate EEPROM image data.
       
  1256         @param device : 'device' object in the slave ESI XML
       
  1257         @return eeprom : "Strings" category EEPROM image data
       
  1258         """ 
       
  1259         eeprom = []
       
  1260         data = ""
       
  1261         count = 0 # number of FMMU
       
  1262         padflag = False
       
  1263         
       
  1264         for fmmu in device.getFmmu():
       
  1265             count += 1
       
  1266             if fmmu.getcontent() == "Outputs":
       
  1267                 data += "01"
       
  1268             if fmmu.getcontent() == "Inputs":
       
  1269                 data += "02"
       
  1270             if fmmu.getcontent() == "MBoxState":
       
  1271                 data += "03"
       
  1272         
       
  1273         # construct of EEPROM data
       
  1274         if data is not "":
       
  1275             #  category header
       
  1276             eeprom.append("28")
       
  1277             eeprom.append("00")
       
  1278             #  category length
       
  1279             if count%2 == 1:
       
  1280                 padflag = True
       
  1281                 eeprom.append("{:0>4x}".format((count+1)/2)[2:4])
       
  1282                 eeprom.append("{:0>4x}".format((count+1)/2)[0:2])
       
  1283             else: 
       
  1284                 eeprom.append("{:0>4x}".format((count)/2)[2:4])
       
  1285                 eeprom.append("{:0>4x}".format((count)/2)[0:2])
       
  1286             for i in range(count):
       
  1287                 if data == "":
       
  1288                     eeprom.append("00")
       
  1289                 else:
       
  1290                     eeprom.append(data[0:2])
       
  1291                 data = data[2:len(data)]
       
  1292             #  padding if length is odd bytes 
       
  1293             if padflag is True:
       
  1294                 eeprom.append("ff")       
       
  1295             
       
  1296         return eeprom
       
  1297     
       
  1298     def ExtractEEPROMSyncMCategory(self, device):
       
  1299         """
       
  1300         Extract "SyncM" category data from slave ESI XML and generate EEPROM image data.
       
  1301         @param device : 'device' object in the slave ESI XML
       
  1302         @return eeprom : "Strings" category EEPROM image data
       
  1303         """ 
       
  1304         eeprom = []
       
  1305         data = ""
       
  1306         number = {"MBoxOut":"01", "MBoxIn":"02", "Outputs":"03", "Inputs":"04"}
       
  1307         
       
  1308         for sm in device.getSm():
       
  1309             for attr in [sm.getStartAddress(),
       
  1310                          sm.getDefaultSize(),
       
  1311                          sm.getControlByte()]:
       
  1312                 if attr is not None:
       
  1313                     data += "{:0>4x}".format(ExtractHexDecValue(attr))[2:4]
       
  1314                     data += "{:0>4x}".format(ExtractHexDecValue(attr))[0:2]
       
  1315                 else:
       
  1316                     data += "0000"  
       
  1317             if sm.getEnable() == "1" or sm.getEnable() == True:
       
  1318                 data += "01"
       
  1319             else:
       
  1320                 data += "00"
       
  1321             data += number[sm.getcontent()]
       
  1322             
       
  1323         if data is not "":
       
  1324             #  category header
       
  1325             eeprom.append("29")
       
  1326             eeprom.append("00")
       
  1327             #  category length 
       
  1328             eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
       
  1329             eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
       
  1330             for i in range(len(data)/2):
       
  1331                 if data == "":
       
  1332                     eeprom.append("00")
       
  1333                 else:
       
  1334                     eeprom.append(data[0:2])
       
  1335                 data = data[2:len(data)]
       
  1336 
       
  1337         return eeprom
       
  1338     
       
  1339     def ExtractEEPROMPDOCategory(self, device, pdotype):
       
  1340         """
       
  1341         Extract ""PDO (Tx, Rx)"" category data from slave ESI XML and generate EEPROM image data.
       
  1342         @param device : 'device' object in the slave ESI XML
       
  1343         @param pdotype : identifier whether "TxPDO" or "RxPDO".
       
  1344         @return eeprom : "Strings" category EEPROM image data
       
  1345         """ 
       
  1346         eeprom = []
       
  1347         data = ""
       
  1348         count = 0
       
  1349         en_fixed = False
       
  1350         en_mandatory = False
       
  1351         en_virtual = False
       
  1352         
       
  1353         for element in eval("device.get%s()"%pdotype):
       
  1354             #  PDO Index
       
  1355             data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[2:4]
       
  1356             data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[0:2]
       
  1357             #  Number of Entries
       
  1358             data += "{:0>2x}".format(len(element.getEntry()))
       
  1359             #  About Sync Manager
       
  1360             if element.getSm() is not None:
       
  1361                 data += "{:0>2x}".format(element.getSm())
       
  1362             else:
       
  1363                 data += "ff"
       
  1364             #  Reference to DC Synch (according to ET1100 documentation) - assume 0
       
  1365             data += "00"
       
  1366             #  Name Index
       
  1367             objname = ""
       
  1368             for name in element.getName():
       
  1369                 objname = name.getcontent()
       
  1370             for name in self.Strings:
       
  1371                 count += 1
       
  1372                 if objname == name:
       
  1373                     break
       
  1374             if len(self.Strings)+1 == count:
       
  1375                 data += "00"
       
  1376             else:
       
  1377                 data += "{:0>2x}".format(count)
       
  1378             count = 0
       
  1379             #  Flags; by Fixed, Mandatory, Virtual attributes ?
       
  1380             if element.getFixed() == True or 1:
       
  1381                 en_fixed = True
       
  1382             if element.getMandatory() == True or 1:
       
  1383                 en_mandatory = True
       
  1384             if element.getVirtual() == True or element.getVirtual():
       
  1385                 en_virtual = True
       
  1386             data += str(int(en_fixed)) + str(int(en_mandatory)) + str(int(en_virtual)) + "0"
       
  1387             
       
  1388             for entry in element.getEntry():
       
  1389                 #   Entry Index
       
  1390                 data += "{:0>4x}".format(ExtractHexDecValue(entry.getIndex().getcontent()))[2:4]
       
  1391                 data += "{:0>4x}".format(ExtractHexDecValue(entry.getIndex().getcontent()))[0:2]
       
  1392                 #   Subindex
       
  1393                 data += "{:0>2x}".format(int(entry.getSubIndex()))
       
  1394                 #   Entry Name Index
       
  1395                 objname = ""
       
  1396                 for name in entry.getName():
       
  1397                     objname = name.getcontent()
       
  1398                 for name in self.Strings:
       
  1399                     count += 1
       
  1400                     if objname == name:
       
  1401                         break
       
  1402                 if len(self.Strings)+1 == count:
       
  1403                     data += "00"
       
  1404                 else:
       
  1405                     data += "{:0>2x}".format(count)
       
  1406                 count = 0
       
  1407                 #   DataType
       
  1408                 if entry.getDataType() is not None:
       
  1409                     if entry.getDataType().getcontent() in self.BaseDataTypeDict:
       
  1410                         data += self.BaseDataTypeDict[entry.getDataType().getcontent()]
       
  1411                     else:
       
  1412                         data += "00"
       
  1413                 else:
       
  1414                     data += "00"
       
  1415                 #   BitLen
       
  1416                 if entry.getBitLen() is not None:
       
  1417                     data += "{:0>2x}".format(int(entry.getBitLen()))
       
  1418                 else:
       
  1419                     data += "00"
       
  1420                 #   Flags; by Fixed attributes ?
       
  1421                 en_fixed = False
       
  1422                 if entry.getFixed() == True or entry.getFixed() == 1:
       
  1423                     en_fixed = True
       
  1424                 data += str(int(en_fixed)) + "000"
       
  1425         
       
  1426         if data is not "":
       
  1427             #  category header
       
  1428             if pdotype == "TxPdo":
       
  1429                 eeprom.append("32")
       
  1430             elif pdotype == "RxPdo":
       
  1431                 eeprom.append("33")
       
  1432             else:
       
  1433                 eeprom.append("00")
       
  1434             eeprom.append("00")
       
  1435             #  category length 
       
  1436             eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
       
  1437             eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
       
  1438             data = str(data.lower())
       
  1439             for i in range(len(data)/2):
       
  1440                 if data == "":
       
  1441                     eeprom.append("00")
       
  1442                 else:
       
  1443                     eeprom.append(data[0:2])
       
  1444                 data = data[2:len(data)]
       
  1445         
       
  1446         return eeprom
       
  1447     
       
  1448     def ExtractEEPROMDCCategory(self, device):
       
  1449         """
       
  1450         Extract "DC(Distributed Clock)" category data from slave ESI XML and generate EEPROM image data.
       
  1451         @param device : 'device' object in the slave ESI XML
       
  1452         @return eeprom : "Strings" category EEPROM image data
       
  1453         """ 
       
  1454         eeprom = []
       
  1455         data = ""
       
  1456         count = 0
       
  1457         namecount = 0
       
  1458         
       
  1459         if device.getDc() is not None:
       
  1460             for element in device.getDc().getOpMode():
       
  1461                 count += 1
       
  1462                 #  assume that word 1-7 are 0x0000
       
  1463                 data += "0000"
       
  1464                 data += "0000"
       
  1465                 data += "0000"
       
  1466                 data += "0000"
       
  1467                 data += "0000"
       
  1468                 data += "0000"
       
  1469                 data += "0000"
       
  1470                 #  word 8-10
       
  1471                 #  AssignActivate
       
  1472                 if element.getAssignActivate() is not None:
       
  1473                     data += "{:0>4x}".format(ExtractHexDecValue(element.getAssignActivate()))[2:4]
       
  1474                     data += "{:0>4x}".format(ExtractHexDecValue(element.getAssignActivate()))[0:2]
       
  1475                 else:
       
  1476                     data += "0000"
       
  1477                 #  Factor of CycleTimeSync0 ? and default is 1?
       
  1478                 if element.getCycleTimeSync0() is not None:
       
  1479                     if element.getCycleTimeSync0().getFactor() is not None:
       
  1480                         data += "{:0>2x}".format(int(element.getCycleTimeSync0().getFactor()))
       
  1481                         data += "00"
       
  1482                     else:
       
  1483                         data += "0100"
       
  1484                 else:
       
  1485                     data += "0100"
       
  1486                 #  Index of Name in STRINGS Category
       
  1487                 #  Name Index
       
  1488                 objname = ""
       
  1489                 for name in element.getName():
       
  1490                     objname += name
       
  1491                 for name in self.Strings:
       
  1492                     namecount += 1
       
  1493                     if objname == name:
       
  1494                         break
       
  1495                 if len(self.Strings)+1 == namecount:
       
  1496                     data += "00"
       
  1497                 else:
       
  1498                     data += "{:0>2x}".format(namecount)
       
  1499                 namecount = 0
       
  1500                 data += "00"
       
  1501                 #  assume that word 11-12 are 0x0000
       
  1502                 data += "0000"
       
  1503                 data += "0000"
       
  1504                 
       
  1505         if data is not "":
       
  1506             #  category header
       
  1507             eeprom.append("3c")
       
  1508             eeprom.append("00")
       
  1509             #  category length 
       
  1510             eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
       
  1511             eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
       
  1512             data = str(data.lower())
       
  1513             for i in range(len(data)/2):
       
  1514                 if data == "":
       
  1515                     eeprom.append("00")
       
  1516                 else:
       
  1517                     eeprom.append(data[0:2])
       
  1518                 data = data[2:len(data)]
       
  1519     
       
  1520         return eeprom
       
  1521     
       
  1522     #-------------------------------------------------------------------------------
       
  1523     #                        Used Register Access
       
  1524     #-------------------------------------------------------------------------------
       
  1525     def RegRead(self, offset, length):
       
  1526         """
       
  1527         Read slave ESC register content using "ethercat reg_read -p %d %s %s" command.
       
  1528         Command example : "ethercat reg_read -p 0 0x0c00 0x0400"
       
  1529         @param offset : register address
       
  1530         @param length : register length
       
  1531         @return return_val : register data
       
  1532         """ 
       
  1533         error, return_val = self.Controler.RemoteExec(REG_READ%(self.Controler.GetSlavePos(), offset, length), return_val = None)
       
  1534         return return_val   
       
  1535     
       
  1536     def RegWrite(self, address, data):
       
  1537         """
       
  1538         Write data to slave ESC register using "ethercat reg_write -p %d %s %s" command.
       
  1539         Command example : "ethercat reg_write -p 0 0x0c04 0x0001"
       
  1540         @param address : register address
       
  1541         @param data : data to write
       
  1542         @return return_val : the execution result of "ethercat reg_write" (for error check)
       
  1543         """ 
       
  1544         error, return_val = self.Controler.RemoteExec(REG_WRITE%(self.Controler.GetSlavePos(), address, data), return_val = None)
       
  1545         return return_val 
       
  1546     
       
  1547     def Rescan(self):
       
  1548         """
       
  1549         Synchronize EEPROM data in master controller with the data in slave device after EEPROM write.
       
  1550         Command example : "ethercat rescan -p 0"
       
  1551         """ 
       
  1552         error, return_val = self.Controler.RemoteExec(RESCAN%(self.Controler.GetSlavePos()), return_val = None)
       
  1553     
       
  1554     #-------------------------------------------------------------------------------
       
  1555     #                        Common Use Methods
       
  1556     #-------------------------------------------------------------------------------
       
  1557     def CheckConnect(self, cyclic_flag):
       
  1558         """
       
  1559         Check connection status (1) between Beremiz and the master (2) between the master and the slave. 
       
  1560         @param cyclic_flag: 0 - one shot, 1 - periodic
       
  1561         @return True or False
       
  1562         """ 
       
  1563         if self.Controler.GetCTRoot()._connector is not None:
       
  1564             # Check connection between the master and the slave. 
       
  1565             # Command example : "ethercat xml -p 0"
       
  1566             error, return_val = self.Controler.RemoteExec(SLAVE_XML%(self.Controler.GetSlavePos()), return_val = None)
       
  1567             number_of_lines = return_val.split("\n")
       
  1568             if len(number_of_lines) <= 2 :  # No slave connected to the master controller
       
  1569                 if not cyclic_flag :
       
  1570                     self.CreateErrorDialog('No connected slaves')
       
  1571                 return False
       
  1572         
       
  1573             elif len(number_of_lines) > 2 :
       
  1574                 return True
       
  1575         else:                               
       
  1576             # The master controller is not connected to Beremiz host
       
  1577             if not cyclic_flag :
       
  1578                 self.CreateErrorDialog('PLC not connected!')
       
  1579             return False
       
  1580         
       
  1581     def CreateErrorDialog(self, mention):
       
  1582         """
       
  1583         Create a dialog to indicate error or warning.
       
  1584         @param mention : Error String
       
  1585         """ 
       
  1586         app_frame = self.Controler.GetCTRoot().AppFrame
       
  1587         dlg = wx.MessageDialog (app_frame, mention, 
       
  1588                                 ' Warning...', 
       
  1589                                 wx.OK | wx.ICON_INFORMATION)
       
  1590         dlg.ShowModal()
       
  1591         dlg.Destroy()