--- a/etherlab/CommonEtherCATFunction.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/CommonEtherCATFunction.py Fri Sep 28 17:20:11 2018 +0300
@@ -25,7 +25,7 @@
pass
try:
return int(value.replace("#", "0"), 16)
-
+
except Exception:
raise ValueError, "Invalid value for HexDecValue \"%s\"" % value
@@ -52,7 +52,7 @@
MASTER_STATE = """
import commands
result = commands.getoutput("ethercat master")
-returnVal =result
+returnVal =result
"""
# --------------------- for slave ----------------------------
@@ -60,84 +60,84 @@
SLAVE_STATE = """
import commands
result = commands.getoutput("ethercat state -p %d %s")
-returnVal = result
+returnVal = result
"""
# ethercat slave
GET_SLAVE = """
import commands
result = commands.getoutput("ethercat slaves")
-returnVal =result
+returnVal =result
"""
# ethercat xml -p (slave position)
SLAVE_XML = """
import commands
result = commands.getoutput("ethercat xml -p %d")
-returnVal = result
+returnVal = result
"""
# ethercat sdos -p (slave position)
SLAVE_SDO = """
import commands
result = commands.getoutput("ethercat sdos -p %d")
-returnVal =result
+returnVal =result
"""
# ethercat upload -p (slave position) (main index) (sub index)
GET_SLOW_SDO = """
import commands
result = commands.getoutput("ethercat upload -p %d %s %s")
-returnVal =result
+returnVal =result
"""
# ethercat download -p (slave position) (main index) (sub index) (value)
SDO_DOWNLOAD = """
import commands
result = commands.getoutput("ethercat download --type %s -p %d %s %s %s")
-returnVal =result
+returnVal =result
"""
# ethercat sii_read -p (slave position)
SII_READ = """
import commands
result = commands.getoutput("ethercat sii_read -p %d")
-returnVal =result
+returnVal =result
"""
# ethercat reg_read -p (slave position) (address) (size)
REG_READ = """
import commands
result = commands.getoutput("ethercat reg_read -p %d %s %s")
-returnVal =result
+returnVal =result
"""
# ethercat sii_write -p (slave position) - (contents)
-SII_WRITE = """
-import subprocess
+SII_WRITE = """
+import subprocess
process = subprocess.Popen(
["ethercat", "-f", "sii_write", "-p", "%d", "-"],
stdin=subprocess.PIPE)
process.communicate(sii_data)
-returnVal = process.returncode
+returnVal = process.returncode
"""
# ethercat reg_write -p (slave position) -t (uinit16) (address) (data)
-REG_WRITE = """
+REG_WRITE = """
import commands
result = commands.getoutput("ethercat reg_write -p %d -t uint16 %s %s")
-returnVal =result
-"""
+returnVal =result
+"""
# ethercat rescan -p (slave position)
-RESCAN = """
+RESCAN = """
import commands
result = commands.getoutput("ethercat rescan -p %d")
-returnVal =result
+returnVal =result
"""
#--------------------------------------------------
-# Common Method For EtherCAT Management
+# Common Method For EtherCAT Management
#--------------------------------------------------
class _CommonSlave:
@@ -147,11 +147,11 @@
# category of SDO data
DatatypeDescription, CommunicationObject, ManufacturerSpecific, \
ProfileSpecific, Reserved, AllSDOData = range(6)
-
+
# store the execution result of "ethercat sdos" command into SaveSDOData.
SaveSDOData = []
-
- # Flags for checking "write" permission of OD entries
+
+ # Flags for checking "write" permission of OD entries
CheckPREOP = False
CheckSAFEOP = False
CheckOP = False
@@ -161,7 +161,7 @@
TxPDOCategory = []
RxPDOInfo = []
RxPDOCategory = []
-
+
# Save EEPROM Data
SiiData = ""
@@ -171,26 +171,26 @@
"FMMUNumber": "",
"SMNumber": "",
"PDIType": ""}
-
+
def __init__(self, controler):
"""
Constructor
@param controler: _EthercatSlaveCTN class in EthercatSlave.py
"""
self.Controler = controler
-
+
self.ClearSDODataSet()
-
+
#-------------------------------------------------------------------------------
# Used Master State
#-------------------------------------------------------------------------------
def GetMasterState(self):
"""
Execute "ethercat master" command and parse the execution result
- @return MasterState
- """
-
- # exectute "ethercat master" command
+ @return MasterState
+ """
+
+ # exectute "ethercat master" command
error, return_val = self.Controler.RemoteExec(MASTER_STATE, return_val = None)
master_state = {}
# parse the reslut
@@ -204,9 +204,9 @@
if '(attached)' in value:
value.remove('(attached)')
master_state[key] = value
-
- return master_state
-
+
+ return master_state
+
#-------------------------------------------------------------------------------
# Used Slave State
#-------------------------------------------------------------------------------
@@ -214,19 +214,19 @@
"""
Set slave state to the specified one using "ethercat states -p %d %s" command.
Command example : "ethercat states -p 0 PREOP" (target slave position and target state are given.)
- @param command : target slave state
+ @param command : target slave state
"""
error, return_val = self.Controler.RemoteExec(SLAVE_STATE%(self.Controler.GetSlavePos(), command), return_val = None)
-
- def GetSlaveStateFromSlave(self):
- """
- Get slave information using "ethercat slaves" command and store the information into internal data structure
- (self.SlaveState) for "Slave State"
+
+ def GetSlaveStateFromSlave(self):
+ """
+ Get slave information using "ethercat slaves" command and store the information into internal data structure
+ (self.SlaveState) for "Slave State"
return_val example : 0 0:0 PREOP + EL9800 (V4.30) (PIC24, SPI, ET1100)
- """
+ """
error, return_val = self.Controler.RemoteExec(GET_SLAVE, return_val = None)
self.SlaveState = return_val
- return return_val
+ return return_val
#-------------------------------------------------------------------------------
# Used SDO Management
@@ -236,10 +236,10 @@
Get SDO objects information of current slave using "ethercat sdos -p %d" command.
Command example : "ethercat sdos -p 0"
@return return_val : execution results of "ethercat sdos" command (need to be parsed later)
- """
+ """
error, return_val = self.Controler.RemoteExec(SLAVE_SDO%(self.Controler.GetSlavePos()), return_val = None)
- return return_val
-
+ return return_val
+
def SDODownload(self, data_type, idx, sub_idx, value):
"""
Set an SDO object value to user-specified value using "ethercat download" command.
@@ -248,64 +248,64 @@
@param idx : index of the SDO entry
@param sub_idx : subindex of the SDO entry
@param value : value of SDO entry
- """
+ """
error, return_val = self.Controler.RemoteExec(SDO_DOWNLOAD%(data_type, self.Controler.GetSlavePos(), idx, sub_idx, value), return_val = None)
-
+
def BackupSDODataSet(self):
"""
- Back-up current SDO entry information to restore the SDO data
+ Back-up current SDO entry information to restore the SDO data
in case that the user cancels SDO update operation.
- """
+ """
self.BackupDatatypeDescription = self.SaveDatatypeDescription
self.BackupCommunicationObject = self.SaveCommunicationObject
self.BackupManufacturerSpecific = self.SaveManufacturerSpecific
self.BackupProfileSpecific = self.SaveProfileSpecific
self.BackupReserved = self.SaveReserved
self.BackupAllSDOData = self.SaveAllSDOData
-
+
def ClearSDODataSet(self):
"""
Clear the specified SDO entry information.
- """
+ """
for count in range(6):
self.SaveSDOData.append([])
-
+
#-------------------------------------------------------------------------------
# Used PDO Monitoring
#-------------------------------------------------------------------------------
def RequestPDOInfo(self):
"""
Load slave information from RootClass (XML data) and parse the information (calling SlavePDOData() method).
- """
+ """
# Load slave information from ESI XML file (def EthercatMaster.py)
slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
-
+
type_infos = slave.getType()
device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
# Initialize PDO data set
self.ClearDataSet()
-
- # if 'device' object is valid, call SavePDOData() to parse PDO data
+
+ # if 'device' object is valid, call SavePDOData() to parse PDO data
if device is not None :
self.SavePDOData(device)
-
+
def SavePDOData(self, device):
"""
Parse PDO data and store the results in TXPDOCategory and RXPDOCategory
Tx(Rx)PDOCategory : index, name, entry number
Tx(Rx)Info : entry index, sub index, name, length, type
@param device : Slave information extracted from ESI XML file
- """
+ """
# Parsing TXPDO entries
for pdo, pdo_info in ([(pdo, "Inputs") for pdo in device.getTxPdo()]):
# Save pdo_index, entry, and name of each entry
pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
entries = pdo.getEntry()
pdo_name = ExtractName(pdo.getName())
-
+
# Initialize entry number count
count = 0
-
+
# Parse entries
for entry in entries:
# Save index and subindex
@@ -322,8 +322,8 @@
}
self.TxPDOInfo.append(entry_infos)
count += 1
-
- categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count}
+
+ categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count}
self.TxPDOCategory.append(categorys)
# Parsing RxPDO entries
@@ -332,11 +332,11 @@
pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
entries = pdo.getEntry()
pdo_name = ExtractName(pdo.getName())
-
+
# Initialize entry number count
- count = 0
-
- # Parse entries
+ count = 0
+
+ # Parse entries
for entry in entries:
# Save index and subindex
index = ExtractHexDecValue(entry.getIndex().getcontent())
@@ -352,51 +352,51 @@
}
self.RxPDOInfo.append(entry_infos)
count += 1
-
- categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count}
- self.RxPDOCategory.append(categorys)
+
+ categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count}
+ self.RxPDOCategory.append(categorys)
def GetTxPDOCategory(self):
"""
Get TxPDOCategory data structure (Meta informaton of TxPDO).
TxPDOCategorys : index, name, number of entries
@return TxPDOCategorys
- """
+ """
return self.TxPDOCategory
-
+
def GetRxPDOCategory(self):
"""
Get RxPDOCategory data structure (Meta information of RxPDO).
RxPDOCategorys : index, name, number of entries
@return RxPDOCategorys
- """
+ """
return self.RxPDOCategory
-
+
def GetTxPDOInfo(self):
"""
- Get TxPDOInfo data structure (Detailed information on TxPDO entries).
+ Get TxPDOInfo data structure (Detailed information on TxPDO entries).
TxPDOInfos : entry index, sub index, name, length, type
@return TxPDOInfos
- """
+ """
return self.TxPDOInfo
-
+
def GetRxPDOInfo(self):
"""
- Get RxPDOInfo data structure (Detailed information on RxPDO entries).
+ Get RxPDOInfo data structure (Detailed information on RxPDO entries).
RxPDOInfos : entry index, sub index, name, length, type
@return RxPDOInfos
- """
+ """
return self.RxPDOInfo
-
+
def ClearDataSet(self):
"""
Initialize PDO management data structure.
- """
+ """
self.TxPDOInfos = []
self.TxPDOCategorys = []
self.RxPDOInfos = []
self.RxPDOCategorys = []
-
+
#-------------------------------------------------------------------------------
# Used EEPROM Management
#-------------------------------------------------------------------------------
@@ -431,13 +431,13 @@
"BIT5": "34",
"BIT6": "35",
"BIT7": "36",
- "BIT8": "37"}
-
+ "BIT8": "37"}
+
def GetSmartViewInfos(self):
"""
Parse XML data for "Smart View" of EEPROM contents.
@return smartview_infos : EEPROM contents dictionary
- """
+ """
smartview_infos = {"eeprom_size": 128,
"pdi_type": 0,
@@ -455,7 +455,7 @@
"mailbox_standardconf_outlength": '0',
"mailbox_standardconf_instart": '0',
"mailbox_standardconf_inlength": '0'}
-
+
slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
type_infos = slave.getType()
device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
@@ -466,7 +466,7 @@
# get EEPROM size; <Device>-<Eeprom>-<ByteSize>
if eeprom_element["name"] == "ByteSize":
smartview_infos["eeprom_size"] = eeprom_element
-
+
elif eeprom_element["name"] == "ConfigData":
configData_data = self.DecimalToHex(eeprom_element)
# get PDI type; <Device>-<Eeprom>-<ConfigData> address 0x00
@@ -478,12 +478,12 @@
elif eeprom_element["name"] == "BootStrap":
bootstrap_data = "{:0>16x}".format(eeprom_element)
# get bootstrap configuration; <Device>-<Eeprom>-<BootStrap>
- for cfg, iter in [("mailbox_bootstrapconf_outstart", 0),
+ for cfg, iter in [("mailbox_bootstrapconf_outstart", 0),
("mailbox_bootstrapconf_outlength", 1),
("mailbox_bootstrapconf_instart", 2),
("mailbox_bootstrapconf_inlength", 3)]:
smartview_infos[cfg] = str(int(bootstrap_data[4*iter+2:4*(iter+1)]+bootstrap_data[4*iter:4*iter+2], 16))
-
+
# get protocol (profile) types supported by mailbox; <Device>-<Mailbox>
mb = device.getMailbox()
if mb is not None:
@@ -491,7 +491,7 @@
if getattr(mb,"get%s"%mailbox_protocol)() is not None:
smartview_infos["supported_mailbox"] += "%s, "%mailbox_protocol
smartview_infos["supported_mailbox"] = smartview_infos["supported_mailbox"].strip(", ")
-
+
# get standard configuration of mailbox; <Device>-<Sm>
for sm_element in device.getSm():
if sm_element.getcontent() == "MBoxOut":
@@ -510,42 +510,42 @@
for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]:
if available_device[0] == type_infos["device_type"]:
smartview_infos["vendor_id"] = "0x" + "{:0>8x}".format(vendor_id)
-
- # product code;
+
+ # product code;
if device.getType().getProductCode() is not None:
product_code = device.getType().getProductCode()
smartview_infos["product_code"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(product_code))
-
- # revision number;
+
+ # revision number;
if device.getType().getRevisionNo() is not None:
revision_no = device.getType().getRevisionNo()
smartview_infos["revision_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(revision_no))
-
+
# serial number;
if device.getType().getSerialNo() is not None:
serial_no = device.getType().getSerialNo()
smartview_infos["serial_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(serial_no))
-
+
return smartview_infos
-
+
else:
return None
-
+
def DecimalToHex(self, decnum):
"""
- Convert decimal value into hexadecimal representation.
+ Convert decimal value into hexadecimal representation.
@param decnum : decimal value
@return hex_data : hexadecimal representation of input value in decimal
- """
+ """
value = "%x" % decnum
value_len = len(value)
if (value_len % 2) == 0:
hex_len = value_len
else:
hex_len = (value_len / 2) * 2 + 2
-
+
hex_data = ("{:0>"+str(hex_len)+"x}").format(decnum)
-
+
return hex_data
def SiiRead(self):
@@ -553,7 +553,7 @@
Get slave EEPROM contents maintained by master device using "ethercat sii_read -p %d" command.
Command example : "ethercat sii_read -p 0"
@return return_val : result of "ethercat sii_read" (binary data)
- """
+ """
error, return_val = self.Controler.RemoteExec(SII_READ%(self.Controler.GetSlavePos()), return_val = None)
self.SiiData = return_val
return return_val
@@ -564,15 +564,15 @@
Command example : "ethercat sii_write -p 0 - (binary contents)"
@param binary : EEPROM contents in binary data format
@return return_val : result of "ethercat sii_write" (If it succeeds, the return value is NULL.)
- """
+ """
error, return_val = self.Controler.RemoteExec(SII_WRITE%(self.Controler.GetSlavePos()), return_val = None, sii_data = binary)
- return return_val
+ return return_val
def LoadData(self):
"""
Loading data from EEPROM use Sii_Read Method
@return self.BinaryCode : slave EEPROM data in binary format (zero-padded)
- """
+ """
return_val = self.Controler.CommonMethod.SiiRead()
self.BinaryCode = return_val
self.Controler.SiiData = self.BinaryCode
@@ -580,7 +580,7 @@
# append zero-filled padding data up to EEPROM size
for index in range(self.SmartViewInfosFromXML["eeprom_size"] - len(self.BinaryCode)):
self.BinaryCode = self.BinaryCode +'ff'.decode('hex')
-
+
return self.BinaryCode
def HexRead(self, binary):
@@ -589,42 +589,42 @@
@param binary : binary digits
@return hexCode : hexadecimal digits
@return hexview_table_row, hexview_table_col : Grid size for "Hex View" UI
- """
+ """
row_code = []
row_text = ""
row = 0
hex_code = []
hexview_table_col = 17
-
+
for index in range(0, len(binary)) :
if len(binary[index]) != 1:
break
else:
- digithexstr = hex(ord(binary[index]))
+ digithexstr = hex(ord(binary[index]))
tempvar2 = digithexstr[2:4]
if len(tempvar2) == 1:
tempvar2 = "0" + tempvar2
- row_code.append(tempvar2)
-
+ row_code.append(tempvar2)
+
if int(digithexstr, 16)>=32 and int(digithexstr, 16)<=126:
row_text = row_text + chr(int(digithexstr, 16))
else:
row_text = row_text + "."
-
- if index != 0 :
+
+ if index != 0 :
if len(row_code) == (hexview_table_col - 1):
row_code.append(row_text)
hex_code.append(row_code)
row_text = ""
row_code = []
- row = row + 1
-
+ row = row + 1
+
hexview_table_row = row
-
+
return hex_code, hexview_table_row, hexview_table_col
-
+
def GenerateEEPROMList(self, data, direction, length):
"""
Generate EEPROM data list by reconstructing 'data' string.
@@ -634,7 +634,7 @@
@param direction : endianness
@param length : data length
@return eeprom_list : reconstructed list data structure
- """
+ """
eeprom_list = []
if direction is 0 or 1:
@@ -646,7 +646,7 @@
data = data[(1-direction)*2:length-direction*2]
length -= 2
return eeprom_list
-
+
def XmlToEeprom(self):
"""
Extract slave EEPROM contents using slave ESI XML file.
@@ -657,8 +657,8 @@
- SyncM category : ExtractEEPROMSyncMCategory()
- Tx/RxPDO category : ExtractEEPROMPDOCategory()
- DC category : ExtractEEPROMDCCategory()
- @return eeprom_binary
- """
+ @return eeprom_binary
+ """
eeprom = []
data = ""
eeprom_size = 0
@@ -668,14 +668,14 @@
slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
type_infos = slave.getType()
device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
-
+
if device is not None:
# get ConfigData for EEPROM offset 0x0000-0x000d; <Device>-<Eeprom>-<ConfigData>
for eeprom_element in device.getEeprom().getcontent():
if eeprom_element["name"] == "ConfigData":
data = self.DecimalToHex(eeprom_element)
eeprom += self.GenerateEEPROMList(data, 0, 28)
-
+
# calculate CRC for EEPROM offset 0x000e-0x000f
crc = 0x48
for segment in eeprom:
@@ -683,15 +683,15 @@
bit = crc & 0x80
crc = (crc << 1) | ((int(segment, 16) >> (7 - i)) & 0x01)
if bit:
- crc ^= 0x07
+ crc ^= 0x07
for k in range(8):
bit = crc & 0x80
crc <<= 1
if bit:
- crc ^= 0x07
+ crc ^= 0x07
eeprom.append(hex(crc)[len(hex(crc))-3:len(hex(crc))-1])
eeprom.append("00")
-
+
# get VendorID for EEPROM offset 0x0010-0x0013;
data = ""
for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
@@ -699,35 +699,35 @@
if available_device[0] == type_infos["device_type"]:
data = "{:0>8x}".format(vendor_id)
eeprom += self.GenerateEEPROMList(data, 1, 8)
-
+
# get Product Code for EEPROM offset 0x0014-0x0017;
data = ""
if device.getType().getProductCode() is not None:
data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getProductCode()))
eeprom += self.GenerateEEPROMList(data, 1, 8)
-
+
# get Revision Number for EEPROM offset 0x0018-0x001b;
data = ""
if device.getType().getRevisionNo() is not None:
data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getRevisionNo()))
- eeprom += self.GenerateEEPROMList(data, 1, 8)
-
+ eeprom += self.GenerateEEPROMList(data, 1, 8)
+
# get Serial Number for EEPROM 0x001c-0x001f;
data = ""
if device.getType().getSerialNo() is not None:
data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getSerialNo()))
eeprom += self.GenerateEEPROMList(data, 1, 8)
-
+
# get Execution Delay for EEPROM 0x0020-0x0021; not analyzed yet
eeprom.append("00")
eeprom.append("00")
-
+
# get Port0/1 Delay for EEPROM offset 0x0022-0x0025; not analyzed yet
eeprom.append("00")
eeprom.append("00")
eeprom.append("00")
eeprom.append("00")
-
+
# reserved for EEPROM offset 0x0026-0x0027;
eeprom.append("00")
eeprom.append("00")
@@ -738,7 +738,7 @@
if eeprom_element["name"] == "BootStrap":
data = "{:0>16x}".format(eeprom_element)
eeprom += self.GenerateEEPROMList(data, 0, 16)
-
+
# get Standard Mailbox for EEPROM offset 0x0030-0x0037; <Device>-<sm>
data = ""
standard_send_mailbox_offset = None
@@ -752,7 +752,7 @@
elif sm_element.getcontent() == "MBoxIn":
standard_send_mailbox_offset = "{:0>4x}".format(ExtractHexDecValue(sm_element.getStartAddress()))
standard_send_mailbox_size = "{:0>4x}".format(ExtractHexDecValue(sm_element.getDefaultSize()))
-
+
if standard_receive_mailbox_offset is None:
eeprom.append("00")
eeprom.append("00")
@@ -777,7 +777,7 @@
else:
eeprom.append(standard_send_mailbox_size[2:4])
eeprom.append(standard_send_mailbox_size[0:2])
-
+
# get supported mailbox protocols for EEPROM offset 0x0038-0x0039;
data = 0
mb = device.getMailbox()
@@ -788,11 +788,11 @@
data = "{:0>4x}".format(data)
eeprom.append(data[2:4])
eeprom.append(data[0:2])
-
+
# resereved for EEPROM offset 0x003a-0x007b;
for i in range(0x007b-0x003a+0x0001):
eeprom.append("00")
-
+
# get EEPROM size for EEPROM offset 0x007c-0x007d;
data = ""
for eeprom_element in device.getEeprom().getcontent():
@@ -806,76 +806,76 @@
else:
eeprom.append(data[2:4])
eeprom.append(data[0:2])
-
- # Version for EEPROM 0x007e-0x007f;
+
+ # Version for EEPROM 0x007e-0x007f;
# According to "EtherCAT Slave Device Description(V0.3.0)"
eeprom.append("01")
eeprom.append("00")
-
+
# append String Category data
for data in self.ExtractEEPROMStringCategory(device):
eeprom.append(data)
-
+
# append General Category data
for data in self.ExtractEEPROMGeneralCategory(device):
eeprom.append(data)
-
+
# append FMMU Category data
for data in self.ExtractEEPROMFMMUCategory(device):
eeprom.append(data)
-
+
# append SyncM Category data
for data in self.ExtractEEPROMSyncMCategory(device):
eeprom.append(data)
-
+
# append TxPDO Category data
for data in self.ExtractEEPROMPDOCategory(device, "TxPdo"):
eeprom.append(data)
-
+
# append RxPDO Category data
for data in self.ExtractEEPROMPDOCategory(device, "RxPdo"):
eeprom.append(data)
-
+
# append DC Category data
for data in self.ExtractEEPROMDCCategory(device):
eeprom.append(data)
-
+
# append padding
padding = eeprom_size-len(eeprom)
for i in range(padding):
eeprom.append("ff")
-
+
# convert binary code
for index in range(eeprom_size):
eeprom_binary = eeprom_binary + eeprom[index].decode('hex')
-
+
return eeprom_binary
-
+
def ExtractEEPROMStringCategory(self, device):
"""
Extract "Strings" category data from slave ESI XML and generate EEPROM image data.
@param device : 'device' object in the slave ESI XML
@return eeprom : "Strings" category EEPROM image data
- """
+ """
eeprom = []
self.Strings = []
- data = ""
+ data = ""
count = 0 # string counter
padflag = False # padding flag if category length is odd
-
+
# index information for General Category in EEPROM
self.GroupIdx = 0
self.ImgIdx = 0
self.OrderIdx = 0
self.NameIdx = 0
-
- # flag for preventing duplicated vendor specific data
+
+ # flag for preventing duplicated vendor specific data
typeflag = False
grouptypeflag = False
groupnameflag = False
devnameflag = False
imageflag = False
-
+
# vendor specific data
# element1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Type>
# vendor_specific_data : vendor specific data (binary type)
@@ -885,7 +885,7 @@
for element in device.getType().getcontent():
data += element
if data is not "" and type(data) == unicode:
- for vendor_spec_string in vendor_spec_strings:
+ for vendor_spec_string in vendor_spec_strings:
if data == vendor_spec_string:
self.OrderIdx = vendor_spec_strings.index(data)+1
typeflag = True
@@ -900,7 +900,7 @@
for character in range(len(data)):
vendor_specific_data += "{:0>2x}".format(ord(data[character]))
data = ""
-
+
# element2-1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<GroupType>
data = device.getGroupType()
if data is not None and type(data) == unicode:
@@ -919,14 +919,14 @@
vendor_specific_data += "{:0>2x}".format(len(data))
for character in range(len(data)):
vendor_specific_data += "{:0>2x}".format(ord(data[character]))
-
- # element2-2; <EtherCATInfo>-<Groups>-<Group>-<Type>
- if grouptypeflag is False:
+
+ # element2-2; <EtherCATInfo>-<Groups>-<Group>-<Type>
+ if grouptypeflag is False:
if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
for group_type, group_etc in vendor["groups"].iteritems():
for device_item in group_etc["devices"]:
- if device == device_item[1]:
+ if device == device_item[1]:
data = group_type
if data is not None and type(data) == unicode:
for vendor_spec_string in vendor_spec_strings:
@@ -945,7 +945,7 @@
for character in range(len(data)):
vendor_specific_data += "{:0>2x}".format(ord(data[character]))
data = ""
-
+
# element3; <EtherCATInfo>-<Descriptions>-<Groups>-<Group>-<Name(LcId is "1033")>
if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
for vendorId, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
@@ -967,7 +967,7 @@
for character in range(len(data)):
vendor_specific_data += "{:0>2x}".format(ord(data[character]))
data = ""
-
+
# element4; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Name(LcId is "1033" or "1"?)>
for element in device.getName():
if element.getLcId() == 1 or element.getLcId()==1033:
@@ -988,7 +988,7 @@
for character in range(len(data)):
vendor_specific_data += "{:0>2x}".format(ord(data[character]))
data = ""
-
+
# element5-1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Image16x14>
if device.getcontent() is not None:
data = device.getcontent()
@@ -1007,7 +1007,7 @@
vendor_specific_data += "{:0>2x}".format(len(data))
for character in range(len(data)):
vendor_specific_data += "{:0>2x}".format(ord(data[character]))
-
+
# element5-2; <EtherCATInfo>-<Descriptions>-<Groups>-<Group>-<Image16x14>
if imageflag is False:
if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
@@ -1032,7 +1032,7 @@
for character in range(len(data)):
vendor_specific_data += "{:0>2x}".format(ord(data[character]))
data = ""
-
+
# DC related elements
# <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Dc>-<OpMode>-<Name>
dc_related_elements = ""
@@ -1046,7 +1046,7 @@
for character in range(len(data)):
dc_related_elements += "{:0>2x}".format(ord(data[character]))
data = ""
-
+
# Input elements(TxPDO)
# <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<TxPdo>; Name
input_elements = ""
@@ -1055,7 +1055,7 @@
for name in element.getName():
data = name.getcontent()
for input in inputs:
- if data == input:
+ if data == input:
data = ""
if data is not "":
count += 1
@@ -1064,12 +1064,12 @@
input_elements += "{:0>2x}".format(len(data))
for character in range(len(data)):
input_elements += "{:0>2x}".format(ord(data[character]))
- data = ""
+ data = ""
for entry in element.getEntry():
for name in entry.getName():
data = name.getcontent()
for input in inputs:
- if data == input:
+ if data == input:
data = ""
if data is not "":
count += 1
@@ -1079,7 +1079,7 @@
for character in range(len(data)):
input_elements += "{:0>2x}".format(ord(data[character]))
data = ""
-
+
# Output elements(RxPDO)
# <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<RxPdo>; Name
output_elements = ""
@@ -1088,7 +1088,7 @@
for name in element.getName():
data = name.getcontent()
for output in outputs:
- if data == output:
+ if data == output:
data = ""
if data is not "":
count += 1
@@ -1097,12 +1097,12 @@
output_elements += "{:0>2x}".format(len(data))
for character in range(len(data)):
output_elements += "{:0>2x}".format(ord(data[character]))
- data = ""
+ data = ""
for entry in element.getEntry():
for name in entry.getName():
data = name.getcontent()
for output in outputs:
- if data == output:
+ if data == output:
data = ""
if data is not "":
count += 1
@@ -1111,8 +1111,8 @@
output_elements += "{:0>2x}".format(len(data))
for character in range(len(data)):
output_elements += "{:0>2x}".format(ord(data[character]))
- data = ""
-
+ data = ""
+
# form eeprom data
# category header
eeprom.append("0a")
@@ -1137,38 +1137,38 @@
eeprom.append("00")
else:
eeprom.append(element[0:2])
- element = element[2:len(element)]
- # padding if length is odd bytes
+ element = element[2:len(element)]
+ # padding if length is odd bytes
if padflag is True:
eeprom.append("ff")
-
+
return eeprom
-
+
def ExtractEEPROMGeneralCategory(self, device):
"""
Extract "General" category data from slave ESI XML and generate EEPROM image data.
@param device : 'device' object in the slave ESI XML
@return eeprom : "Strings" category EEPROM image data
- """
+ """
eeprom = []
data = ""
-
+
# category header
eeprom.append("1e")
eeprom.append("00")
-
+
# category length
eeprom.append("10")
eeprom.append("00")
-
+
# word 1 : Group Type index and Image index in STRINGS Category
eeprom.append("{:0>2x}".format(self.GroupIdx))
eeprom.append("{:0>2x}".format(self.ImgIdx))
-
+
# word 2 : Device Type index and Device Name index in STRINGS Category
eeprom.append("{:0>2x}".format(self.OrderIdx))
eeprom.append("{:0>2x}".format(self.NameIdx))
-
+
# word 3 : Physical Layer Port info. and CoE Details
eeprom.append("01") # Physical Layer Port info - assume 01
# CoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<CoE>
@@ -1178,12 +1178,12 @@
if mb is not None :
coe = mb.getCoE()
if coe is not None:
- for bit,flag in enumerate(["SdoInfo", "PdoAssign", "PdoConfig",
+ for bit,flag in enumerate(["SdoInfo", "PdoAssign", "PdoConfig",
"PdoUpload", "CompleteAccess"]):
if getattr(coe,"get%s"%flag)() is not None:
- coe_details += 1<<bit
+ coe_details += 1<<bit
eeprom.append("{:0>2x}".format(coe_details))
-
+
# word 4 : FoE Details and EoE Details
# FoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<FoE>
if mb is not None and mb.getFoE() is not None:
@@ -1195,7 +1195,7 @@
eeprom.append("01")
else:
eeprom.append("00")
-
+
# word 5 : SoE Channels(reserved) and DS402 Channels
# SoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<SoE>
if mb is not None and mb.getSoE() is not None:
@@ -1209,10 +1209,10 @@
if coe is not None :
ds402ch = coe.getDS402Channels()
eeprom.append("01" if ds402ch in [True,1] else "00")
-
+
# word 6 : SysmanClass(reserved) and Flags
eeprom.append("00") # reserved
- # Flags
+ # Flags
en_safeop = False
en_lrw = False
if device.getType().getTcCfgModeSafeOp() == True \
@@ -1221,10 +1221,10 @@
if device.getType().getUseLrdLwr() == True \
or device.getType().getUseLrdLwr() == 1:
en_lrw = True
-
+
flags = "0b"+"000000"+str(int(en_lrw))+str(int(en_safeop))
eeprom.append("{:0>2x}".format(int(flags, 2)))
-
+
# word 7 : Current On EBus (assume 0x0000)
eeprom.append("00")
eeprom.append("00")
@@ -1247,20 +1247,20 @@
eeprom.append("00")
eeprom.append("00")
eeprom.append("00")
-
+
return eeprom
-
+
def ExtractEEPROMFMMUCategory(self, device):
"""
Extract "FMMU" category data from slave ESI XML and generate EEPROM image data.
@param device : 'device' object in the slave ESI XML
@return eeprom : "Strings" category EEPROM image data
- """
+ """
eeprom = []
data = ""
count = 0 # number of FMMU
padflag = False
-
+
for fmmu in device.getFmmu():
count += 1
if fmmu.getcontent() == "Outputs":
@@ -1269,7 +1269,7 @@
data += "02"
if fmmu.getcontent() == "MBoxState":
data += "03"
-
+
# construct of EEPROM data
if data is not "":
# category header
@@ -1280,7 +1280,7 @@
padflag = True
eeprom.append("{:0>4x}".format((count+1)/2)[2:4])
eeprom.append("{:0>4x}".format((count+1)/2)[0:2])
- else:
+ else:
eeprom.append("{:0>4x}".format((count)/2)[2:4])
eeprom.append("{:0>4x}".format((count)/2)[0:2])
for i in range(count):
@@ -1289,22 +1289,22 @@
else:
eeprom.append(data[0:2])
data = data[2:len(data)]
- # padding if length is odd bytes
+ # padding if length is odd bytes
if padflag is True:
- eeprom.append("ff")
-
+ eeprom.append("ff")
+
return eeprom
-
+
def ExtractEEPROMSyncMCategory(self, device):
"""
Extract "SyncM" category data from slave ESI XML and generate EEPROM image data.
@param device : 'device' object in the slave ESI XML
@return eeprom : "Strings" category EEPROM image data
- """
+ """
eeprom = []
data = ""
number = {"MBoxOut":"01", "MBoxIn":"02", "Outputs":"03", "Inputs":"04"}
-
+
for sm in device.getSm():
for attr in [sm.getStartAddress(),
sm.getDefaultSize(),
@@ -1313,18 +1313,18 @@
data += "{:0>4x}".format(ExtractHexDecValue(attr))[2:4]
data += "{:0>4x}".format(ExtractHexDecValue(attr))[0:2]
else:
- data += "0000"
+ data += "0000"
if sm.getEnable() == "1" or sm.getEnable() == True:
data += "01"
else:
data += "00"
data += number[sm.getcontent()]
-
+
if data is not "":
# category header
eeprom.append("29")
eeprom.append("00")
- # category length
+ # category length
eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
for i in range(len(data)/2):
@@ -1335,21 +1335,21 @@
data = data[2:len(data)]
return eeprom
-
+
def ExtractEEPROMPDOCategory(self, device, pdotype):
"""
Extract ""PDO (Tx, Rx)"" category data from slave ESI XML and generate EEPROM image data.
@param device : 'device' object in the slave ESI XML
@param pdotype : identifier whether "TxPDO" or "RxPDO".
@return eeprom : "Strings" category EEPROM image data
- """
+ """
eeprom = []
data = ""
count = 0
en_fixed = False
en_mandatory = False
en_virtual = False
-
+
for element in eval("device.get%s()"%pdotype):
# PDO Index
data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[2:4]
@@ -1384,7 +1384,7 @@
if element.getVirtual() == True or element.getVirtual():
en_virtual = True
data += str(int(en_fixed)) + str(int(en_mandatory)) + str(int(en_virtual)) + "0"
-
+
for entry in element.getEntry():
# Entry Index
data += "{:0>4x}".format(ExtractHexDecValue(entry.getIndex().getcontent()))[2:4]
@@ -1422,7 +1422,7 @@
if entry.getFixed() == True or entry.getFixed() == 1:
en_fixed = True
data += str(int(en_fixed)) + "000"
-
+
if data is not "":
# category header
if pdotype == "TxPdo":
@@ -1432,7 +1432,7 @@
else:
eeprom.append("00")
eeprom.append("00")
- # category length
+ # category length
eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
data = str(data.lower())
@@ -1442,20 +1442,20 @@
else:
eeprom.append(data[0:2])
data = data[2:len(data)]
-
+
return eeprom
-
+
def ExtractEEPROMDCCategory(self, device):
"""
Extract "DC(Distributed Clock)" category data from slave ESI XML and generate EEPROM image data.
@param device : 'device' object in the slave ESI XML
@return eeprom : "Strings" category EEPROM image data
- """
+ """
eeprom = []
data = ""
count = 0
namecount = 0
-
+
if device.getDc() is not None:
for element in device.getDc().getOpMode():
count += 1
@@ -1501,12 +1501,12 @@
# assume that word 11-12 are 0x0000
data += "0000"
data += "0000"
-
+
if data is not "":
# category header
eeprom.append("3c")
eeprom.append("00")
- # category length
+ # category length
eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
data = str(data.lower())
@@ -1516,9 +1516,9 @@
else:
eeprom.append(data[0:2])
data = data[2:len(data)]
-
+
return eeprom
-
+
#-------------------------------------------------------------------------------
# Used Register Access
#-------------------------------------------------------------------------------
@@ -1529,10 +1529,10 @@
@param offset : register address
@param length : register length
@return return_val : register data
- """
+ """
error, return_val = self.Controler.RemoteExec(REG_READ%(self.Controler.GetSlavePos(), offset, length), return_val = None)
- return return_val
-
+ return return_val
+
def RegWrite(self, address, data):
"""
Write data to slave ESC register using "ethercat reg_write -p %d %s %s" command.
@@ -1540,28 +1540,28 @@
@param address : register address
@param data : data to write
@return return_val : the execution result of "ethercat reg_write" (for error check)
- """
+ """
error, return_val = self.Controler.RemoteExec(REG_WRITE%(self.Controler.GetSlavePos(), address, data), return_val = None)
- return return_val
-
+ return return_val
+
def Rescan(self):
"""
Synchronize EEPROM data in master controller with the data in slave device after EEPROM write.
Command example : "ethercat rescan -p 0"
- """
+ """
error, return_val = self.Controler.RemoteExec(RESCAN%(self.Controler.GetSlavePos()), return_val = None)
-
+
#-------------------------------------------------------------------------------
# Common Use Methods
#-------------------------------------------------------------------------------
def CheckConnect(self, cyclic_flag):
"""
- Check connection status (1) between Beremiz and the master (2) between the master and the slave.
+ Check connection status (1) between Beremiz and the master (2) between the master and the slave.
@param cyclic_flag: 0 - one shot, 1 - periodic
@return True or False
- """
+ """
if self.Controler.GetCTRoot()._connector is not None:
- # Check connection between the master and the slave.
+ # Check connection between the master and the slave.
# Command example : "ethercat xml -p 0"
error, return_val = self.Controler.RemoteExec(SLAVE_XML%(self.Controler.GetSlavePos()), return_val = None)
number_of_lines = return_val.split("\n")
@@ -1569,23 +1569,23 @@
if not cyclic_flag :
self.CreateErrorDialog('No connected slaves')
return False
-
+
elif len(number_of_lines) > 2 :
return True
- else:
+ else:
# The master controller is not connected to Beremiz host
if not cyclic_flag :
self.CreateErrorDialog('PLC not connected!')
return False
-
+
def CreateErrorDialog(self, mention):
"""
Create a dialog to indicate error or warning.
@param mention : Error String
- """
+ """
app_frame = self.Controler.GetCTRoot().AppFrame
- dlg = wx.MessageDialog (app_frame, mention,
- ' Warning...',
+ dlg = wx.MessageDialog (app_frame, mention,
+ ' Warning...',
wx.OK | wx.ICON_INFORMATION)
dlg.ShowModal()
- dlg.Destroy()
+ dlg.Destroy()
--- a/etherlab/ConfigEditor.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/ConfigEditor.py Fri Sep 28 17:20:11 2018 +0300
@@ -67,22 +67,22 @@
LOCATION_MODEL = re.compile("(?:%[IQM](?:[XBWLD]?([0-9]+(?:\.[0-9]+)*)))$")
class NodeVariablesSizer(wx.FlexGridSizer):
-
+
def __init__(self, parent, controler, position_column=False):
wx.FlexGridSizer.__init__(self, cols=1, hgap=0, rows=2, vgap=5)
self.AddGrowableCol(0)
self.AddGrowableRow(1)
-
+
self.Controler = controler
self.PositionColumn = position_column
-
+
self.VariablesFilter = wx.ComboBox(parent, style=wx.TE_PROCESS_ENTER)
self.VariablesFilter.Bind(wx.EVT_COMBOBOX, self.OnVariablesFilterChanged)
self.VariablesFilter.Bind(wx.EVT_TEXT_ENTER, self.OnVariablesFilterChanged)
self.VariablesFilter.Bind(wx.EVT_CHAR, self.OnVariablesFilterKeyDown)
self.AddWindow(self.VariablesFilter, flag=wx.GROW)
-
- self.VariablesGrid = wx.gizmos.TreeListCtrl(parent,
+
+ self.VariablesGrid = wx.gizmos.TreeListCtrl(parent,
style=wx.TR_DEFAULT_STYLE |
wx.TR_ROW_LINES |
wx.TR_COLUMN_LINES |
@@ -91,46 +91,46 @@
self.VariablesGrid.GetMainWindow().Bind(wx.EVT_LEFT_DOWN,
self.OnVariablesGridLeftClick)
self.AddWindow(self.VariablesGrid, flag=wx.GROW)
-
+
self.Filters = []
for desc, value in VARIABLES_FILTERS:
self.VariablesFilter.Append(desc)
self.Filters.append(value)
-
+
self.VariablesFilter.SetSelection(0)
self.CurrentFilter = self.Filters[0]
self.VariablesFilterFirstCharacter = True
-
+
if position_column:
for colname, colsize, colalign in zip(GetVariablesTableColnames(position_column),
[40, 80, 350, 80, 100, 80, 150],
- [wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT,
- wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT,
+ [wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT,
+ wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT,
wx.ALIGN_LEFT]):
self.VariablesGrid.AddColumn(_(colname), colsize, colalign)
self.VariablesGrid.SetMainColumn(2)
else:
for colname, colsize, colalign in zip(GetVariablesTableColnames(),
[40, 350, 80, 100, 80, 150],
- [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT,
+ [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT,
wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]):
self.VariablesGrid.AddColumn(_(colname), colsize, colalign)
self.VariablesGrid.SetMainColumn(1)
-
+
def RefreshView(self):
entries = self.Controler.GetSlaveVariables(self.CurrentFilter)
self.RefreshVariablesGrid(entries)
-
+
def RefreshVariablesGrid(self, entries):
root = self.VariablesGrid.GetRootItem()
if not root.IsOk():
root = self.VariablesGrid.AddRoot(_("Slave entries"))
self.GenerateVariablesGridBranch(root, entries, GetVariablesTableColnames(self.PositionColumn))
self.VariablesGrid.Expand(root)
-
+
def GenerateVariablesGridBranch(self, root, entries, colnames, idx=0):
item, root_cookie = self.VariablesGrid.GetFirstChild(root)
-
+
no_more_items = not item.IsOk()
for entry in entries:
idx += 1
@@ -153,7 +153,7 @@
if not no_more_items:
item, root_cookie = self.VariablesGrid.GetNextChild(root, root_cookie)
no_more_items = not item.IsOk()
-
+
if not no_more_items:
to_delete = []
while item.IsOk():
@@ -161,9 +161,9 @@
item, root_cookie = self.VariablesGrid.GetNextChild(root, root_cookie)
for item in to_delete:
self.VariablesGrid.Delete(item)
-
+
return idx
-
+
def OnVariablesFilterChanged(self, event):
filter = self.VariablesFilter.GetSelection()
if filter != -1:
@@ -190,29 +190,29 @@
self.VariablesFilter.SetValue(VARIABLE_INDEX_FILTER_FORMAT % self.CurrentFilter[0])
self.VariablesFilterFirstCharacter = True
event.Skip()
-
+
def OnVariablesFilterKeyDown(self, event):
if self.VariablesFilterFirstCharacter:
keycode = event.GetKeyCode()
- if keycode not in [wx.WXK_RETURN,
+ if keycode not in [wx.WXK_RETURN,
wx.WXK_NUMPAD_ENTER]:
self.VariablesFilterFirstCharacter = False
if keycode not in NAVIGATION_KEYS:
self.VariablesFilter.SetValue("")
- if keycode not in [wx.WXK_DELETE,
- wx.WXK_NUMPAD_DELETE,
+ if keycode not in [wx.WXK_DELETE,
+ wx.WXK_NUMPAD_DELETE,
wx.WXK_BACK]:
event.Skip()
else:
event.Skip()
-
+
def OnVariablesGridLeftClick(self, event):
item, flags, col = self.VariablesGrid.HitTest(event.GetPosition())
if item.IsOk():
entry = self.VariablesGrid.GetItemPyData(item)
data_type = entry.get("Type", "")
data_size = self.Controler.GetSizeOfType(data_type)
-
+
if col == -1 and data_size is not None:
pdo_mapping = entry.get("PDOMapping", "")
access = entry.get("Access", "")
@@ -225,7 +225,7 @@
node_name = self.Controler.GetSlaveName(slave_pos)
else:
node_name = self.Controler.CTNName()
-
+
if pdo_mapping != "":
var_name = "%s_%4.4x_%2.2x" % (node_name, entry_index, entry_subindex)
if pdo_mapping == "T":
@@ -234,13 +234,13 @@
dir = "%Q"
location = "%s%s" % (dir, data_size) + \
".".join(map(lambda x:str(x), location + (entry_index, entry_subindex)))
-
+
data = wx.TextDataObject(str((location, "location", data_type, var_name, "", access)))
dragSource = wx.DropSource(self.VariablesGrid)
dragSource.SetData(data)
dragSource.DoDragDrop()
return
-
+
elif self.PositionColumn:
location = self.Controler.GetCurrentLocation() +\
(slave_pos, entry_index, entry_subindex)
@@ -249,51 +249,51 @@
dragSource.SetData(data)
dragSource.DoDragDrop()
return
-
+
event.Skip()
class NodeEditor(ConfTreeNodeEditor):
-
+
CONFNODEEDITOR_TABS = [
(_("Ethercat node"), "_create_EthercatNodeEditor"),
# Add Notebook Tab for EtherCAT Management Treebook
(_("EtherCAT Management"), "_create_EtherCATManagementEditor")
]
-
+
def _create_EthercatNodeEditor(self, prnt):
self.EthercatNodeEditor = wx.Panel(prnt, style=wx.TAB_TRAVERSAL)
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(1)
-
+
variables_label = wx.StaticText(self.EthercatNodeEditor,
label=_('Variable entries:'))
main_sizer.AddWindow(variables_label, border=10, flag=wx.TOP|wx.LEFT|wx.RIGHT)
-
+
self.NodeVariables = NodeVariablesSizer(self.EthercatNodeEditor, self.Controler)
- main_sizer.AddSizer(self.NodeVariables, border=10,
+ main_sizer.AddSizer(self.NodeVariables, border=10,
flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.EthercatNodeEditor.SetSizer(main_sizer)
return self.EthercatNodeEditor
-
+
def __init__(self, parent, controler, window):
ConfTreeNodeEditor.__init__(self, parent, controler, window)
-
+
# add Contoler for use EthercatSlave.py Method
self.Controler = controler
-
+
def GetBufferState(self):
return False, False
-
+
def RefreshView(self):
ConfTreeNodeEditor.RefreshView(self)
-
+
self.NodeVariables.RefreshView()
- # -------------------For EtherCAT Management ----------------------------------------------
+ # -------------------For EtherCAT Management ----------------------------------------------
def _create_EtherCATManagementEditor(self, prnt):
self.EtherCATManagementEditor = wx.ScrolledWindow(prnt,
style=wx.TAB_TRAVERSAL|wx.HSCROLL|wx.VSCROLL)
@@ -302,14 +302,14 @@
self.EtherCATManagermentEditor_Main_Sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
self.EtherCATManagermentEditor_Main_Sizer.AddGrowableCol(0)
self.EtherCATManagermentEditor_Main_Sizer.AddGrowableRow(0)
-
+
self.EtherCATManagementTreebook = EtherCATManagementTreebook(self.EtherCATManagementEditor, self.Controler, self)
-
+
self.EtherCATManagermentEditor_Main_Sizer.AddSizer(self.EtherCATManagementTreebook, border=10, flag=wx.GROW)
self.EtherCATManagementEditor.SetSizer(self.EtherCATManagermentEditor_Main_Sizer)
return self.EtherCATManagementEditor
-
+
def OnResize(self, event):
self.EtherCATManagementEditor.GetBestSize()
xstart, ystart = self.EtherCATManagementEditor.GetViewStart()
@@ -318,7 +318,7 @@
posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
self.EtherCATManagementEditor.Scroll(posx, posy)
- self.EtherCATManagementEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
+ self.EtherCATManagementEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
event.Skip()
# -------------------------------------------------------------------------------------------------------
@@ -328,13 +328,13 @@
def GetProcessVariablesTableColnames():
_ = lambda x : x
- return ["#", _("Name"),
- _("Read from (nodeid, index, subindex)"),
+ return ["#", _("Name"),
+ _("Read from (nodeid, index, subindex)"),
_("Write to (nodeid, index, subindex)"),
_("Description")]
class ProcessVariablesTable(CustomTable):
-
+
def GetValue(self, row, col):
if row < self.GetNumberRows():
if col == 0:
@@ -351,7 +351,7 @@
return value
return "%d, #x%0.4X, #x%0.2X" % value
return self.data[row].get(colname, "")
-
+
def SetValue(self, row, col, value):
if col < len(self.colnames):
colname = self.GetColLabelValue(col, False)
@@ -361,7 +361,7 @@
self.data[row]["WriteTo"] = value
else:
self.data[row][colname] = value
-
+
def _updateColAttrs(self, grid):
"""
wx.grid.Grid -> update the column attributes to add the
@@ -380,18 +380,18 @@
grid.SetReadOnly(row, col, False)
else:
grid.SetReadOnly(row, col, True)
-
+
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
-
+
self.ResizeRow(grid, row)
class ProcessVariableDropTarget(wx.TextDropTarget):
-
+
def __init__(self, parent):
wx.TextDropTarget.__init__(self)
self.ParentWindow = parent
-
+
def OnDropText(self, x, y, data):
self.ParentWindow.Select()
x, y = self.ParentWindow.ProcessVariablesGrid.CalcUnscrolledPosition(x, y)
@@ -413,7 +413,7 @@
if result is not None:
location = map(int, result.group(1).split('.'))
master_location = self.ParentWindow.GetMasterLocation()
- if (master_location == tuple(location[:len(master_location)]) and
+ if (master_location == tuple(location[:len(master_location)]) and
len(location) - len(master_location) == 3):
values = tuple(location[len(master_location):])
var_type = self.ParentWindow.Controler.GetSlaveVariableDataType(*values)
@@ -436,10 +436,10 @@
message = _("'Read from' and 'Write to' variables types are not compatible")
else:
message = _("Invalid value \"%s\" for process variable")%data
-
+
if message is not None:
wx.CallAfter(self.ShowMessage, message)
-
+
def ShowMessage(self, message):
message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
message.ShowModal()
@@ -450,11 +450,11 @@
return [_("Position"), _("Index"), _("Subindex"), _("Value"), _("Description")]
class StartupCommandDropTarget(wx.TextDropTarget):
-
+
def __init__(self, parent):
wx.TextDropTarget.__init__(self)
self.ParentWindow = parent
-
+
def OnDropText(self, x, y, data):
self.ParentWindow.Select()
message = None
@@ -478,7 +478,7 @@
access = values[2]
if location is not None:
master_location = self.ParentWindow.GetMasterLocation()
- if (master_location == tuple(location[:len(master_location)]) and
+ if (master_location == tuple(location[:len(master_location)]) and
len(location) - len(master_location) == 3):
if access in ["wo", "rw"]:
self.ParentWindow.AddStartupCommand(*location[len(master_location):])
@@ -486,10 +486,10 @@
message = _("Entry can't be write through SDO")
else:
message = _("Invalid value \"%s\" for startup command")%data
-
+
if message is not None:
wx.CallAfter(self.ShowMessage, message)
-
+
def ShowMessage(self, message):
message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
message.ShowModal()
@@ -514,7 +514,7 @@
elif colname == "Subindex":
return "#x%0.2X" % value
return value
-
+
def SetValue(self, row, col, value):
if col < len(self.colnames):
colname = self.GetColLabelValue(col, False)
@@ -532,10 +532,10 @@
self.old_value = self.data[row][colname]
value = int(value)
self.data[row][colname] = value
-
+
def GetOldValue(self):
return self.old_value
-
+
def _updateColAttrs(self, grid):
"""
wx.grid.Grid -> update the column attributes to add the
@@ -554,13 +554,13 @@
else:
editor = wx.grid.GridCellTextEditor()
renderer = wx.grid.GridCellStringRenderer()
-
+
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
grid.SetReadOnly(row, col, False)
-
+
self.ResizeRow(grid, row)
-
+
def GetCommandIndex(self, position, command_idx):
for row, command in enumerate(self.data):
if command["Position"] == position and command["command_idx"] == command_idx:
@@ -568,15 +568,15 @@
return None
class MasterNodesVariablesSizer(NodeVariablesSizer):
-
+
def __init__(self, parent, controler):
NodeVariablesSizer.__init__(self, parent, controler, True)
-
+
self.CurrentNodesFilter = {}
-
+
def SetCurrentNodesFilter(self, nodes_filter):
self.CurrentNodesFilter = nodes_filter
-
+
def RefreshView(self):
if self.CurrentNodesFilter is not None:
args = self.CurrentNodesFilter.copy()
@@ -587,27 +587,27 @@
NODE_POSITION_FILTER_FORMAT = _("Node Position: %d")
class MasterEditor(ConfTreeNodeEditor):
-
+
CONFNODEEDITOR_TABS = [
(_("Network"), "_create_EthercatMasterEditor"),
(_("Master State"), "_create_MasterStateEditor")
]
-
+
def _create_MasterStateEditor(self, prnt):
self.MasterStateEditor = wx.ScrolledWindow(prnt, style=wx.TAB_TRAVERSAL|wx.HSCROLL|wx.VSCROLL)
self.MasterStateEditor.Bind(wx.EVT_SIZE, self.OnResize)
-
+
self.MasterStateEditor_Panel_Main_Sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
self.MasterStateEditor_Panel_Main_Sizer.AddGrowableCol(0)
self.MasterStateEditor_Panel_Main_Sizer.AddGrowableRow(0)
-
+
self.MasterStateEditor_Panel = MasterStatePanelClass(self.MasterStateEditor, self.Controler)
-
+
self.MasterStateEditor_Panel_Main_Sizer.AddSizer(self.MasterStateEditor_Panel, border=10, flag=wx.GROW)
-
+
self.MasterStateEditor.SetSizer(self.MasterStateEditor_Panel_Main_Sizer)
return self.MasterStateEditor
-
+
def OnResize(self, event):
self.MasterStateEditor.GetBestSize()
xstart, ystart = self.MasterStateEditor.GetViewStart()
@@ -616,80 +616,80 @@
posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
self.MasterStateEditor.Scroll(posx, posy)
- self.MasterStateEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
+ self.MasterStateEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
event.Skip()
-
+
def _create_EthercatMasterEditor(self, prnt):
- self.EthercatMasterEditor = wx.ScrolledWindow(prnt,
+ self.EthercatMasterEditor = wx.ScrolledWindow(prnt,
style=wx.TAB_TRAVERSAL|wx.HSCROLL|wx.VSCROLL)
self.EthercatMasterEditor.Bind(wx.EVT_SIZE, self.OnResize)
-
+
self.EthercatMasterEditorSizer = wx.BoxSizer(wx.VERTICAL)
-
+
self.NodesFilter = wx.ComboBox(self.EthercatMasterEditor,
style=wx.TE_PROCESS_ENTER)
self.Bind(wx.EVT_COMBOBOX, self.OnNodesFilterChanged, self.NodesFilter)
self.Bind(wx.EVT_TEXT_ENTER, self.OnNodesFilterChanged, self.NodesFilter)
self.NodesFilter.Bind(wx.EVT_CHAR, self.OnNodesFilterKeyDown)
-
+
process_variables_header = wx.BoxSizer(wx.HORIZONTAL)
-
+
process_variables_label = wx.StaticText(self.EthercatMasterEditor,
label=_("Process variables mapped between nodes:"))
process_variables_header.AddWindow(process_variables_label, 1,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
for name, bitmap, help in [
("AddVariableButton", "add_element", _("Add process variable")),
("DeleteVariableButton", "remove_element", _("Remove process variable")),
("UpVariableButton", "up", _("Move process variable up")),
("DownVariableButton", "down", _("Move process variable down"))]:
- button = wx.lib.buttons.GenBitmapButton(self.EthercatMasterEditor, bitmap=GetBitmap(bitmap),
+ button = wx.lib.buttons.GenBitmapButton(self.EthercatMasterEditor, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
button.SetToolTipString(help)
setattr(self, name, button)
process_variables_header.AddWindow(button, border=5, flag=wx.LEFT)
-
+
self.ProcessVariablesGrid = CustomGrid(self.EthercatMasterEditor, style=wx.VSCROLL)
self.ProcessVariablesGrid.SetMinSize(wx.Size(0, 150))
self.ProcessVariablesGrid.SetDropTarget(ProcessVariableDropTarget(self))
- self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
self.OnProcessVariablesGridCellChange)
- self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK,
+ self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK,
self.OnProcessVariablesGridCellLeftClick)
self.ProcessVariablesGrid.Bind(wx.EVT_KEY_DOWN, self.OnProcessVariablesGridKeyDown)
-
+
startup_commands_header = wx.BoxSizer(wx.HORIZONTAL)
-
+
startup_commands_label = wx.StaticText(self.EthercatMasterEditor,
label=_("Startup service variables assignments:"))
startup_commands_header.AddWindow(startup_commands_label, 1,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
for name, bitmap, help in [
("AddCommandButton", "add_element", _("Add startup service variable")),
("DeleteCommandButton", "remove_element", _("Remove startup service variable"))]:
- button = wx.lib.buttons.GenBitmapButton(self.EthercatMasterEditor, bitmap=GetBitmap(bitmap),
+ button = wx.lib.buttons.GenBitmapButton(self.EthercatMasterEditor, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
button.SetToolTipString(help)
setattr(self, name, button)
startup_commands_header.AddWindow(button, border=5, flag=wx.LEFT)
-
+
self.StartupCommandsGrid = CustomGrid(self.EthercatMasterEditor, style=wx.VSCROLL)
self.StartupCommandsGrid.SetDropTarget(StartupCommandDropTarget(self))
self.StartupCommandsGrid.SetMinSize(wx.Size(0, 150))
- self.StartupCommandsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.StartupCommandsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
self.OnStartupCommandsGridCellChange)
- self.StartupCommandsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
+ self.StartupCommandsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
self.OnStartupCommandsGridEditorShow)
-
+
self.NodesVariables = MasterNodesVariablesSizer(self.EthercatMasterEditor, self.Controler)
-
+
main_staticbox = wx.StaticBox(self.EthercatMasterEditor, label=_("Node filter:"))
staticbox_sizer = wx.StaticBoxSizer(main_staticbox, wx.VERTICAL)
self.EthercatMasterEditorSizer.AddSizer(staticbox_sizer, 0, border=10, flag=wx.GROW|wx.ALL)
-
+
main_staticbox_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=0)
main_staticbox_sizer.AddGrowableCol(0)
main_staticbox_sizer.AddGrowableRow(2)
@@ -697,61 +697,61 @@
main_staticbox_sizer.AddGrowableRow(5)
staticbox_sizer.AddSizer(main_staticbox_sizer, 1, flag=wx.GROW)
main_staticbox_sizer.AddWindow(self.NodesFilter, border=5, flag=wx.GROW|wx.ALL)
- main_staticbox_sizer.AddSizer(process_variables_header, border=5,
+ main_staticbox_sizer.AddSizer(process_variables_header, border=5,
flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
- main_staticbox_sizer.AddWindow(self.ProcessVariablesGrid, 1,
+ main_staticbox_sizer.AddWindow(self.ProcessVariablesGrid, 1,
border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
- main_staticbox_sizer.AddSizer(startup_commands_header,
+ main_staticbox_sizer.AddSizer(startup_commands_header,
border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
- main_staticbox_sizer.AddWindow(self.StartupCommandsGrid, 1,
+ main_staticbox_sizer.AddWindow(self.StartupCommandsGrid, 1,
border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
-
+
second_staticbox = wx.StaticBox(self.EthercatMasterEditor, label=_("Nodes variables filter:"))
second_staticbox_sizer = wx.StaticBoxSizer(second_staticbox, wx.VERTICAL)
second_staticbox_sizer.AddSizer(self.NodesVariables, 1, border=5, flag=wx.GROW|wx.ALL)
-
- main_staticbox_sizer.AddSizer(second_staticbox_sizer, 1,
+
+ main_staticbox_sizer.AddSizer(second_staticbox_sizer, 1,
border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
-
+
self.EthercatMasterEditor.SetSizer(self.EthercatMasterEditorSizer)
-
+
return self.EthercatMasterEditor
def __init__(self, parent, controler, window):
ConfTreeNodeEditor.__init__(self, parent, controler, window)
-
+
# ------------------------------------------------------------------
self.Controler = controler
# ------------------------------------------------------------------
-
+
self.ProcessVariables = []
self.CellShown = None
self.NodesFilterFirstCharacter = True
-
+
self.ProcessVariablesDefaultValue = {"Name": "", "ReadFrom": "", "WriteTo": "", "Description": ""}
self.ProcessVariablesTable = ProcessVariablesTable(self, [], GetProcessVariablesTableColnames())
self.ProcessVariablesColSizes = [40, 100, 150, 150, 200]
self.ProcessVariablesColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
-
+
self.ProcessVariablesGrid.SetTable(self.ProcessVariablesTable)
self.ProcessVariablesGrid.SetButtons({"Add": self.AddVariableButton,
"Delete": self.DeleteVariableButton,
"Up": self.UpVariableButton,
"Down": self.DownVariableButton})
-
+
def _AddVariablesElement(new_row):
self.ProcessVariablesTable.InsertRow(new_row, self.ProcessVariablesDefaultValue.copy())
self.SaveProcessVariables()
self.ProcessVariablesTable.ResetView(self.ProcessVariablesGrid)
return new_row
setattr(self.ProcessVariablesGrid, "_AddRow", _AddVariablesElement)
-
+
def _DeleteVariablesElement(row):
self.ProcessVariablesTable.RemoveRow(row)
self.SaveProcessVariables()
self.ProcessVariablesTable.ResetView(self.ProcessVariablesGrid)
setattr(self.ProcessVariablesGrid, "_DeleteRow", _DeleteVariablesElement)
-
+
def _MoveVariablesElement(row, move):
new_row = self.ProcessVariablesTable.MoveRow(row, move)
if new_row != row:
@@ -759,7 +759,7 @@
self.ProcessVariablesTable.ResetView(self.ProcessVariablesGrid)
return new_row
setattr(self.ProcessVariablesGrid, "_MoveRow", _MoveVariablesElement)
-
+
_refresh_buttons = getattr(self.ProcessVariablesGrid, "RefreshButtons")
def _RefreshButtons():
if self.NodesFilter.GetSelection() == 0:
@@ -770,7 +770,7 @@
self.UpVariableButton.Enable(False)
self.DownVariableButton.Enable(False)
setattr(self.ProcessVariablesGrid, "RefreshButtons", _RefreshButtons)
-
+
self.ProcessVariablesGrid.SetRowLabelSize(0)
for col in range(self.ProcessVariablesTable.GetNumberCols()):
attr = wx.grid.GridCellAttr()
@@ -779,16 +779,16 @@
self.ProcessVariablesGrid.SetColMinimalWidth(col, self.ProcessVariablesColSizes[col])
self.ProcessVariablesGrid.AutoSizeColumn(col, False)
self.ProcessVariablesGrid.RefreshButtons()
-
+
self.StartupCommandsDefaultValue = {"Position": 0, "Index": 0, "Subindex": 0, "Value": 0, "Description": ""}
self.StartupCommandsTable = StartupCommandsTable(self, [], GetStartupCommandsTableColnames())
self.StartupCommandsColSizes = [100, 100, 50, 100, 200]
self.StartupCommandsColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT]
-
+
self.StartupCommandsGrid.SetTable(self.StartupCommandsTable)
self.StartupCommandsGrid.SetButtons({"Add": self.AddCommandButton,
"Delete": self.DeleteCommandButton})
-
+
def _AddCommandsElement(new_row):
command = self.StartupCommandsDefaultValue.copy()
command_idx = self.Controler.AppendStartupCommand(command)
@@ -796,14 +796,14 @@
self.RefreshBuffer()
return self.StartupCommandsTable.GetCommandIndex(command["Position"], command_idx)
setattr(self.StartupCommandsGrid, "_AddRow", _AddCommandsElement)
-
+
def _DeleteCommandsElement(row):
command = self.StartupCommandsTable.GetRow(row)
self.Controler.RemoveStartupCommand(command["Position"], command["command_idx"])
self.RefreshStartupCommands()
self.RefreshBuffer()
setattr(self.StartupCommandsGrid, "_DeleteRow", _DeleteCommandsElement)
-
+
self.StartupCommandsGrid.SetRowLabelSize(0)
for col in range(self.StartupCommandsTable.GetNumberCols()):
attr = wx.grid.GridCellAttr()
@@ -812,32 +812,32 @@
self.StartupCommandsGrid.SetColMinimalWidth(col, self.StartupCommandsColSizes[col])
self.StartupCommandsGrid.AutoSizeColumn(col, False)
self.StartupCommandsGrid.RefreshButtons()
-
+
def RefreshBuffer(self):
self.ParentWindow.RefreshTitle()
self.ParentWindow.RefreshFileMenu()
self.ParentWindow.RefreshEditMenu()
self.ParentWindow.RefreshPageTitles()
-
+
def GetBufferState(self):
return self.Controler.GetBufferState()
-
+
def Undo(self):
self.Controler.LoadPrevious()
self.RefreshView()
-
+
def Redo(self):
self.Controler.LoadNext()
self.RefreshView()
-
+
def RefreshView(self):
ConfTreeNodeEditor.RefreshView(self)
-
+
self.RefreshNodesFilter()
self.RefreshProcessVariables()
self.RefreshStartupCommands()
self.NodesVariables.RefreshView()
-
+
def RefreshNodesFilter(self):
value = self.NodesFilter.GetValue()
self.NodesFilter.Clear()
@@ -857,7 +857,7 @@
except Exception:
self.NodesFilter.SetSelection(0)
self.RefreshCurrentNodesFilter()
-
+
def RefreshCurrentNodesFilter(self):
filter = self.NodesFilter.GetSelection()
if filter != -1:
@@ -879,7 +879,7 @@
self.NodesFilter.SetValue(NODE_POSITION_FILTER_FORMAT % self.CurrentNodesFilter["slave_pos"])
self.NodesFilterFirstCharacter = True
self.NodesVariables.SetCurrentNodesFilter(self.CurrentNodesFilter)
-
+
def RefreshProcessVariables(self):
if self.CurrentNodesFilter is not None:
self.ProcessVariables = self.Controler.GetProcessVariables()
@@ -892,7 +892,7 @@
self.ProcessVariablesTable.SetData(data)
self.ProcessVariablesTable.ResetView(self.ProcessVariablesGrid)
self.ProcessVariablesGrid.RefreshButtons()
-
+
def SaveProcessVariables(self):
if self.CurrentNodesFilter is not None:
if len(self.CurrentNodesFilter) > 0:
@@ -900,7 +900,7 @@
else:
self.Controler.SetProcessVariables(self.ProcessVariablesTable.GetData())
self.RefreshBuffer()
-
+
def RefreshStartupCommands(self, position=None, command_idx=None):
if self.CurrentNodesFilter is not None:
col = max(self.StartupCommandsGrid.GetGridCursorCol(), 0)
@@ -909,15 +909,15 @@
self.StartupCommandsTable.ResetView(self.StartupCommandsGrid)
if position is not None and command_idx is not None:
self.SelectStartupCommand(position, command_idx, col)
-
+
def SelectStartupCommand(self, position, command_idx, col):
self.StartupCommandsGrid.SetSelectedCell(
self.StartupCommandsTable.GetCommandIndex(position, command_idx),
col)
-
+
def GetMasterLocation(self):
return self.Controler.GetCurrentLocation()
-
+
def AddStartupCommand(self, position, index, subindex):
col = max(self.StartupCommandsGrid.GetGridCursorCol(), 0)
command = self.StartupCommandsDefaultValue.copy()
@@ -928,7 +928,7 @@
self.RefreshStartupCommands()
self.RefreshBuffer()
self.SelectStartupCommand(position, command_idx, col)
-
+
def OnNodesFilterChanged(self, event):
self.RefreshCurrentNodesFilter()
if self.CurrentNodesFilter is not None:
@@ -936,22 +936,22 @@
self.RefreshStartupCommands()
self.NodesVariables.RefreshView()
event.Skip()
-
+
def OnNodesFilterKeyDown(self, event):
if self.NodesFilterFirstCharacter:
keycode = event.GetKeyCode()
- if keycode not in [wx.WXK_RETURN,
+ if keycode not in [wx.WXK_RETURN,
wx.WXK_NUMPAD_ENTER]:
self.NodesFilterFirstCharacter = False
if keycode not in NAVIGATION_KEYS:
self.NodesFilter.SetValue("")
- if keycode not in [wx.WXK_DELETE,
- wx.WXK_NUMPAD_DELETE,
+ if keycode not in [wx.WXK_DELETE,
+ wx.WXK_NUMPAD_DELETE,
wx.WXK_BACK]:
event.Skip()
else:
event.Skip()
-
+
def OnProcessVariablesGridCellChange(self, event):
row, col = event.GetRow(), event.GetCol()
colname = self.ProcessVariablesTable.GetColLabelValue(col, False)
@@ -973,7 +973,7 @@
dialog.ShowModal()
dialog.Destroy()
event.Veto()
-
+
def OnProcessVariablesGridCellLeftClick(self, event):
row = event.GetRow()
if event.GetCol() == 0:
@@ -984,30 +984,30 @@
number = self.ProcessVariablesTable.GetValueByName(row, "Number")
location = "%%M%s" % data_size + \
".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + (number,)))
-
+
data = wx.TextDataObject(str((location, "location", var_type, var_name, "")))
dragSource = wx.DropSource(self.ProcessVariablesGrid)
dragSource.SetData(data)
dragSource.DoDragDrop()
event.Skip()
-
+
def OnProcessVariablesGridKeyDown(self, event):
keycode = event.GetKeyCode()
col = self.ProcessVariablesGrid.GetGridCursorCol()
row = self.ProcessVariablesGrid.GetGridCursorRow()
colname = self.ProcessVariablesTable.GetColLabelValue(col, False)
- if (keycode in (wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE) and
+ if (keycode in (wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE) and
(colname.startswith("Read from") or colname.startswith("Write to"))):
self.ProcessVariablesTable.SetValue(row, col, "")
self.SaveProcessVariables()
wx.CallAfter(self.ProcessVariablesTable.ResetView, self.ProcessVariablesGrid)
else:
event.Skip()
-
+
def OnStartupCommandsGridEditorShow(self, event):
self.CellShown = event.GetRow(), event.GetCol()
event.Skip()
-
+
def OnStartupCommandsGridCellChange(self, event):
row, col = event.GetRow(), event.GetCol()
if self.CellShown == (row, col):
@@ -1029,7 +1029,7 @@
else:
command = self.StartupCommandsTable.GetRow(row)
self.Controler.SetStartupCommandInfos(command)
- if colname in ["Index", "SubIndex"]:
+ if colname in ["Index", "SubIndex"]:
wx.CallAfter(self.RefreshStartupCommands, command["Position"], command["command_idx"])
if message is None:
self.RefreshBuffer()
@@ -1041,7 +1041,7 @@
event.Veto()
else:
event.Veto()
-
+
def OnResize(self, event):
self.EthercatMasterEditor.GetBestSize()
xstart, ystart = self.EthercatMasterEditor.GetViewStart()
@@ -1050,10 +1050,10 @@
posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
self.EthercatMasterEditor.Scroll(posx, posy)
- self.EthercatMasterEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
+ self.EthercatMasterEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
event.Skip()
-
+
#def OnButtonClick(self, event):
# self.MasterState = self.Controler.getMasterState()
# if self.MasterState:
@@ -1067,7 +1067,7 @@
# self.TxByte.SetValue(self.MasterState["TXbyte"])
# self.TxError.SetValue(self.MasterState["TXerror"])
# self.LostFrames.SetValue(self.MasterState["lost"])
-
+
# self.TxFrameRate1.SetValue(self.MasterState["TXframerate1"])
# self.TxFrameRate2.SetValue(self.MasterState["TXframerate2"])
# self.TxFrameRate3.SetValue(self.MasterState["TXframerate3"])
@@ -1080,41 +1080,41 @@
# self.FrameLoss1.SetValue(self.MasterState["frameloss1"])
# self.FrameLoss2.SetValue(self.MasterState["frameloss2"])
# self.FrameLoss3.SetValue(self.MasterState["frameloss3"])
-
+
class LibraryEditorSizer(wx.FlexGridSizer):
-
+
def __init__(self, parent, module_library, buttons):
wx.FlexGridSizer.__init__(self, cols=1, hgap=0, rows=4, vgap=5)
-
+
self.ModuleLibrary = module_library
self.ParentWindow = parent
-
+
self.AddGrowableCol(0)
self.AddGrowableRow(1)
self.AddGrowableRow(3)
-
- ESI_files_label = wx.StaticText(parent,
+
+ ESI_files_label = wx.StaticText(parent,
label=_("ESI Files:"))
- self.AddWindow(ESI_files_label, border=10,
+ self.AddWindow(ESI_files_label, border=10,
flag=wx.TOP|wx.LEFT|wx.RIGHT)
-
+
folder_tree_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=0)
folder_tree_sizer.AddGrowableCol(0)
folder_tree_sizer.AddGrowableRow(0)
- self.AddSizer(folder_tree_sizer, border=10,
+ self.AddSizer(folder_tree_sizer, border=10,
flag=wx.GROW|wx.LEFT|wx.RIGHT)
-
+
self.ESIFiles = FolderTree(parent, self.GetPath(), editable=False)
self.ESIFiles.SetFilter(".xml")
folder_tree_sizer.AddWindow(self.ESIFiles, flag=wx.GROW)
-
+
buttons_sizer = wx.BoxSizer(wx.VERTICAL)
- folder_tree_sizer.AddSizer(buttons_sizer,
+ folder_tree_sizer.AddSizer(buttons_sizer,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
for idx, (name, bitmap, help, callback) in enumerate(buttons):
- button = wx.lib.buttons.GenBitmapButton(parent,
- bitmap=GetBitmap(bitmap),
+ button = wx.lib.buttons.GenBitmapButton(parent,
+ bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
button.SetToolTipString(help)
setattr(self, name, button)
@@ -1127,12 +1127,12 @@
if callback is not None:
parent.Bind(wx.EVT_BUTTON, callback, button)
buttons_sizer.AddWindow(button, border=10, flag=flag)
-
- modules_label = wx.StaticText(parent,
+
+ modules_label = wx.StaticText(parent,
label=_("Modules library:"))
- self.AddSizer(modules_label, border=10,
+ self.AddSizer(modules_label, border=10,
flag=wx.LEFT|wx.RIGHT)
-
+
self.ModulesGrid = wx.gizmos.TreeListCtrl(parent,
style=wx.TR_DEFAULT_STYLE |
wx.TR_ROW_LINES |
@@ -1145,51 +1145,51 @@
self.OnModulesGridBeginLabelEdit)
self.ModulesGrid.Bind(wx.EVT_TREE_END_LABEL_EDIT,
self.OnModulesGridEndLabelEdit)
- self.ModulesGrid.GetHeaderWindow().Bind(wx.EVT_MOTION,
+ self.ModulesGrid.GetHeaderWindow().Bind(wx.EVT_MOTION,
self.OnModulesGridHeaderMotion)
- self.AddWindow(self.ModulesGrid, border=10,
+ self.AddWindow(self.ModulesGrid, border=10,
flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
for colname, colsize, colalign in zip(
- [_("Name")] + [param_infos["column_label"]
- for param, param_infos in
+ [_("Name")] + [param_infos["column_label"]
+ for param, param_infos in
self.ModuleLibrary.MODULES_EXTRA_PARAMS],
- [400] + [param_infos["column_size"]
- for param, param_infos in
+ [400] + [param_infos["column_size"]
+ for param, param_infos in
self.ModuleLibrary.MODULES_EXTRA_PARAMS],
[wx.ALIGN_LEFT] + [wx.ALIGN_RIGHT] * len(self.ModuleLibrary.MODULES_EXTRA_PARAMS)):
self.ModulesGrid.AddColumn(_(colname), colsize, colalign, edit=True)
self.ModulesGrid.SetMainColumn(0)
-
+
self.CurrentSelectedCol = None
self.LastToolTipCol = None
-
+
def GetPath(self):
return self.ModuleLibrary.GetPath()
-
+
def SetControlMinSize(self, size):
self.ESIFiles.SetMinSize(size)
self.ModulesGrid.SetMinSize(size)
-
+
def GetSelectedFilePath(self):
return self.ESIFiles.GetPath()
-
+
def RefreshView(self):
self.ESIFiles.RefreshTree()
self.RefreshModulesGrid()
-
+
def RefreshModulesGrid(self):
root = self.ModulesGrid.GetRootItem()
if not root.IsOk():
root = self.ModulesGrid.AddRoot("Modules")
- self.GenerateModulesGridBranch(root,
- self.ModuleLibrary.GetModulesLibrary(),
+ self.GenerateModulesGridBranch(root,
+ self.ModuleLibrary.GetModulesLibrary(),
GetVariablesTableColnames())
self.ModulesGrid.Expand(root)
-
+
def GenerateModulesGridBranch(self, root, modules, colnames):
item, root_cookie = self.ModulesGrid.GetFirstChild(root)
-
+
no_more_items = not item.IsOk()
for module in modules:
if no_more_items:
@@ -1197,8 +1197,8 @@
self.ModulesGrid.SetItemText(item, module["name"], 0)
if module["infos"] is not None:
for param_idx, (param, param_infos) in enumerate(self.ModuleLibrary.MODULES_EXTRA_PARAMS):
- self.ModulesGrid.SetItemText(item,
- str(module["infos"][param]),
+ self.ModulesGrid.SetItemText(item,
+ str(module["infos"][param]),
param_idx + 1)
else:
self.ModulesGrid.SetItemBackgroundColour(item, wx.LIGHT_GREY)
@@ -1207,7 +1207,7 @@
if not no_more_items:
item, root_cookie = self.ModulesGrid.GetNextChild(root, root_cookie)
no_more_items = not item.IsOk()
-
+
if not no_more_items:
to_delete = []
while item.IsOk():
@@ -1215,44 +1215,44 @@
item, root_cookie = self.ModulesGrid.GetNextChild(root, root_cookie)
for item in to_delete:
self.ModulesGrid.Delete(item)
-
+
def OnImportButton(self, event):
dialog = wx.FileDialog(self.ParentWindow,
- _("Choose an XML file"),
- os.getcwd(), "",
+ _("Choose an XML file"),
+ os.getcwd(), "",
_("XML files (*.xml)|*.xml|All files|*.*"), wx.OPEN)
-
+
if dialog.ShowModal() == wx.ID_OK:
filepath = dialog.GetPath()
if self.ModuleLibrary.ImportModuleLibrary(filepath):
wx.CallAfter(self.RefreshView)
else:
- message = wx.MessageDialog(self,
- _("No such XML file: %s\n") % filepath,
+ message = wx.MessageDialog(self,
+ _("No such XML file: %s\n") % filepath,
_("Error"), wx.OK|wx.ICON_ERROR)
message.ShowModal()
message.Destroy()
dialog.Destroy()
-
+
event.Skip()
-
+
def OnDeleteButton(self, event):
filepath = self.GetSelectedFilePath()
if os.path.isfile(filepath):
folder, filename = os.path.split(filepath)
-
- dialog = wx.MessageDialog(self.ParentWindow,
- _("Do you really want to delete the file '%s'?") % filename,
+
+ dialog = wx.MessageDialog(self.ParentWindow,
+ _("Do you really want to delete the file '%s'?") % filename,
_("Delete File"), wx.YES_NO|wx.ICON_QUESTION)
remove = dialog.ShowModal() == wx.ID_YES
dialog.Destroy()
-
+
if remove:
os.remove(filepath)
self.ModuleLibrary.LoadModules()
wx.CallAfter(self.RefreshView)
event.Skip()
-
+
def OnModulesGridLeftDown(self, event):
item, flags, col = self.ModulesGrid.HitTest(event.GetPosition())
if item.IsOk():
@@ -1293,8 +1293,8 @@
wx.CallAfter(self.RefreshModulesGrid)
event.Skip()
except ValueError:
- message = wx.MessageDialog(self,
- _("Module %s must be an integer!") % stripped_column_label,
+ message = wx.MessageDialog(self,
+ _("Module %s must be an integer!") % stripped_column_label,
_("Error"), wx.OK|wx.ICON_ERROR)
message.ShowModal()
message.Destroy()
@@ -1303,7 +1303,7 @@
event.Veto()
else:
event.Veto()
-
+
def OnModulesGridHeaderMotion(self, event):
item, flags, col = self.ModulesGrid.HitTest(event.GetPosition())
if col != self.LastToolTipCol and self.LastToolTipCol is not None:
@@ -1312,51 +1312,51 @@
if col > 0 and self.LastToolTipCol != col:
self.LastToolTipCol = col
param, param_infos = self.ModuleLibrary.MODULES_EXTRA_PARAMS[col - 1]
- wx.CallAfter(self.ModulesGrid.GetHeaderWindow().SetToolTipString,
+ wx.CallAfter(self.ModulesGrid.GetHeaderWindow().SetToolTipString,
param_infos["description"])
event.Skip()
class DatabaseManagementDialog(wx.Dialog):
-
+
def __init__(self, parent, database):
wx.Dialog.__init__(self, parent,
size=wx.Size(700, 500), title=_('ESI Files Database management'),
style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
+
self.DatabaseSizer = LibraryEditorSizer(self, database,
[("ImportButton", "ImportESI", _("Import file to ESI files database"), None),
("DeleteButton", "remove_element", _("Remove file from database"), None)])
self.DatabaseSizer.SetControlMinSize(wx.Size(0, 0))
main_sizer.AddSizer(self.DatabaseSizer, border=10,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
button_sizer.GetAffirmativeButton().SetLabel(_("Add file to project"))
button_sizer.GetCancelButton().SetLabel(_("Close"))
- main_sizer.AddSizer(button_sizer, border=10,
+ main_sizer.AddSizer(button_sizer, border=10,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.SetSizer(main_sizer)
-
+
self.DatabaseSizer.RefreshView()
-
+
def GetValue(self):
return self.DatabaseSizer.GetSelectedFilePath()
class LibraryEditor(ConfTreeNodeEditor):
-
+
CONFNODEEDITOR_TABS = [
(_("Modules Library"), "_create_ModuleLibraryEditor")]
-
+
def _create_ModuleLibraryEditor(self, prnt):
self.ModuleLibraryEditor = wx.ScrolledWindow(prnt,
style=wx.TAB_TRAVERSAL|wx.HSCROLL|wx.VSCROLL)
self.ModuleLibraryEditor.Bind(wx.EVT_SIZE, self.OnResize)
-
+
self.ModuleLibrarySizer = LibraryEditorSizer(self.ModuleLibraryEditor,
self.Controler.GetModulesLibraryInstance(),
[("ImportButton", "ImportESI", _("Import ESI file"), None),
@@ -1364,30 +1364,30 @@
("DeleteButton", "remove_element", _("Remove file from library"), None)])
self.ModuleLibrarySizer.SetControlMinSize(wx.Size(0, 200))
self.ModuleLibraryEditor.SetSizer(self.ModuleLibrarySizer)
-
+
return self.ModuleLibraryEditor
def __init__(self, parent, controler, window):
ConfTreeNodeEditor.__init__(self, parent, controler, window)
-
+
self.RefreshView()
-
+
def RefreshView(self):
ConfTreeNodeEditor.RefreshView(self)
self.ModuleLibrarySizer.RefreshView()
def OnAddButton(self, event):
- dialog = DatabaseManagementDialog(self,
+ dialog = DatabaseManagementDialog(self,
self.Controler.GetModulesDatabaseInstance())
-
+
if dialog.ShowModal() == wx.ID_OK:
module_library = self.Controler.GetModulesLibraryInstance()
module_library.ImportModuleLibrary(dialog.GetValue())
-
+
dialog.Destroy()
-
+
wx.CallAfter(self.ModuleLibrarySizer.RefreshView)
-
+
event.Skip()
def OnResize(self, event):
@@ -1398,7 +1398,6 @@
posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
self.ModuleLibraryEditor.Scroll(posx, posy)
- self.ModuleLibraryEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
+ self.ModuleLibraryEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
event.Skip()
-
--- a/etherlab/EtherCATManagementEditor.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/EtherCATManagementEditor.py Fri Sep 28 17:20:11 2018 +0300
@@ -23,7 +23,7 @@
import wx.grid as gridlib
#-------------------------------------------------------------
-# ------------ for register management ---------------
+# ------------ for register management ---------------
from xml.dom import minidom
#-------------------------------------------------------------
@@ -39,7 +39,7 @@
# Sync Managers Table
#-------------------------------------------------------------------------------
class SyncManagersTable(CustomTable):
- def GetValue(self, row, col):
+ def GetValue(self, row, col):
if row < self.GetNumberRows():
if col == 0:
return row
@@ -60,15 +60,15 @@
self.parent = parent
self.Controler = controler
self.NodeEditor = node_editor
-
+
self.EtherCATManagementClassObject = {}
-
+
# fill EtherCAT Management Treebook
for pname, pclass, subs in [
("Slave State", SlaveStatePanelClass, []),
("SDO Management", SDOPanelClass, []),
("PDO Monitoring", PDOPanelClass, []),
- ("ESC Management", EEPROMAccessPanel, [
+ ("ESC Management", EEPROMAccessPanel, [
("Smart View", SlaveSiiSmartView),
("Hex View", HexView)]),
("Register Access", RegisterAccessPanel, [])]:
@@ -78,22 +78,22 @@
self.Bind(wx.EVT_TREEBOOK_PAGE_CHANGED, self.OnPageChanged)
self.Bind(wx.EVT_TREEBOOK_PAGE_CHANGING, self.OnPageChanging)
-
+
def OnPageChanged(self, event):
old = event.GetOldSelection()
new = event.GetSelection()
sel = event.GetSelection()
event.Skip()
-
+
def OnPageChanging(self, event):
old = event.GetOldSelection()
new = event.GetSelection()
sel = event.GetSelection()
- event.Skip()
-
+ event.Skip()
+
#-------------------------------------------------------------------------------
# For SlaveState Panel
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class SlaveStatePanelClass(wx.Panel):
def __init__(self, parent, controler):
"""
@@ -104,13 +104,13 @@
wx.Panel.__init__(self, parent, -1, (0, 0), size=wx.DefaultSize, style = wx.SUNKEN_BORDER)
self.Controler = controler
self.parent = parent
-
+
# initialize SlaveStatePanel UI dictionaries
self.StaticBoxDic = {}
self.StaticTextDic = {}
self.TextCtrlDic = {}
self.ButtonDic = {}
-
+
# iniitalize BoxSizer and FlexGridSizer
self.SizerDic = {
"SlaveState_main_sizer" : wx.BoxSizer(wx.VERTICAL),
@@ -120,15 +120,15 @@
"SlaveState_sizer" : wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10),
"SlaveState_up_sizer" : wx.FlexGridSizer(cols=4, hgap=10, rows=2, vgap=10),
"SlaveState_down_sizer" : wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=10)}
-
+
# initialize StaticBox and StaticBoxSizer
for box_name, box_label in [
("SlaveInfosDetailsBox", "Slave Informations"),
("SyncManagerBox", "Sync Manager"),
("SlaveStateBox", "Slave State Transition && Monitoring")]:
self.StaticBoxDic[box_name] = wx.StaticBox(self, label=_(box_label))
- self.SizerDic[box_name] = wx.StaticBoxSizer(self.StaticBoxDic[box_name])
-
+ self.SizerDic[box_name] = wx.StaticBoxSizer(self.StaticBoxDic[box_name])
+
for statictext_name, statictext_label, textctrl_name in [
("VendorLabel", "Vendor:", "vendor"),
("ProductcodeLabel", "Product code:", "product_code"),
@@ -136,16 +136,16 @@
("PhysicsLabel", "Physics:", "physics")]:
self.StaticTextDic[statictext_name] = wx.StaticText(self, label=_(statictext_label))
self.TextCtrlDic[textctrl_name] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
- self.SizerDic["SlaveInfosDetailsInnerSizer"].AddMany([self.StaticTextDic[statictext_name],
- self.TextCtrlDic[textctrl_name]])
-
+ self.SizerDic["SlaveInfosDetailsInnerSizer"].AddMany([self.StaticTextDic[statictext_name],
+ self.TextCtrlDic[textctrl_name]])
+
self.SizerDic["SlaveInfosDetailsBox"].AddSizer(self.SizerDic["SlaveInfosDetailsInnerSizer"])
-
- self.SyncManagersGrid = CustomGrid(self, size=wx.Size(605,155), style=wx.VSCROLL)
-
- self.SizerDic["SyncManagerInnerSizer"].Add(self.SyncManagersGrid)
+
+ self.SyncManagersGrid = CustomGrid(self, size=wx.Size(605,155), style=wx.VSCROLL)
+
+ self.SizerDic["SyncManagerInnerSizer"].Add(self.SyncManagersGrid)
self.SizerDic["SyncManagerBox"].Add(self.SizerDic["SyncManagerInnerSizer"])
-
+
for button_name, button_id, button_label, button_tooltipstring, event_method, sub_item in [
("InitButton", 0, "INIT", "State Transition to \"Init\" State", self.OnButtonClick, []),
("PreOPButton", 1, "PREOP", "State Transition to \"PreOP\" State", self.OnButtonClick, [
@@ -160,46 +160,46 @@
for statictext_name, statictext_label, textctrl_name in sub_item :
self.StaticTextDic[statictext_name] = wx.StaticText(self, label=_(statictext_label))
self.TextCtrlDic[textctrl_name] = wx.TextCtrl(self, size=wx.DefaultSize, style=wx.TE_READONLY)
- self.SizerDic["SlaveState_up_sizer"].AddMany([self.StaticTextDic[statictext_name],
+ self.SizerDic["SlaveState_up_sizer"].AddMany([self.StaticTextDic[statictext_name],
self.TextCtrlDic[textctrl_name]])
-
+
for button_name, button_label, button_tooltipstring, event_method in [
("StartTimerButton", "Start State Monitoring", "Slave State Update Restart", self.StartTimer),
("StopTimerButton", "Stop State Monitoring", "Slave State Update Stop", self.CurrentStateThreadStop)]:
self.ButtonDic[button_name] = wx.Button(self, label=_(button_label))
self.ButtonDic[button_name].Bind(wx.EVT_BUTTON, event_method)
self.ButtonDic[button_name].SetToolTipString(button_tooltipstring)
- self.SizerDic["SlaveState_down_sizer"].Add(self.ButtonDic[button_name])
-
- self.SizerDic["SlaveState_sizer"].AddMany([self.SizerDic["SlaveState_up_sizer"],
+ self.SizerDic["SlaveState_down_sizer"].Add(self.ButtonDic[button_name])
+
+ self.SizerDic["SlaveState_sizer"].AddMany([self.SizerDic["SlaveState_up_sizer"],
self.SizerDic["SlaveState_down_sizer"]])
-
+
self.SizerDic["SlaveStateBox"].Add(self.SizerDic["SlaveState_sizer"])
-
+
self.SizerDic["SlaveState_inner_main_sizer"].AddMany([
self.SizerDic["SlaveInfosDetailsBox"], self.SizerDic["SyncManagerBox"],
self.SizerDic["SlaveStateBox"]])
-
+
self.SizerDic["SlaveState_main_sizer"].Add(self.SizerDic["SlaveState_inner_main_sizer"])
-
+
self.SetSizer(self.SizerDic["SlaveState_main_sizer"])
-
+
# register a timer for periodic exectuion of slave state update (period: 1000 ms)
self.Bind(wx.EVT_TIMER, self.GetCurrentState)
-
+
self.CreateSyncManagerTable()
-
+
self.Centre()
-
+
def CreateSyncManagerTable(self):
"""
Create grid for "SyncManager"
"""
- # declare Table object
+ # declare Table object
self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames())
self.SyncManagersGrid.SetTable(self.SyncManagersTable)
# set grid alignment attr. (CENTER)
- self.SyncManagersGridColAlignements = [wx.ALIGN_CENTRE, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE,
+ self.SyncManagersGridColAlignements = [wx.ALIGN_CENTRE, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE,
wx.ALIGN_CENTRE, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE]
# set grid size
self.SyncManagersGridColSizes = [40, 150, 100, 100, 100, 100]
@@ -209,10 +209,10 @@
attr.SetAlignment(self.SyncManagersGridColAlignements[col], wx.ALIGN_CENTRE)
self.SyncManagersGrid.SetColAttr(col, attr)
self.SyncManagersGrid.SetColMinimalWidth(col, self.SyncManagersGridColSizes[col])
- self.SyncManagersGrid.AutoSizeColumn(col, False)
-
+ self.SyncManagersGrid.AutoSizeColumn(col, False)
+
self.RefreshSlaveInfos()
-
+
def RefreshSlaveInfos(self):
"""
Fill data in "Slave Information" and "SyncManager"
@@ -220,7 +220,7 @@
slave_infos = self.Controler.GetSlaveInfos()
sync_manager_section = ["vendor", "product_code", "revision_number", "physics"]
if slave_infos is not None:
- # this method is same as "TextCtrl.SetValue"
+ # this method is same as "TextCtrl.SetValue"
for textctrl_name in sync_manager_section:
self.TextCtrlDic[textctrl_name].SetValue(slave_infos[textctrl_name])
self.SyncManagersTable.SetData(slave_infos["sync_managers"])
@@ -230,7 +230,7 @@
self.TextCtrlDic[textctrl_name].SetValue("")
self.SyncManagersTable.SetData([])
self.SyncManagersTable.ResetView(self.SyncManagersGrid)
-
+
def OnButtonClick(self, event):
"""
Event handler for slave state transition button click (Init, PreOP, SafeOP, OP button)
@@ -239,7 +239,7 @@
check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
if check_connect_flag :
state_dic = ["INIT", "PREOP", "SAFEOP", "OP"]
-
+
# If target state is one of {INIT, PREOP, SAFEOP}, request slave state transition immediately.
if event.GetId() < 3 :
self.Controler.CommonMethod.RequestSlaveState(state_dic[event.GetId()])
@@ -254,8 +254,8 @@
self.Controler.CommonMethod.RequestSlaveState("OP")
self.TextCtrlDic["TargetState"].SetValue("OP")
else :
- self.Controler.CommonMethod.CreateErrorDialog("PLC is Not Started")
-
+ self.Controler.CommonMethod.CreateErrorDialog("PLC is Not Started")
+
def GetCurrentState(self, event):
"""
Timer event handler for periodic slave state monitoring (Default period: 1 sec = 1000 msec).
@@ -268,8 +268,8 @@
try :
self.SetCurrentState(line[self.Controler.GetSlavePos()])
except Exception:
- pass
-
+ pass
+
def SetCurrentState(self, line):
"""
Show current slave state using the executiob result of "ethercat slaves" command.
@@ -281,10 +281,10 @@
# Result example : 0 0:0 PREOP + EL9800 (V4.30) (PIC24, SPI, ET1100)
token = line.split(" ")
if token[2] in state_array:
- self.TextCtrlDic["CurrentState"].SetValue(token[2])
+ self.TextCtrlDic["CurrentState"].SetValue(token[2])
except Exception:
- pass
-
+ pass
+
def StartTimer(self, event):
"""
Event handler for "Start State Monitoring" button.
@@ -294,7 +294,7 @@
self.SlaveStateThread = wx.Timer(self)
# set timer period (1000 ms)
self.SlaveStateThread.Start(1000)
-
+
def CurrentStateThreadStop(self, event):
"""
Event handler for "Stop State Monitoring" button.
@@ -305,10 +305,10 @@
self.SlaveStateThread.Stop()
except Exception:
pass
-
+
#-------------------------------------------------------------------------------
# For SDO Management Panel
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class SDOPanelClass(wx.Panel):
def __init__(self, parent, controler):
"""
@@ -317,64 +317,64 @@
@param controler: _EthercatSlaveCTN class in EthercatSlave.py
"""
wx.Panel.__init__(self, parent, -1)
-
+
self.DatatypeDescription, self.CommunicationObject, self.ManufacturerSpecific, \
self.ProfileSpecific, self.Reserved, self.AllSDOData = range(6)
-
+
self.Controler = controler
-
+
self.SDOManagementMainSizer = wx.BoxSizer(wx.VERTICAL)
self.SDOManagementInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10)
-
- self.SDOUpdate = wx.Button(self, label=_('update'))
+
+ self.SDOUpdate = wx.Button(self, label=_('update'))
self.SDOUpdate.Bind(wx.EVT_BUTTON, self.SDOInfoUpdate)
-
+
self.CallSDONoteBook = SDONoteBook(self, controler=self.Controler)
self.SDOManagementInnerMainSizer.Add(self.SDOUpdate)
- self.SDOManagementInnerMainSizer.Add(self.CallSDONoteBook, wx.ALL | wx.EXPAND)
+ self.SDOManagementInnerMainSizer.Add(self.CallSDONoteBook, wx.ALL | wx.EXPAND)
self.SDOManagementMainSizer.Add(self.SDOManagementInnerMainSizer)
-
+
self.SetSizer(self.SDOManagementMainSizer)
-
+
def SDOInfoUpdate(self, event):
"""
Evenet handler for SDO "update" button.
- - Load SDO data from current slave
+ - Load SDO data from current slave
@param event : wx.EVT_BUTTON object
- """
+ """
self.Controler.CommonMethod.SaveSDOData = []
self.Controler.CommonMethod.ClearSDODataSet()
self.SDOFlag = False
-
+
# Check whether beremiz connected or not.
check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
if check_connect_flag:
self.SDOs = self.Controler.CommonMethod.GetSlaveSDOFromSlave()
# SDOFlag is "False", user click "Cancel" button
- self.SDOFlag = self.SDOParser()
+ self.SDOFlag = self.SDOParser()
if self.SDOFlag :
- self.CallSDONoteBook.CreateNoteBook()
+ self.CallSDONoteBook.CreateNoteBook()
self.Refresh()
-
- def SDOParser(self):
+
+ def SDOParser(self):
"""
Parse SDO data set that obtain "SDOInfoUpdate" Method
- @return True or False
- """
+ @return True or False
+ """
slaveSDO_progress = wx.ProgressDialog("Slave SDO Monitoring", "Now Uploading...",
maximum = len(self.SDOs.splitlines()), parent=self,
- style = wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME |
- wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME |
- wx.PD_AUTO_HIDE | wx.PD_SMOOTH)
-
+ style = wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME |
+ wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME |
+ wx.PD_AUTO_HIDE | wx.PD_SMOOTH)
+
# If keep_going flag is False, SDOParser method is stop and return "False".
keep_going = True
count = 0
-
- # SDO data example
+
+ # SDO data example
# SDO 0x1000, "Device type"
# 0x1000:00,r-r-r-,uint32,32 bit,"Device type",0x00020192, 131474
for details_line in self.SDOs.splitlines():
@@ -387,64 +387,64 @@
else :
# line_token = ['0x1000:00,r-r-r-,uint32,32 bit,', 'Device type', ',0x00020192, 131474']
token_head, name, token_tail = line_token
-
+
# token_head = ['0x1000:00', 'r-r-r-', 'uint32', '32 bit', '']
token_head = token_head.split(",")
ful_idx, access, type, size, empty = token_head
# ful_idx.split(":") = ['0x1000', '00']
idx, sub_idx = ful_idx.split(":")
-
+
# token_tail = ['', '0x00020192', '131474']
token_tail = token_tail.split(",")
try :
empty, hex_val, dec_val = token_tail
-
+
# SDO data is not return "dec value"
- # line example :
- # 0x1702:01,rwr-r-,uint32,32 bit," 1st mapping", ----
+ # line example :
+ # 0x1702:01,rwr-r-,uint32,32 bit," 1st mapping", ----
except Exception:
empty, hex_val = token_tail
-
+
name_after_check = self.StringTest(name)
-
+
# convert hex type
sub_idx = "0x" + sub_idx
if type == "octet_string":
hex_val = ' ---- '
-
+
# SResult of SlaveSDO data parsing. (data type : dictionary)
- self.Data = {'idx':idx.strip(), 'subIdx':sub_idx.strip(), 'access':access.strip(),
- 'type':type.strip(), 'size':size.strip(), 'name':name_after_check.strip("\""),
+ self.Data = {'idx':idx.strip(), 'subIdx':sub_idx.strip(), 'access':access.strip(),
+ 'type':type.strip(), 'size':size.strip(), 'name':name_after_check.strip("\""),
'value':hex_val.strip(), "category":title_name.strip("\"")}
-
+
category_divide_value = [0x1000, 0x2000, 0x6000, 0xa000, 0xffff]
for count in range(len(category_divide_value)) :
if int(idx, 0) < category_divide_value[count]:
self.Controler.CommonMethod.SaveSDOData[count].append(self.Data)
break
-
+
self.Controler.CommonMethod.SaveSDOData[self.AllSDOData].append(self.Data)
-
+
if count >= len(self.SDOs.splitlines()) / 2:
(keep_going, skip) = slaveSDO_progress.Update(count, "Please waiting a moment!!")
else:
(keep_going, skip) = slaveSDO_progress.Update(count)
-
- # If user click "Cancel" loop suspend immediately
+
+ # If user click "Cancel" loop suspend immediately
if (keep_going == False):
break
-
- slaveSDO_progress.Destroy()
- return keep_going
+
+ slaveSDO_progress.Destroy()
+ return keep_going
def StringTest(self, check_string):
"""
- Test value 'name' is alphanumeric
- @param check_string : input data for check
+ Test value 'name' is alphanumeric
+ @param check_string : input data for check
@return result : output data after check
- """
+ """
# string.printable is print this result
#'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
#!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c
@@ -456,11 +456,11 @@
result = check_string[:len(check_string) - i]
break
return result
-
-
+
+
#-------------------------------------------------------------------------------
# For SDO Notebook (divide category)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class SDONoteBook(wx.Notebook):
def __init__(self, parent, controler):
"""
@@ -468,23 +468,23 @@
@param parent: Reference to the parent SDOPanelClass class
@param controler: _EthercatSlaveCTN class in EthercatSlave.py
"""
- wx.Notebook.__init__(self, parent, id = -1, size=(850,500))
+ wx.Notebook.__init__(self, parent, id = -1, size=(850,500))
self.Controler = controler
self.parent = parent
-
+
self.CreateNoteBook()
-
+
self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
-
- def CreateNoteBook(self):
+
+ def CreateNoteBook(self):
"""
Create each NoteBook page, divided SDO index
According to EtherCAT Communication(03/2011), 158p
- """
+ """
self.Data = []
count = 1
-
+
page_texts = [("all", self.parent.AllSDOData),
("0x0000 - 0x0ff", self.parent.DatatypeDescription),
("0x1000 - 0x1fff", self.parent.CommunicationObject),
@@ -500,12 +500,12 @@
"All SDO Object"]
self.DeleteAllPages()
-
+
for txt, count in page_texts:
self.Data = self.Controler.CommonMethod.SaveSDOData[count]
- self.Win = SlaveSDOTable(self, self.Data)
+ self.Win = SlaveSDOTable(self, self.Data)
self.AddPage(self.Win, txt)
-
+
def OnPageChanged(self, event):
old = event.GetOldSelection()
new = event.GetSelection()
@@ -520,17 +520,17 @@
#-------------------------------------------------------------------------------
# For SDO Grid (fill index, subindex, etc...)
-#-------------------------------------------------------------------------------
-class SlaveSDOTable(wx.grid.Grid):
+#-------------------------------------------------------------------------------
+class SlaveSDOTable(wx.grid.Grid):
def __init__(self, parent, data):
"""
Constructor
@param parent: Reference to the parent SDOPanelClass class
@param data: SDO data after parsing "SDOParser" method
"""
- wx.grid.Grid.__init__(self, parent, -1, size=(830,490),
+ wx.grid.Grid.__init__(self, parent, -1, size=(830,490),
style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
-
+
self.Controler = parent.Controler
self.parent = parent
self.SDOFlag = True
@@ -538,55 +538,55 @@
self.SDOs = []
else :
self.SDOs = data
-
+
self.CreateGrid(len(self.SDOs), 8)
- SDOCellSize = [(0, 65), (1, 65), (2, 50), (3, 55),
+ SDOCellSize = [(0, 65), (1, 65), (2, 50), (3, 55),
(4, 40), (5, 200), (6, 250), (7, 85)]
-
+
for (index, size) in SDOCellSize:
self.SetColSize(index, size)
-
+
self.SetRowLabelSize(0)
-
+
SDOTableLabel = [(0, "Index"), (1, "Subindex"), (2, "Access"),
(3, "Type"), (4, "Size"), (5, "Category"),
(6, "Name"), (7, "Value")]
-
+
for (index, label) in SDOTableLabel:
self.SetColLabelValue(index, label)
self.SetColLabelAlignment(index, wx.ALIGN_CENTRE)
-
+
attr = wx.grid.GridCellAttr()
- # for SDO download
+ # for SDO download
self.Bind(gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.SDOModifyDialog)
-
- for i in range(7):
- self.SetColAttr(i,attr)
-
+
+ for i in range(7):
+ self.SetColAttr(i,attr)
+
self.SetColLabelAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
-
- self.SetTableValue()
-
+
+ self.SetTableValue()
+
def SetTableValue(self):
"""
Cell is filled by new parsing data
"""
sdo_list = ['idx', 'subIdx', 'access', 'type', 'size', 'category', 'name', 'value']
for row_idx in range(len(self.SDOs)):
- for col_idx in range(len(self.SDOs[row_idx])):
+ for col_idx in range(len(self.SDOs[row_idx])):
self.SetCellValue(row_idx, col_idx, self.SDOs[row_idx][sdo_list[col_idx]])
self.SetReadOnly(row_idx, col_idx, True)
if col_idx < 5 :
self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
-
+
def CheckSDODataAccess(self, row):
"""
CheckSDODataAccess method is checking that access data has "w"
Access field consist 6 char, if mean
rw rw rw
- (preop) (safeop) (op)
- Example Access field : rwrwrw, rwrw--
+ (preop) (safeop) (op)
+ Example Access field : rwrwrw, rwrw--
@param row : Selected cell by user
@return Write_flag : If data has "w", flag is true
"""
@@ -595,23 +595,23 @@
if check[1:2] == 'w' :
self.Controler.CommonMethod.Check_PREOP = True
write_flag = True
- if check[3:4] == 'w' :
+ if check[3:4] == 'w' :
self.Controler.CommonMethod.Check_SAFEOP = True
write_flag = True
if check[5:] =='w' :
self.Controler.CommonMethod.Check_OP = True
write_flag = True
-
+
return write_flag
-
+
def DecideSDODownload(self, state):
"""
- compare current state and "access" field,
+ compare current state and "access" field,
result notify SDOModifyDialog method
@param state : current slave state
@return True or False
"""
- # Example of 'state' parameter : "0 0:0 PREOP + EL9800 (V4.30) (PIC24, SPI, ET1100)"
+ # Example of 'state' parameter : "0 0:0 PREOP + EL9800 (V4.30) (PIC24, SPI, ET1100)"
state = state[self.Controler.GetSlavePos()].split(" ")[2]
if state == "PREOP" and self.Controler.CommonMethod.Check_PREOP :
return True
@@ -619,9 +619,9 @@
return True
elif state == "OP" and self.Controler.CommonMethod.Check_OP :
return True
-
+
return False
-
+
def ClearStateFlag(self):
"""
Initialize StateFlag
@@ -630,45 +630,45 @@
self.Controler.CommonMethod.Check_PREOP = False
self.Controler.CommonMethod.Check_SAFEOP = False
self.Controler.CommonMethod.Check_OP = False
-
+
def SDOModifyDialog (self, event):
"""
Create dialog for SDO value modify
- if user enter data, perform command "ethercat download"
+ if user enter data, perform command "ethercat download"
@param event : gridlib.EVT_GRID_CELL_LEFT_DCLICK object
"""
self.ClearStateFlag()
-
- # CheckSDODataAccess is checking that OD(Object Dictionary) has "w"
- if event.GetCol() == 7 and self.CheckSDODataAccess(event.GetRow()) :
+
+ # CheckSDODataAccess is checking that OD(Object Dictionary) has "w"
+ if event.GetCol() == 7 and self.CheckSDODataAccess(event.GetRow()) :
dlg = wx.TextEntryDialog (self, "Enter hex or dec value (if enter dec value, it automatically conversed hex value)",
"SDOModifyDialog", style = wx.OK | wx.CANCEL)
- start_value = self.GetCellValue(event.GetRow(), event.GetCol())
+ start_value = self.GetCellValue(event.GetRow(), event.GetCol())
dlg.SetValue(start_value)
-
+
if dlg.ShowModal() == wx.ID_OK:
try :
int(dlg.GetValue(), 0)
# check "Access" field
if self.DecideSDODownload(self.Controler.CommonMethod.SlaveState[self.Controler.GetSlavePos()]) :
# Request "SDODownload"
- self.Controler.CommonMethod.SDODownload(self.SDOs[event.GetRow()]['type'], self.SDOs[event.GetRow()]['idx'],
+ self.Controler.CommonMethod.SDODownload(self.SDOs[event.GetRow()]['type'], self.SDOs[event.GetRow()]['idx'],
self.SDOs[event.GetRow()]['subIdx'], dlg.GetValue())
self.SetCellValue(event.GetRow(), event.GetCol(), hex(int(dlg.GetValue(), 0)))
else :
- self.Controler.CommonMethod.CreateErrorDialog('You cannot SDO download this state')
+ self.Controler.CommonMethod.CreateErrorDialog('You cannot SDO download this state')
# Error occured process of "int(variable)"
# User input is not hex, dec value
except ValueError:
- self.Controler.CommonMethod.CreateErrorDialog('You can input only hex, dec value')
+ self.Controler.CommonMethod.CreateErrorDialog('You can input only hex, dec value')
#-------------------------------------------------------------------------------
# For PDO Monitoring Panel
-# PDO Class UI : Panel -> Choicebook (RxPDO, TxPDO) ->
+# PDO Class UI : Panel -> Choicebook (RxPDO, TxPDO) ->
# Notebook (PDO Index) -> Grid (PDO entry)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class PDOPanelClass(wx.Panel):
def __init__(self, parent, controler):
"""
@@ -681,12 +681,12 @@
self.PDOMonitoringEditorMainSizer = wx.BoxSizer(wx.VERTICAL)
self.PDOMonitoringEditorInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10)
-
- self.CallPDOChoicebook = PDOChoicebook(self, controler=self.Controler)
- self.PDOMonitoringEditorInnerMainSizer.Add(self.CallPDOChoicebook, wx.ALL)
-
+
+ self.CallPDOChoicebook = PDOChoicebook(self, controler=self.Controler)
+ self.PDOMonitoringEditorInnerMainSizer.Add(self.CallPDOChoicebook, wx.ALL)
+
self.PDOMonitoringEditorMainSizer.Add(self.PDOMonitoringEditorInnerMainSizer)
-
+
self.SetSizer(self.PDOMonitoringEditorMainSizer)
def PDOInfoUpdate(self):
@@ -701,7 +701,7 @@
#-------------------------------------------------------------------------------
# For PDO Choicebook (divide Tx, Rx PDO)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class PDOChoicebook(wx.Choicebook):
def __init__(self, parent, controler):
"""
@@ -711,15 +711,15 @@
"""
wx.Choicebook.__init__(self, parent, id=-1, size=(500, 500), style=wx.CHB_DEFAULT)
self.Controler = controler
-
+
RxWin = PDONoteBook(self, controler=self.Controler, name="Rx")
TxWin = PDONoteBook(self, controler=self.Controler, name="Tx")
self.AddPage(RxWin, "RxPDO")
self.AddPage(TxWin, "TxPDO")
-
+
self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
-
+
def OnPageChanged(self, event):
old = event.GetOldSelection()
new = event.GetSelection()
@@ -730,12 +730,12 @@
old = event.GetOldSelection()
new = event.GetSelection()
sel = self.GetSelection()
- event.Skip()
+ event.Skip()
#-------------------------------------------------------------------------------
# For PDO Notebook (divide PDO index)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class PDONoteBook(wx.Notebook):
def __init__(self, parent, name, controler):
"""
@@ -746,12 +746,12 @@
"""
wx.Notebook.__init__(self, parent, id=-1, size=(640, 400))
self.Controler = controler
-
+
count = 0
page_texts = []
-
+
self.Controler.CommonMethod.RequestPDOInfo()
-
+
if name == "Tx" :
# obtain pdo_info and pdo_entry
# pdo_info include (PDO index, name, number of entry)
@@ -761,22 +761,22 @@
title = str(hex(tmp['pdo_index']))
page_texts.append(title)
# RX PDO case
- else :
+ else :
pdo_info = self.Controler.CommonMethod.GetRxPDOCategory()
pdo_entry = self.Controler.CommonMethod.GetRxPDOInfo()
for tmp in pdo_info :
title = str(hex(tmp['pdo_index']))
page_texts.append(title)
-
+
# Add page depending on the number of pdo_info
for txt in page_texts:
win = PDOEntryTable(self, pdo_info, pdo_entry, count)
self.AddPage(win, txt)
- count += 1
+ count += 1
self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
-
+
def OnPageChanged(self, event):
old = event.GetOldSelection()
new = event.GetSelection()
@@ -787,12 +787,12 @@
old = event.GetOldSelection()
new = event.GetSelection()
sel = self.GetSelection()
- event.Skip()
+ event.Skip()
#-------------------------------------------------------------------------------
# For PDO Grid (fill entry index, subindex etc...)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class PDOEntryTable(wx.grid.Grid):
def __init__(self, parent, info, entry, count):
"""
@@ -802,38 +802,38 @@
@param entry : data structure including index, name, entry number
@param count : page number
"""
- wx.grid.Grid.__init__(self, parent, -1, size=(500, 400), pos=wx.Point(0,0),
+ wx.grid.Grid.__init__(self, parent, -1, size=(500, 400), pos=wx.Point(0,0),
style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
-
+
self.Controler = parent.Controler
-
+
self.PDOInfo = info
self.PDOEntry = entry
self.Count = count
-
+
self.CreateGrid(self.PDOInfo[self.Count]['number_of_entry'], 5)
- self.SetColLabelSize(25)
+ self.SetColLabelSize(25)
self.SetRowLabelSize(0)
-
+
PDOTableLabel = [(0, "Index"), (1, "Subindex"), (2, "Length"),
(3, "Type"), (4, "Name")]
-
+
for (index, label) in PDOTableLabel:
self.SetColLabelValue(index, label)
-
+
PDOCellSize = [(0, 45), (1, 65), (2, 55), (3, 40), (4, 300)]
-
+
for (index, size) in PDOCellSize:
self.SetColSize(index, size)
self.SetColLabelAlignment(index, wx.ALIGN_LEFT)
-
+
attr = wx.grid.GridCellAttr()
-
+
for i in range(5):
self.SetColAttr(i, attr)
-
+
self.SetTableValue()
-
+
def SetTableValue(self):
"""
Cell is filled by new parsing data in XML
@@ -844,7 +844,7 @@
list_index += self.PDOInfo[i]['number_of_entry']
start_value = list_index - self.PDOInfo[self.Count]['number_of_entry']
-
+
pdo_list = ['entry_index', 'subindex', 'bitlen', 'type', 'name']
for row_idx in range(self.PDOInfo[self.Count]['number_of_entry']):
for col_idx in range(len(self.PDOEntry[row_idx])):
@@ -863,9 +863,9 @@
#-------------------------------------------------------------------------------
-# For EEPROM Access Main Panel
+# For EEPROM Access Main Panel
# (This class explain EEPROM Access)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class EEPROMAccessPanel(wx.Panel):
def __init__(self, parent, controler):
"""
@@ -875,19 +875,19 @@
"""
wx.Panel.__init__(self, parent, -1)
sizer = wx.FlexGridSizer(cols=1, hgap=20,rows=3, vgap=20)
-
+
line = wx.StaticText(self, -1, "\n EEPROM Access is composed to SmartView and HexView. \
\n\n - SmartView shows Config Data, Device Identity, Mailbox settings, etc. \
\n\n - HexView shows EEPROM's contents.")
-
+
sizer.Add(line)
-
+
self.SetSizer(sizer)
#-------------------------------------------------------------------------------
-# For Smart View Panel
-#-------------------------------------------------------------------------------
+# For Smart View Panel
+#-------------------------------------------------------------------------------
class SlaveSiiSmartView(wx.Panel):
def __init__(self, parent, controler):
"""
@@ -898,8 +898,8 @@
wx.Panel.__init__(self, parent, -1)
self.parent = parent
self.Controler = controler
-
- self.PDIType = {0 :['none', '00000000'],
+
+ self.PDIType = {0 :['none', '00000000'],
4 :['Digital I/O', '00000100'],
5 :['SPI Slave', '00000101'],
7 :['EtherCAT Bridge (port3)', '00000111'],
@@ -914,7 +914,7 @@
20 :['0 Digtal Input and 32 Digital Output', '00010100'],
128:['On-chip bus', '11111111']
}
-
+
sizer = wx.FlexGridSizer(cols=1, hgap=5, rows=2, vgap=5)
button_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=5)
@@ -923,78 +923,78 @@
btn = wx.Button(self, -1, button, size=(150, 40))
button_sizer.Add(btn, border=10, flag=wx.ALL)
btn.Bind(wx.EVT_BUTTON, mapping_method)
-
+
self.TreeListCtrl = SmartViewTreeListCtrl(self, self.Controler)
-
+
sizer.Add(button_sizer, border=10, flag=wx.ALL)
sizer.Add(self.TreeListCtrl, border=10, flag=wx.ALL)
self.SetSizer(sizer)
-
+
self.Create_SmartView()
-
+
def Create_SmartView(self):
"""
SmartView shows information based on XML as initial value.
- """
+ """
self.Controler.CommonMethod.SmartViewInfosFromXML = self.Controler.CommonMethod.GetSmartViewInfos()
self.SetXMLData()
-
+
def WriteToEEPROM(self, event):
"""
Open binary file (user select) and write the selected binary data to EEPROM
@param event : wx.EVT_BUTTON object
- """
+ """
# Check whether beremiz connected or not, and whether status is "Started" or not.
check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
if check_connect_flag:
status, count = self.Controler.GetCTRoot()._connector.GetPLCstatus()
if status is not "Started":
dialog = wx.FileDialog(self, _("Choose a binary file"), os.getcwd(), "", _("bin files (*.bin)|*.bin"), wx.OPEN)
-
+
if dialog.ShowModal() == wx.ID_OK:
filepath = dialog.GetPath()
try:
binfile = open(filepath,"rb")
self.SiiBinary = binfile.read()
dialog.Destroy()
-
+
self.Controler.CommonMethod.SiiWrite(self.SiiBinary)
# refresh data structure kept by master
self.Controler.CommonMethod.Rescan()
- # save binary data as inner global data of beremiz
+ # save binary data as inner global data of beremiz
# for fast loading when slave plugin node is reopened.
self.Controler.CommonMethod.SiiData = self.SiiBinary
self.SetEEPROMData()
except Exception:
self.Controler.CommonMethod.CreateErrorDialog('The file does not exist!')
dialog.Destroy()
-
+
def ReadFromEEPROM(self, event):
"""
Refresh displayed data based on slave EEPROM and save binary file through dialog
@param event : wx.EVT_BUTTON object
- """
+ """
# Check whether beremiz connected or not.
check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
if check_connect_flag:
self.SiiBinary = self.Controler.CommonMethod.LoadData()
self.SetEEPROMData()
- dialog = wx.FileDialog(self, _("Save as..."), os.getcwd(),
- "slave0.bin", _("bin files (*.bin)|*.bin|All files|*.*"),
+ dialog = wx.FileDialog(self, _("Save as..."), os.getcwd(),
+ "slave0.bin", _("bin files (*.bin)|*.bin|All files|*.*"),
wx.SAVE|wx.OVERWRITE_PROMPT)
-
+
if dialog.ShowModal() == wx.ID_OK:
filepath = dialog.GetPath()
binfile = open(filepath,"wb")
binfile.write(self.SiiBinary)
binfile.close()
-
+
dialog.Destroy()
-
+
def SetXMLData(self):
"""
Set data based on XML initially
- """
+ """
# Config Data: EEPROM Size, PDI Type, Device Emulation
# Find PDI Type in pdiType dictionary
cnt_pdi_type = self.Controler.CommonMethod.SmartViewInfosFromXML["pdi_type"]
@@ -1003,14 +1003,14 @@
cnt_pdi_type = self.PDIType[i][0]
break
# Set Config Data
- for treelist, data in [("EEPROM Size (Bytes)",
+ for treelist, data in [("EEPROM Size (Bytes)",
str(self.Controler.CommonMethod.SmartViewInfosFromXML["eeprom_size"])),
- ("PDI Type",
+ ("PDI Type",
cnt_pdi_type),
- ("Device Emulation",
+ ("Device Emulation",
self.Controler.CommonMethod.SmartViewInfosFromXML["device_emulation"])]:
self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.ConfigData[treelist], data, 1)
-
+
# Device Identity: Vendor ID, Product Code, Revision No., Serial No.
# Set Device Identity
for treelist, data in [("Vendor ID", self.Controler.CommonMethod.SmartViewInfosFromXML["vendor_id"]),
@@ -1018,30 +1018,30 @@
("Revision No.", self.Controler.CommonMethod.SmartViewInfosFromXML["revision_no"]),
("Serial No.", self.Controler.CommonMethod.SmartViewInfosFromXML["serial_no"])]:
self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.DeviceIdentity[treelist], data, 1)
-
+
# Mailbox: Supported Mailbox, Bootstrap Configuration, Standard Configuration
# Set Mailbox
for treelist, data in [("Supported Mailbox", self.Controler.CommonMethod.SmartViewInfosFromXML["supported_mailbox"]),
("Bootstrap Configuration", ""),
("Standard Configuration", "")]:
- self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1)
+ self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1)
# Set Bootstrap Configuration: Receive Offset, Receive Size, Send Offset, Send Size
for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outstart"]),
("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outlength"]),
("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_instart"]),
("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_inlength"])]:
- self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1)
+ self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1)
# Set Standard Configuration: Receive Offset, Receive Size, Send Offset, Send Size
for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outstart"]),
("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outlength"]),
("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_instart"]),
("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_inlength"])]:
self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1)
-
+
def SetEEPROMData(self):
"""
Set data based on slave EEPROM.
- """
+ """
# sii_dict = { Parameter : (WordAddress, WordSize) }
sii_dict= { 'PDIControl' : ( '0', 1),
'PDIConfiguration' : ( '1', 1),
@@ -1071,7 +1071,7 @@
'Following Category Word Size' : ('41', 1),
'Category Data' : ('42', 1),
}
-
+
# Config Data: EEPROM Size, PDI Type, Device Emulation
# EEPROM's data in address '0x003f' is Size of EEPROM in KBit-1
eeprom_size = str((int(self.GetWordAddressData( sii_dict.get('Size'),10 ))+1)/8*1024)
@@ -1082,13 +1082,13 @@
cnt_pdi_type = self.PDIType[i][0]
break
# Get Device Emulation
- device_emulation = str(bool(int("{:0>16b}".format(int(self.GetWordAddressData( sii_dict.get('PDIControl'),16 ), 16))[7])))
+ device_emulation = str(bool(int("{:0>16b}".format(int(self.GetWordAddressData( sii_dict.get('PDIControl'),16 ), 16))[7])))
# Set Config Data
for treelist, data in [("EEPROM Size (Bytes)", eeprom_size),
("PDI Type", cnt_pdi_type),
("Device Emulation", device_emulation)]:
self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.ConfigData[treelist], data, 1)
-
+
# Device Identity: Vendor ID, Product Code, Revision No., Serial No.
# Set Device Identity
for treelist, data in [("Vendor ID", self.GetWordAddressData( sii_dict.get('VendorID'),16 )),
@@ -1096,10 +1096,10 @@
("Revision No.", self.GetWordAddressData( sii_dict.get('RevisionNumber'),16 )),
("Serial No.", self.GetWordAddressData( sii_dict.get('SerialNumber'),16 ))]:
self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.DeviceIdentity[treelist], data, 1)
-
+
# Mailbox
# EEORPOM's word address '1c' indicates supported mailbox protocol.
- # each value of mailbox protocol :
+ # each value of mailbox protocol :
# VoE(0x0020), SoE(0x0010), FoE(0x0008), CoE(0x0004), EoE(0x0002), AoE(0x0001)
supported_mailbox = ""
mailbox_protocol=["VoE, ", "SoE, ", "FoE, ", "CoE, ", "EoE, ", "AoE, "]
@@ -1112,20 +1112,20 @@
for treelist, data in [("Supported Mailbox", supported_mailbox),
("Bootstrap Configuration", ""),
("Standard Configuration", "")]:
- self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1)
+ self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1)
# Set Bootstrap Configuration: Receive Offset, Receive Size, Send Offset, Send Size
for treelist, data in [("Receive Offset", self.GetWordAddressData( sii_dict.get('BootstrapReceiveMailboxOffset'),10 )),
("Receive Size", self.GetWordAddressData( sii_dict.get('BootstrapReceiveMailboxSize'),10 )),
("Send Offset", self.GetWordAddressData( sii_dict.get('BootstrapSendMailboxOffset'),10 )),
("Send Size", self.GetWordAddressData( sii_dict.get('BootstrapSendMailboxSize'),10 ))]:
- self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1)
+ self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1)
# Set Standard Configuration: Receive Offset, Receive Size, Send Offset, Send Size
for treelist, data in [("Receive Offset", self.GetWordAddressData( sii_dict.get('StandardReceiveMailboxOffset'),10 )),
("Receive Size", self.GetWordAddressData( sii_dict.get('StandardReceiveMailboxSize'),10 )),
("Send Offset", self.GetWordAddressData( sii_dict.get('StandardSendMailboxOffset'),10 )),
("Send Size", self.GetWordAddressData( sii_dict.get('StandardSendMailboxSize'),10 ))]:
- self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1)
-
+ self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1)
+
def MakeStaticBoxSizer(self, boxlabel):
"""
Make StaticBoxSizer
@@ -1136,14 +1136,14 @@
sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
return sizer
-
+
def GetWordAddressData(self, dict_tuple, format):
"""
This method converts word address data from EEPROM binary.
@param dict_tuple : element of 'sii_dict' dictionary in SetEEPROMData()
@param format : format of data. It can be 16(hex), 10(decimal) and 2(binary).
@return formatted value
- """
+ """
offset = int(str(dict_tuple[0]), 16) * 2
length = int(str(dict_tuple[1]), 16) * 2
list = []
@@ -1151,21 +1151,21 @@
for index in range(length):
hexdata = hex(ord(self.SiiBinary[offset + index]))[2:]
list.append(hexdata.zfill(2))
-
+
list.reverse()
data = list[0:length]
if format == 16:
- return '0x' + ''.join(data)
+ return '0x' + ''.join(data)
elif format == 10:
return str(int(str(''.join(data)), 16))
- elif format == 2:
- ''.join(data)
+ elif format == 2:
+ ''.join(data)
#-------------------------------------------------------------------------------
# For Smart View TreeListCtrl
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class SmartViewTreeListCtrl(wx.Panel):
def __init__(self, parent, Controler):
"""
@@ -1175,26 +1175,26 @@
"""
wx.Panel.__init__(self, parent, -1, size=(350, 500))
-
- self.Tree = wx.gizmos.TreeListCtrl(self, -1, size=(350, 500),
+
+ self.Tree = wx.gizmos.TreeListCtrl(self, -1, size=(350, 500),
style=wx.TR_DEFAULT_STYLE
|wx.TR_FULL_ROW_HIGHLIGHT
|wx.TR_HIDE_ROOT
|wx.TR_COLUMN_LINES
|wx.TR_ROW_LINES)
-
+
self.Tree.AddColumn("Description", width=200)
self.Tree.AddColumn("Value", width=140)
self.Tree.SetMainColumn(0)
-
+
self.Root = self.Tree.AddRoot("")
-
+
# Add item
# Level 1 nodes
self.Level1Nodes = {}
for lv1 in ["Config Data", "Device Identity", "Mailbox"]:
self.Level1Nodes[lv1] = self.Tree.AppendItem(self.Root, lv1)
-
+
# Level 2 nodes
# Config Data
self.ConfigData = {}
@@ -1208,7 +1208,7 @@
self.Mailbox = {}
for lv2 in ["Supported Mailbox", "Bootstrap Configuration", "Standard Configuration"]:
self.Mailbox[lv2] = self.Tree.AppendItem(self.Level1Nodes["Mailbox"], lv2)
-
+
# Level 3 nodes
# Children of Bootstrap Configuration
self.BootstrapConfig = {}
@@ -1218,13 +1218,13 @@
self.StandardConfig = {}
for lv3 in ["Receive Offset", "Receive Size", "Send Offset", "Send Size"]:
self.StandardConfig[lv3] = self.Tree.AppendItem(self.Mailbox["Standard Configuration"], lv3)
-
+
# Expand Tree
- for tree in [self.Root,
- self.Level1Nodes["Config Data"],
- self.Level1Nodes["Device Identity"],
+ for tree in [self.Root,
+ self.Level1Nodes["Config Data"],
+ self.Level1Nodes["Device Identity"],
self.Level1Nodes["Mailbox"],
- self.Mailbox["Bootstrap Configuration"],
+ self.Mailbox["Bootstrap Configuration"],
self.Mailbox["Standard Configuration"]]:
self.Tree.Expand(tree)
@@ -1232,7 +1232,7 @@
#-------------------------------------------------------------------------------
# For Hex View Panel
# shows EEPROM binary as hex data and characters.
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class HexView(wx.Panel):
def __init__(self, parent, controler):
"""
@@ -1243,10 +1243,10 @@
wx.Panel.__init__(self, parent, -1)
self.parent = parent
self.Controler = controler
-
+
self.HexRow = 8
self.HexCol = 17
-
+
self.HexViewSizer = {"view" : wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10),
"siiButton" : wx.BoxSizer()}
self.HexViewButton = {}
@@ -1256,16 +1256,16 @@
("Write to File", self.OnButtonWriteToBinFile),
("Read from File", self.OnButtonReadFromBinFile),
("XML to EEPROM Image", self.OnButtonXmlToEEPROMImg)]:
- self.HexViewButton[key] = wx.Button(self, -1, key)
+ self.HexViewButton[key] = wx.Button(self, -1, key)
self.HexViewButton[key].Bind(wx.EVT_BUTTON, evt_handler)
self.HexViewSizer["siiButton"].Add(self.HexViewButton[key])
self.SiiBinary = self.Controler.CommonMethod.XmlToEeprom()
self.HexCode, self.HexRow, self.HexCol = self.Controler.CommonMethod.HexRead(self.SiiBinary)
self.SiiGrid = SiiGridTable(self, self.Controler, self.HexRow, self.HexCol)
- self.HexViewSizer["view"].AddMany([self.HexViewSizer["siiButton"], self.SiiGrid])
+ self.HexViewSizer["view"].AddMany([self.HexViewSizer["siiButton"], self.SiiGrid])
self.SiiGrid.CreateGrid(self.HexRow, self.HexCol)
- self.SetSizer(self.HexViewSizer["view"])
+ self.SetSizer(self.HexViewSizer["view"])
self.HexViewSizer["view"].FitInside(self.parent.parent)
self.parent.parent.FitInside()
self.SiiGrid.SetValue(self.HexCode)
@@ -1275,7 +1275,7 @@
"""
Destroy existing grid and recreate
@param row, col : Hex View grid size
- """
+ """
self.HexViewSizer["view"].Detach(self.SiiGrid)
self.SiiGrid.Destroy()
self.SiiGrid = SiiGridTable(self, self.Controler, row, col)
@@ -1290,7 +1290,7 @@
Load EEPROM data from slave and refresh Hex View grid
Binded to 'Sii Upload' button.
@param event : wx.EVT_BUTTON object
- """
+ """
# Check whether beremiz connected or not.
check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
if check_connect_flag:
@@ -1300,29 +1300,29 @@
self.UpdateSiiGridTable(self.HexRow, self.HexCol)
self.SiiGrid.SetValue(self.HexCode)
self.SiiGrid.Update()
-
+
def OnButtonSiiDownload(self, event):
"""
- Write current EEPROM data to slave and refresh data structure kept by master
+ Write current EEPROM data to slave and refresh data structure kept by master
Binded to 'Sii Download' button.
@param event : wx.EVT_BUTTON object
- """
- # Check whether beremiz connected or not,
- # and whether status is "Started" or not.
+ """
+ # Check whether beremiz connected or not,
+ # and whether status is "Started" or not.
check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
if check_connect_flag:
status, count = self.Controler.GetCTRoot()._connector.GetPLCstatus()
if status is not "Started":
self.Controler.CommonMethod.SiiWrite(self.SiiBinary)
self.Controler.CommonMethod.Rescan()
-
+
def OnButtonWriteToBinFile(self, event):
- """
+ """
Save current EEPROM data to binary file through FileDialog
Binded to 'Write to File' button.
@param event : wx.EVT_BUTTON object
- """
- dialog = wx.FileDialog(self, _("Save as..."), os.getcwd(), "slave0.bin",
+ """
+ dialog = wx.FileDialog(self, _("Save as..."), os.getcwd(), "slave0.bin",
_("bin files (*.bin)|*.bin|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT)
if dialog.ShowModal() == wx.ID_OK:
@@ -1330,33 +1330,33 @@
binfile = open(filepath,"wb")
binfile.write(self.SiiBinary)
binfile.close()
-
- dialog.Destroy()
-
+
+ dialog.Destroy()
+
def OnButtonReadFromBinFile(self, event):
"""
Load binary file through FileDialog
Binded to 'Read from File' button.
@param event : wx.EVT_BUTTON object
"""
- dialog = wx.FileDialog(self, _("Choose a binary file"), os.getcwd(), "",
+ dialog = wx.FileDialog(self, _("Choose a binary file"), os.getcwd(), "",
_("bin files (*.bin)|*.bin"), wx.OPEN)
-
+
if dialog.ShowModal() == wx.ID_OK:
filepath = dialog.GetPath()
-
+
try:
binfile = open(filepath, "rb")
self.SiiBinary = binfile.read()
self.HexCode, self.HexRow, self.HexCol = self.Controler.CommonMethod.HexRead(self.SiiBinary)
- self.UpdateSiiGridTable(self.HexRow, self.HexCol)
+ self.UpdateSiiGridTable(self.HexRow, self.HexCol)
self.SiiGrid.SetValue(self.HexCode)
self.SiiGrid.Update()
except Exception:
self.Controler.CommonMethod.CreateErrorDialog('The file does not exist!')
-
+
dialog.Destroy()
-
+
def OnButtonXmlToEEPROMImg(self, event):
"""
Create EEPROM data based XML data that current imported
@@ -1372,8 +1372,8 @@
#-------------------------------------------------------------------------------
# For Hex View grid (fill hex data)
-#-------------------------------------------------------------------------------
-class SiiGridTable(wx.grid.Grid):
+#-------------------------------------------------------------------------------
+class SiiGridTable(wx.grid.Grid):
def __init__(self, parent, controler, row, col):
"""
Constructor
@@ -1384,10 +1384,10 @@
self.parent = parent
self.Controler = controler
self.Row = row
- self.Col = col
-
- wx.grid.Grid.__init__(self, parent, -1, size=(830,450),
- style=wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
+ self.Col = col
+
+ wx.grid.Grid.__init__(self, parent, -1, size=(830,450),
+ style=wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
def SetValue(self, value):
"""
@@ -1403,28 +1403,28 @@
else:
self.SetColLabelValue(col, '%s'%col)
self.SetColSize(col, (self.GetSize().x-120)/20)
-
+
# set data into table
row = col = 0
- for row_idx in value:
+ for row_idx in value:
col = 0
self.SetRowLabelValue(row, "0x"+"{:0>4x}".format(row*(self.Col-1)))
for hex in row_idx:
self.SetCellValue(row, col, hex)
-
- if col == 16:
+
+ if col == 16:
self.SetCellAlignment(row, col, wx.ALIGN_LEFT, wx.ALIGN_CENTER)
else:
self.SetCellAlignment(row, col, wx.ALIGN_CENTRE, wx.ALIGN_CENTER)
-
+
self.SetReadOnly(row, col, True)
col = col + 1
row = row + 1
-
+
#-------------------------------------------------------------------------------
# For Register Access Panel
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class RegisterAccessPanel(wx.Panel):
def __init__(self, parent, controler):
"""
@@ -1435,31 +1435,31 @@
self.parent = parent
self.Controler = controler
self.__init_data()
-
+
wx.Panel.__init__(self, parent, -1)
-
+
sizer = wx.FlexGridSizer(cols=1, hgap=20, rows=2, vgap=5)
button_sizer = wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=10)
-
+
self.ReloadButton = wx.Button(self, -1, "Reload")
- self.CompactViewCheckbox = wx.CheckBox(self, -1, "Compact View")
+ self.CompactViewCheckbox = wx.CheckBox(self, -1, "Compact View")
self.RegisterNotebook = RegisterNotebook(self, self.Controler)
-
+
button_sizer.AddMany([self.ReloadButton, self.CompactViewCheckbox])
sizer.AddMany([button_sizer, self.RegisterNotebook])
self.SetSizer(sizer)
-
+
self.ReloadButton.Bind(wx.EVT_BUTTON, self.OnReloadButton)
self.CompactViewCheckbox.Bind(wx.EVT_CHECKBOX, self.ToggleCompactViewCheckbox)
-
+
for index in range(4):
self.RegisterNotebook.RegPage[index].MainTable.CreateGrid(self.MainRow[index], self.MainCol)
self.RegisterNotebook.RegPage[index].MainTable.SetValue(self, 0, index*512, (index+1)*512)
-
+
# data default setting
- if self.Controler.CommonMethod.RegData == "":
- self.CompactViewCheckbox.Disable()
- for index in range(4):
+ if self.Controler.CommonMethod.RegData == "":
+ self.CompactViewCheckbox.Disable()
+ for index in range(4):
self.RegisterNotebook.RegPage[index].MainTable.SetValue(self, 0, index*512, (index+1)*512)
else: # If data was saved,
self.BasicSetData()
@@ -1473,22 +1473,22 @@
"""
# flag for compact view
self.CompactFlag = False
-
+
# main grid의 rows and cols
self.MainRow = [512, 512, 512, 512]
self.MainCol = 4
-
+
# main grids' data range
self.PageRange = []
for index in range(4):
self.PageRange.append([512*index, 512*(index+1)])
-
+
# Previous value of register data for register description configuration
self.PreRegSpec = {"ESCType": "",
"FMMUNumber": "",
"SMNumber": "",
"PDIType": ""}
-
+
def LoadData(self):
"""
Get data from the register.
@@ -1499,26 +1499,26 @@
#return value : 0x11
for index in range(4):
self.Controler.CommonMethod.RegData = self.Controler.CommonMethod.RegData + " " + self.Controler.CommonMethod.RegRead("0x"+"{:0>4x}".format(index*1024), "0x0400")
-
- # store previous value
+
+ # store previous value
# (ESC type, port number of FMMU, port number of SM, and PDI type))
for reg_spec in ["ESCType","FMMUNumber","SMNumber", "PDIType"]:
self.PreRegSpec[reg_spec] = self.Controler.CommonMethod.CrtRegSpec[reg_spec]
-
- # update registers' description
+
+ # update registers' description
# (ESC type, port number of FMMU, port number of SM, and PDI type)
for reg_spec, address in [("ESCType", "0x0000"),
("FMMUNumber", "0x0004"),
("SMNumber", "0x0005"),
("PDIType", "0x0140")]:
self.Controler.CommonMethod.CrtRegSpec[reg_spec] = self.Controler.CommonMethod.RegRead(address, "0x0001")
-
+
# Enable compactView checkbox
self.CompactViewCheckbox.Enable()
-
+
def BasicSetData(self):
"""
- Get and save the description of registers.
+ Get and save the description of registers.
It's done by parsing register_information.xml.
"""
# parse the above register's value
@@ -1528,11 +1528,11 @@
# If the value is 0x12, the result is 18 (It's converted to decimal value)
self.FMMUNumber = int(self.Controler.CommonMethod.CrtRegSpec["FMMUNumber"], 16)
self.SMNumber = int(self.Controler.CommonMethod.CrtRegSpec["SMNumber"], 16)
-
+
# initialize description dictionary of register main table and register sub table.
self.RegisterDescriptionDict = {}
self.RegisterSubGridDict = {}
-
+
# ./EthercatMaster/register_information.xml contains register description.
if wx.Platform == '__WXMSW__':
reg_info_file = open("../../EthercatMaster/register_information.xml", 'r')
@@ -1540,7 +1540,7 @@
reg_info_file = open("./EthercatMaster/register_information.xml", 'r')
reg_info_tree = minidom.parse(reg_info_file)
reg_info_file.close()
-
+
# parse register description
for register_info in reg_info_tree.childNodes:
for register in register_info.childNodes:
@@ -1550,7 +1550,7 @@
("pdi", "type", self.PDIType),
("fmmu", "number", self.FMMUNumber),
("sm", "number", self.SMNumber)]:
- if property in register.attributes.keys():
+ if property in register.attributes.keys():
if type == "type":
if register.attributes[property].value == value:
self.GetRegisterInfo(reg_info_tree, register)
@@ -1562,7 +1562,7 @@
else:
self.GetRegisterInfo(reg_info_tree, register)
break
-
+
def GetRegisterInfo(self, reg_info_tree, register):
"""
Save the register's description into the dictionary.
@@ -1573,7 +1573,7 @@
# temporary variables for register main table idescription dictionary
reg_index = ""
reg_main_description = ""
-
+
for data in register.childNodes:
if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Index":
for index in data.childNodes:
@@ -1581,15 +1581,15 @@
if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Description":
for description in data.childNodes:
reg_main_description = description.nodeValue
-
- # Add description for register main table
+
+ # Add description for register main table
if reg_index is not "" and reg_main_description is not "":
self.RegisterDescriptionDict[reg_index] = reg_main_description
-
+
if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Details":
# declare register sub table description dictionary about this index
self.RegisterSubGridDict[reg_index] = []
-
+
for detail in data.childNodes:
if detail.nodeType == reg_info_tree.ELEMENT_NODE and detail.nodeName == "Detail":
# If it depends on the property(ESC type, PDI type, FMMU number, SM number)
@@ -1597,7 +1597,7 @@
("pdi", "type", self.PDIType),
("fmmu", "number", self.FMMUNumber),
("sm", "number", self.SMNumber)]:
- if property in detail.attributes.keys():
+ if property in detail.attributes.keys():
if type == "type":
if detail.attributes[property].value == value:
self.GetRegisterDetailInfo(reg_info_tree, reg_index, detail)
@@ -1609,7 +1609,7 @@
else:
self.GetRegisterDetailInfo(reg_info_tree, reg_index, detail)
break
-
+
def GetRegisterDetailInfo(self, reg_info_tree, reg_index, detail):
"""
Get the resgister's detailed description(for sub table) from the reg_info_tree.
@@ -1617,30 +1617,30 @@
@param reg_index: index of the register
@param detail: description of the register
"""
- # temporary variables for register sub table description dictionary
- # - It is initialized in every sub description
+ # temporary variables for register sub table description dictionary
+ # - It is initialized in every sub description
reg_bit_range = ""
reg_sub_description = ""
reg_enum_dictionary = {}
-
+
for detail_data in detail.childNodes:
- if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Range":
+ if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Range":
for range in detail_data.childNodes:
reg_bit_range = range.nodeValue
if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Description":
for description in detail_data.childNodes:
reg_sub_description = description.nodeValue
-
+
if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Enum":
for enum in detail_data.childNodes:
if enum.nodeType == reg_info_tree.ELEMENT_NODE and enum.nodeName == "item":
-
- # temporary variables for a description of each value
- # For example, if the bit is 1, it is 'enabled'('On', 'True', etc.),
- # otherwise 'disabled'('Off', 'False', etc.).
+
+ # temporary variables for a description of each value
+ # For example, if the bit is 1, it is 'enabled'('On', 'True', etc.),
+ # otherwise 'disabled'('Off', 'False', etc.).
reg_sub_value = ""
reg_sub_value_description = ""
-
+
for item in enum.childNodes:
if item.nodeType == reg_info_tree.ELEMENT_NODE and item.nodeName == "value":
for value in item.childNodes:
@@ -1648,16 +1648,16 @@
if item.nodeType == reg_info_tree.ELEMENT_NODE and item.nodeName == "Description":
for description in item.childNodes:
reg_sub_value_description = description.nodeValue
-
+
# Add a description of each value to register enum dictionary
if reg_sub_value is not "" and reg_sub_value_description is not "":
reg_enum_dictionary[reg_sub_value] = reg_sub_value_description
-
+
# add a description to register sub table description dictionary
if reg_bit_range is not "" and reg_sub_description is not "":
- self.RegisterSubGridDict[reg_index].append([reg_bit_range,
+ self.RegisterSubGridDict[reg_index].append([reg_bit_range,
reg_sub_description, reg_enum_dictionary])
-
+
def ParseData(self):
"""
Transform the data into dec, hex, string, and description
@@ -1665,30 +1665,30 @@
row_data = []
self.RegMonitorData = []
reg_word = ""
-
+
reg_data = self.Controler.CommonMethod.RegData.split()
-
+
# loop for register(0x0000:0x0fff)
for address in range(0x1000):
- # arrange 2 Bytes of register data
+ # arrange 2 Bytes of register data
reg_word = reg_data[address].split('x')[1] + reg_word
if (address%2) == 1:
# append address
hex_address = "{:0>4x}".format(address-1)
row_data.append(hex_address)
-
+
# append description
if self.RegisterDescriptionDict.has_key(hex_address):
row_data.append(self.RegisterDescriptionDict[hex_address])
else:
row_data.append("")
-
+
# append Decimal value
row_data.append(str(int(reg_word, 16)))
-
+
# append Hex value
row_data.append('0x'+reg_word)
-
+
# append ASCII value
char_data = ""
for iter in range(2):
@@ -1697,11 +1697,11 @@
else:
char_data = char_data + "."
row_data.append(char_data)
-
+
self.RegMonitorData.append(row_data)
reg_word = "" # initialize regWord
row_data = []
-
+
def OnReloadButton(self, event):
"""
Handle the click event of the 'Reload' button.
@@ -1717,10 +1717,10 @@
# set data into UI
if self.CompactFlag:
self.ToggleCompactViewCheckbox(True)
- else :
+ else :
for index in range(4):
- self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
- self.PageRange[index][0], self.PageRange[index][1],
+ self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
+ self.PageRange[index][0], self.PageRange[index][1],
self.RegMonitorData)
def ToggleCompactViewCheckbox(self, event):
@@ -1730,12 +1730,12 @@
If not, show all the registers.
@param event: wx.EVT_CHECKBOX object
"""
-
+
# If "Compact View" Checkbox is True
## 'event' is argument of this method or event of checkbox.
if event==True or event.GetEventObject().GetValue():
self.CompactFlag = True
-
+
reg_compact_data = []
page_row = [0, 0, 0, 0]
for index in range(4):
@@ -1758,34 +1758,34 @@
self.PageRange[index][1] = page_row[index]
for iter in range(index):
self.PageRange[index][0] += page_row[iter]
- self.PageRange[index][1] += page_row[iter]
-
+ self.PageRange[index][1] += page_row[iter]
+
# Update table
for index in range(4):
- self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
- self.PageRange[index][0], self.PageRange[index][1],
+ self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
+ self.PageRange[index][0], self.PageRange[index][1],
reg_compact_data)
-
- # Compact View Checkbox is False
+
+ # Compact View Checkbox is False
else:
self.CompactFlag = False
# Setting original rows, cols and range
self.MainRow = [512, 512, 512, 512]
self.PageRange = []
-
+
for index in range(4):
self.PageRange.append([512*index, 512*(index+1)])
-
- # Update table
+
+ # Update table
for index in range(4):
- self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
- self.PageRange[index][0], self.PageRange[index][1],
+ self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
+ self.PageRange[index][0], self.PageRange[index][1],
self.RegMonitorData)
-
+
#-------------------------------------------------------------------------------
# For Register Access Notebook (divide index range)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class RegisterNotebook(wx.Notebook):
def __init__(self, parent, controler):
"""
@@ -1794,21 +1794,21 @@
@param controler: _EthercatSlaveCTN class in EthercatSlave.py
"""
wx.Notebook.__init__(self, parent, id = -1)
-
+
self.parent = parent
self.Controler = controler
-
+
# Initialize pages
self.RegPage = []
for iter in range(4):
self.RegPage.append(None)
-
+
for index in range(4):
- self.RegPage[index] = RegisterNotebookPanel(self, self.Controler,
+ self.RegPage[index] = RegisterNotebookPanel(self, self.Controler,
parent.MainRow[index], parent.MainCol)
- self.AddPage(self.RegPage[index],
+ self.AddPage(self.RegPage[index],
"0x"+"{:0>4x}".format(index*1024)+" - 0x"+"{:0>4x}".format((index+1)*1024-1))
-
+
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
@@ -1826,9 +1826,9 @@
#-------------------------------------------------------------------------------
-# For Register Access Notebook Panel
+# For Register Access Notebook Panel
# (Main UI : including main, sub table)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class RegisterNotebookPanel(wx.Panel):
def __init__(self, parent, controler, row, col):
"""
@@ -1838,26 +1838,26 @@
@param row, col: size of the table
"""
wx.Panel.__init__(self, parent, -1)
-
+
self.parent = parent
self.Controler = controler
self.Row = row
self.Col = col
sub_row = 0
sub_col = 4
-
+
self.Sizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=30)
-
+
self.MainTable = RegisterMainTable(self, self.Row, self.Col, self.Controler)
self.SubTable = RegisterSubTable(self, sub_row, sub_col)
-
+
self.SubTable.CreateGrid(sub_row, sub_col)
self.SubTable.SetValue(self, [])
-
+
self.Sizer.AddMany([self.MainTable, self.SubTable])
-
+
self.SetSizer(self.Sizer)
-
+
def UpdateMainTable(self, row, col, low_index, high_index, data):
"""
Updates main table.
@@ -1892,13 +1892,13 @@
self.SubTable.CreateGrid(row, col)
self.SubTable.SetValue(self, data)
self.SubTable.Update()
-
+
#-------------------------------------------------------------------------------
# For Register Access Notebook Panel (Main Table)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class RegisterMainTable(wx.grid.Grid):
- def __init__(self, parent, row, col, controler):
+ def __init__(self, parent, row, col, controler):
"""
Constructor
@param parent: RegisterNotebook object
@@ -1911,16 +1911,16 @@
self.Col = col
self.Controler = controler
self.RegisterAccessPanel = self.parent.parent.parent
-
- wx.grid.Grid.__init__(self, parent, -1, size=(820,300),
- style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
-
+
+ wx.grid.Grid.__init__(self, parent, -1, size=(820,300),
+ style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
+
for evt, mapping_method in [(gridlib.EVT_GRID_CELL_LEFT_CLICK, self.OnSelectCell),
(gridlib.EVT_GRID_CELL_LEFT_CLICK, self.OnSelectCell),
(gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.OnRegModifyDialog)]:
self.Bind(evt, mapping_method)
-
- def SetValue(self, parent, reg_monitor_data, low_index, high_index):
+
+ def SetValue(self, parent, reg_monitor_data, low_index, high_index):
"""
Set the RegMonitorData into the main table.
@param parent: RegisterNotebook object
@@ -1929,21 +1929,21 @@
@param high_index: the highest index of the page
"""
self.RegMonitorData = reg_monitor_data
-
+
# set label name and size
- register_maintable_label = [(0, "Description"), (1, "Dec"),
+ register_maintable_label = [(0, "Description"), (1, "Dec"),
(2, "Hex"), (3, "Char")]
-
+
for (index, label) in register_maintable_label:
self.SetColLabelValue(index, label)
-
+
self.SetColSize(0, 200)
-
+
# if reg_monitor_data is 0, it is initialization of register access.
if reg_monitor_data == 0:
return 0
-
- # set data into UI
+
+ # set data into UI
row = col = 0
for row_index in reg_monitor_data[low_index:high_index]:
col = 0
@@ -1954,8 +1954,8 @@
self.SetReadOnly(row, col, True)
col = col + 1
row = row + 1
-
- def OnSelectCell(self, event):
+
+ def OnSelectCell(self, event):
"""
Handles the event of the cell of the main table.
@param event: gridlib object (left click)
@@ -1964,17 +1964,17 @@
if self.RegMonitorData == 0:
event.Skip()
return 0
-
+
sub_row = 0
sub_col = 4
-
+
address = self.GetRowLabelValue(event.GetRow())
-
+
reg_sub_grid_data = []
-
+
BIT_RANGE, NAME, DESCRIPTIONS = range(3)
-
- # Check if this register's detail description is exist or not,
+
+ # Check if this register's detail description is exist or not,
# and create data structure for the detail description table ; sub grid
if address in self.RegisterAccessPanel.RegisterSubGridDict:
for element in self.RegisterAccessPanel.RegisterSubGridDict[address]:
@@ -1991,11 +1991,11 @@
row_data.append('')
reg_sub_grid_data.append(row_data)
sub_row = sub_row + 1
-
+
self.parent.UpdateSubTable(sub_row, sub_col, reg_sub_grid_data)
# event.Skip() updates UI of selecting cell
event.Skip()
-
+
def OnRegModifyDialog(self, event):
"""
Handle the event of the cell of the main table.
@@ -2004,16 +2004,16 @@
"""
# user can enter a value in case that user double-clicked 'Dec' or 'Hex' value.
if event.GetCol() == 1 or event.GetCol() == 2:
- dlg = wx.TextEntryDialog(self, "Enter hex(0xnnnn) or dec(n) value",
+ dlg = wx.TextEntryDialog(self, "Enter hex(0xnnnn) or dec(n) value",
"Register Modify Dialog", style = wx.OK|wx.CANCEL)
-
+
# Setting value in initial dialog value
start_value = self.GetCellValue(event.GetRow(), event.GetCol())
dlg.SetValue(start_value)
-
+
if dlg.ShowModal() == wx.ID_OK:
try:
- # It int(input) success, this input is dev or hex value.
+ # It int(input) success, this input is dev or hex value.
# Otherwise, it's error, so it goes except.
int(dlg.GetValue(), 0)
@@ -2023,7 +2023,7 @@
if len(return_val)==0:
# set dec
- self.SetCellValue(event.GetRow(), 1, str(int(dlg.GetValue(), 0)))
+ self.SetCellValue(event.GetRow(), 1, str(int(dlg.GetValue(), 0)))
# set hex
hex_data = '0x'+"{:0>4x}".format(int(dlg.GetValue(), 0))
self.SetCellValue(event.GetRow(), 2, hex_data)
@@ -2035,19 +2035,19 @@
char_data = char_data + chr(int(hex_data[(iter+1)*2:(iter+2)*2], 16))
else:
char_data = char_data + "."
-
- self.SetCellValue(event.GetRow(), 3, char_data)
-
+
+ self.SetCellValue(event.GetRow(), 3, char_data)
+
else:
self.Controler.CommonMethod.CreateErrorDialog('You can\'t modify it. This register is read-only or it\'s not connected.')
-
+
except ValueError:
self.Controler.CommonMethod.CreateErrorDialog('You entered wrong value. You can enter dec or hex value only.')
-
-
+
+
#-------------------------------------------------------------------------------
# For Register Access Notebook Panel (Sub Table)
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class RegisterSubTable(wx.grid.Grid):
def __init__(self, parent, row, col):
"""
@@ -2060,8 +2060,8 @@
self.Row = row
self.Col = col
- wx.grid.Grid.__init__(self, parent, -1, size=(820,150),
- style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
+ wx.grid.Grid.__init__(self, parent, -1, size=(820,150),
+ style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
def SetValue(self, parent, data):
"""
@@ -2070,30 +2070,30 @@
@param data: data
"""
# lset label name and size
- Register_SubTable_Label = [(0, "Bits"), (1, "Name"),
+ Register_SubTable_Label = [(0, "Bits"), (1, "Name"),
(2, "Value"), (3, "Enum")]
-
+
for (index, label) in Register_SubTable_Label:
self.SetColLabelValue(index, label)
-
+
self.SetColSize(1, 200)
self.SetColSize(3, 200)
-
+
# set data into table
row = col = 0
- for rowData in data:
- col = 0
+ for rowData in data:
+ col = 0
for element in rowData:
self.SetCellValue(row, col, element)
self.SetCellAlignment(row, col, wx.ALIGN_CENTRE, wx.ALIGN_CENTER)
self.SetReadOnly(row, col, True)
col = col + 1
row = row + 1
-
+
#-------------------------------------------------------------------------------
# For Master State Panel
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class MasterStatePanelClass(wx.Panel):
def __init__(self, parent, controler):
"""
@@ -2101,14 +2101,14 @@
@param parent: wx.ScrollWindow object
@Param controler: _EthercatSlaveCTN class in EthercatSlave.py
"""
- wx.Panel.__init__(self, parent, -1, (0, 0),
+ wx.Panel.__init__(self, parent, -1, (0, 0),
size=wx.DefaultSize, style = wx.SUNKEN_BORDER)
self.Controler = controler
self.parent = parent
self.StaticBox = {}
self.StaticText = {}
self.TextCtrl = {}
-
+
# ----------------------- Main Sizer and Update Button --------------------------------------------
self.MasterStateSizer = {"main" : wx.BoxSizer(wx.VERTICAL)}
for key, attr in [
@@ -2123,15 +2123,15 @@
self.UpdateButton = wx.Button(self, label=_('Update'))
self.UpdateButton.Bind(wx.EVT_BUTTON, self.OnButtonClick)
-
- for key, label in [
+
+ for key, label in [
('masterState', 'EtherCAT Master State'),
('deviceInfo', 'Ethernet Network Card Information'),
('frameInfo', 'Network Frame Information')]:
self.StaticBox[key] = wx.StaticBox(self, label=_(label))
self.MasterStateSizer[key] = wx.StaticBoxSizer(self.StaticBox[key])
-
-
+
+
# ----------------------- Master State -----------------------------------------------------------
for key, label in [
('Phase', 'Phase:'),
@@ -2139,11 +2139,11 @@
('Slaves', 'Slave Count:')]:
self.StaticText[key] = wx.StaticText(self, label=_(label))
self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
- self.MasterStateSizer['innerMasterState'].AddMany([self.StaticText[key], self.TextCtrl[key]])
-
+ self.MasterStateSizer['innerMasterState'].AddMany([self.StaticText[key], self.TextCtrl[key]])
+
self.MasterStateSizer['masterState'].AddSizer(self.MasterStateSizer['innerMasterState'])
-
- # ----------------------- Ethernet Network Card Information ---------------------------------------
+
+ # ----------------------- Ethernet Network Card Information ---------------------------------------
for key, label in [
('Main', 'MAC Address:'),
('Link', 'Link State:'),
@@ -2153,24 +2153,24 @@
self.StaticText[key] = wx.StaticText(self, label=_(label))
self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
self.MasterStateSizer['innerDeviceInfo'].AddMany([self.StaticText[key], self.TextCtrl[key]])
-
+
self.MasterStateSizer['deviceInfo'].AddSizer(self.MasterStateSizer['innerDeviceInfo'])
-
+
# ----------------------- Network Frame Information -----------------------------------------------
for key, label in [
- ('Tx frame rate [1/s]', 'Tx Frame Rate [1/s]:'),
- ('Rx frame rate [1/s]', 'Tx Rate [kByte/s]:'),
+ ('Tx frame rate [1/s]', 'Tx Frame Rate [1/s]:'),
+ ('Rx frame rate [1/s]', 'Tx Rate [kByte/s]:'),
('Loss rate [1/s]', 'Loss Rate [1/s]:'),
('Frame loss [%]', 'Frame Loss [%]:')]:
self.StaticText[key] = wx.StaticText(self, label=_(label))
self.MasterStateSizer['innerFrameInfo'].Add(self.StaticText[key])
- self.TextCtrl[key] = {}
- for index in ['0', '1', '2']:
+ self.TextCtrl[key] = {}
+ for index in ['0', '1', '2']:
self.TextCtrl[key][index] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
self.MasterStateSizer['innerFrameInfo'].Add(self.TextCtrl[key][index])
-
+
self.MasterStateSizer['frameInfo'].AddSizer(self.MasterStateSizer['innerFrameInfo'])
-
+
# --------------------------------- Main Sizer ----------------------------------------------------
for key, sub, in [
('innerTopHalf', [
@@ -2184,7 +2184,7 @@
self.MasterStateSizer['main'].AddSizer(self.UpdateButton)
self.MasterStateSizer['main'].AddSizer(self.MasterStateSizer['innerMain'])
-
+
self.SetSizer(self.MasterStateSizer['main'])
def OnButtonClick(self, event):
--- a/etherlab/EthercatCFileGenerator.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/EthercatCFileGenerator.py Fri Sep 28 17:20:11 2018 +0300
@@ -72,7 +72,7 @@
entry_infos["data_type"] = DATATYPECONVERSION.get(entry_infos["var_type"], None)
if entry_infos["data_type"] is None:
raise ValueError, _("Type of location \"%s\" not yet supported!") % entry_infos["var_name"]
-
+
if not entry_infos.get("no_decl", False):
if entry_infos.has_key("real_var"):
str_completion["located_variables_declaration"].append(
@@ -88,40 +88,40 @@
"IEC_%(var_type)s *%(extra_decl)s = &%(real_var)s;" % entry_infos)
elif not entry_infos.has_key("real_var"):
entry_infos["real_var"] = "beremiz" + entry_infos["var_name"]
-
+
str_completion["used_pdo_entry_offset_variables_declaration"].append(
"unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos)
-
+
if entry_infos["data_type"] == "BIT":
str_completion["used_pdo_entry_offset_variables_declaration"].append(
"unsigned int slave%(slave)d_%(index).4x_%(subindex).2x_bit;" % entry_infos)
-
+
str_completion["used_pdo_entry_configuration"].append(
- (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, " +
- "0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x, " +
+ (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, " +
+ "0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x, " +
"&slave%(slave)d_%(index).4x_%(subindex).2x_bit},") % entry_infos)
-
+
if entry_infos["dir"] == "I":
str_completion["retrieve_variables"].append(
- (" %(real_var)s = EC_READ_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
+ (" %(real_var)s = EC_READ_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
"slave%(slave)d_%(index).4x_%(subindex).2x_bit);") % entry_infos)
elif entry_infos["dir"] == "Q":
str_completion["publish_variables"].append(
- (" EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
+ (" EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
"slave%(slave)d_%(index).4x_%(subindex).2x_bit, %(real_var)s);") % entry_infos)
-
+
else:
str_completion["used_pdo_entry_configuration"].append(
- (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, " +
+ (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, " +
"%(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x},") % entry_infos)
-
+
if entry_infos["dir"] == "I":
str_completion["retrieve_variables"].append(
- (" %(real_var)s = EC_READ_%(data_type)s(domain1_pd + " +
+ (" %(real_var)s = EC_READ_%(data_type)s(domain1_pd + " +
"slave%(slave)d_%(index).4x_%(subindex).2x);") % entry_infos)
elif entry_infos["dir"] == "Q":
str_completion["publish_variables"].append(
- (" EC_WRITE_%(data_type)s(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
+ (" EC_WRITE_%(data_type)s(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
"%(real_var)s);") % entry_infos)
def ExclusionSortFunction(x, y):
@@ -134,22 +134,22 @@
return -cmp(x["matching"], y["matching"])
class _EthercatCFileGenerator:
-
+
def __init__(self, controler):
self.Controler = controler
-
+
self.Slaves = []
self.UsedVariables = {}
def __del__(self):
- self.Controler = None
-
+ self.Controler = None
+
def DeclareSlave(self, slave_index, slave):
self.Slaves.append((slave_index, slave.getInfo().getAutoIncAddr(), slave))
def DeclareVariable(self, slave_index, index, subindex, iec_type, dir, name, no_decl=False):
slave_variables = self.UsedVariables.setdefault(slave_index, {})
-
+
entry_infos = slave_variables.get((index, subindex), None)
if entry_infos is None:
slave_variables[(index, subindex)] = {
@@ -164,16 +164,16 @@
else:
raise ValueError, _("Output variables can't be defined with different locations (%s and %s)") % (entry_infos["infos"][2], name)
else:
- raise ValueError, _("Definition conflict for location \"%s\"") % name
-
+ raise ValueError, _("Definition conflict for location \"%s\"") % name
+
def GenerateCFile(self, filepath, location_str, master_number):
-
+
# Extract etherlab master code template
plc_etherlab_filepath = os.path.join(os.path.split(__file__)[0], "plc_etherlab.c")
plc_etherlab_file = open(plc_etherlab_filepath, 'r')
plc_etherlab_code = plc_etherlab_file.read()
plc_etherlab_file.close()
-
+
# Initialize strings for formatting master code template
str_completion = {
"location": location_str,
@@ -189,49 +189,49 @@
"retrieve_variables": [],
"publish_variables": [],
}
-
+
# Initialize variable storing variable mapping state
for slave_entries in self.UsedVariables.itervalues():
for entry_infos in slave_entries.itervalues():
entry_infos["mapped"] = False
-
+
# Sort slaves by position (IEC_Channel)
self.Slaves.sort()
# Initialize dictionary storing alias auto-increment position values
alias = {}
-
+
# Generating code for each slave
for (slave_idx, slave_alias, slave) in self.Slaves:
type_infos = slave.getType()
-
+
# Defining slave alias and auto-increment position
if alias.get(slave_alias) is not None:
alias[slave_alias] += 1
else:
alias[slave_alias] = 0
slave_pos = (slave_alias, alias[slave_alias])
-
+
# Extract slave device informations
device, module_extra_params = self.Controler.GetModuleInfos(type_infos)
if device is None:
raise ValueError, _("No informations found for device %s!") % (type_infos["device_type"])
-
+
# Extract slaves variables to be mapped
slave_variables = self.UsedVariables.get(slave_idx, {})
-
+
# Extract slave device object dictionary entries
device_entries = device.GetEntriesList()
-
+
# Adding code for declaring slave in master code template strings
for element in ["vendor", "product_code", "revision_number"]:
type_infos[element] = ExtractHexDecValue(type_infos[element])
type_infos.update(dict(zip(["slave", "alias", "position"], (slave_idx,) + slave_pos)))
-
+
# Extract slave device CoE informations
device_coe = device.getCoE()
if device_coe is not None:
-
- # If device support CanOpen over Ethernet, adding code for calling
+
+ # If device support CanOpen over Ethernet, adding code for calling
# init commands when initializing slave in master code template strings
initCmds = []
for initCmd in device_coe.getInitCmd():
@@ -256,37 +256,37 @@
}
init_cmd_infos.update(type_infos)
str_completion["slaves_initialization"] += SLAVE_INITIALIZATION_TEMPLATE % init_cmd_infos
-
+
# Extract slave device PDO configuration capabilities
PdoAssign = device_coe.getPdoAssign()
PdoConfig = device_coe.getPdoConfig()
else:
PdoAssign = PdoConfig = False
-
+
# Test if slave has a configuration or need one
if len(device.getTxPdo() + device.getRxPdo()) > 0 or len(slave_variables) > 0 and PdoConfig and PdoAssign:
-
+
str_completion["slaves_declaration"] += "static ec_slave_config_t *slave%(slave)d = NULL;\n" % type_infos
str_completion["slaves_configuration"] += SLAVE_CONFIGURATION_TEMPLATE % type_infos
-
- # Initializing
+
+ # Initializing
pdos_infos = {
"pdos_entries_infos": [],
"pdos_infos": [],
- "pdos_sync_infos": [],
+ "pdos_sync_infos": [],
}
pdos_infos.update(type_infos)
-
+
sync_managers = []
for sync_manager_idx, sync_manager in enumerate(device.getSm()):
sync_manager_infos = {
- "index": sync_manager_idx,
+ "index": sync_manager_idx,
"name": sync_manager.getcontent(),
"slave": slave_idx,
- "pdos": [],
+ "pdos": [],
"pdos_number": 0,
}
-
+
sync_manager_control_byte = ExtractHexDecValue(sync_manager.getControlByte())
sync_manager_direction = sync_manager_control_byte & 0x0c
sync_manager_watchdog = sync_manager_control_byte & 0x40
@@ -298,50 +298,50 @@
sync_manager_infos["watchdog"] = "EC_WD_ENABLE"
else:
sync_manager_infos["watchdog"] = "EC_WD_DISABLE"
-
+
sync_managers.append(sync_manager_infos)
-
+
pdos_index = []
exclusive_pdos = {}
selected_pdos = []
for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
[(pdo, "Outputs") for pdo in device.getRxPdo()]):
-
+
pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
pdos_index.append(pdo_index)
-
+
excluded_list = pdo.getExclude()
if len(excluded_list) > 0:
exclusion_list = [pdo_index]
for excluded in excluded_list:
exclusion_list.append(ExtractHexDecValue(excluded.getcontent()))
exclusion_list.sort()
-
+
exclusion_scope = exclusive_pdos.setdefault(tuple(exclusion_list), [])
-
+
entries = pdo.getEntry()
pdo_mapping_match = {
- "index": pdo_index,
- "matching": 0,
- "count": len(entries),
+ "index": pdo_index,
+ "matching": 0,
+ "count": len(entries),
"assigned": pdo.getSm() is not None
}
exclusion_scope.append(pdo_mapping_match)
-
+
for entry in entries:
index = ExtractHexDecValue(entry.getIndex().getcontent())
subindex = ExtractHexDecValue(entry.getSubIndex())
if slave_variables.get((index, subindex), None) is not None:
pdo_mapping_match["matching"] += 1
-
+
if pdo.getFixed() != True:
pdo_mapping_match["matching"] += \
module_extra_params["max_pdo_size"] - \
pdo_mapping_match["count"]
-
+
elif pdo.getMandatory():
selected_pdos.append(pdo_index)
-
+
excluded_pdos = []
for exclusion_scope in exclusive_pdos.itervalues():
exclusion_scope.sort(ExclusionSortFunction)
@@ -349,22 +349,22 @@
if exclusion_scope[0]["matching"] > 0:
selected_pdos.append(exclusion_scope[0]["index"])
start_excluding_index = 1
- excluded_pdos.extend([pdo["index"]
- for pdo in exclusion_scope[start_excluding_index:]
+ excluded_pdos.extend([pdo["index"]
+ for pdo in exclusion_scope[start_excluding_index:]
if PdoAssign or not pdo["assigned"]])
-
+
for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
[(pdo, "Outputs") for pdo in device.getRxPdo()]):
entries = pdo.getEntry()
-
+
pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
if pdo_index in excluded_pdos:
continue
-
+
pdo_needed = pdo_index in selected_pdos
-
+
entries_infos = []
-
+
for entry in entries:
index = ExtractHexDecValue(entry.getIndex().getcontent())
subindex = ExtractHexDecValue(entry.getSubIndex())
@@ -376,30 +376,30 @@
}
entry_infos.update(type_infos)
entries_infos.append(" {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
-
+
entry_declaration = slave_variables.get((index, subindex), None)
if entry_declaration is not None and not entry_declaration["mapped"]:
pdo_needed = True
-
- entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"],
+
+ entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"],
entry_declaration["infos"])))
entry_declaration["mapped"] = True
-
+
entry_type = entry.getDataType().getcontent()
if entry_infos["var_type"] != entry_type:
message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
- if (self.Controler.GetSizeOfType(entry_infos["var_type"]) !=
+ if (self.Controler.GetSizeOfType(entry_infos["var_type"]) !=
self.Controler.GetSizeOfType(entry_type)):
raise ValueError, message
else:
self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
-
- if (entry_infos["dir"] == "I" and pdo_type != "Inputs" or
+
+ if (entry_infos["dir"] == "I" and pdo_type != "Inputs" or
entry_infos["dir"] == "Q" and pdo_type != "Outputs"):
raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
-
+
ConfigureVariable(entry_infos, str_completion)
-
+
elif pdo_type == "Outputs" and entry.getDataType() is not None and device_coe is not None:
data_type = entry.getDataType().getcontent()
entry_infos["dir"] = "Q"
@@ -407,18 +407,18 @@
entry_infos["data_type"] = DATATYPECONVERSION.get(data_type)
entry_infos["var_type"] = data_type
entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos
-
+
ConfigureVariable(entry_infos, str_completion)
-
+
str_completion["slaves_output_pdos_default_values_extraction"] += \
SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos
-
+
if pdo_needed:
for excluded in pdo.getExclude():
excluded_index = ExtractHexDecValue(excluded.getcontent())
if excluded_index not in excluded_pdos:
excluded_pdos.append(excluded_index)
-
+
sm = pdo.getSm()
if sm is None:
for sm_idx, sync_manager in enumerate(sync_managers):
@@ -426,40 +426,40 @@
sm = sm_idx
if sm is None:
raise ValueError, _("No sync manager available for %s pdo!") % pdo_type
-
+
sync_managers[sm]["pdos_number"] += 1
sync_managers[sm]["pdos"].append(
{"slave": slave_idx,
"index": pdo_index,
"name": ExtractName(pdo.getName()),
- "type": pdo_type,
+ "type": pdo_type,
"entries": entries_infos,
"entries_number": len(entries_infos),
"fixed": pdo.getFixed() == True})
-
+
if PdoConfig and PdoAssign:
dynamic_pdos = {}
dynamic_pdos_number = 0
- for category, min_index, max_index in [("Inputs", 0x1600, 0x1800),
+ for category, min_index, max_index in [("Inputs", 0x1600, 0x1800),
("Outputs", 0x1a00, 0x1C00)]:
for sync_manager in sync_managers:
if sync_manager["name"] == category:
category_infos = dynamic_pdos.setdefault(category, {})
category_infos["sync_manager"] = sync_manager
- category_infos["pdos"] = [pdo for pdo in category_infos["sync_manager"]["pdos"]
+ category_infos["pdos"] = [pdo for pdo in category_infos["sync_manager"]["pdos"]
if not pdo["fixed"] and pdo["type"] == category]
category_infos["current_index"] = min_index
category_infos["max_index"] = max_index
break
-
+
for (index, subindex), entry_declaration in slave_variables.iteritems():
-
+
if not entry_declaration["mapped"]:
entry = device_entries.get((index, subindex), None)
if entry is None:
raise ValueError, _("Unknown entry index 0x%4.4x, subindex 0x%2.2x for device %s") % \
(index, subindex, type_infos["device_type"])
-
+
entry_infos = {
"index": index,
"subindex": subindex,
@@ -467,31 +467,31 @@
"bitlen": entry["BitSize"],
}
entry_infos.update(type_infos)
-
- entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"],
+
+ entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"],
entry_declaration["infos"])))
entry_declaration["mapped"] = True
-
+
if entry_infos["var_type"] != entry["Type"]:
message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
- if (self.Controler.GetSizeOfType(entry_infos["var_type"]) !=
+ if (self.Controler.GetSizeOfType(entry_infos["var_type"]) !=
self.Controler.GetSizeOfType(entry["Type"])):
raise ValueError, message
else:
self.Controler.GetCTRoot().logger.write_warning(message + "\n")
-
+
if entry_infos["dir"] == "I" and entry["PDOMapping"] in ["T", "RT"]:
pdo_type = "Inputs"
elif entry_infos["dir"] == "Q" and entry["PDOMapping"] in ["R", "RT"]:
pdo_type = "Outputs"
else:
raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
-
+
if not dynamic_pdos.has_key(pdo_type):
raise ValueError, _("No Sync manager defined for %s!") % pdo_type
-
+
ConfigureVariable(entry_infos, str_completion)
-
+
if len(dynamic_pdos[pdo_type]["pdos"]) > 0:
pdo = dynamic_pdos[pdo_type]["pdos"][0]
elif module_extra_params["add_pdo"]:
@@ -500,12 +500,12 @@
if dynamic_pdos[pdo_type]["current_index"] >= dynamic_pdos[pdo_type]["max_index"]:
raise ValueError, _("No more free PDO index available for %s!") % pdo_type
pdos_index.append(dynamic_pdos[pdo_type]["current_index"])
-
+
dynamic_pdos_number += 1
pdo = {"slave": slave_idx,
"index": dynamic_pdos[pdo_type]["current_index"],
"name": "Dynamic PDO %d" % dynamic_pdos_number,
- "type": pdo_type,
+ "type": pdo_type,
"entries": [],
"entries_number": 0,
"fixed": False}
@@ -514,55 +514,55 @@
dynamic_pdos[pdo_type]["pdos"].append(pdo)
else:
break
-
+
pdo["entries"].append(" {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
if entry_infos["bitlen"] < module_extra_params["pdo_alignment"]:
pdo["entries"].append(" {0x0000, 0x00, %d}, /* None */" % (
module_extra_params["pdo_alignment"] - entry_infos["bitlen"]))
pdo["entries_number"] += 1
-
+
if pdo["entries_number"] == module_extra_params["max_pdo_size"]:
dynamic_pdos[pdo_type]["pdos"].pop(0)
-
+
pdo_offset = 0
entry_offset = 0
for sync_manager_infos in sync_managers:
-
+
for pdo_infos in sync_manager_infos["pdos"]:
pdo_infos["offset"] = entry_offset
pdo_entries = pdo_infos["entries"]
pdos_infos["pdos_infos"].append(
- (" {0x%(index).4x, %(entries_number)d, " +
+ (" {0x%(index).4x, %(entries_number)d, " +
"slave_%(slave)d_pdo_entries + %(offset)d}, /* %(name)s */") % pdo_infos)
entry_offset += len(pdo_entries)
pdos_infos["pdos_entries_infos"].extend(pdo_entries)
-
+
sync_manager_infos["offset"] = pdo_offset
pdo_offset_shift = sync_manager_infos["pdos_number"]
pdos_infos["pdos_sync_infos"].append(
- (" {%(index)d, %(sync_manager_type)s, %(pdos_number)d, " +
+ (" {%(index)d, %(sync_manager_type)s, %(pdos_number)d, " +
("slave_%(slave)d_pdos + %(offset)d" if pdo_offset_shift else "NULL") +
", %(watchdog)s},") % sync_manager_infos)
- pdo_offset += pdo_offset_shift
-
+ pdo_offset += pdo_offset_shift
+
for element in ["pdos_entries_infos", "pdos_infos", "pdos_sync_infos"]:
pdos_infos[element] = "\n".join(pdos_infos[element])
-
+
str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos
-
+
for (index, subindex), entry_declaration in slave_variables.iteritems():
if not entry_declaration["mapped"]:
message = _("Entry index 0x%4.4x, subindex 0x%2.2x not mapped for device %s") % \
(index, subindex, type_infos["device_type"])
self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
-
- for element in ["used_pdo_entry_offset_variables_declaration",
- "used_pdo_entry_configuration",
- "located_variables_declaration",
- "retrieve_variables",
+
+ for element in ["used_pdo_entry_offset_variables_declaration",
+ "used_pdo_entry_configuration",
+ "located_variables_declaration",
+ "retrieve_variables",
"publish_variables"]:
str_completion[element] = "\n".join(str_completion[element])
-
+
etherlabfile = open(filepath, 'w')
etherlabfile.write(plc_etherlab_code % str_completion)
etherlabfile.close()
--- a/etherlab/EthercatCIA402Slave.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/EthercatCIA402Slave.py Fri Sep 28 17:20:11 2018 +0300
@@ -20,7 +20,7 @@
from ConfigEditor import CIA402NodeEditor
# Definition of node variables that have to be mapped in PDO
-# [(name, index, subindex, type,
+# [(name, index, subindex, type,
# direction for master ('I': input, 'Q': output)),...]
NODE_VARIABLES = [
("ControlWord", 0x6040, 0x00, "UINT", "Q"),
@@ -38,12 +38,12 @@
# Definition of optional node variables that can be added to PDO mapping.
# A checkbox will be displayed for each section in node configuration panel to
# enable them
-# [(section_name,
-# [{'description', (name, index, subindex, type,
+# [(section_name,
+# [{'description', (name, index, subindex, type,
# direction for master ('I': input, 'Q': output)),
-# 'retrieve', string_template_for_retrieve_variable (None: not retrieved,
+# 'retrieve', string_template_for_retrieve_variable (None: not retrieved,
# default string template if not defined),
-# 'publish', string_template_for_publish_variable (None: not published,
+# 'publish', string_template_for_publish_variable (None: not published,
# default string template if not defined),
# },...]
EXTRA_NODE_VARIABLES = [
@@ -74,16 +74,16 @@
# List of parameters name in no configuration panel for optional variable
# sections
EXTRA_NODE_VARIABLES_DICT = {
- "Enable" + name: params
+ "Enable" + name: params
for name, params in EXTRA_NODE_VARIABLES}
# List of block to define to interface MCL to fieldbus for specific functions
FIELDBUS_INTERFACE_GLOBAL_INSTANCES = [
- {"blocktype": "GetTorqueLimit",
+ {"blocktype": "GetTorqueLimit",
"inputs": [],
"outputs": [{"name": "TorqueLimitPos", "type": "UINT"},
{"name": "TorqueLimitNeg", "type": "UINT"}]},
- {"blocktype": "SetTorqueLimit",
+ {"blocktype": "SetTorqueLimit",
"inputs": [{"name": "TorqueLimitPos", "type": "UINT"},
{"name": "TorqueLimitNeg", "type": "UINT"}],
"outputs": []},
@@ -104,12 +104,12 @@
</xsd:schema>
""" % ("\n".join(["""\
<xsd:attribute name="Enable%s" type="xsd:boolean"
- use="optional" default="false"/>""" % category
+ use="optional" default="false"/>""" % category
for category, variables in EXTRA_NODE_VARIABLES]) + AxisXSD)
-
+
NODE_PROFILE = 402
EditorType = CIA402NodeEditor
-
+
ConfNodeMethods = [
{"bitmap" : "CIA402AxisRef",
"name" : _("Axis Ref"),
@@ -122,25 +122,25 @@
"method" : "_getCIA402NetworkPosition",
"push": True},
]
-
+
#--------------------------------------------------
# class code
-#--------------------------------------------------
-
+#--------------------------------------------------
+
def __init__(self):
# ----------- call ethercat mng. function --------------
self.CommonMethod = _CommonSlave(self)
-
+
def GetIconName(self):
return "CIA402Slave"
-
+
def SetParamsAttribute(self, path, value):
if path == "CIA402SlaveParams.Type":
path = "SlaveParams.Type"
elif path == "CIA402SlaveParams.Alias":
path = "SlaveParams.Alias"
return _EthercatSlaveCTN.SetParamsAttribute(self, path, value)
-
+
def GetVariableLocationTree(self):
axis_name = self.CTNName()
current_location = self.GetCurrentLocation()
@@ -163,44 +163,44 @@
"location": self.GetFullIEC_Channel(),
"children": children,
}
-
+
def CTNGlobalInstances(self):
current_location = self.GetCurrentLocation()
- return [("%s_%s" % (block_infos["blocktype"],
+ return [("%s_%s" % (block_infos["blocktype"],
"_".join(map(str, current_location))),
- "EtherLab%s" % block_infos["blocktype"], "")
+ "EtherLab%s" % block_infos["blocktype"], "")
for block_infos in FIELDBUS_INTERFACE_GLOBAL_INSTANCES]
-
+
def StartDragNDrop(self, data):
data_obj = wx.TextDataObject(str(data))
dragSource = wx.DropSource(self.GetCTRoot().AppFrame)
dragSource.SetData(data_obj)
dragSource.DoDragDrop()
-
+
def _getCIA402NetworkPosition(self):
self.StartDragNDrop(
- ("%%IW%s" % ".".join(map(str, self.GetCurrentLocation())),
+ ("%%IW%s" % ".".join(map(str, self.GetCurrentLocation())),
"location", "UINT", self.CTNName() + "_Pos", ""))
-
+
def _getCIA402AxisRef(self):
self.StartDragNDrop(
- ("%%IW%s.402" % ".".join(map(str, self.GetCurrentLocation())),
+ ("%%IW%s.402" % ".".join(map(str, self.GetCurrentLocation())),
"location", "AXIS_REF", self.CTNName(), ""))
-
+
def CTNGenerate_C(self, buildpath, locations):
current_location = self.GetCurrentLocation()
-
+
location_str = "_".join(map(lambda x:str(x), current_location))
slave_pos = self.GetSlavePos()
MCL_headers = Headers
-
- # Open CIA402 node code template file
- plc_cia402node_filepath = os.path.join(os.path.split(__file__)[0],
+
+ # Open CIA402 node code template file
+ plc_cia402node_filepath = os.path.join(os.path.split(__file__)[0],
"plc_cia402node.c")
plc_cia402node_file = open(plc_cia402node_filepath, 'r')
plc_cia402node_code = plc_cia402node_file.read()
plc_cia402node_file.close()
-
+
# Init list of generated strings for each code template file section
fieldbus_interface_declaration = []
fieldbus_interface_definition = []
@@ -210,31 +210,31 @@
extern_located_variables_declaration = []
entry_variables = []
init_entry_variables = []
-
+
# Fieldbus interface code sections
for blocktype_infos in FIELDBUS_INTERFACE_GLOBAL_INSTANCES:
blocktype = blocktype_infos["blocktype"]
ucase_blocktype = blocktype.upper()
blockname = "_".join([ucase_blocktype, location_str])
-
+
extract_inputs = "\n".join(["""\
__SET_VAR(%s->, %s,, %s);""" % (blockname, input_name, input_value)
for (input_name, input_value) in [
("EXECUTE", "__GET_VAR(data__->EXECUTE)")] + [
- (input["name"].upper(),
+ (input["name"].upper(),
"__GET_VAR(data__->%s)" % input["name"].upper())
for input in blocktype_infos["inputs"]]
])
-
-
+
+
return_outputs = "\n".join(["""\
- __SET_VAR(data__->,%(output_name)s,,
+ __SET_VAR(data__->,%(output_name)s,,
__GET_VAR(%(blockname)s->%(output_name)s));""" % locals()
for output_name in ["DONE", "BUSY", "ERROR"] + [
output["name"].upper()
for output in blocktype_infos["outputs"]]
])
-
+
fieldbus_interface_declaration.append("""
extern void ETHERLAB%(ucase_blocktype)s_body__(ETHERLAB%(ucase_blocktype)s* data__);
void __%(blocktype)s_%(location_str)s(MC_%(ucase_blocktype)s *data__) {
@@ -245,88 +245,88 @@
ETHERLAB%(ucase_blocktype)s_body__(%(blockname)s);
%(return_outputs)s
}""" % locals())
-
+
fieldbus_interface_definition.append("""\
AxsPub.axis->__mcl_func_MC_%(blocktype)s = __%(blocktype)s_%(location_str)s;\
""" % locals())
-
+
# Get a copy list of default variables to map
variables = NODE_VARIABLES[:]
-
+
# Set AxisRef public struct members value
node_params = self.CTNParams[1].getElementInfos(self.CTNParams[0])
for param in node_params["children"]:
param_name = param["name"]
-
+
# Param is optional variables section enable flag
extra_node_variable_infos = EXTRA_NODE_VARIABLES_DICT.get(param_name)
if extra_node_variable_infos is not None:
param_name = param_name.replace("Enable", "") + "Enabled"
-
+
if not param["value"]:
continue
-
+
# Optional variables section is enabled
for variable_infos in extra_node_variable_infos:
var_name = variable_infos["description"][0]
-
+
# Add each variables defined in section description to the
# list of variables to map
variables.append(variable_infos["description"])
-
+
# Add code to publish or retrive variable
for var_exchange_dir, str_list, default_template in [
("retrieve", extra_variables_retrieve,
" AxsPub.axis->%(var_name)s = *(AxsPub.%(var_name)s);"),
("publish", extra_variables_publish,
" *(AxsPub.%(var_name)s) = AxsPub.axis->%(var_name)s;")]:
-
- template = variable_infos.get(var_exchange_dir,
+
+ template = variable_infos.get(var_exchange_dir,
default_template)
if template is not None:
extra_variables_publish.append(template % locals())
-
+
# Set AxisRef public struct member value if defined
if param["value"] is not None:
param_value = ({True: "1", False: "0"}[param["value"]]
if param["type"] == "boolean"
else str(param["value"]))
-
+
init_axis_params.append("""\
AxsPub.axis->%(param_name)s = %(param_value)s;""" % locals())
-
+
# Add each variable in list of variables to map to master list of
# variables to add to network configuration
for name, index, subindex, var_type, dir in variables:
var_size = self.GetSizeOfType(var_type)
var_name = """\
__%(dir)s%(var_size)s%(location_str)s_%(index)d_%(subindex)d""" % locals()
-
+
extern_located_variables_declaration.append(
"IEC_%(var_type)s *%(var_name)s;" % locals())
entry_variables.append(
" IEC_%(var_type)s *%(name)s;" % locals())
init_entry_variables.append(
" AxsPub.%(name)s = %(var_name)s;" % locals())
-
+
self.CTNParent.FileGenerator.DeclareVariable(
slave_pos, index, subindex, var_type, dir, var_name)
-
+
# Add newline between string in list of generated strings for sections
[fieldbus_interface_declaration, fieldbus_interface_definition,
init_axis_params, extra_variables_retrieve, extra_variables_publish,
- extern_located_variables_declaration, entry_variables,
+ extern_located_variables_declaration, entry_variables,
init_entry_variables] = map(lambda l: "\n".join(l), [
fieldbus_interface_declaration, fieldbus_interface_definition,
init_axis_params, extra_variables_retrieve, extra_variables_publish,
- extern_located_variables_declaration, entry_variables,
+ extern_located_variables_declaration, entry_variables,
init_entry_variables])
-
+
# Write generated content to CIA402 node file
- Gen_CIA402Nodefile_path = os.path.join(buildpath,
+ Gen_CIA402Nodefile_path = os.path.join(buildpath,
"cia402node_%s.c"%location_str)
cia402nodefile = open(Gen_CIA402Nodefile_path, 'w')
cia402nodefile.write(plc_cia402node_code % locals())
cia402nodefile.close()
-
+
return [(Gen_CIA402Nodefile_path, '"-I%s"'%os.path.abspath(self.GetCTRoot().GetIECLibPath()))],"",True
--- a/etherlab/EthercatMaster.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/EthercatMaster.py Fri Sep 28 17:20:11 2018 +0300
@@ -79,21 +79,21 @@
etherlab_ext_file = open(GetLocalPath("etherlab_ext.c"), 'r')
etherlab_ext_code = etherlab_ext_file.read()
etherlab_ext_file.close()
-
+
Gen_etherlabfile_path = os.path.join(buildpath, "etherlab_ext.c")
ethelabfile = open(Gen_etherlabfile_path,'w')
ethelabfile.write(etherlab_ext_code)
ethelabfile.close()
-
+
runtimefile_path = os.path.join(os.path.split(__file__)[0], "runtime_etherlab.py")
- return ((["etherlab_ext"], [(Gen_etherlabfile_path, IECCFLAGS)], True), "",
+ return ((["etherlab_ext"], [(Gen_etherlabfile_path, IECCFLAGS)], True), "",
("runtime_etherlab.py", file(GetLocalPath("runtime_etherlab.py"))))
-
+
#--------------------------------------------------
# Ethercat MASTER
#--------------------------------------------------
-EtherCATConfigParser = GenerateParserFromXSD(os.path.join(os.path.dirname(__file__), "EtherCATConfig.xsd"))
+EtherCATConfigParser = GenerateParserFromXSD(os.path.join(os.path.dirname(__file__), "EtherCATConfig.xsd"))
def sort_commands(x, y):
if x["Index"] == y["Index"]:
@@ -102,7 +102,7 @@
cls = EtherCATConfigParser.GetElementClass("Slave", "Config")
if cls:
-
+
def getType(self):
slave_info = self.getInfo()
return {"device_type": slave_info.getName(),
@@ -118,7 +118,7 @@
slave_info.setProductCode(ExtractHexDecValue(type_infos["product_code"]))
slave_info.setRevisionNo(ExtractHexDecValue(type_infos["revision_number"]))
setattr(cls, "setType", setType)
-
+
def getInitCmds(self, create_default=False):
Mailbox = self.getMailbox()
if Mailbox is None:
@@ -140,7 +140,7 @@
InitCmds = CoE.getInitCmds()
return InitCmds
setattr(cls, "getInitCmds", getInitCmds)
-
+
def getStartupCommands(self):
pos = self.getInfo().getPhysAddr()
InitCmds = self.getInitCmds()
@@ -161,7 +161,7 @@
commands.sort(sort_commands)
return commands
setattr(cls, "getStartupCommands", getStartupCommands)
-
+
def appendStartupCommand(self, command_infos):
InitCmds = self.getInitCmds(True)
command = EtherCATConfigParser.CreateElement("InitCmd", "InitCmds", 1)
@@ -172,7 +172,7 @@
command.setComment(command_infos["Description"])
return len(InitCmds.getInitCmd()) - 1
setattr(cls, "appendStartupCommand", appendStartupCommand)
-
+
def setStartupCommand(self, command_infos):
InitCmds = self.getInitCmds()
if InitCmds is not None:
@@ -184,7 +184,7 @@
command.setData(command_infos["Value"])
command.setComment(command_infos["Description"])
setattr(cls, "setStartupCommand", setStartupCommand)
-
+
def removeStartupCommand(self, command_idx):
InitCmds = self.getInitCmds()
if InitCmds is not None:
@@ -218,7 +218,7 @@
</xsd:schema>
"""
-ProcessVariablesParser = GenerateParserFromXSDstring(ProcessVariablesXSD)
+ProcessVariablesParser = GenerateParserFromXSDstring(ProcessVariablesXSD)
class _EthercatCTN:
@@ -226,7 +226,7 @@
if HAS_MCL:
CTNChildrenTypes.append(("EthercatCIA402Slave", _EthercatCIA402SlaveCTN, "Ethercat CIA402 Slave"))
EditorType = MasterEditor
-
+
def __init__(self):
config_filepath = self.ConfigFileName()
config_is_saved = False
@@ -241,14 +241,14 @@
except Exception, e:
error = e.message
config_xmlfile.close()
-
+
if error is not None:
self.GetCTRoot().logger.write_error(
- _("Couldn't load %s network configuration file.") % CTNName)
-
+ _("Couldn't load %s network configuration file.") % CTNName)
+
if self.Config is None:
self.Config = EtherCATConfigParser.CreateElement("EtherCATConfig")
-
+
process_filepath = self.ProcessVariablesFileName()
process_is_saved = False
self.ProcessVariables = None
@@ -262,32 +262,32 @@
except Exception, e:
error = e.message
process_xmlfile.close()
-
+
if error is not None:
self.GetCTRoot().logger.write_error(
- _("Couldn't load %s network process variables file.") % CTNName)
-
+ _("Couldn't load %s network process variables file.") % CTNName)
+
if self.ProcessVariables is None:
self.ProcessVariables = ProcessVariablesParser.CreateElement("ProcessVariables")
-
+
if config_is_saved and process_is_saved:
self.CreateBuffer(True)
else:
self.CreateBuffer(False)
self.OnCTNSave()
-
+
# ----------- call ethercat mng. function --------------
self.CommonMethod = _CommonSlave(self)
-
+
def GetIconName(self):
return "Ethercat"
-
+
def GetContextualMenuItems(self):
return [("Add Ethercat Slave", "Add Ethercat Slave to Master", self.OnAddEthercatSlave)]
-
+
def OnAddEthercatSlave(self, event):
app_frame = self.GetCTRoot().AppFrame
- dialog = BrowseValuesLibraryDialog(app_frame,
+ dialog = BrowseValuesLibraryDialog(app_frame,
"Ethercat Slave Type", self.GetSlaveTypesLibrary())
if dialog.ShowModal() == wx.ID_OK:
type_infos = dialog.GetValueInfos()
@@ -303,7 +303,7 @@
new_child._OpenView()
app_frame._Refresh(TITLE, FILEMENU, PROJECTTREE)
dialog.Destroy()
-
+
def ExtractHexDecValue(self, value):
return ExtractHexDecValue(value)
@@ -312,10 +312,10 @@
def ConfigFileName(self):
return os.path.join(self.CTNPath(), "config.xml")
-
+
def ProcessVariablesFileName(self):
return os.path.join(self.CTNPath(), "process_variables.xml")
-
+
def FilterSlave(self, slave, vendor=None, slave_pos=None, slave_profile=None):
if slave_pos is not None and slave.getInfo().getPhysAddr() != slave_pos:
return False
@@ -355,7 +355,7 @@
commands.append((slave.getInfo().getPhysAddr(), slave.getStartupCommands()))
commands.sort()
return reduce(lambda x, y: x + y[1], commands, [])
-
+
def AppendStartupCommand(self, command_infos):
slave = self.GetSlave(command_infos["Position"])
if slave is not None:
@@ -363,20 +363,20 @@
self.BufferModel()
return command_idx
return None
-
+
def SetStartupCommandInfos(self, command_infos):
slave = self.GetSlave(command_infos["Position"])
if slave is not None:
slave.setStartupCommand(command_infos)
self.BufferModel()
-
+
def RemoveStartupCommand(self, slave_pos, command_idx, buffer=True):
slave = self.GetSlave(slave_pos)
if slave is not None:
slave.removeStartupCommand(command_idx)
if buffer:
self.BufferModel()
-
+
def SetProcessVariables(self, variables):
vars = []
for var in variables:
@@ -406,7 +406,7 @@
vars.append(variable)
self.ProcessVariables.setvariable(vars)
self.BufferModel()
-
+
def GetProcessVariables(self):
variables = []
idx = 0
@@ -431,19 +431,19 @@
variables.append(var)
idx += 1
return variables
-
+
def _ScanNetwork(self):
app_frame = self.GetCTRoot().AppFrame
-
+
execute = True
if len(self.Children) > 0:
- dialog = wx.MessageDialog(app_frame,
- _("The current network configuration will be deleted.\nDo you want to continue?"),
- _("Scan Network"),
+ dialog = wx.MessageDialog(app_frame,
+ _("The current network configuration will be deleted.\nDo you want to continue?"),
+ _("Scan Network"),
wx.YES_NO|wx.ICON_QUESTION)
execute = dialog.ShowModal() == wx.ID_YES
dialog.Destroy()
-
+
if execute:
error, returnVal = self.RemoteExec(SCAN_COMMAND, returnVal = None)
if error != 0:
@@ -453,7 +453,7 @@
elif returnVal is not None:
for child in self.IECSortedChildren():
self._doRemoveChild(child)
-
+
for slave in returnVal:
type_infos = {
"vendor": slave["vendor_id"],
@@ -470,10 +470,10 @@
self.SetSlaveAlias(slave["idx"], slave["alias"])
type_infos["device_type"] = device.getType().getcontent()
self.SetSlaveType(slave["idx"], type_infos)
-
+
if app_frame:
app_frame.RefreshProjectTree()
-
+
def CTNAddChild(self, CTNName, CTNType, IEC_Channel=0):
"""
Create the confnodes that may be added as child to this node self
@@ -481,7 +481,7 @@
@param CTNName: string for the name of the confnode instance
"""
newConfNodeOpj = ConfigTreeNode.CTNAddChild(self, CTNName, CTNType, IEC_Channel)
-
+
slave = self.GetSlave(newConfNodeOpj.BaseParams.getIEC_Channel())
if slave is None:
slave = EtherCATConfigParser.CreateElement("Slave", "Config")
@@ -492,7 +492,7 @@
slave_infos.setAutoIncAddr(0)
self.BufferModel()
self.OnCTNSave()
-
+
return newConfNodeOpj
def _doRemoveChild(self, CTNInstance):
@@ -523,33 +523,33 @@
if self._View is not None:
self._View.RefreshView()
self._View.RefreshBuffer()
-
+
def GetSlaveAlias(self, slave_pos):
slave = self.GetSlave(slave_pos)
if slave is not None:
slave_info = slave.getInfo()
return slave_info.getAutoIncAddr()
return None
-
+
def SetSlaveAlias(self, slave_pos, alias):
slave = self.GetSlave(slave_pos)
if slave is not None:
slave_info = slave.getInfo()
slave_info.setAutoIncAddr(alias)
self.BufferModel()
-
+
def GetSlaveType(self, slave_pos):
slave = self.GetSlave(slave_pos)
if slave is not None:
return slave.getType()
return None
-
+
def SetSlaveType(self, slave_pos, type_infos):
slave = self.GetSlave(slave_pos)
if slave is not None:
slave.setType(type_infos)
self.BufferModel()
-
+
def GetSlaveInfos(self, slave_pos):
slave = self.GetSlave(slave_pos)
if slave is not None:
@@ -562,7 +562,7 @@
"entries": self.GetSlaveVariables(device)})
return infos
return None
-
+
def GetSlaveVariables(self, slave_pos=None, limits=None, device=None):
if device is None and slave_pos is not None:
slave = self.GetSlave(slave_pos)
@@ -592,7 +592,7 @@
entries.append(entry)
return entries
return []
-
+
def GetSlaveVariableDataType(self, slave_pos, index, subindex):
slave = self.GetSlave(slave_pos)
if slave is not None:
@@ -603,7 +603,7 @@
if entry_infos is not None:
return entry_infos["Type"]
return None
-
+
def GetNodesVariables(self, vendor=None, slave_pos=None, slave_profile=None, limits=None):
entries = []
for slave_position in self.GetSlaves():
@@ -618,22 +618,22 @@
continue
entries.extend(self.GetSlaveVariables(slave_position, limits, device))
return entries
-
+
def GetModuleInfos(self, type_infos):
return self.CTNParent.GetModuleInfos(type_infos)
-
+
def GetSlaveTypesLibrary(self, profile_filter=None):
return self.CTNParent.GetModulesLibrary(profile_filter)
-
+
def GetLibraryVendors(self):
return self.CTNParent.GetVendors()
-
+
def GetDeviceLocationTree(self, slave_pos, current_location, device_name):
slave = self.GetSlave(slave_pos)
- vars = []
+ vars = []
if slave is not None:
type_infos = slave.getType()
-
+
device, module_extra_params = self.GetModuleInfos(type_infos)
if device is not None:
sync_managers = []
@@ -644,7 +644,7 @@
sync_managers.append(LOCATION_VAR_OUTPUT)
else:
sync_managers.append(LOCATION_VAR_INPUT)
-
+
entries = device.GetEntriesList().items()
entries.sort()
for (index, subindex), entry in entries:
@@ -655,44 +655,44 @@
if var_class == LOCATION_VAR_INPUT:
var_dir = "%I"
else:
- var_dir = "%Q"
-
+ var_dir = "%Q"
+
vars.append({"name": "0x%4.4x-0x%2.2x: %s" % (index, subindex, entry["Name"]),
"type": var_class,
"size": var_size,
"IEC_type": entry["Type"],
"var_name": "%s_%4.4x_%2.2x" % ("_".join(device_name.split()), index, subindex),
- "location": "%s%s%s"%(var_dir, var_size, ".".join(map(str, current_location +
+ "location": "%s%s%s"%(var_dir, var_size, ".".join(map(str, current_location +
(index, subindex)))),
"description": "",
"children": []})
-
+
return vars
-
+
def CTNTestModified(self):
- return self.ChangesToSave or not self.ModelIsSaved()
+ return self.ChangesToSave or not self.ModelIsSaved()
def OnCTNSave(self, from_project_path=None):
config_filepath = self.ConfigFileName()
-
+
config_xmlfile = open(config_filepath,"w")
config_xmlfile.write(etree.tostring(
- self.Config,
- pretty_print=True,
- xml_declaration=True,
+ self.Config,
+ pretty_print=True,
+ xml_declaration=True,
encoding='utf-8'))
config_xmlfile.close()
-
+
process_filepath = self.ProcessVariablesFileName()
-
+
process_xmlfile = open(process_filepath,"w")
process_xmlfile.write(etree.tostring(
- self.ProcessVariables,
- pretty_print=True,
- xml_declaration=True,
+ self.ProcessVariables,
+ pretty_print=True,
+ xml_declaration=True,
encoding='utf-8'))
process_xmlfile.close()
-
+
self.Buffer.CurrentSaved()
return True
@@ -703,13 +703,13 @@
current_location = self.GetCurrentLocation()
# define a unique name for the generated C file
location_str = "_".join(map(lambda x:str(x), current_location))
-
+
Gen_Ethercatfile_path = os.path.join(buildpath, "ethercat_%s.c"%location_str)
-
+
self.FileGenerator = _EthercatCFileGenerator(self)
-
+
LocationCFilesAndCFLAGS, LDFLAGS, extra_files = ConfigTreeNode._Generate_C(self, buildpath, locations)
-
+
for idx, variable in enumerate(self.ProcessVariables.getvariable()):
name = None
var_type = None
@@ -734,42 +734,42 @@
name = self.GetProcessVariableName(location, var_type)
self.FileGenerator.DeclareVariable(
pos, index, subindex, var_type, "Q", name, True)
-
+
self.FileGenerator.GenerateCFile(Gen_Ethercatfile_path, location_str, self.BaseParams.getIEC_Channel())
-
- LocationCFilesAndCFLAGS.insert(0,
- (current_location,
- [(Gen_Ethercatfile_path, '"-I%s"'%os.path.abspath(self.GetCTRoot().GetIECLibPath()))],
+
+ LocationCFilesAndCFLAGS.insert(0,
+ (current_location,
+ [(Gen_Ethercatfile_path, '"-I%s"'%os.path.abspath(self.GetCTRoot().GetIECLibPath()))],
True))
LDFLAGS.append("-lethercat_rtdm -lrtdm")
-
+
return LocationCFilesAndCFLAGS, LDFLAGS, extra_files
ConfNodeMethods = [
{"bitmap" : "ScanNetwork",
- "name" : _("Scan Network"),
+ "name" : _("Scan Network"),
"tooltip" : _("Scan Network"),
"method" : "_ScanNetwork"},
]
def CTNGenerate_C(self, buildpath, locations):
current_location = self.GetCurrentLocation()
-
+
slaves = self.GetSlaves()
for slave_pos in slaves:
slave = self.GetSlave(slave_pos)
if slave is not None:
self.FileGenerator.DeclareSlave(slave_pos, slave)
-
+
for location in locations:
loc = location["LOC"][len(current_location):]
slave_pos = loc[0]
if slave_pos in slaves and len(loc) == 3 and location["DIR"] != "M":
self.FileGenerator.DeclareVariable(
slave_pos, loc[1], loc[2], location["IEC_TYPE"], location["DIR"], location["NAME"])
-
+
return [],"",False
-
+
#-------------------------------------------------------------------------------
# Current Buffering Management Functions
#-------------------------------------------------------------------------------
@@ -779,18 +779,18 @@
"""
def Copy(self, model):
return deepcopy(model)
-
+
def CreateBuffer(self, saved):
self.Buffer = UndoBuffer(
- (EtherCATConfigParser.Dumps(self.Config),
- ProcessVariablesParser.Dumps(self.ProcessVariables)),
+ (EtherCATConfigParser.Dumps(self.Config),
+ ProcessVariablesParser.Dumps(self.ProcessVariables)),
saved)
-
+
def BufferModel(self):
self.Buffer.Buffering(
- (EtherCATConfigParser.Dumps(self.Config),
+ (EtherCATConfigParser.Dumps(self.Config),
ProcessVariablesParser.Dumps(self.ProcessVariables)))
-
+
def ModelIsSaved(self):
if self.Buffer is not None:
return self.Buffer.IsCurrentSaved()
@@ -801,14 +801,13 @@
config, process_variables = self.Buffer.Previous()
self.Config = EtherCATConfigParser.Loads(config)
self.ProcessVariables = ProcessVariablesParser.Loads(process_variables)
-
+
def LoadNext(self):
config, process_variables = self.Buffer.Next()
self.Config = EtherCATConfigParser.Loads(config)
self.ProcessVariables = ProcessVariablesParser.Loads(process_variables)
-
+
def GetBufferState(self):
first = self.Buffer.IsFirst()
last = self.Buffer.IsLast()
return not first, not last
-
--- a/etherlab/EthercatSlave.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/EthercatSlave.py Fri Sep 28 17:20:11 2018 +0300
@@ -17,16 +17,16 @@
from ConfigEditor import NodeEditor
#------------------------------------------
-from CommonEtherCATFunction import _CommonSlave
+from CommonEtherCATFunction import _CommonSlave
#------------------------------------------
TYPECONVERSION = {"BOOL" : "X", "SINT" : "B", "INT" : "W", "DINT" : "D", "LINT" : "L",
- "USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L",
+ "USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L",
"BYTE" : "B", "WORD" : "W", "DWORD" : "D", "LWORD" : "L"}
DATATYPECONVERSION = {"BOOL" : "BIT", "SINT" : "S8", "INT" : "S16", "DINT" : "S32", "LINT" : "S64",
- "USINT" : "U8", "UINT" : "U16", "UDINT" : "U32", "ULINT" : "U64",
+ "USINT" : "U8", "UINT" : "U16", "UDINT" : "U32", "ULINT" : "U64",
"BYTE" : "U8", "WORD" : "U16", "DWORD" : "U32", "LWORD" : "U64"}
VARCLASSCONVERSION = {"T": LOCATION_VAR_INPUT, "R": LOCATION_VAR_OUTPUT, "RT": LOCATION_VAR_MEMORY}
@@ -66,23 +66,23 @@
class _EthercatSlaveCTN:
NODE_PROFILE = None
EditorType = NodeEditor
-
+
def __init__(self):
# ----------- call ethercat mng. function --------------
self.CommonMethod = _CommonSlave(self)
-
+
def GetIconName(self):
return "Slave"
-
+
def ExtractHexDecValue(self, value):
return ExtractHexDecValue(value)
-
+
def GetSizeOfType(self, type):
return TYPECONVERSION.get(self.GetCTRoot().GetBaseType(type), None)
-
+
def GetSlavePos(self):
return self.BaseParams.getIEC_Channel()
-
+
def GetParamsAttributes(self, path = None):
if path:
parts = path.split(".", 1)
@@ -96,30 +96,30 @@
params.append(self.CTNParams[1].getElementInfos(self.CTNParams[0]))
else:
params.append({
- 'use': 'required',
- 'type': 'element',
- 'name': 'SlaveParams',
- 'value': None,
+ 'use': 'required',
+ 'type': 'element',
+ 'name': 'SlaveParams',
+ 'value': None,
'children': []
})
-
+
slave_type = self.CTNParent.GetSlaveType(self.GetSlavePos())
params[0]['children'].insert(0,
- {'use': 'optional',
- 'type': self.CTNParent.GetSlaveTypesLibrary(self.NODE_PROFILE),
- 'name': 'Type',
- 'value': (slave_type["device_type"], slave_type)})
+ {'use': 'optional',
+ 'type': self.CTNParent.GetSlaveTypesLibrary(self.NODE_PROFILE),
+ 'name': 'Type',
+ 'value': (slave_type["device_type"], slave_type)})
params[0]['children'].insert(1,
- {'use': 'optional',
- 'type': 'unsignedLong',
- 'name': 'Alias',
+ {'use': 'optional',
+ 'type': 'unsignedLong',
+ 'name': 'Alias',
'value': self.CTNParent.GetSlaveAlias(self.GetSlavePos())})
return params
-
+
def SetParamsAttribute(self, path, value):
self.GetSlaveInfos()
position = self.BaseParams.getIEC_Channel()
-
+
if path == "SlaveParams.Type":
self.CTNParent.SetSlaveType(position, value)
slave_type = self.CTNParent.GetSlaveType(self.GetSlavePos())
@@ -133,21 +133,21 @@
elif path == "SlaveParams.Alias":
self.CTNParent.SetSlaveAlias(position, value)
return value, True
-
+
value, refresh = ConfigTreeNode.SetParamsAttribute(self, path, value)
-
+
# Filter IEC_Channel, Slave_Type and Alias that have specific behavior
if path == "BaseParams.IEC_Channel" and value != position:
self.CTNParent.SetSlavePosition(position, value)
-
+
return value, refresh
-
+
def GetSlaveInfos(self):
return self.CTNParent.GetSlaveInfos(self.GetSlavePos())
-
+
def GetSlaveVariables(self, limits):
return self.CTNParent.GetSlaveVariables(self.GetSlavePos(), limits)
-
+
def GetVariableLocationTree(self):
return {"name": self.BaseParams.getName(),
"type": LOCATION_CONFNODE,
--- a/etherlab/etherlab.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/etherlab.py Fri Sep 28 17:20:11 2018 +0300
@@ -30,14 +30,14 @@
# Ethercat ConfNode
#--------------------------------------------------
-EtherCATInfoParser = GenerateParserFromXSD(os.path.join(os.path.dirname(__file__), "EtherCATInfo.xsd"))
+EtherCATInfoParser = GenerateParserFromXSD(os.path.join(os.path.dirname(__file__), "EtherCATInfo.xsd"))
EtherCATInfo_XPath = lambda xpath: etree.XPath(xpath)
def HexDecValue(context, *args):
return str(ExtractHexDecValue(args[0][0]))
def EntryName(context, *args):
- return ExtractName(args[0],
+ return ExtractName(args[0],
args[1][0] if len(args) > 1 else None)
ENTRY_INFOS_KEYS = [
@@ -56,14 +56,14 @@
def __init__(self, entries):
self.Entries = entries
-
+
def AddEntry(self, context, *args):
index, subindex = map(lambda x: int(x[0]), args[:2])
new_entry_infos = {
key: translate(arg[0]) if len(arg) > 0 else default
for (key, translate, default), arg
in zip(ENTRY_INFOS_KEYS, args)}
-
+
if (index, subindex) != (0, 0):
entry_infos = self.Entries.get((index, subindex))
if entry_infos is not None:
@@ -79,12 +79,12 @@
cls = EtherCATInfoParser.GetElementClass("DeviceType")
if cls:
-
+
profile_numbers_xpath = EtherCATInfo_XPath("Profile/ProfileNo")
def GetProfileNumbers(self):
return [number.text for number in profile_numbers_xpath(self)]
setattr(cls, "GetProfileNumbers", GetProfileNumbers)
-
+
def getCoE(self):
mailbox = self.getMailbox()
if mailbox is not None:
@@ -94,20 +94,20 @@
def GetEntriesList(self, limits=None):
entries = {}
-
+
factory = EntryListFactory(entries)
-
+
entries_list_xslt_tree = etree.XSLT(
entries_list_xslt, extensions = {
("entries_list_ns", "AddEntry"): factory.AddEntry,
("entries_list_ns", "HexDecValue"): HexDecValue,
("entries_list_ns", "EntryName"): EntryName})
entries_list_xslt_tree(self, **dict(zip(
- ["min_index", "max_index"],
+ ["min_index", "max_index"],
map(lambda x: etree.XSLT.strparam(str(x)),
limits if limits is not None else [0x0000, 0xFFFF])
)))
-
+
return entries
setattr(cls, "GetEntriesList", GetEntriesList)
@@ -147,7 +147,7 @@
MODULES_EXTRA_PARAMS = [
("pdo_alignment", {
- "column_label": _("PDO alignment"),
+ "column_label": _("PDO alignment"),
"column_size": 150,
"default": 8,
"description": _(
@@ -160,7 +160,7 @@
"""Maximal number of entries mapped in a PDO
including empty entries used for PDO alignment""")}),
("add_pdo", {
- "column_label": _("Creating new PDO"),
+ "column_label": _("Creating new PDO"),
"column_size": 150,
"default": 0,
"description": _(
@@ -168,36 +168,36 @@
for mapping needed location variables
(1 if possible)""")})
]
-
+
def __init__(self, path, parent_library=None):
self.Path = path
if not os.path.exists(self.Path):
os.makedirs(self.Path)
self.ParentLibrary = parent_library
-
+
if parent_library is not None:
self.LoadModules()
else:
self.Library = None
self.LoadModulesExtraParams()
-
+
def GetPath(self):
return self.Path
-
+
def GetModulesExtraParamsFilePath(self):
return os.path.join(self.Path, "modules_extra_params.cfg")
-
+
groups_xpath = EtherCATInfo_XPath("Descriptions/Groups/Group")
devices_xpath = EtherCATInfo_XPath("Descriptions/Devices/Device")
def LoadModules(self):
self.Library = {}
-
+
files = os.listdir(self.Path)
for file in files:
filepath = os.path.join(self.Path, file)
if os.path.isfile(filepath) and os.path.splitext(filepath)[-1] == ".xml":
self.modules_infos = None
-
+
xmlfile = open(filepath, 'r')
try:
self.modules_infos, error = EtherCATInfoParser.LoadXMLString(xmlfile.read())
@@ -207,37 +207,37 @@
except Exception, exc:
self.modules_infos, error = None, unicode(exc)
xmlfile.close()
-
+
if self.modules_infos is not None:
vendor = self.modules_infos.getVendor()
-
+
vendor_category = self.Library.setdefault(
- ExtractHexDecValue(vendor.getId()),
- {"name": ExtractName(vendor.getName(), _("Miscellaneous")),
+ ExtractHexDecValue(vendor.getId()),
+ {"name": ExtractName(vendor.getName(), _("Miscellaneous")),
"groups": {}})
-
+
for group in self.groups_xpath(self.modules_infos):
group_type = group.getType()
-
- vendor_category["groups"].setdefault(group_type,
- {"name": ExtractName(group.getName(), group_type),
+
+ vendor_category["groups"].setdefault(group_type,
+ {"name": ExtractName(group.getName(), group_type),
"parent": group.getParentGroup(),
- "order": group.getSortOrder(),
+ "order": group.getSortOrder(),
#"value": group.getcontent()["value"],
"devices": []})
-
+
for device in self.devices_xpath(self.modules_infos):
device_group = device.getGroupType()
if not vendor_category["groups"].has_key(device_group):
raise ValueError, "Not such group \"%\"" % device_group
vendor_category["groups"][device_group]["devices"].append(
(device.getType().getcontent(), device))
-
+
else:
-
+
self.GetCTRoot().logger.write_error(
_("Couldn't load %s XML file:\n%s") % (filepath, error))
-
+
return self.Library
def GetModulesLibrary(self, profile_filter=None):
@@ -290,7 +290,7 @@
def GetVendors(self):
return [(vendor_id, vendor["name"]) for vendor_id, vendor in self.Library.items()]
-
+
def GetModuleInfos(self, module_infos):
vendor = ExtractHexDecValue(module_infos["vendor"])
vendor_infos = self.Library.get(vendor)
@@ -301,21 +301,21 @@
revision_number = ExtractHexDecValue(device_infos.getType().getRevisionNo())
if (product_code == ExtractHexDecValue(module_infos["product_code"]) and
revision_number == ExtractHexDecValue(module_infos["revision_number"])):
- self.cntdevice = device_infos
- self.cntdeviceType = device_type
+ self.cntdevice = device_infos
+ self.cntdeviceType = device_type
return device_infos, self.GetModuleExtraParams(vendor, product_code, revision_number)
return None, None
-
+
def ImportModuleLibrary(self, filepath):
if os.path.isfile(filepath):
shutil.copy(filepath, self.Path)
self.LoadModules()
return True
return False
-
+
def LoadModulesExtraParams(self):
self.ModulesExtraParams = {}
-
+
csvfile_path = self.GetModulesExtraParamsFilePath()
if os.path.exists(csvfile_path):
csvfile = open(csvfile_path, "rb")
@@ -336,44 +336,44 @@
self.ModulesExtraParams[
tuple(map(int, row[:3]))] = params_values
csvfile.close()
-
+
def SaveModulesExtraParams(self):
csvfile = open(self.GetModulesExtraParamsFilePath(), "wb")
extra_params = [param for param, params_infos in self.MODULES_EXTRA_PARAMS]
writer = csv.writer(csvfile, delimiter=';')
writer.writerow(['Vendor', 'product_code', 'revision_number'] + extra_params)
for (vendor, product_code, revision_number), module_extra_params in self.ModulesExtraParams.iteritems():
- writer.writerow([vendor, product_code, revision_number] +
- [module_extra_params.get(param, '')
+ writer.writerow([vendor, product_code, revision_number] +
+ [module_extra_params.get(param, '')
for param in extra_params])
csvfile.close()
-
+
def SetModuleExtraParam(self, vendor, product_code, revision_number, param, value):
vendor = ExtractHexDecValue(vendor)
product_code = ExtractHexDecValue(product_code)
revision_number = ExtractHexDecValue(revision_number)
-
+
module_infos = (vendor, product_code, revision_number)
self.ModulesExtraParams.setdefault(module_infos, {})
self.ModulesExtraParams[module_infos][param] = value
-
+
self.SaveModulesExtraParams()
-
+
def GetModuleExtraParams(self, vendor, product_code, revision_number):
vendor = ExtractHexDecValue(vendor)
product_code = ExtractHexDecValue(product_code)
revision_number = ExtractHexDecValue(revision_number)
-
+
if self.ParentLibrary is not None:
extra_params = self.ParentLibrary.GetModuleExtraParams(vendor, product_code, revision_number)
else:
extra_params = {}
-
+
extra_params.update(self.ModulesExtraParams.get((vendor, product_code, revision_number), {}))
-
+
for param, param_infos in self.MODULES_EXTRA_PARAMS:
extra_params.setdefault(param, param_infos["default"])
-
+
return extra_params
USERDATA_DIR = wx.StandardPaths.Get().GetUserDataDir()
@@ -384,50 +384,49 @@
os.path.join(USERDATA_DIR, "ethercat_modules"))
class RootClass:
-
+
CTNChildrenTypes = [("EthercatNode",_EthercatCTN,"Ethercat Master")]
EditorType = LibraryEditor
-
-
+
+
def __init__(self):
self.ModulesLibrary = None
self.LoadModulesLibrary()
-
+
def GetIconName(self):
return "Ethercat"
-
+
def GetModulesLibraryPath(self, project_path=None):
if project_path is None:
project_path = self.CTNPath()
- return os.path.join(project_path, "modules")
-
+ return os.path.join(project_path, "modules")
+
def OnCTNSave(self, from_project_path=None):
if from_project_path is not None:
shutil.copytree(self.GetModulesLibraryPath(from_project_path),
self.GetModulesLibraryPath())
return True
-
+
def CTNGenerate_C(self, buildpath, locations):
return [],"",False
-
+
def LoadModulesLibrary(self):
if self.ModulesLibrary is None:
self.ModulesLibrary = ModulesLibrary(self.GetModulesLibraryPath(), ModulesDatabase)
else:
self.ModulesLibrary.LoadModulesLibrary()
-
+
def GetModulesDatabaseInstance(self):
return ModulesDatabase
-
+
def GetModulesLibraryInstance(self):
return self.ModulesLibrary
-
+
def GetModulesLibrary(self, profile_filter=None):
return self.ModulesLibrary.GetModulesLibrary(profile_filter)
-
+
def GetVendors(self):
return self.ModulesLibrary.GetVendors()
-
+
def GetModuleInfos(self, module_infos):
return self.ModulesLibrary.GetModuleInfos(module_infos)
-
--- a/etherlab/runtime_etherlab.py Fri Sep 28 17:15:53 2018 +0300
+++ b/etherlab/runtime_etherlab.py Fri Sep 28 17:20:11 2018 +0300
@@ -17,12 +17,12 @@
cmdfmt = "ethercat upload -p %d -t %s 0x%.4x 0x%.2x"
else:
cmdfmt = "ethercat download -p %d -t %s 0x%.4x 0x%.2x %s"
-
+
command = cmdfmt % params[1:]
SDOProc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
res = SDOProc.wait()
output = SDOProc.communicate()[0]
-
+
if params[0] == "upload":
Result = None
if res == 0:
@@ -36,18 +36,18 @@
Result = int(dec_value)
else:
Result = res == 0
-
+
SDOAnswered()
if res != 0 :
PLCObject.LogMessage(
- LogLevelsDict["WARNING"],
+ LogLevelsDict["WARNING"],
"%s : %s"%(command,output))
-
+
def EthercatSDOUpload(pos, index, subindex, var_type):
global SDOThread
SDOThread = Thread(target=SDOThreadProc, args=["upload", pos, var_type, index, subindex])
SDOThread.start()
-
+
def EthercatSDODownload(pos, index, subindex, var_type, value):
global SDOThread
SDOThread = Thread(target=SDOThreadProc, args=["download", pos, var_type, index, subindex, value])
@@ -63,7 +63,7 @@
"""
Logs Kernel messages starting with EtherCAT
Uses GLibc wrapper to Linux syscall "klogctl"
- Last 4 KB are polled, and lines compared to last
+ Last 4 KB are polled, and lines compared to last
captured line to detect new lines
"""
global StopKMSGThread
@@ -78,7 +78,7 @@
log = s.value[:l-1]
if last :
log = log.rpartition(last)[2]
- if log :
+ if log :
last = log.rpartition('\n')[2]
for lvl,msg in re.findall(
r'<(\d)>\[\s*\d*\.\d*\]\s*(EtherCAT\s*.*)$',
@@ -88,7 +88,7 @@
"4":"WARNING",
"3":"CRITICAL"}.get(lvl,"DEBUG")],
msg)
- time.sleep(0.5)
+ time.sleep(0.5)
def _runtime_etherlab_init():
global KMSGPollThread, StopKMSGThread
@@ -105,4 +105,3 @@
SDOThread = None
StopKMSGThread = True
KMSGPollThread = None
-