etherlab/EtherCATManagementEditor.py
changeset 2355 fec77f2b9e07
parent 2354 9460872f1440
child 2356 c26e0c66d8d5
equal deleted inserted replaced
2354:9460872f1440 2355:fec77f2b9e07
    21 # ------------ for SDO Management --------------------
    21 # ------------ for SDO Management --------------------
    22 import string
    22 import string
    23 import wx.grid as gridlib
    23 import wx.grid as gridlib
    24 #-------------------------------------------------------------
    24 #-------------------------------------------------------------
    25 
    25 
    26 # ------------ for register management --------------- 
    26 # ------------ for register management ---------------
    27 from xml.dom import minidom
    27 from xml.dom import minidom
    28 #-------------------------------------------------------------
    28 #-------------------------------------------------------------
    29 
    29 
    30 # ----------------------------- For Sync Manager Table -----------------------------------
    30 # ----------------------------- For Sync Manager Table -----------------------------------
    31 def GetSyncManagersTableColnames():
    31 def GetSyncManagersTableColnames():
    37 
    37 
    38 #-------------------------------------------------------------------------------
    38 #-------------------------------------------------------------------------------
    39 #                    Sync Managers Table
    39 #                    Sync Managers Table
    40 #-------------------------------------------------------------------------------
    40 #-------------------------------------------------------------------------------
    41 class SyncManagersTable(CustomTable):
    41 class SyncManagersTable(CustomTable):
    42     def GetValue(self, row, col): 
    42     def GetValue(self, row, col):
    43         if row < self.GetNumberRows():
    43         if row < self.GetNumberRows():
    44             if col == 0:
    44             if col == 0:
    45                 return row
    45                 return row
    46             return self.data[row].get(self.GetColLabelValue(col, False), "")
    46             return self.data[row].get(self.GetColLabelValue(col, False), "")
    47 
    47 
    58         """
    58         """
    59         wx.Treebook.__init__(self, parent, -1, size=wx.DefaultSize, style=wx.BK_DEFAULT)
    59         wx.Treebook.__init__(self, parent, -1, size=wx.DefaultSize, style=wx.BK_DEFAULT)
    60         self.parent = parent
    60         self.parent = parent
    61         self.Controler = controler
    61         self.Controler = controler
    62         self.NodeEditor = node_editor
    62         self.NodeEditor = node_editor
    63         
    63 
    64         self.EtherCATManagementClassObject = {}
    64         self.EtherCATManagementClassObject = {}
    65         
    65 
    66         # fill EtherCAT Management Treebook
    66         # fill EtherCAT Management Treebook
    67         for pname, pclass, subs in [
    67         for pname, pclass, subs in [
    68             ("Slave State",        SlaveStatePanelClass, []),
    68             ("Slave State",        SlaveStatePanelClass, []),
    69             ("SDO Management",     SDOPanelClass, []),
    69             ("SDO Management",     SDOPanelClass, []),
    70             ("PDO Monitoring",     PDOPanelClass, []),
    70             ("PDO Monitoring",     PDOPanelClass, []),
    71             ("ESC Management",     EEPROMAccessPanel, [        
    71             ("ESC Management",     EEPROMAccessPanel, [
    72                     ("Smart View", SlaveSiiSmartView),
    72                     ("Smart View", SlaveSiiSmartView),
    73                     ("Hex View", HexView)]),
    73                     ("Hex View", HexView)]),
    74             ("Register Access",     RegisterAccessPanel, [])]:
    74             ("Register Access",     RegisterAccessPanel, [])]:
    75                 self.AddPage(pclass(self, self.Controler), pname)
    75                 self.AddPage(pclass(self, self.Controler), pname)
    76                 for spname, spclass in subs:
    76                 for spname, spclass in subs:
    77                     self.AddSubPage(spclass(self, self.Controler), spname)
    77                     self.AddSubPage(spclass(self, self.Controler), spname)
    78 
    78 
    79         self.Bind(wx.EVT_TREEBOOK_PAGE_CHANGED, self.OnPageChanged)
    79         self.Bind(wx.EVT_TREEBOOK_PAGE_CHANGED, self.OnPageChanged)
    80         self.Bind(wx.EVT_TREEBOOK_PAGE_CHANGING, self.OnPageChanging)
    80         self.Bind(wx.EVT_TREEBOOK_PAGE_CHANGING, self.OnPageChanging)
    81         
    81 
    82     def OnPageChanged(self, event):
    82     def OnPageChanged(self, event):
    83         old = event.GetOldSelection()
    83         old = event.GetOldSelection()
    84         new = event.GetSelection()
    84         new = event.GetSelection()
    85         sel = event.GetSelection()
    85         sel = event.GetSelection()
    86         event.Skip()
    86         event.Skip()
    87         
    87 
    88     def OnPageChanging(self, event):
    88     def OnPageChanging(self, event):
    89         old = event.GetOldSelection()
    89         old = event.GetOldSelection()
    90         new = event.GetSelection()
    90         new = event.GetSelection()
    91         sel = event.GetSelection()
    91         sel = event.GetSelection()
    92         event.Skip()    
    92         event.Skip()
    93         
    93 
    94 #-------------------------------------------------------------------------------
    94 #-------------------------------------------------------------------------------
    95 #                    For SlaveState Panel
    95 #                    For SlaveState Panel
    96 #-------------------------------------------------------------------------------        
    96 #-------------------------------------------------------------------------------
    97 class SlaveStatePanelClass(wx.Panel):
    97 class SlaveStatePanelClass(wx.Panel):
    98     def __init__(self, parent, controler):
    98     def __init__(self, parent, controler):
    99         """
    99         """
   100         Constructor
   100         Constructor
   101         @param parent: Reference to the parent EtherCATManagementTreebook class
   101         @param parent: Reference to the parent EtherCATManagementTreebook class
   102         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   102         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   103         """
   103         """
   104         wx.Panel.__init__(self, parent, -1, (0, 0), size=wx.DefaultSize, style = wx.SUNKEN_BORDER)
   104         wx.Panel.__init__(self, parent, -1, (0, 0), size=wx.DefaultSize, style = wx.SUNKEN_BORDER)
   105         self.Controler = controler
   105         self.Controler = controler
   106         self.parent = parent
   106         self.parent = parent
   107         
   107 
   108         # initialize SlaveStatePanel UI dictionaries
   108         # initialize SlaveStatePanel UI dictionaries
   109         self.StaticBoxDic = {}
   109         self.StaticBoxDic = {}
   110         self.StaticTextDic = {}
   110         self.StaticTextDic = {}
   111         self.TextCtrlDic = {}
   111         self.TextCtrlDic = {}
   112         self.ButtonDic = {}
   112         self.ButtonDic = {}
   113         
   113 
   114         # iniitalize BoxSizer and FlexGridSizer
   114         # iniitalize BoxSizer and FlexGridSizer
   115         self.SizerDic = {
   115         self.SizerDic = {
   116             "SlaveState_main_sizer" : wx.BoxSizer(wx.VERTICAL),
   116             "SlaveState_main_sizer" : wx.BoxSizer(wx.VERTICAL),
   117             "SlaveState_inner_main_sizer" : wx.FlexGridSizer(cols=1, hgap=50, rows=3, vgap=10),
   117             "SlaveState_inner_main_sizer" : wx.FlexGridSizer(cols=1, hgap=50, rows=3, vgap=10),
   118             "SlaveInfosDetailsInnerSizer" : wx.FlexGridSizer(cols=4, hgap=10, rows=2, vgap=10),
   118             "SlaveInfosDetailsInnerSizer" : wx.FlexGridSizer(cols=4, hgap=10, rows=2, vgap=10),
   119             "SyncManagerInnerSizer" : wx.FlexGridSizer(cols=1, hgap=5, rows=1, vgap=5),
   119             "SyncManagerInnerSizer" : wx.FlexGridSizer(cols=1, hgap=5, rows=1, vgap=5),
   120             "SlaveState_sizer" : wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10),
   120             "SlaveState_sizer" : wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10),
   121             "SlaveState_up_sizer" : wx.FlexGridSizer(cols=4, hgap=10, rows=2, vgap=10),
   121             "SlaveState_up_sizer" : wx.FlexGridSizer(cols=4, hgap=10, rows=2, vgap=10),
   122             "SlaveState_down_sizer" : wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=10)}
   122             "SlaveState_down_sizer" : wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=10)}
   123         
   123 
   124         # initialize StaticBox and StaticBoxSizer
   124         # initialize StaticBox and StaticBoxSizer
   125         for box_name, box_label in [
   125         for box_name, box_label in [
   126                 ("SlaveInfosDetailsBox", "Slave Informations"),
   126                 ("SlaveInfosDetailsBox", "Slave Informations"),
   127                 ("SyncManagerBox", "Sync Manager"),
   127                 ("SyncManagerBox", "Sync Manager"),
   128                 ("SlaveStateBox", "Slave State Transition && Monitoring")]:
   128                 ("SlaveStateBox", "Slave State Transition && Monitoring")]:
   129             self.StaticBoxDic[box_name] = wx.StaticBox(self, label=_(box_label))
   129             self.StaticBoxDic[box_name] = wx.StaticBox(self, label=_(box_label))
   130             self.SizerDic[box_name] = wx.StaticBoxSizer(self.StaticBoxDic[box_name])  
   130             self.SizerDic[box_name] = wx.StaticBoxSizer(self.StaticBoxDic[box_name])
   131         
   131 
   132         for statictext_name, statictext_label, textctrl_name in [
   132         for statictext_name, statictext_label, textctrl_name in [
   133                 ("VendorLabel", "Vendor:", "vendor"),
   133                 ("VendorLabel", "Vendor:", "vendor"),
   134                 ("ProductcodeLabel", "Product code:", "product_code"),
   134                 ("ProductcodeLabel", "Product code:", "product_code"),
   135                 ("RevisionnumberLabel", "Slave Count:", "revision_number"),
   135                 ("RevisionnumberLabel", "Slave Count:", "revision_number"),
   136                 ("PhysicsLabel", "Physics:", "physics")]:
   136                 ("PhysicsLabel", "Physics:", "physics")]:
   137             self.StaticTextDic[statictext_name] = wx.StaticText(self, label=_(statictext_label))
   137             self.StaticTextDic[statictext_name] = wx.StaticText(self, label=_(statictext_label))
   138             self.TextCtrlDic[textctrl_name] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
   138             self.TextCtrlDic[textctrl_name] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
   139             self.SizerDic["SlaveInfosDetailsInnerSizer"].AddMany([self.StaticTextDic[statictext_name], 
   139             self.SizerDic["SlaveInfosDetailsInnerSizer"].AddMany([self.StaticTextDic[statictext_name],
   140                                                                self.TextCtrlDic[textctrl_name]])    
   140                                                                self.TextCtrlDic[textctrl_name]])
   141         
   141 
   142         self.SizerDic["SlaveInfosDetailsBox"].AddSizer(self.SizerDic["SlaveInfosDetailsInnerSizer"])
   142         self.SizerDic["SlaveInfosDetailsBox"].AddSizer(self.SizerDic["SlaveInfosDetailsInnerSizer"])
   143         
   143 
   144         self.SyncManagersGrid = CustomGrid(self, size=wx.Size(605,155), style=wx.VSCROLL)      
   144         self.SyncManagersGrid = CustomGrid(self, size=wx.Size(605,155), style=wx.VSCROLL)
   145                
   145 
   146         self.SizerDic["SyncManagerInnerSizer"].Add(self.SyncManagersGrid)    
   146         self.SizerDic["SyncManagerInnerSizer"].Add(self.SyncManagersGrid)
   147         self.SizerDic["SyncManagerBox"].Add(self.SizerDic["SyncManagerInnerSizer"])
   147         self.SizerDic["SyncManagerBox"].Add(self.SizerDic["SyncManagerInnerSizer"])
   148         
   148 
   149         for button_name, button_id, button_label, button_tooltipstring, event_method, sub_item in [
   149         for button_name, button_id, button_label, button_tooltipstring, event_method, sub_item in [
   150                 ("InitButton",   0, "INIT", "State Transition to \"Init\" State",     self.OnButtonClick, []),
   150                 ("InitButton",   0, "INIT", "State Transition to \"Init\" State",     self.OnButtonClick, []),
   151                 ("PreOPButton",  1, "PREOP", "State Transition to \"PreOP\" State",   self.OnButtonClick, [
   151                 ("PreOPButton",  1, "PREOP", "State Transition to \"PreOP\" State",   self.OnButtonClick, [
   152                         ("TargetStateLabel", "Target State:" , "TargetState")]),
   152                         ("TargetStateLabel", "Target State:" , "TargetState")]),
   153                 ("SafeOPButton", 2, "SAFEOP", "State Transition to \"SafeOP\" State", self.OnButtonClick, []),
   153                 ("SafeOPButton", 2, "SAFEOP", "State Transition to \"SafeOP\" State", self.OnButtonClick, []),
   158             self.ButtonDic[button_name].SetToolTipString(button_tooltipstring)
   158             self.ButtonDic[button_name].SetToolTipString(button_tooltipstring)
   159             self.SizerDic["SlaveState_up_sizer"].Add(self.ButtonDic[button_name])
   159             self.SizerDic["SlaveState_up_sizer"].Add(self.ButtonDic[button_name])
   160             for statictext_name, statictext_label, textctrl_name in sub_item :
   160             for statictext_name, statictext_label, textctrl_name in sub_item :
   161                 self.StaticTextDic[statictext_name] = wx.StaticText(self, label=_(statictext_label))
   161                 self.StaticTextDic[statictext_name] = wx.StaticText(self, label=_(statictext_label))
   162                 self.TextCtrlDic[textctrl_name] = wx.TextCtrl(self, size=wx.DefaultSize, style=wx.TE_READONLY)
   162                 self.TextCtrlDic[textctrl_name] = wx.TextCtrl(self, size=wx.DefaultSize, style=wx.TE_READONLY)
   163                 self.SizerDic["SlaveState_up_sizer"].AddMany([self.StaticTextDic[statictext_name], 
   163                 self.SizerDic["SlaveState_up_sizer"].AddMany([self.StaticTextDic[statictext_name],
   164                                                                self.TextCtrlDic[textctrl_name]])
   164                                                                self.TextCtrlDic[textctrl_name]])
   165                 
   165 
   166         for button_name, button_label, button_tooltipstring, event_method in [
   166         for button_name, button_label, button_tooltipstring, event_method in [
   167                 ("StartTimerButton", "Start State Monitoring", "Slave State Update Restart", self.StartTimer),
   167                 ("StartTimerButton", "Start State Monitoring", "Slave State Update Restart", self.StartTimer),
   168                 ("StopTimerButton", "Stop State Monitoring", "Slave State Update Stop", self.CurrentStateThreadStop)]:
   168                 ("StopTimerButton", "Stop State Monitoring", "Slave State Update Stop", self.CurrentStateThreadStop)]:
   169             self.ButtonDic[button_name] = wx.Button(self, label=_(button_label))
   169             self.ButtonDic[button_name] = wx.Button(self, label=_(button_label))
   170             self.ButtonDic[button_name].Bind(wx.EVT_BUTTON, event_method)
   170             self.ButtonDic[button_name].Bind(wx.EVT_BUTTON, event_method)
   171             self.ButtonDic[button_name].SetToolTipString(button_tooltipstring)
   171             self.ButtonDic[button_name].SetToolTipString(button_tooltipstring)
   172             self.SizerDic["SlaveState_down_sizer"].Add(self.ButtonDic[button_name])   
   172             self.SizerDic["SlaveState_down_sizer"].Add(self.ButtonDic[button_name])
   173         
   173 
   174         self.SizerDic["SlaveState_sizer"].AddMany([self.SizerDic["SlaveState_up_sizer"], 
   174         self.SizerDic["SlaveState_sizer"].AddMany([self.SizerDic["SlaveState_up_sizer"],
   175             self.SizerDic["SlaveState_down_sizer"]])
   175             self.SizerDic["SlaveState_down_sizer"]])
   176         
   176 
   177         self.SizerDic["SlaveStateBox"].Add(self.SizerDic["SlaveState_sizer"])
   177         self.SizerDic["SlaveStateBox"].Add(self.SizerDic["SlaveState_sizer"])
   178         
   178 
   179         self.SizerDic["SlaveState_inner_main_sizer"].AddMany([
   179         self.SizerDic["SlaveState_inner_main_sizer"].AddMany([
   180             self.SizerDic["SlaveInfosDetailsBox"], self.SizerDic["SyncManagerBox"],
   180             self.SizerDic["SlaveInfosDetailsBox"], self.SizerDic["SyncManagerBox"],
   181             self.SizerDic["SlaveStateBox"]])
   181             self.SizerDic["SlaveStateBox"]])
   182         
   182 
   183         self.SizerDic["SlaveState_main_sizer"].Add(self.SizerDic["SlaveState_inner_main_sizer"])
   183         self.SizerDic["SlaveState_main_sizer"].Add(self.SizerDic["SlaveState_inner_main_sizer"])
   184         
   184 
   185         self.SetSizer(self.SizerDic["SlaveState_main_sizer"])
   185         self.SetSizer(self.SizerDic["SlaveState_main_sizer"])
   186         
   186 
   187         # register a timer for periodic exectuion of slave state update (period: 1000 ms)
   187         # register a timer for periodic exectuion of slave state update (period: 1000 ms)
   188         self.Bind(wx.EVT_TIMER, self.GetCurrentState)
   188         self.Bind(wx.EVT_TIMER, self.GetCurrentState)
   189         
   189 
   190         self.CreateSyncManagerTable()
   190         self.CreateSyncManagerTable()
   191         
   191 
   192         self.Centre()
   192         self.Centre()
   193     
   193 
   194     def CreateSyncManagerTable(self):
   194     def CreateSyncManagerTable(self):
   195         """
   195         """
   196         Create grid for "SyncManager"
   196         Create grid for "SyncManager"
   197         """
   197         """
   198         # declare Table object 
   198         # declare Table object
   199         self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames())
   199         self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames())
   200         self.SyncManagersGrid.SetTable(self.SyncManagersTable)
   200         self.SyncManagersGrid.SetTable(self.SyncManagersTable)
   201         # set grid alignment attr. (CENTER)
   201         # set grid alignment attr. (CENTER)
   202         self.SyncManagersGridColAlignements = [wx.ALIGN_CENTRE, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE, 
   202         self.SyncManagersGridColAlignements = [wx.ALIGN_CENTRE, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE,
   203                                                wx.ALIGN_CENTRE, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE]
   203                                                wx.ALIGN_CENTRE, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE]
   204         # set grid size
   204         # set grid size
   205         self.SyncManagersGridColSizes = [40, 150, 100, 100, 100, 100]
   205         self.SyncManagersGridColSizes = [40, 150, 100, 100, 100, 100]
   206         self.SyncManagersGrid.SetRowLabelSize(0)
   206         self.SyncManagersGrid.SetRowLabelSize(0)
   207         for col in range(self.SyncManagersTable.GetNumberCols()):
   207         for col in range(self.SyncManagersTable.GetNumberCols()):
   208             attr = wx.grid.GridCellAttr()
   208             attr = wx.grid.GridCellAttr()
   209             attr.SetAlignment(self.SyncManagersGridColAlignements[col], wx.ALIGN_CENTRE)
   209             attr.SetAlignment(self.SyncManagersGridColAlignements[col], wx.ALIGN_CENTRE)
   210             self.SyncManagersGrid.SetColAttr(col, attr)
   210             self.SyncManagersGrid.SetColAttr(col, attr)
   211             self.SyncManagersGrid.SetColMinimalWidth(col, self.SyncManagersGridColSizes[col])
   211             self.SyncManagersGrid.SetColMinimalWidth(col, self.SyncManagersGridColSizes[col])
   212             self.SyncManagersGrid.AutoSizeColumn(col, False) 
   212             self.SyncManagersGrid.AutoSizeColumn(col, False)
   213         
   213 
   214         self.RefreshSlaveInfos()
   214         self.RefreshSlaveInfos()
   215         
   215 
   216     def RefreshSlaveInfos(self):
   216     def RefreshSlaveInfos(self):
   217         """
   217         """
   218         Fill data in "Slave Information" and "SyncManager"
   218         Fill data in "Slave Information" and "SyncManager"
   219         """
   219         """
   220         slave_infos = self.Controler.GetSlaveInfos()
   220         slave_infos = self.Controler.GetSlaveInfos()
   221         sync_manager_section = ["vendor", "product_code", "revision_number", "physics"]
   221         sync_manager_section = ["vendor", "product_code", "revision_number", "physics"]
   222         if slave_infos is not None:
   222         if slave_infos is not None:
   223             # this method is same as "TextCtrl.SetValue" 
   223             # this method is same as "TextCtrl.SetValue"
   224             for textctrl_name in sync_manager_section:
   224             for textctrl_name in sync_manager_section:
   225                 self.TextCtrlDic[textctrl_name].SetValue(slave_infos[textctrl_name])
   225                 self.TextCtrlDic[textctrl_name].SetValue(slave_infos[textctrl_name])
   226             self.SyncManagersTable.SetData(slave_infos["sync_managers"])
   226             self.SyncManagersTable.SetData(slave_infos["sync_managers"])
   227             self.SyncManagersTable.ResetView(self.SyncManagersGrid)
   227             self.SyncManagersTable.ResetView(self.SyncManagersGrid)
   228         else:
   228         else:
   229             for textctrl_name in sync_manager_section:
   229             for textctrl_name in sync_manager_section:
   230                 self.TextCtrlDic[textctrl_name].SetValue("")
   230                 self.TextCtrlDic[textctrl_name].SetValue("")
   231             self.SyncManagersTable.SetData([])
   231             self.SyncManagersTable.SetData([])
   232             self.SyncManagersTable.ResetView(self.SyncManagersGrid)
   232             self.SyncManagersTable.ResetView(self.SyncManagersGrid)
   233         
   233 
   234     def OnButtonClick(self, event):
   234     def OnButtonClick(self, event):
   235         """
   235         """
   236         Event handler for slave state transition button click (Init, PreOP, SafeOP, OP button)
   236         Event handler for slave state transition button click (Init, PreOP, SafeOP, OP button)
   237         @param event : wx.EVT_BUTTON object
   237         @param event : wx.EVT_BUTTON object
   238         """
   238         """
   239         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
   239         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
   240         if check_connect_flag :
   240         if check_connect_flag :
   241             state_dic = ["INIT", "PREOP", "SAFEOP", "OP"]
   241             state_dic = ["INIT", "PREOP", "SAFEOP", "OP"]
   242               
   242 
   243             # If target state is one of {INIT, PREOP, SAFEOP}, request slave state transition immediately.
   243             # If target state is one of {INIT, PREOP, SAFEOP}, request slave state transition immediately.
   244             if event.GetId() < 3 :
   244             if event.GetId() < 3 :
   245                 self.Controler.CommonMethod.RequestSlaveState(state_dic[event.GetId()])
   245                 self.Controler.CommonMethod.RequestSlaveState(state_dic[event.GetId()])
   246                 self.TextCtrlDic["TargetState"].SetValue(state_dic[event.GetId()])
   246                 self.TextCtrlDic["TargetState"].SetValue(state_dic[event.GetId()])
   247 
   247 
   252                 status, count = self.Controler.GetCTRoot()._connector.GetPLCstatus()
   252                 status, count = self.Controler.GetCTRoot()._connector.GetPLCstatus()
   253                 if status == "Started" :
   253                 if status == "Started" :
   254                     self.Controler.CommonMethod.RequestSlaveState("OP")
   254                     self.Controler.CommonMethod.RequestSlaveState("OP")
   255                     self.TextCtrlDic["TargetState"].SetValue("OP")
   255                     self.TextCtrlDic["TargetState"].SetValue("OP")
   256                 else :
   256                 else :
   257                     self.Controler.CommonMethod.CreateErrorDialog("PLC is Not Started")  
   257                     self.Controler.CommonMethod.CreateErrorDialog("PLC is Not Started")
   258      
   258 
   259     def GetCurrentState(self, event):
   259     def GetCurrentState(self, event):
   260         """
   260         """
   261         Timer event handler for periodic slave state monitoring (Default period: 1 sec = 1000 msec).
   261         Timer event handler for periodic slave state monitoring (Default period: 1 sec = 1000 msec).
   262         @param event : wx.TIMER object
   262         @param event : wx.TIMER object
   263         """
   263         """
   266             returnVal = self.Controler.CommonMethod.GetSlaveStateFromSlave()
   266             returnVal = self.Controler.CommonMethod.GetSlaveStateFromSlave()
   267             line = returnVal.split("\n")
   267             line = returnVal.split("\n")
   268             try :
   268             try :
   269                 self.SetCurrentState(line[self.Controler.GetSlavePos()])
   269                 self.SetCurrentState(line[self.Controler.GetSlavePos()])
   270             except Exception:
   270             except Exception:
   271                 pass  
   271                 pass
   272             
   272 
   273     def SetCurrentState(self, line):
   273     def SetCurrentState(self, line):
   274         """
   274         """
   275         Show current slave state using the executiob result of "ethercat slaves" command.
   275         Show current slave state using the executiob result of "ethercat slaves" command.
   276         @param line : result of "ethercat slaves" command
   276         @param line : result of "ethercat slaves" command
   277         """
   277         """
   279         try :
   279         try :
   280             # parse the execution result of  "ethercat slaves" command
   280             # parse the execution result of  "ethercat slaves" command
   281             # Result example : 0  0:0  PREOP  +  EL9800 (V4.30) (PIC24, SPI, ET1100)
   281             # Result example : 0  0:0  PREOP  +  EL9800 (V4.30) (PIC24, SPI, ET1100)
   282             token = line.split("  ")
   282             token = line.split("  ")
   283             if token[2] in state_array:
   283             if token[2] in state_array:
   284                 self.TextCtrlDic["CurrentState"].SetValue(token[2])           
   284                 self.TextCtrlDic["CurrentState"].SetValue(token[2])
   285         except Exception:
   285         except Exception:
   286             pass     
   286             pass
   287         
   287 
   288     def StartTimer(self, event):
   288     def StartTimer(self, event):
   289         """
   289         """
   290         Event handler for "Start State Monitoring" button.
   290         Event handler for "Start State Monitoring" button.
   291           - start slave state monitoring thread
   291           - start slave state monitoring thread
   292         @param event : wx.EVT_BUTTON object
   292         @param event : wx.EVT_BUTTON object
   293         """
   293         """
   294         self.SlaveStateThread = wx.Timer(self)
   294         self.SlaveStateThread = wx.Timer(self)
   295         # set timer period (1000 ms)
   295         # set timer period (1000 ms)
   296         self.SlaveStateThread.Start(1000)
   296         self.SlaveStateThread.Start(1000)
   297         
   297 
   298     def CurrentStateThreadStop(self, event):
   298     def CurrentStateThreadStop(self, event):
   299         """
   299         """
   300         Event handler for "Stop State Monitoring" button.
   300         Event handler for "Stop State Monitoring" button.
   301           - stop slave state monitoring thread
   301           - stop slave state monitoring thread
   302         @param event : wx.EVT_BUTTON object
   302         @param event : wx.EVT_BUTTON object
   303         """
   303         """
   304         try:
   304         try:
   305             self.SlaveStateThread.Stop()
   305             self.SlaveStateThread.Stop()
   306         except Exception:
   306         except Exception:
   307             pass
   307             pass
   308         
   308 
   309 #-------------------------------------------------------------------------------
   309 #-------------------------------------------------------------------------------
   310 #                    For SDO Management Panel
   310 #                    For SDO Management Panel
   311 #-------------------------------------------------------------------------------  
   311 #-------------------------------------------------------------------------------
   312 class SDOPanelClass(wx.Panel):
   312 class SDOPanelClass(wx.Panel):
   313     def __init__(self, parent, controler):
   313     def __init__(self, parent, controler):
   314         """
   314         """
   315         Constructor
   315         Constructor
   316         @param parent: Reference to the parent EtherCATManagementTreebook class
   316         @param parent: Reference to the parent EtherCATManagementTreebook class
   317         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   317         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   318         """
   318         """
   319         wx.Panel.__init__(self, parent, -1)
   319         wx.Panel.__init__(self, parent, -1)
   320         
   320 
   321         self.DatatypeDescription, self.CommunicationObject, self.ManufacturerSpecific, \
   321         self.DatatypeDescription, self.CommunicationObject, self.ManufacturerSpecific, \
   322         self.ProfileSpecific, self.Reserved, self.AllSDOData = range(6)
   322         self.ProfileSpecific, self.Reserved, self.AllSDOData = range(6)
   323         
   323 
   324         self.Controler = controler
   324         self.Controler = controler
   325         
   325 
   326         self.SDOManagementMainSizer = wx.BoxSizer(wx.VERTICAL)
   326         self.SDOManagementMainSizer = wx.BoxSizer(wx.VERTICAL)
   327         self.SDOManagementInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10)
   327         self.SDOManagementInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10)
   328              
   328 
   329         self.SDOUpdate = wx.Button(self, label=_('update'))          
   329         self.SDOUpdate = wx.Button(self, label=_('update'))
   330         self.SDOUpdate.Bind(wx.EVT_BUTTON, self.SDOInfoUpdate)
   330         self.SDOUpdate.Bind(wx.EVT_BUTTON, self.SDOInfoUpdate)
   331         
   331 
   332         self.CallSDONoteBook = SDONoteBook(self, controler=self.Controler)
   332         self.CallSDONoteBook = SDONoteBook(self, controler=self.Controler)
   333         self.SDOManagementInnerMainSizer.Add(self.SDOUpdate)
   333         self.SDOManagementInnerMainSizer.Add(self.SDOUpdate)
   334         self.SDOManagementInnerMainSizer.Add(self.CallSDONoteBook, wx.ALL | wx.EXPAND)           
   334         self.SDOManagementInnerMainSizer.Add(self.CallSDONoteBook, wx.ALL | wx.EXPAND)
   335 
   335 
   336         self.SDOManagementMainSizer.Add(self.SDOManagementInnerMainSizer)
   336         self.SDOManagementMainSizer.Add(self.SDOManagementInnerMainSizer)
   337         
   337 
   338         self.SetSizer(self.SDOManagementMainSizer)
   338         self.SetSizer(self.SDOManagementMainSizer)
   339         
   339 
   340     def SDOInfoUpdate(self, event):
   340     def SDOInfoUpdate(self, event):
   341         """
   341         """
   342         Evenet handler for SDO "update" button.
   342         Evenet handler for SDO "update" button.
   343           - Load SDO data from current slave 
   343           - Load SDO data from current slave
   344         @param event : wx.EVT_BUTTON object
   344         @param event : wx.EVT_BUTTON object
   345         """     
   345         """
   346         self.Controler.CommonMethod.SaveSDOData = []
   346         self.Controler.CommonMethod.SaveSDOData = []
   347         self.Controler.CommonMethod.ClearSDODataSet()
   347         self.Controler.CommonMethod.ClearSDODataSet()
   348         self.SDOFlag = False
   348         self.SDOFlag = False
   349         
   349 
   350         # Check whether beremiz connected or not.
   350         # Check whether beremiz connected or not.
   351         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
   351         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
   352         if check_connect_flag:
   352         if check_connect_flag:
   353             self.SDOs = self.Controler.CommonMethod.GetSlaveSDOFromSlave()
   353             self.SDOs = self.Controler.CommonMethod.GetSlaveSDOFromSlave()
   354             # SDOFlag is "False", user click "Cancel" button
   354             # SDOFlag is "False", user click "Cancel" button
   355             self.SDOFlag = self.SDOParser() 
   355             self.SDOFlag = self.SDOParser()
   356 
   356 
   357             if self.SDOFlag :
   357             if self.SDOFlag :
   358                 self.CallSDONoteBook.CreateNoteBook()      
   358                 self.CallSDONoteBook.CreateNoteBook()
   359                 self.Refresh()
   359                 self.Refresh()
   360     
   360 
   361     def SDOParser(self):  
   361     def SDOParser(self):
   362         """
   362         """
   363         Parse SDO data set that obtain "SDOInfoUpdate" Method
   363         Parse SDO data set that obtain "SDOInfoUpdate" Method
   364         @return True or False 
   364         @return True or False
   365         """       
   365         """
   366 
   366 
   367         slaveSDO_progress = wx.ProgressDialog("Slave SDO Monitoring", "Now Uploading...",
   367         slaveSDO_progress = wx.ProgressDialog("Slave SDO Monitoring", "Now Uploading...",
   368                                maximum = len(self.SDOs.splitlines()), parent=self,
   368                                maximum = len(self.SDOs.splitlines()), parent=self,
   369                                style = wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | 
   369                                style = wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME |
   370                                        wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME | 
   370                                        wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME |
   371                                        wx.PD_AUTO_HIDE | wx.PD_SMOOTH)        
   371                                        wx.PD_AUTO_HIDE | wx.PD_SMOOTH)
   372         
   372 
   373         # If keep_going flag is False, SDOParser method is stop and return "False".
   373         # If keep_going flag is False, SDOParser method is stop and return "False".
   374         keep_going = True
   374         keep_going = True
   375         count = 0
   375         count = 0
   376              
   376 
   377         # SDO data example 
   377         # SDO data example
   378         # SDO 0x1000, "Device type"
   378         # SDO 0x1000, "Device type"
   379         # 0x1000:00,r-r-r-,uint32,32 bit,"Device type",0x00020192, 131474
   379         # 0x1000:00,r-r-r-,uint32,32 bit,"Device type",0x00020192, 131474
   380         for details_line in self.SDOs.splitlines():
   380         for details_line in self.SDOs.splitlines():
   381             count += 1
   381             count += 1
   382             line_token = details_line.split("\"")
   382             line_token = details_line.split("\"")
   385                 title_name = line_token[1]
   385                 title_name = line_token[1]
   386             # else case : 0x1000:00,r-r-r-,uint32,32 bit,"Device type",0x00020192, 131474
   386             # else case : 0x1000:00,r-r-r-,uint32,32 bit,"Device type",0x00020192, 131474
   387             else :
   387             else :
   388                 # line_token = ['0x1000:00,r-r-r-,uint32,32 bit,', 'Device type', ',0x00020192, 131474']
   388                 # line_token = ['0x1000:00,r-r-r-,uint32,32 bit,', 'Device type', ',0x00020192, 131474']
   389                 token_head, name, token_tail = line_token
   389                 token_head, name, token_tail = line_token
   390                 
   390 
   391                 # token_head = ['0x1000:00', 'r-r-r-', 'uint32', '32 bit', '']
   391                 # token_head = ['0x1000:00', 'r-r-r-', 'uint32', '32 bit', '']
   392                 token_head = token_head.split(",")
   392                 token_head = token_head.split(",")
   393                 ful_idx, access, type, size, empty = token_head
   393                 ful_idx, access, type, size, empty = token_head
   394                 # ful_idx.split(":") = ['0x1000', '00']
   394                 # ful_idx.split(":") = ['0x1000', '00']
   395                 idx, sub_idx = ful_idx.split(":")
   395                 idx, sub_idx = ful_idx.split(":")
   396                 
   396 
   397                 # token_tail = ['', '0x00020192', '131474']
   397                 # token_tail = ['', '0x00020192', '131474']
   398                 token_tail = token_tail.split(",")
   398                 token_tail = token_tail.split(",")
   399                 try :
   399                 try :
   400                     empty, hex_val, dec_val = token_tail
   400                     empty, hex_val, dec_val = token_tail
   401                     
   401 
   402                 # SDO data is not return "dec value"
   402                 # SDO data is not return "dec value"
   403                 # line example : 
   403                 # line example :
   404                 # 0x1702:01,rwr-r-,uint32,32 bit," 1st mapping", ---- 
   404                 # 0x1702:01,rwr-r-,uint32,32 bit," 1st mapping", ----
   405                 except Exception:
   405                 except Exception:
   406                     empty, hex_val = token_tail
   406                     empty, hex_val = token_tail
   407                 
   407 
   408                 name_after_check = self.StringTest(name)
   408                 name_after_check = self.StringTest(name)
   409                 
   409 
   410                 # convert hex type
   410                 # convert hex type
   411                 sub_idx = "0x" + sub_idx
   411                 sub_idx = "0x" + sub_idx
   412 
   412 
   413                 if type == "octet_string":
   413                 if type == "octet_string":
   414                     hex_val = ' ---- '
   414                     hex_val = ' ---- '
   415             
   415 
   416                 # SResult of SlaveSDO data parsing. (data type : dictionary)
   416                 # SResult of SlaveSDO data parsing. (data type : dictionary)
   417                 self.Data = {'idx':idx.strip(), 'subIdx':sub_idx.strip(), 'access':access.strip(), 
   417                 self.Data = {'idx':idx.strip(), 'subIdx':sub_idx.strip(), 'access':access.strip(),
   418                              'type':type.strip(), 'size':size.strip(),  'name':name_after_check.strip("\""), 
   418                              'type':type.strip(), 'size':size.strip(),  'name':name_after_check.strip("\""),
   419                              'value':hex_val.strip(), "category":title_name.strip("\"")}
   419                              'value':hex_val.strip(), "category":title_name.strip("\"")}
   420                 
   420 
   421                 category_divide_value = [0x1000, 0x2000, 0x6000, 0xa000, 0xffff]
   421                 category_divide_value = [0x1000, 0x2000, 0x6000, 0xa000, 0xffff]
   422 
   422 
   423                 for count in range(len(category_divide_value)) :
   423                 for count in range(len(category_divide_value)) :
   424                     if int(idx, 0) < category_divide_value[count]:
   424                     if int(idx, 0) < category_divide_value[count]:
   425                         self.Controler.CommonMethod.SaveSDOData[count].append(self.Data)
   425                         self.Controler.CommonMethod.SaveSDOData[count].append(self.Data)
   426                         break
   426                         break
   427                 
   427 
   428                 self.Controler.CommonMethod.SaveSDOData[self.AllSDOData].append(self.Data)
   428                 self.Controler.CommonMethod.SaveSDOData[self.AllSDOData].append(self.Data)
   429                       
   429 
   430             if count >= len(self.SDOs.splitlines()) / 2:
   430             if count >= len(self.SDOs.splitlines()) / 2:
   431                 (keep_going, skip) = slaveSDO_progress.Update(count, "Please waiting a moment!!")
   431                 (keep_going, skip) = slaveSDO_progress.Update(count, "Please waiting a moment!!")
   432             else:
   432             else:
   433                 (keep_going, skip) = slaveSDO_progress.Update(count)
   433                 (keep_going, skip) = slaveSDO_progress.Update(count)
   434                 
   434 
   435             # If user click "Cancel" loop suspend immediately 
   435             # If user click "Cancel" loop suspend immediately
   436             if (keep_going == False):
   436             if (keep_going == False):
   437                 break
   437                 break
   438             
   438 
   439         slaveSDO_progress.Destroy()      
   439         slaveSDO_progress.Destroy()
   440         return keep_going  
   440         return keep_going
   441 
   441 
   442     def StringTest(self, check_string):
   442     def StringTest(self, check_string):
   443         """
   443         """
   444         Test value 'name' is alphanumeric  
   444         Test value 'name' is alphanumeric
   445         @param check_string : input data for check 
   445         @param check_string : input data for check
   446         @return result : output data after check
   446         @return result : output data after check
   447         """  
   447         """
   448         # string.printable is print this result
   448         # string.printable is print this result
   449         #'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
   449         #'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
   450         #!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c
   450         #!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c
   451         allow_range = string.printable
   451         allow_range = string.printable
   452         result = check_string
   452         result = check_string
   454             # string.isalnum() is check whether string is alphanumeric or not
   454             # string.isalnum() is check whether string is alphanumeric or not
   455             if check_string[len(check_string)-1-i:len(check_string)-i] in allow_range :
   455             if check_string[len(check_string)-1-i:len(check_string)-i] in allow_range :
   456                 result = check_string[:len(check_string) - i]
   456                 result = check_string[:len(check_string) - i]
   457                 break
   457                 break
   458         return result
   458         return result
   459     
   459 
   460     
   460 
   461 #-------------------------------------------------------------------------------
   461 #-------------------------------------------------------------------------------
   462 #                    For SDO Notebook (divide category)
   462 #                    For SDO Notebook (divide category)
   463 #-------------------------------------------------------------------------------  
   463 #-------------------------------------------------------------------------------
   464 class SDONoteBook(wx.Notebook):
   464 class SDONoteBook(wx.Notebook):
   465     def __init__(self, parent, controler):
   465     def __init__(self, parent, controler):
   466         """
   466         """
   467         Constructor
   467         Constructor
   468         @param parent: Reference to the parent SDOPanelClass class
   468         @param parent: Reference to the parent SDOPanelClass class
   469         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   469         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   470         """
   470         """
   471         wx.Notebook.__init__(self, parent, id = -1, size=(850,500))      
   471         wx.Notebook.__init__(self, parent, id = -1, size=(850,500))
   472         self.Controler = controler
   472         self.Controler = controler
   473         self.parent = parent
   473         self.parent = parent
   474         
   474 
   475         self.CreateNoteBook()
   475         self.CreateNoteBook()
   476         
   476 
   477         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
   477         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
   478         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
   478         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
   479         
   479 
   480     def CreateNoteBook(self): 
   480     def CreateNoteBook(self):
   481         """
   481         """
   482         Create each NoteBook page, divided SDO index
   482         Create each NoteBook page, divided SDO index
   483         According to EtherCAT Communication(03/2011), 158p
   483         According to EtherCAT Communication(03/2011), 158p
   484         """   
   484         """
   485         self.Data = []
   485         self.Data = []
   486         count = 1
   486         count = 1
   487         
   487 
   488         page_texts = [("all", self.parent.AllSDOData),
   488         page_texts = [("all", self.parent.AllSDOData),
   489                      ("0x0000 - 0x0ff", self.parent.DatatypeDescription),
   489                      ("0x0000 - 0x0ff", self.parent.DatatypeDescription),
   490                      ("0x1000 - 0x1fff", self.parent.CommunicationObject),
   490                      ("0x1000 - 0x1fff", self.parent.CommunicationObject),
   491                      ("0x2000 - 0x5fff", self.parent.ManufacturerSpecific),
   491                      ("0x2000 - 0x5fff", self.parent.ManufacturerSpecific),
   492                      ("0x6000 - 0x9fff", self.parent.ProfileSpecific),
   492                      ("0x6000 - 0x9fff", self.parent.ProfileSpecific),
   498                                "SDO Index 0x6000 - 0x9fff : Profile specific",
   498                                "SDO Index 0x6000 - 0x9fff : Profile specific",
   499                                "SDO Index 0xa000 - 0xffff : Reserved",
   499                                "SDO Index 0xa000 - 0xffff : Reserved",
   500                                "All SDO Object"]
   500                                "All SDO Object"]
   501 
   501 
   502         self.DeleteAllPages()
   502         self.DeleteAllPages()
   503         
   503 
   504         for txt, count in page_texts:
   504         for txt, count in page_texts:
   505             self.Data = self.Controler.CommonMethod.SaveSDOData[count]
   505             self.Data = self.Controler.CommonMethod.SaveSDOData[count]
   506             self.Win = SlaveSDOTable(self, self.Data) 
   506             self.Win = SlaveSDOTable(self, self.Data)
   507             self.AddPage(self.Win, txt)
   507             self.AddPage(self.Win, txt)
   508         
   508 
   509     def OnPageChanged(self, event):
   509     def OnPageChanged(self, event):
   510         old = event.GetOldSelection()
   510         old = event.GetOldSelection()
   511         new = event.GetSelection()
   511         new = event.GetSelection()
   512         sel = self.GetSelection()
   512         sel = self.GetSelection()
   513         event.Skip()
   513         event.Skip()
   518         sel = self.GetSelection()
   518         sel = self.GetSelection()
   519         event.Skip()
   519         event.Skip()
   520 
   520 
   521 #-------------------------------------------------------------------------------
   521 #-------------------------------------------------------------------------------
   522 #                    For SDO Grid (fill index, subindex, etc...)
   522 #                    For SDO Grid (fill index, subindex, etc...)
   523 #-------------------------------------------------------------------------------  
   523 #-------------------------------------------------------------------------------
   524 class SlaveSDOTable(wx.grid.Grid):  
   524 class SlaveSDOTable(wx.grid.Grid):
   525     def __init__(self, parent, data):
   525     def __init__(self, parent, data):
   526         """
   526         """
   527         Constructor
   527         Constructor
   528         @param parent: Reference to the parent SDOPanelClass class
   528         @param parent: Reference to the parent SDOPanelClass class
   529         @param data: SDO data after parsing "SDOParser" method
   529         @param data: SDO data after parsing "SDOParser" method
   530         """
   530         """
   531         wx.grid.Grid.__init__(self, parent, -1, size=(830,490), 
   531         wx.grid.Grid.__init__(self, parent, -1, size=(830,490),
   532                               style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
   532                               style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
   533         
   533 
   534         self.Controler = parent.Controler
   534         self.Controler = parent.Controler
   535         self.parent = parent
   535         self.parent = parent
   536         self.SDOFlag = True
   536         self.SDOFlag = True
   537         if data is None :
   537         if data is None :
   538             self.SDOs = []
   538             self.SDOs = []
   539         else :
   539         else :
   540             self.SDOs = data
   540             self.SDOs = data
   541         
   541 
   542         self.CreateGrid(len(self.SDOs), 8)
   542         self.CreateGrid(len(self.SDOs), 8)
   543         SDOCellSize = [(0, 65), (1, 65), (2, 50), (3, 55), 
   543         SDOCellSize = [(0, 65), (1, 65), (2, 50), (3, 55),
   544                          (4, 40), (5, 200), (6, 250), (7, 85)]
   544                          (4, 40), (5, 200), (6, 250), (7, 85)]
   545         
   545 
   546         for (index, size) in SDOCellSize:
   546         for (index, size) in SDOCellSize:
   547             self.SetColSize(index, size)
   547             self.SetColSize(index, size)
   548         
   548 
   549         self.SetRowLabelSize(0)
   549         self.SetRowLabelSize(0)
   550         
   550 
   551         SDOTableLabel = [(0, "Index"), (1, "Subindex"), (2, "Access"),
   551         SDOTableLabel = [(0, "Index"), (1, "Subindex"), (2, "Access"),
   552                          (3, "Type"), (4, "Size"), (5, "Category"),
   552                          (3, "Type"), (4, "Size"), (5, "Category"),
   553                          (6, "Name"), (7, "Value")]
   553                          (6, "Name"), (7, "Value")]
   554         
   554 
   555         for (index, label) in SDOTableLabel:
   555         for (index, label) in SDOTableLabel:
   556             self.SetColLabelValue(index, label)
   556             self.SetColLabelValue(index, label)
   557             self.SetColLabelAlignment(index, wx.ALIGN_CENTRE)
   557             self.SetColLabelAlignment(index, wx.ALIGN_CENTRE)
   558             
   558 
   559         attr = wx.grid.GridCellAttr()
   559         attr = wx.grid.GridCellAttr()
   560 
   560 
   561         # for SDO download 
   561         # for SDO download
   562         self.Bind(gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.SDOModifyDialog)
   562         self.Bind(gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.SDOModifyDialog)
   563         
   563 
   564         for i in range(7): 
   564         for i in range(7):
   565             self.SetColAttr(i,attr)                   
   565             self.SetColAttr(i,attr)
   566         
   566 
   567         self.SetColLabelAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
   567         self.SetColLabelAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
   568             
   568 
   569         self.SetTableValue()  
   569         self.SetTableValue()
   570              
   570 
   571     def SetTableValue(self):
   571     def SetTableValue(self):
   572         """
   572         """
   573         Cell is filled by new parsing data
   573         Cell is filled by new parsing data
   574         """
   574         """
   575         sdo_list = ['idx', 'subIdx', 'access', 'type', 'size', 'category', 'name', 'value']
   575         sdo_list = ['idx', 'subIdx', 'access', 'type', 'size', 'category', 'name', 'value']
   576         for row_idx in range(len(self.SDOs)):
   576         for row_idx in range(len(self.SDOs)):
   577             for col_idx in range(len(self.SDOs[row_idx])):          
   577             for col_idx in range(len(self.SDOs[row_idx])):
   578                 self.SetCellValue(row_idx, col_idx, self.SDOs[row_idx][sdo_list[col_idx]])
   578                 self.SetCellValue(row_idx, col_idx, self.SDOs[row_idx][sdo_list[col_idx]])
   579                 self.SetReadOnly(row_idx, col_idx, True)
   579                 self.SetReadOnly(row_idx, col_idx, True)
   580                 if col_idx < 5 :
   580                 if col_idx < 5 :
   581                     self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
   581                     self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
   582         
   582 
   583     def CheckSDODataAccess(self, row):
   583     def CheckSDODataAccess(self, row):
   584         """
   584         """
   585         CheckSDODataAccess method is checking that access data has "w"
   585         CheckSDODataAccess method is checking that access data has "w"
   586         Access field consist 6 char, if mean
   586         Access field consist 6 char, if mean
   587            rw      rw     rw
   587            rw      rw     rw
   588         (preop) (safeop) (op) 
   588         (preop) (safeop) (op)
   589         Example Access field : rwrwrw, rwrw-- 
   589         Example Access field : rwrwrw, rwrw--
   590         @param row : Selected cell by user
   590         @param row : Selected cell by user
   591         @return Write_flag : If data has "w", flag is true
   591         @return Write_flag : If data has "w", flag is true
   592         """
   592         """
   593         write_flag = False
   593         write_flag = False
   594         check = self.SDOs[row]['access']
   594         check = self.SDOs[row]['access']
   595         if check[1:2] == 'w' :
   595         if check[1:2] == 'w' :
   596             self.Controler.CommonMethod.Check_PREOP = True
   596             self.Controler.CommonMethod.Check_PREOP = True
   597             write_flag = True
   597             write_flag = True
   598         if check[3:4] == 'w' : 
   598         if check[3:4] == 'w' :
   599             self.Controler.CommonMethod.Check_SAFEOP = True
   599             self.Controler.CommonMethod.Check_SAFEOP = True
   600             write_flag = True
   600             write_flag = True
   601         if check[5:] =='w' :
   601         if check[5:] =='w' :
   602             self.Controler.CommonMethod.Check_OP = True
   602             self.Controler.CommonMethod.Check_OP = True
   603             write_flag = True
   603             write_flag = True
   604             
   604 
   605         return write_flag
   605         return write_flag
   606     
   606 
   607     def DecideSDODownload(self, state):
   607     def DecideSDODownload(self, state):
   608         """
   608         """
   609         compare current state and "access" field, 
   609         compare current state and "access" field,
   610         result notify SDOModifyDialog method
   610         result notify SDOModifyDialog method
   611         @param state : current slave state
   611         @param state : current slave state
   612         @return True or False
   612         @return True or False
   613         """
   613         """
   614         # Example of 'state' parameter : "0  0:0  PREOP  +  EL9800 (V4.30) (PIC24, SPI, ET1100)" 
   614         # Example of 'state' parameter : "0  0:0  PREOP  +  EL9800 (V4.30) (PIC24, SPI, ET1100)"
   615         state = state[self.Controler.GetSlavePos()].split("  ")[2]
   615         state = state[self.Controler.GetSlavePos()].split("  ")[2]
   616         if state == "PREOP" and self.Controler.CommonMethod.Check_PREOP :
   616         if state == "PREOP" and self.Controler.CommonMethod.Check_PREOP :
   617             return True
   617             return True
   618         elif state == "SAFEOP" and self.Controler.CommonMethod.Check_SAFEOP :
   618         elif state == "SAFEOP" and self.Controler.CommonMethod.Check_SAFEOP :
   619             return True
   619             return True
   620         elif state == "OP" and self.Controler.CommonMethod.Check_OP :
   620         elif state == "OP" and self.Controler.CommonMethod.Check_OP :
   621             return True
   621             return True
   622         
   622 
   623         return False
   623         return False
   624     
   624 
   625     def ClearStateFlag(self):
   625     def ClearStateFlag(self):
   626         """
   626         """
   627         Initialize StateFlag
   627         Initialize StateFlag
   628         StateFlag is notice SDOData access each slave state
   628         StateFlag is notice SDOData access each slave state
   629         """
   629         """
   630         self.Controler.CommonMethod.Check_PREOP = False
   630         self.Controler.CommonMethod.Check_PREOP = False
   631         self.Controler.CommonMethod.Check_SAFEOP = False
   631         self.Controler.CommonMethod.Check_SAFEOP = False
   632         self.Controler.CommonMethod.Check_OP = False
   632         self.Controler.CommonMethod.Check_OP = False
   633     
   633 
   634     def SDOModifyDialog (self, event):
   634     def SDOModifyDialog (self, event):
   635         """
   635         """
   636         Create dialog for SDO value modify
   636         Create dialog for SDO value modify
   637         if user enter data, perform command "ethercat download"  
   637         if user enter data, perform command "ethercat download"
   638         @param event : gridlib.EVT_GRID_CELL_LEFT_DCLICK object
   638         @param event : gridlib.EVT_GRID_CELL_LEFT_DCLICK object
   639         """
   639         """
   640         self.ClearStateFlag()
   640         self.ClearStateFlag()
   641         
   641 
   642         # CheckSDODataAccess is checking that OD(Object Dictionary) has "w" 
   642         # CheckSDODataAccess is checking that OD(Object Dictionary) has "w"
   643         if event.GetCol() == 7 and self.CheckSDODataAccess(event.GetRow()) :    
   643         if event.GetCol() == 7 and self.CheckSDODataAccess(event.GetRow()) :
   644             dlg = wx.TextEntryDialog (self, "Enter hex or dec value (if enter dec value, it automatically conversed hex value)",
   644             dlg = wx.TextEntryDialog (self, "Enter hex or dec value (if enter dec value, it automatically conversed hex value)",
   645                                       "SDOModifyDialog", style = wx.OK | wx.CANCEL)
   645                                       "SDOModifyDialog", style = wx.OK | wx.CANCEL)
   646 
   646 
   647             start_value = self.GetCellValue(event.GetRow(), event.GetCol()) 
   647             start_value = self.GetCellValue(event.GetRow(), event.GetCol())
   648             dlg.SetValue(start_value)
   648             dlg.SetValue(start_value)
   649             
   649 
   650             if dlg.ShowModal() == wx.ID_OK:
   650             if dlg.ShowModal() == wx.ID_OK:
   651                 try :
   651                 try :
   652                     int(dlg.GetValue(), 0)
   652                     int(dlg.GetValue(), 0)
   653                     # check "Access" field
   653                     # check "Access" field
   654                     if self.DecideSDODownload(self.Controler.CommonMethod.SlaveState[self.Controler.GetSlavePos()]) :
   654                     if self.DecideSDODownload(self.Controler.CommonMethod.SlaveState[self.Controler.GetSlavePos()]) :
   655                         # Request "SDODownload"
   655                         # Request "SDODownload"
   656                         self.Controler.CommonMethod.SDODownload(self.SDOs[event.GetRow()]['type'], self.SDOs[event.GetRow()]['idx'], 
   656                         self.Controler.CommonMethod.SDODownload(self.SDOs[event.GetRow()]['type'], self.SDOs[event.GetRow()]['idx'],
   657                                                    self.SDOs[event.GetRow()]['subIdx'], dlg.GetValue())
   657                                                    self.SDOs[event.GetRow()]['subIdx'], dlg.GetValue())
   658                         self.SetCellValue(event.GetRow(), event.GetCol(), hex(int(dlg.GetValue(), 0)))
   658                         self.SetCellValue(event.GetRow(), event.GetCol(), hex(int(dlg.GetValue(), 0)))
   659                     else :
   659                     else :
   660                         self.Controler.CommonMethod.CreateErrorDialog('You cannot SDO download this state')                  
   660                         self.Controler.CommonMethod.CreateErrorDialog('You cannot SDO download this state')
   661                 # Error occured process of "int(variable)"
   661                 # Error occured process of "int(variable)"
   662                 # User input is not hex, dec value
   662                 # User input is not hex, dec value
   663                 except ValueError:
   663                 except ValueError:
   664                     self.Controler.CommonMethod.CreateErrorDialog('You can input only hex, dec value')    
   664                     self.Controler.CommonMethod.CreateErrorDialog('You can input only hex, dec value')
   665 
   665 
   666 
   666 
   667 #-------------------------------------------------------------------------------
   667 #-------------------------------------------------------------------------------
   668 #                 For PDO Monitoring Panel
   668 #                 For PDO Monitoring Panel
   669 # PDO Class UI  : Panel -> Choicebook (RxPDO, TxPDO) -> 
   669 # PDO Class UI  : Panel -> Choicebook (RxPDO, TxPDO) ->
   670 #                 Notebook (PDO Index) -> Grid (PDO entry)
   670 #                 Notebook (PDO Index) -> Grid (PDO entry)
   671 #-------------------------------------------------------------------------------  
   671 #-------------------------------------------------------------------------------
   672 class PDOPanelClass(wx.Panel):
   672 class PDOPanelClass(wx.Panel):
   673     def __init__(self, parent, controler):
   673     def __init__(self, parent, controler):
   674         """
   674         """
   675         Constructor
   675         Constructor
   676         @param parent: Reference to the parent EtherCATManagementTreebook class
   676         @param parent: Reference to the parent EtherCATManagementTreebook class
   679         wx.Panel.__init__(self, parent, -1)
   679         wx.Panel.__init__(self, parent, -1)
   680         self.Controler = controler
   680         self.Controler = controler
   681 
   681 
   682         self.PDOMonitoringEditorMainSizer = wx.BoxSizer(wx.VERTICAL)
   682         self.PDOMonitoringEditorMainSizer = wx.BoxSizer(wx.VERTICAL)
   683         self.PDOMonitoringEditorInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10)
   683         self.PDOMonitoringEditorInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10)
   684         
   684 
   685         self.CallPDOChoicebook = PDOChoicebook(self, controler=self.Controler)   
   685         self.CallPDOChoicebook = PDOChoicebook(self, controler=self.Controler)
   686         self.PDOMonitoringEditorInnerMainSizer.Add(self.CallPDOChoicebook, wx.ALL)    
   686         self.PDOMonitoringEditorInnerMainSizer.Add(self.CallPDOChoicebook, wx.ALL)
   687         
   687 
   688         self.PDOMonitoringEditorMainSizer.Add(self.PDOMonitoringEditorInnerMainSizer)
   688         self.PDOMonitoringEditorMainSizer.Add(self.PDOMonitoringEditorInnerMainSizer)
   689         
   689 
   690         self.SetSizer(self.PDOMonitoringEditorMainSizer)
   690         self.SetSizer(self.PDOMonitoringEditorMainSizer)
   691 
   691 
   692     def PDOInfoUpdate(self):
   692     def PDOInfoUpdate(self):
   693         """
   693         """
   694         Call RequestPDOInfo method and create Choicebook
   694         Call RequestPDOInfo method and create Choicebook
   699         self.Refresh()
   699         self.Refresh()
   700 
   700 
   701 
   701 
   702 #-------------------------------------------------------------------------------
   702 #-------------------------------------------------------------------------------
   703 #                    For PDO Choicebook (divide Tx, Rx PDO)
   703 #                    For PDO Choicebook (divide Tx, Rx PDO)
   704 #-------------------------------------------------------------------------------  
   704 #-------------------------------------------------------------------------------
   705 class PDOChoicebook(wx.Choicebook):
   705 class PDOChoicebook(wx.Choicebook):
   706     def __init__(self, parent, controler):
   706     def __init__(self, parent, controler):
   707         """
   707         """
   708         Constructor
   708         Constructor
   709         @param parent: Reference to the parent PDOPanelClass class
   709         @param parent: Reference to the parent PDOPanelClass class
   710         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   710         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   711         """
   711         """
   712         wx.Choicebook.__init__(self, parent, id=-1, size=(500, 500), style=wx.CHB_DEFAULT)
   712         wx.Choicebook.__init__(self, parent, id=-1, size=(500, 500), style=wx.CHB_DEFAULT)
   713         self.Controler = controler
   713         self.Controler = controler
   714         
   714 
   715         RxWin = PDONoteBook(self, controler=self.Controler, name="Rx")
   715         RxWin = PDONoteBook(self, controler=self.Controler, name="Rx")
   716         TxWin = PDONoteBook(self, controler=self.Controler, name="Tx")
   716         TxWin = PDONoteBook(self, controler=self.Controler, name="Tx")
   717         self.AddPage(RxWin, "RxPDO")
   717         self.AddPage(RxWin, "RxPDO")
   718         self.AddPage(TxWin, "TxPDO")
   718         self.AddPage(TxWin, "TxPDO")
   719         
   719 
   720         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
   720         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
   721         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
   721         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
   722         
   722 
   723     def OnPageChanged(self, event):
   723     def OnPageChanged(self, event):
   724         old = event.GetOldSelection()
   724         old = event.GetOldSelection()
   725         new = event.GetSelection()
   725         new = event.GetSelection()
   726         sel = self.GetSelection()
   726         sel = self.GetSelection()
   727         event.Skip()
   727         event.Skip()
   728 
   728 
   729     def OnPageChanging(self, event):
   729     def OnPageChanging(self, event):
   730         old = event.GetOldSelection()
   730         old = event.GetOldSelection()
   731         new = event.GetSelection()
   731         new = event.GetSelection()
   732         sel = self.GetSelection()
   732         sel = self.GetSelection()
   733         event.Skip()     
   733         event.Skip()
   734 
   734 
   735 
   735 
   736 #-------------------------------------------------------------------------------
   736 #-------------------------------------------------------------------------------
   737 #                    For PDO Notebook (divide PDO index)
   737 #                    For PDO Notebook (divide PDO index)
   738 #-------------------------------------------------------------------------------  
   738 #-------------------------------------------------------------------------------
   739 class PDONoteBook(wx.Notebook):
   739 class PDONoteBook(wx.Notebook):
   740     def __init__(self, parent, name, controler):
   740     def __init__(self, parent, name, controler):
   741         """
   741         """
   742         Constructor
   742         Constructor
   743         @param parent: Reference to the parent PDOChoicebook class
   743         @param parent: Reference to the parent PDOChoicebook class
   744         @param name: identifier whether RxPDO or TxPDO
   744         @param name: identifier whether RxPDO or TxPDO
   745         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   745         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   746         """
   746         """
   747         wx.Notebook.__init__(self, parent, id=-1, size=(640, 400))
   747         wx.Notebook.__init__(self, parent, id=-1, size=(640, 400))
   748         self.Controler = controler
   748         self.Controler = controler
   749         
   749 
   750         count = 0
   750         count = 0
   751         page_texts = []
   751         page_texts = []
   752         
   752 
   753         self.Controler.CommonMethod.RequestPDOInfo()
   753         self.Controler.CommonMethod.RequestPDOInfo()
   754         
   754 
   755         if name == "Tx" :
   755         if name == "Tx" :
   756             # obtain pdo_info and pdo_entry
   756             # obtain pdo_info and pdo_entry
   757             # pdo_info include (PDO index, name, number of entry)
   757             # pdo_info include (PDO index, name, number of entry)
   758             pdo_info =  self.Controler.CommonMethod.GetTxPDOCategory()
   758             pdo_info =  self.Controler.CommonMethod.GetTxPDOCategory()
   759             pdo_entry = self.Controler.CommonMethod.GetTxPDOInfo()
   759             pdo_entry = self.Controler.CommonMethod.GetTxPDOInfo()
   760             for tmp in pdo_info :
   760             for tmp in pdo_info :
   761                 title = str(hex(tmp['pdo_index']))
   761                 title = str(hex(tmp['pdo_index']))
   762                 page_texts.append(title)
   762                 page_texts.append(title)
   763         # RX PDO case
   763         # RX PDO case
   764         else :  
   764         else :
   765             pdo_info = self.Controler.CommonMethod.GetRxPDOCategory()
   765             pdo_info = self.Controler.CommonMethod.GetRxPDOCategory()
   766             pdo_entry = self.Controler.CommonMethod.GetRxPDOInfo()
   766             pdo_entry = self.Controler.CommonMethod.GetRxPDOInfo()
   767             for tmp in pdo_info :
   767             for tmp in pdo_info :
   768                 title = str(hex(tmp['pdo_index']))
   768                 title = str(hex(tmp['pdo_index']))
   769                 page_texts.append(title)
   769                 page_texts.append(title)
   770                
   770 
   771         # Add page depending on the number of pdo_info
   771         # Add page depending on the number of pdo_info
   772         for txt in page_texts:
   772         for txt in page_texts:
   773             win = PDOEntryTable(self, pdo_info, pdo_entry, count)
   773             win = PDOEntryTable(self, pdo_info, pdo_entry, count)
   774             self.AddPage(win, txt)
   774             self.AddPage(win, txt)
   775             count += 1  
   775             count += 1
   776 
   776 
   777         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
   777         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged)
   778         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
   778         self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging)
   779         
   779 
   780     def OnPageChanged(self, event):
   780     def OnPageChanged(self, event):
   781         old = event.GetOldSelection()
   781         old = event.GetOldSelection()
   782         new = event.GetSelection()
   782         new = event.GetSelection()
   783         sel = self.GetSelection()
   783         sel = self.GetSelection()
   784         event.Skip()
   784         event.Skip()
   785 
   785 
   786     def OnPageChanging(self, event):
   786     def OnPageChanging(self, event):
   787         old = event.GetOldSelection()
   787         old = event.GetOldSelection()
   788         new = event.GetSelection()
   788         new = event.GetSelection()
   789         sel = self.GetSelection()
   789         sel = self.GetSelection()
   790         event.Skip()     
   790         event.Skip()
   791 
   791 
   792 
   792 
   793 #-------------------------------------------------------------------------------
   793 #-------------------------------------------------------------------------------
   794 #                    For PDO Grid (fill entry index, subindex etc...)
   794 #                    For PDO Grid (fill entry index, subindex etc...)
   795 #-------------------------------------------------------------------------------  
   795 #-------------------------------------------------------------------------------
   796 class PDOEntryTable(wx.grid.Grid):
   796 class PDOEntryTable(wx.grid.Grid):
   797     def __init__(self, parent, info, entry, count):
   797     def __init__(self, parent, info, entry, count):
   798         """
   798         """
   799         Constructor
   799         Constructor
   800         @param parent: Reference to the parent PDONoteBook class
   800         @param parent: Reference to the parent PDONoteBook class
   801         @param info : data structure including entry index, sub index, name, length, type
   801         @param info : data structure including entry index, sub index, name, length, type
   802         @param entry : data structure including index, name, entry number
   802         @param entry : data structure including index, name, entry number
   803         @param count : page number
   803         @param count : page number
   804         """
   804         """
   805         wx.grid.Grid.__init__(self, parent, -1, size=(500, 400), pos=wx.Point(0,0), 
   805         wx.grid.Grid.__init__(self, parent, -1, size=(500, 400), pos=wx.Point(0,0),
   806                               style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
   806                               style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
   807         
   807 
   808         self.Controler = parent.Controler
   808         self.Controler = parent.Controler
   809         
   809 
   810         self.PDOInfo = info
   810         self.PDOInfo = info
   811         self.PDOEntry = entry
   811         self.PDOEntry = entry
   812         self.Count = count
   812         self.Count = count
   813         
   813 
   814         self.CreateGrid(self.PDOInfo[self.Count]['number_of_entry'], 5)
   814         self.CreateGrid(self.PDOInfo[self.Count]['number_of_entry'], 5)
   815         self.SetColLabelSize(25)   
   815         self.SetColLabelSize(25)
   816         self.SetRowLabelSize(0)
   816         self.SetRowLabelSize(0)
   817         
   817 
   818         PDOTableLabel = [(0, "Index"), (1, "Subindex"), (2, "Length"),
   818         PDOTableLabel = [(0, "Index"), (1, "Subindex"), (2, "Length"),
   819                          (3, "Type"), (4, "Name")]
   819                          (3, "Type"), (4, "Name")]
   820         
   820 
   821         for (index, label) in PDOTableLabel:
   821         for (index, label) in PDOTableLabel:
   822             self.SetColLabelValue(index, label)
   822             self.SetColLabelValue(index, label)
   823         
   823 
   824         PDOCellSize = [(0, 45), (1, 65), (2, 55), (3, 40), (4, 300)]
   824         PDOCellSize = [(0, 45), (1, 65), (2, 55), (3, 40), (4, 300)]
   825         
   825 
   826         for (index, size) in PDOCellSize:
   826         for (index, size) in PDOCellSize:
   827             self.SetColSize(index, size)
   827             self.SetColSize(index, size)
   828             self.SetColLabelAlignment(index, wx.ALIGN_LEFT)
   828             self.SetColLabelAlignment(index, wx.ALIGN_LEFT)
   829         
   829 
   830         attr = wx.grid.GridCellAttr()
   830         attr = wx.grid.GridCellAttr()
   831         
   831 
   832         for i in range(5):
   832         for i in range(5):
   833             self.SetColAttr(i, attr)
   833             self.SetColAttr(i, attr)
   834          
   834 
   835         self.SetTableValue()
   835         self.SetTableValue()
   836             
   836 
   837     def SetTableValue(self):
   837     def SetTableValue(self):
   838         """
   838         """
   839         Cell is filled by new parsing data in XML
   839         Cell is filled by new parsing data in XML
   840         """
   840         """
   841         list_index = 0
   841         list_index = 0
   842         # number of entry
   842         # number of entry
   843         for i in range(self.Count + 1) :
   843         for i in range(self.Count + 1) :
   844             list_index += self.PDOInfo[i]['number_of_entry']
   844             list_index += self.PDOInfo[i]['number_of_entry']
   845 
   845 
   846         start_value = list_index - self.PDOInfo[self.Count]['number_of_entry']
   846         start_value = list_index - self.PDOInfo[self.Count]['number_of_entry']
   847         
   847 
   848         pdo_list = ['entry_index', 'subindex', 'bitlen', 'type', 'name']
   848         pdo_list = ['entry_index', 'subindex', 'bitlen', 'type', 'name']
   849         for row_idx in range(self.PDOInfo[self.Count]['number_of_entry']):
   849         for row_idx in range(self.PDOInfo[self.Count]['number_of_entry']):
   850             for col_idx in range(len(self.PDOEntry[row_idx])):
   850             for col_idx in range(len(self.PDOEntry[row_idx])):
   851                 # entry index is converted hex value.
   851                 # entry index is converted hex value.
   852                 if col_idx == 0 :
   852                 if col_idx == 0 :
   861                 self.SetRowSize(row_idx, 25)
   861                 self.SetRowSize(row_idx, 25)
   862             start_value += 1
   862             start_value += 1
   863 
   863 
   864 
   864 
   865 #-------------------------------------------------------------------------------
   865 #-------------------------------------------------------------------------------
   866 #                    For EEPROM Access Main Panel 
   866 #                    For EEPROM Access Main Panel
   867 #                 (This class explain EEPROM Access)
   867 #                 (This class explain EEPROM Access)
   868 #-------------------------------------------------------------------------------  
   868 #-------------------------------------------------------------------------------
   869 class EEPROMAccessPanel(wx.Panel):
   869 class EEPROMAccessPanel(wx.Panel):
   870     def __init__(self, parent, controler):
   870     def __init__(self, parent, controler):
   871         """
   871         """
   872         Constructor
   872         Constructor
   873         @param parent: Reference to the parent EtherCATManagementTreebook class
   873         @param parent: Reference to the parent EtherCATManagementTreebook class
   874         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   874         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   875         """
   875         """
   876         wx.Panel.__init__(self, parent, -1)
   876         wx.Panel.__init__(self, parent, -1)
   877         sizer = wx.FlexGridSizer(cols=1, hgap=20,rows=3, vgap=20)
   877         sizer = wx.FlexGridSizer(cols=1, hgap=20,rows=3, vgap=20)
   878         
   878 
   879         line = wx.StaticText(self, -1, "\n  EEPROM Access is composed to SmartView and HexView. \
   879         line = wx.StaticText(self, -1, "\n  EEPROM Access is composed to SmartView and HexView. \
   880                                               \n\n   - SmartView shows Config Data, Device Identity, Mailbox settings, etc. \
   880                                               \n\n   - SmartView shows Config Data, Device Identity, Mailbox settings, etc. \
   881                                               \n\n   - HexView shows EEPROM's contents.")
   881                                               \n\n   - HexView shows EEPROM's contents.")
   882         
   882 
   883         sizer.Add(line)
   883         sizer.Add(line)
   884         
   884 
   885         self.SetSizer(sizer)
   885         self.SetSizer(sizer)
   886 
   886 
   887 
   887 
   888 #-------------------------------------------------------------------------------
   888 #-------------------------------------------------------------------------------
   889 #                    For Smart View Panel 
   889 #                    For Smart View Panel
   890 #-------------------------------------------------------------------------------  
   890 #-------------------------------------------------------------------------------
   891 class SlaveSiiSmartView(wx.Panel):
   891 class SlaveSiiSmartView(wx.Panel):
   892     def __init__(self, parent, controler):
   892     def __init__(self, parent, controler):
   893         """
   893         """
   894         Constructor
   894         Constructor
   895         @param parent: Reference to the parent EtherCATManagementTreebook class
   895         @param parent: Reference to the parent EtherCATManagementTreebook class
   896         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   896         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
   897         """
   897         """
   898         wx.Panel.__init__(self, parent, -1)
   898         wx.Panel.__init__(self, parent, -1)
   899         self.parent = parent
   899         self.parent = parent
   900         self.Controler = controler
   900         self.Controler = controler
   901         
   901 
   902         self.PDIType = {0  :['none', '00000000'], 
   902         self.PDIType = {0  :['none', '00000000'],
   903                         4  :['Digital I/O', '00000100'],
   903                         4  :['Digital I/O', '00000100'],
   904                         5  :['SPI Slave', '00000101'],
   904                         5  :['SPI Slave', '00000101'],
   905                         7  :['EtherCAT Bridge (port3)', '00000111'],
   905                         7  :['EtherCAT Bridge (port3)', '00000111'],
   906                         8  :['uC async. 16bit', '00001000'],
   906                         8  :['uC async. 16bit', '00001000'],
   907                         9  :['uC async. 8bit', '00001001'],
   907                         9  :['uC async. 8bit', '00001001'],
   912                         18 :['16 Digtal Input and 16 Digital Output','00010010'],
   912                         18 :['16 Digtal Input and 16 Digital Output','00010010'],
   913                         19 :['8 Digtal Input and 24 Digital Output', '00010011'],
   913                         19 :['8 Digtal Input and 24 Digital Output', '00010011'],
   914                         20 :['0 Digtal Input and 32 Digital Output', '00010100'],
   914                         20 :['0 Digtal Input and 32 Digital Output', '00010100'],
   915                         128:['On-chip bus', '11111111']
   915                         128:['On-chip bus', '11111111']
   916                         }
   916                         }
   917         
   917 
   918         sizer = wx.FlexGridSizer(cols=1, hgap=5, rows=2, vgap=5)
   918         sizer = wx.FlexGridSizer(cols=1, hgap=5, rows=2, vgap=5)
   919         button_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=5)
   919         button_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=5)
   920 
   920 
   921         for button, mapping_method in [("Write EEPROM", self.WriteToEEPROM),
   921         for button, mapping_method in [("Write EEPROM", self.WriteToEEPROM),
   922                                        ("Read EEPROM", self.ReadFromEEPROM)]:
   922                                        ("Read EEPROM", self.ReadFromEEPROM)]:
   923             btn = wx.Button(self, -1, button, size=(150, 40))
   923             btn = wx.Button(self, -1, button, size=(150, 40))
   924             button_sizer.Add(btn, border=10, flag=wx.ALL)
   924             button_sizer.Add(btn, border=10, flag=wx.ALL)
   925             btn.Bind(wx.EVT_BUTTON, mapping_method)
   925             btn.Bind(wx.EVT_BUTTON, mapping_method)
   926         
   926 
   927         self.TreeListCtrl = SmartViewTreeListCtrl(self, self.Controler)
   927         self.TreeListCtrl = SmartViewTreeListCtrl(self, self.Controler)
   928         
   928 
   929         sizer.Add(button_sizer, border=10, flag=wx.ALL)
   929         sizer.Add(button_sizer, border=10, flag=wx.ALL)
   930         sizer.Add(self.TreeListCtrl, border=10, flag=wx.ALL)
   930         sizer.Add(self.TreeListCtrl, border=10, flag=wx.ALL)
   931         self.SetSizer(sizer)
   931         self.SetSizer(sizer)
   932         
   932 
   933         self.Create_SmartView()
   933         self.Create_SmartView()
   934         
   934 
   935     def Create_SmartView(self):
   935     def Create_SmartView(self):
   936         """
   936         """
   937         SmartView shows information based on XML as initial value.
   937         SmartView shows information based on XML as initial value.
   938         """  
   938         """
   939         self.Controler.CommonMethod.SmartViewInfosFromXML = self.Controler.CommonMethod.GetSmartViewInfos()
   939         self.Controler.CommonMethod.SmartViewInfosFromXML = self.Controler.CommonMethod.GetSmartViewInfos()
   940         self.SetXMLData()
   940         self.SetXMLData()
   941                 
   941 
   942     def WriteToEEPROM(self, event):
   942     def WriteToEEPROM(self, event):
   943         """
   943         """
   944         Open binary file (user select) and write the selected binary data to EEPROM
   944         Open binary file (user select) and write the selected binary data to EEPROM
   945         @param event : wx.EVT_BUTTON object
   945         @param event : wx.EVT_BUTTON object
   946         """  
   946         """
   947         # Check whether beremiz connected or not, and whether status is "Started" or not.
   947         # Check whether beremiz connected or not, and whether status is "Started" or not.
   948         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
   948         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
   949         if check_connect_flag:
   949         if check_connect_flag:
   950             status, count = self.Controler.GetCTRoot()._connector.GetPLCstatus()
   950             status, count = self.Controler.GetCTRoot()._connector.GetPLCstatus()
   951             if status is not "Started":
   951             if status is not "Started":
   952                 dialog = wx.FileDialog(self, _("Choose a binary file"), os.getcwd(), "",  _("bin files (*.bin)|*.bin"), wx.OPEN)
   952                 dialog = wx.FileDialog(self, _("Choose a binary file"), os.getcwd(), "",  _("bin files (*.bin)|*.bin"), wx.OPEN)
   953                 
   953 
   954                 if dialog.ShowModal() == wx.ID_OK:
   954                 if dialog.ShowModal() == wx.ID_OK:
   955                     filepath = dialog.GetPath()
   955                     filepath = dialog.GetPath()
   956                     try:
   956                     try:
   957                         binfile = open(filepath,"rb")
   957                         binfile = open(filepath,"rb")
   958                         self.SiiBinary = binfile.read()
   958                         self.SiiBinary = binfile.read()
   959                         dialog.Destroy()
   959                         dialog.Destroy()
   960                         
   960 
   961                         self.Controler.CommonMethod.SiiWrite(self.SiiBinary)
   961                         self.Controler.CommonMethod.SiiWrite(self.SiiBinary)
   962                         # refresh data structure kept by master
   962                         # refresh data structure kept by master
   963                         self.Controler.CommonMethod.Rescan()
   963                         self.Controler.CommonMethod.Rescan()
   964                         # save binary data as inner global data of beremiz 
   964                         # save binary data as inner global data of beremiz
   965                         # for fast loading when slave plugin node is reopened.
   965                         # for fast loading when slave plugin node is reopened.
   966                         self.Controler.CommonMethod.SiiData = self.SiiBinary
   966                         self.Controler.CommonMethod.SiiData = self.SiiBinary
   967                         self.SetEEPROMData()
   967                         self.SetEEPROMData()
   968                     except Exception:
   968                     except Exception:
   969                         self.Controler.CommonMethod.CreateErrorDialog('The file does not exist!')
   969                         self.Controler.CommonMethod.CreateErrorDialog('The file does not exist!')
   970                         dialog.Destroy()
   970                         dialog.Destroy()
   971     
   971 
   972     def ReadFromEEPROM(self, event):
   972     def ReadFromEEPROM(self, event):
   973         """
   973         """
   974         Refresh displayed data based on slave EEPROM and save binary file through dialog
   974         Refresh displayed data based on slave EEPROM and save binary file through dialog
   975         @param event : wx.EVT_BUTTON object
   975         @param event : wx.EVT_BUTTON object
   976         """  
   976         """
   977         # Check whether beremiz connected or not.
   977         # Check whether beremiz connected or not.
   978         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
   978         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
   979         if check_connect_flag:
   979         if check_connect_flag:
   980             self.SiiBinary = self.Controler.CommonMethod.LoadData()
   980             self.SiiBinary = self.Controler.CommonMethod.LoadData()
   981             self.SetEEPROMData()
   981             self.SetEEPROMData()
   982             dialog = wx.FileDialog(self, _("Save as..."), os.getcwd(), 
   982             dialog = wx.FileDialog(self, _("Save as..."), os.getcwd(),
   983                                    "slave0.bin",  _("bin files (*.bin)|*.bin|All files|*.*"), 
   983                                    "slave0.bin",  _("bin files (*.bin)|*.bin|All files|*.*"),
   984                                    wx.SAVE|wx.OVERWRITE_PROMPT)
   984                                    wx.SAVE|wx.OVERWRITE_PROMPT)
   985         
   985 
   986             if dialog.ShowModal() == wx.ID_OK:
   986             if dialog.ShowModal() == wx.ID_OK:
   987                 filepath = dialog.GetPath()
   987                 filepath = dialog.GetPath()
   988                 binfile = open(filepath,"wb")
   988                 binfile = open(filepath,"wb")
   989                 binfile.write(self.SiiBinary)
   989                 binfile.write(self.SiiBinary)
   990                 binfile.close()
   990                 binfile.close()
   991     
   991 
   992             dialog.Destroy()
   992             dialog.Destroy()
   993     
   993 
   994     def SetXMLData(self):
   994     def SetXMLData(self):
   995         """
   995         """
   996         Set data based on XML initially
   996         Set data based on XML initially
   997         """  
   997         """
   998         # Config Data: EEPROM Size, PDI Type, Device Emulation
   998         # Config Data: EEPROM Size, PDI Type, Device Emulation
   999         # Find PDI Type in pdiType dictionary
   999         # Find PDI Type in pdiType dictionary
  1000         cnt_pdi_type = self.Controler.CommonMethod.SmartViewInfosFromXML["pdi_type"]
  1000         cnt_pdi_type = self.Controler.CommonMethod.SmartViewInfosFromXML["pdi_type"]
  1001         for i in self.PDIType.keys():
  1001         for i in self.PDIType.keys():
  1002             if cnt_pdi_type == i:
  1002             if cnt_pdi_type == i:
  1003                 cnt_pdi_type = self.PDIType[i][0]
  1003                 cnt_pdi_type = self.PDIType[i][0]
  1004                 break
  1004                 break
  1005         #  Set Config Data
  1005         #  Set Config Data
  1006         for treelist, data in [("EEPROM Size (Bytes)", 
  1006         for treelist, data in [("EEPROM Size (Bytes)",
  1007                                 str(self.Controler.CommonMethod.SmartViewInfosFromXML["eeprom_size"])),
  1007                                 str(self.Controler.CommonMethod.SmartViewInfosFromXML["eeprom_size"])),
  1008                                ("PDI Type", 
  1008                                ("PDI Type",
  1009                                 cnt_pdi_type),
  1009                                 cnt_pdi_type),
  1010                                ("Device Emulation", 
  1010                                ("Device Emulation",
  1011                                 self.Controler.CommonMethod.SmartViewInfosFromXML["device_emulation"])]:
  1011                                 self.Controler.CommonMethod.SmartViewInfosFromXML["device_emulation"])]:
  1012             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.ConfigData[treelist], data, 1)
  1012             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.ConfigData[treelist], data, 1)
  1013         
  1013 
  1014         # Device Identity: Vendor ID, Product Code, Revision No., Serial No.
  1014         # Device Identity: Vendor ID, Product Code, Revision No., Serial No.
  1015         #  Set Device Identity
  1015         #  Set Device Identity
  1016         for treelist, data in [("Vendor ID", self.Controler.CommonMethod.SmartViewInfosFromXML["vendor_id"]),
  1016         for treelist, data in [("Vendor ID", self.Controler.CommonMethod.SmartViewInfosFromXML["vendor_id"]),
  1017                                ("Product Code", self.Controler.CommonMethod.SmartViewInfosFromXML["product_code"]),
  1017                                ("Product Code", self.Controler.CommonMethod.SmartViewInfosFromXML["product_code"]),
  1018                                ("Revision No.", self.Controler.CommonMethod.SmartViewInfosFromXML["revision_no"]),
  1018                                ("Revision No.", self.Controler.CommonMethod.SmartViewInfosFromXML["revision_no"]),
  1019                                ("Serial No.", self.Controler.CommonMethod.SmartViewInfosFromXML["serial_no"])]:
  1019                                ("Serial No.", self.Controler.CommonMethod.SmartViewInfosFromXML["serial_no"])]:
  1020             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.DeviceIdentity[treelist], data, 1)
  1020             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.DeviceIdentity[treelist], data, 1)
  1021              
  1021 
  1022         # Mailbox: Supported Mailbox, Bootstrap Configuration, Standard Configuration
  1022         # Mailbox: Supported Mailbox, Bootstrap Configuration, Standard Configuration
  1023         #  Set Mailbox
  1023         #  Set Mailbox
  1024         for treelist, data in [("Supported Mailbox", self.Controler.CommonMethod.SmartViewInfosFromXML["supported_mailbox"]),
  1024         for treelist, data in [("Supported Mailbox", self.Controler.CommonMethod.SmartViewInfosFromXML["supported_mailbox"]),
  1025                                ("Bootstrap Configuration", ""),
  1025                                ("Bootstrap Configuration", ""),
  1026                                ("Standard Configuration", "")]:
  1026                                ("Standard Configuration", "")]:
  1027             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1)       
  1027             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1)
  1028         #  Set Bootstrap Configuration: Receive Offset, Receive Size, Send Offset, Send Size
  1028         #  Set Bootstrap Configuration: Receive Offset, Receive Size, Send Offset, Send Size
  1029         for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outstart"]),
  1029         for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outstart"]),
  1030                                ("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outlength"]),
  1030                                ("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outlength"]),
  1031                                ("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_instart"]),
  1031                                ("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_instart"]),
  1032                                ("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_inlength"])]:
  1032                                ("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_inlength"])]:
  1033             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1)      
  1033             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1)
  1034         #  Set Standard Configuration: Receive Offset, Receive Size, Send Offset, Send Size
  1034         #  Set Standard Configuration: Receive Offset, Receive Size, Send Offset, Send Size
  1035         for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outstart"]),
  1035         for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outstart"]),
  1036                                ("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outlength"]),
  1036                                ("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outlength"]),
  1037                                ("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_instart"]),
  1037                                ("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_instart"]),
  1038                                ("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_inlength"])]:
  1038                                ("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_inlength"])]:
  1039             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1)
  1039             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1)
  1040         
  1040 
  1041     def SetEEPROMData(self):
  1041     def SetEEPROMData(self):
  1042         """
  1042         """
  1043         Set data based on slave EEPROM.
  1043         Set data based on slave EEPROM.
  1044         """  
  1044         """
  1045         # sii_dict = { Parameter : (WordAddress, WordSize) }
  1045         # sii_dict = { Parameter : (WordAddress, WordSize) }
  1046         sii_dict= { 'PDIControl' :                          ( '0', 1),
  1046         sii_dict= { 'PDIControl' :                          ( '0', 1),
  1047                     'PDIConfiguration' :                    ( '1', 1),
  1047                     'PDIConfiguration' :                    ( '1', 1),
  1048                     'PulseLengthOfSYNCSignals' :            ( '2', 1),
  1048                     'PulseLengthOfSYNCSignals' :            ( '2', 1),
  1049                     'ExtendedPDIConfiguration' :            ( '3', 1),
  1049                     'ExtendedPDIConfiguration' :            ( '3', 1),
  1069                     'Version' :                             ('3f', 1),
  1069                     'Version' :                             ('3f', 1),
  1070                     'First Category Type/Vendor Specific' : ('40', 1),
  1070                     'First Category Type/Vendor Specific' : ('40', 1),
  1071                     'Following Category Word Size' :        ('41', 1),
  1071                     'Following Category Word Size' :        ('41', 1),
  1072                     'Category Data' :                       ('42', 1),
  1072                     'Category Data' :                       ('42', 1),
  1073                 }
  1073                 }
  1074         
  1074 
  1075         # Config Data: EEPROM Size, PDI Type, Device Emulation
  1075         # Config Data: EEPROM Size, PDI Type, Device Emulation
  1076         # EEPROM's data in address '0x003f' is Size of EEPROM in KBit-1
  1076         # EEPROM's data in address '0x003f' is Size of EEPROM in KBit-1
  1077         eeprom_size = str((int(self.GetWordAddressData( sii_dict.get('Size'),10 ))+1)/8*1024)
  1077         eeprom_size = str((int(self.GetWordAddressData( sii_dict.get('Size'),10 ))+1)/8*1024)
  1078         # Find PDI Type in pdiType dictionary
  1078         # Find PDI Type in pdiType dictionary
  1079         cnt_pdi_type = int(self.GetWordAddressData( sii_dict.get('PDIControl'),16 ).split('x')[1][2:4], 16)
  1079         cnt_pdi_type = int(self.GetWordAddressData( sii_dict.get('PDIControl'),16 ).split('x')[1][2:4], 16)
  1080         for i in self.PDIType.keys():
  1080         for i in self.PDIType.keys():
  1081             if cnt_pdi_type == i:
  1081             if cnt_pdi_type == i:
  1082                 cnt_pdi_type = self.PDIType[i][0]
  1082                 cnt_pdi_type = self.PDIType[i][0]
  1083                 break
  1083                 break
  1084         #  Get Device Emulation
  1084         #  Get Device Emulation
  1085         device_emulation = str(bool(int("{:0>16b}".format(int(self.GetWordAddressData( sii_dict.get('PDIControl'),16 ), 16))[7])))    
  1085         device_emulation = str(bool(int("{:0>16b}".format(int(self.GetWordAddressData( sii_dict.get('PDIControl'),16 ), 16))[7])))
  1086         #  Set Config Data
  1086         #  Set Config Data
  1087         for treelist, data in [("EEPROM Size (Bytes)", eeprom_size),
  1087         for treelist, data in [("EEPROM Size (Bytes)", eeprom_size),
  1088                                ("PDI Type", cnt_pdi_type),
  1088                                ("PDI Type", cnt_pdi_type),
  1089                                ("Device Emulation", device_emulation)]:
  1089                                ("Device Emulation", device_emulation)]:
  1090             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.ConfigData[treelist], data, 1)
  1090             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.ConfigData[treelist], data, 1)
  1091         
  1091 
  1092         # Device Identity: Vendor ID, Product Code, Revision No., Serial No.
  1092         # Device Identity: Vendor ID, Product Code, Revision No., Serial No.
  1093         #  Set Device Identity
  1093         #  Set Device Identity
  1094         for treelist, data in [("Vendor ID", self.GetWordAddressData( sii_dict.get('VendorID'),16 )),
  1094         for treelist, data in [("Vendor ID", self.GetWordAddressData( sii_dict.get('VendorID'),16 )),
  1095                                ("Product Code", self.GetWordAddressData( sii_dict.get('ProductCode'),16 )),
  1095                                ("Product Code", self.GetWordAddressData( sii_dict.get('ProductCode'),16 )),
  1096                                ("Revision No.", self.GetWordAddressData( sii_dict.get('RevisionNumber'),16 )),
  1096                                ("Revision No.", self.GetWordAddressData( sii_dict.get('RevisionNumber'),16 )),
  1097                                ("Serial No.", self.GetWordAddressData( sii_dict.get('SerialNumber'),16 ))]:
  1097                                ("Serial No.", self.GetWordAddressData( sii_dict.get('SerialNumber'),16 ))]:
  1098             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.DeviceIdentity[treelist], data, 1)
  1098             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.DeviceIdentity[treelist], data, 1)
  1099       
  1099 
  1100         # Mailbox
  1100         # Mailbox
  1101         # EEORPOM's word address '1c' indicates supported mailbox protocol.
  1101         # EEORPOM's word address '1c' indicates supported mailbox protocol.
  1102         # each value of mailbox protocol : 
  1102         # each value of mailbox protocol :
  1103         # VoE(0x0020), SoE(0x0010), FoE(0x0008), CoE(0x0004), EoE(0x0002), AoE(0x0001)
  1103         # VoE(0x0020), SoE(0x0010), FoE(0x0008), CoE(0x0004), EoE(0x0002), AoE(0x0001)
  1104         supported_mailbox = ""
  1104         supported_mailbox = ""
  1105         mailbox_protocol=["VoE,  ", "SoE,  ", "FoE,  ", "CoE,  ", "EoE,  ", "AoE,  "]
  1105         mailbox_protocol=["VoE,  ", "SoE,  ", "FoE,  ", "CoE,  ", "EoE,  ", "AoE,  "]
  1106         mailbox_data = "{:0>8b}".format(int(self.GetWordAddressData( sii_dict.get('MailboxProtocol'),16 ), 16))
  1106         mailbox_data = "{:0>8b}".format(int(self.GetWordAddressData( sii_dict.get('MailboxProtocol'),16 ), 16))
  1107         for protocol in range(6):
  1107         for protocol in range(6):
  1110         supported_mailbox = supported_mailbox.strip(",  ")
  1110         supported_mailbox = supported_mailbox.strip(",  ")
  1111         #  Set Mailbox
  1111         #  Set Mailbox
  1112         for treelist, data in [("Supported Mailbox", supported_mailbox),
  1112         for treelist, data in [("Supported Mailbox", supported_mailbox),
  1113                                ("Bootstrap Configuration", ""),
  1113                                ("Bootstrap Configuration", ""),
  1114                                ("Standard Configuration", "")]:
  1114                                ("Standard Configuration", "")]:
  1115             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1)       
  1115             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1)
  1116         #  Set Bootstrap Configuration: Receive Offset, Receive Size, Send Offset, Send Size
  1116         #  Set Bootstrap Configuration: Receive Offset, Receive Size, Send Offset, Send Size
  1117         for treelist, data in [("Receive Offset", self.GetWordAddressData( sii_dict.get('BootstrapReceiveMailboxOffset'),10 )),
  1117         for treelist, data in [("Receive Offset", self.GetWordAddressData( sii_dict.get('BootstrapReceiveMailboxOffset'),10 )),
  1118                                ("Receive Size", self.GetWordAddressData( sii_dict.get('BootstrapReceiveMailboxSize'),10 )),
  1118                                ("Receive Size", self.GetWordAddressData( sii_dict.get('BootstrapReceiveMailboxSize'),10 )),
  1119                                ("Send Offset", self.GetWordAddressData( sii_dict.get('BootstrapSendMailboxOffset'),10 )),
  1119                                ("Send Offset", self.GetWordAddressData( sii_dict.get('BootstrapSendMailboxOffset'),10 )),
  1120                                ("Send Size", self.GetWordAddressData( sii_dict.get('BootstrapSendMailboxSize'),10 ))]:
  1120                                ("Send Size", self.GetWordAddressData( sii_dict.get('BootstrapSendMailboxSize'),10 ))]:
  1121             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1)      
  1121             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1)
  1122         #  Set Standard Configuration: Receive Offset, Receive Size, Send Offset, Send Size
  1122         #  Set Standard Configuration: Receive Offset, Receive Size, Send Offset, Send Size
  1123         for treelist, data in [("Receive Offset", self.GetWordAddressData( sii_dict.get('StandardReceiveMailboxOffset'),10 )),
  1123         for treelist, data in [("Receive Offset", self.GetWordAddressData( sii_dict.get('StandardReceiveMailboxOffset'),10 )),
  1124                                ("Receive Size", self.GetWordAddressData( sii_dict.get('StandardReceiveMailboxSize'),10 )),
  1124                                ("Receive Size", self.GetWordAddressData( sii_dict.get('StandardReceiveMailboxSize'),10 )),
  1125                                ("Send Offset", self.GetWordAddressData( sii_dict.get('StandardSendMailboxOffset'),10 )),
  1125                                ("Send Offset", self.GetWordAddressData( sii_dict.get('StandardSendMailboxOffset'),10 )),
  1126                                ("Send Size", self.GetWordAddressData( sii_dict.get('StandardSendMailboxSize'),10 ))]:
  1126                                ("Send Size", self.GetWordAddressData( sii_dict.get('StandardSendMailboxSize'),10 ))]:
  1127             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1)         
  1127             self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1)
  1128                 
  1128 
  1129     def MakeStaticBoxSizer(self, boxlabel):
  1129     def MakeStaticBoxSizer(self, boxlabel):
  1130         """
  1130         """
  1131         Make StaticBoxSizer
  1131         Make StaticBoxSizer
  1132         @param boxlabel : label of box sizer
  1132         @param boxlabel : label of box sizer
  1133         @return sizer : the StaticBoxSizer labeled 'boxlabel'
  1133         @return sizer : the StaticBoxSizer labeled 'boxlabel'
  1134         """
  1134         """
  1135         box = wx.StaticBox(self, -1, boxlabel)
  1135         box = wx.StaticBox(self, -1, boxlabel)
  1136         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1136         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1137 
  1137 
  1138         return sizer
  1138         return sizer
  1139         
  1139 
  1140     def GetWordAddressData(self, dict_tuple, format):
  1140     def GetWordAddressData(self, dict_tuple, format):
  1141         """
  1141         """
  1142         This method converts word address data from EEPROM binary.
  1142         This method converts word address data from EEPROM binary.
  1143         @param dict_tuple : element of 'sii_dict' dictionary in SetEEPROMData()
  1143         @param dict_tuple : element of 'sii_dict' dictionary in SetEEPROMData()
  1144         @param format : format of data. It can be 16(hex), 10(decimal) and 2(binary).
  1144         @param format : format of data. It can be 16(hex), 10(decimal) and 2(binary).
  1145         @return formatted value
  1145         @return formatted value
  1146         """  
  1146         """
  1147         offset = int(str(dict_tuple[0]), 16) * 2
  1147         offset = int(str(dict_tuple[0]), 16) * 2
  1148         length = int(str(dict_tuple[1]), 16) * 2
  1148         length = int(str(dict_tuple[1]), 16) * 2
  1149         list = []
  1149         list = []
  1150         data = ''
  1150         data = ''
  1151         for index in range(length):
  1151         for index in range(length):
  1152             hexdata = hex(ord(self.SiiBinary[offset + index]))[2:]
  1152             hexdata = hex(ord(self.SiiBinary[offset + index]))[2:]
  1153             list.append(hexdata.zfill(2))
  1153             list.append(hexdata.zfill(2))
  1154             
  1154 
  1155         list.reverse()
  1155         list.reverse()
  1156         data = list[0:length]
  1156         data = list[0:length]
  1157 
  1157 
  1158         if format == 16:
  1158         if format == 16:
  1159             return '0x' + ''.join(data) 
  1159             return '0x' + ''.join(data)
  1160         elif format == 10:
  1160         elif format == 10:
  1161             return str(int(str(''.join(data)), 16))
  1161             return str(int(str(''.join(data)), 16))
  1162         elif format == 2: 
  1162         elif format == 2:
  1163             ''.join(data)           
  1163             ''.join(data)
  1164 
  1164 
  1165 
  1165 
  1166 #-------------------------------------------------------------------------------
  1166 #-------------------------------------------------------------------------------
  1167 #                    For Smart View TreeListCtrl
  1167 #                    For Smart View TreeListCtrl
  1168 #-------------------------------------------------------------------------------  
  1168 #-------------------------------------------------------------------------------
  1169 class SmartViewTreeListCtrl(wx.Panel):
  1169 class SmartViewTreeListCtrl(wx.Panel):
  1170     def __init__(self, parent, Controler):
  1170     def __init__(self, parent, Controler):
  1171         """
  1171         """
  1172         Constructor
  1172         Constructor
  1173         @param parent: Reference to the parent SlaveSiiSmartView class
  1173         @param parent: Reference to the parent SlaveSiiSmartView class
  1174         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1174         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1175         """
  1175         """
  1176 
  1176 
  1177         wx.Panel.__init__(self, parent, -1, size=(350, 500))
  1177         wx.Panel.__init__(self, parent, -1, size=(350, 500))
  1178         
  1178 
  1179         self.Tree = wx.gizmos.TreeListCtrl(self, -1, size=(350, 500), 
  1179         self.Tree = wx.gizmos.TreeListCtrl(self, -1, size=(350, 500),
  1180                                            style=wx.TR_DEFAULT_STYLE
  1180                                            style=wx.TR_DEFAULT_STYLE
  1181                                                 |wx.TR_FULL_ROW_HIGHLIGHT
  1181                                                 |wx.TR_FULL_ROW_HIGHLIGHT
  1182                                                 |wx.TR_HIDE_ROOT
  1182                                                 |wx.TR_HIDE_ROOT
  1183                                                 |wx.TR_COLUMN_LINES
  1183                                                 |wx.TR_COLUMN_LINES
  1184                                                 |wx.TR_ROW_LINES)
  1184                                                 |wx.TR_ROW_LINES)
  1185         
  1185 
  1186         self.Tree.AddColumn("Description", width=200)
  1186         self.Tree.AddColumn("Description", width=200)
  1187         self.Tree.AddColumn("Value", width=140)
  1187         self.Tree.AddColumn("Value", width=140)
  1188         self.Tree.SetMainColumn(0)
  1188         self.Tree.SetMainColumn(0)
  1189         
  1189 
  1190         self.Root = self.Tree.AddRoot("")
  1190         self.Root = self.Tree.AddRoot("")
  1191         
  1191 
  1192         # Add item
  1192         # Add item
  1193         #  Level 1 nodes
  1193         #  Level 1 nodes
  1194         self.Level1Nodes = {}
  1194         self.Level1Nodes = {}
  1195         for lv1 in ["Config Data", "Device Identity", "Mailbox"]:
  1195         for lv1 in ["Config Data", "Device Identity", "Mailbox"]:
  1196             self.Level1Nodes[lv1] = self.Tree.AppendItem(self.Root, lv1)
  1196             self.Level1Nodes[lv1] = self.Tree.AppendItem(self.Root, lv1)
  1197         
  1197 
  1198         #  Level 2 nodes
  1198         #  Level 2 nodes
  1199         #   Config Data
  1199         #   Config Data
  1200         self.ConfigData = {}
  1200         self.ConfigData = {}
  1201         for lv2 in ["EEPROM Size (Bytes)", "PDI Type", "Device Emulation"]:
  1201         for lv2 in ["EEPROM Size (Bytes)", "PDI Type", "Device Emulation"]:
  1202             self.ConfigData[lv2] = self.Tree.AppendItem(self.Level1Nodes["Config Data"], lv2)
  1202             self.ConfigData[lv2] = self.Tree.AppendItem(self.Level1Nodes["Config Data"], lv2)
  1206             self.DeviceIdentity[lv2] = self.Tree.AppendItem(self.Level1Nodes["Device Identity"], lv2)
  1206             self.DeviceIdentity[lv2] = self.Tree.AppendItem(self.Level1Nodes["Device Identity"], lv2)
  1207         #   Mailbox
  1207         #   Mailbox
  1208         self.Mailbox = {}
  1208         self.Mailbox = {}
  1209         for lv2 in ["Supported Mailbox", "Bootstrap Configuration", "Standard Configuration"]:
  1209         for lv2 in ["Supported Mailbox", "Bootstrap Configuration", "Standard Configuration"]:
  1210             self.Mailbox[lv2] = self.Tree.AppendItem(self.Level1Nodes["Mailbox"], lv2)
  1210             self.Mailbox[lv2] = self.Tree.AppendItem(self.Level1Nodes["Mailbox"], lv2)
  1211         
  1211 
  1212         #  Level 3 nodes
  1212         #  Level 3 nodes
  1213         #   Children of Bootstrap Configuration
  1213         #   Children of Bootstrap Configuration
  1214         self.BootstrapConfig = {}
  1214         self.BootstrapConfig = {}
  1215         for lv3 in ["Receive Offset", "Receive Size", "Send Offset", "Send Size"]:
  1215         for lv3 in ["Receive Offset", "Receive Size", "Send Offset", "Send Size"]:
  1216             self.BootstrapConfig[lv3] = self.Tree.AppendItem(self.Mailbox["Bootstrap Configuration"], lv3)
  1216             self.BootstrapConfig[lv3] = self.Tree.AppendItem(self.Mailbox["Bootstrap Configuration"], lv3)
  1217         #   Children of Standard Configuration
  1217         #   Children of Standard Configuration
  1218         self.StandardConfig = {}
  1218         self.StandardConfig = {}
  1219         for lv3 in ["Receive Offset", "Receive Size", "Send Offset", "Send Size"]:
  1219         for lv3 in ["Receive Offset", "Receive Size", "Send Offset", "Send Size"]:
  1220             self.StandardConfig[lv3] = self.Tree.AppendItem(self.Mailbox["Standard Configuration"], lv3)
  1220             self.StandardConfig[lv3] = self.Tree.AppendItem(self.Mailbox["Standard Configuration"], lv3)
  1221         
  1221 
  1222         # Expand Tree
  1222         # Expand Tree
  1223         for tree in [self.Root, 
  1223         for tree in [self.Root,
  1224                      self.Level1Nodes["Config Data"], 
  1224                      self.Level1Nodes["Config Data"],
  1225                      self.Level1Nodes["Device Identity"], 
  1225                      self.Level1Nodes["Device Identity"],
  1226                      self.Level1Nodes["Mailbox"],
  1226                      self.Level1Nodes["Mailbox"],
  1227                      self.Mailbox["Bootstrap Configuration"], 
  1227                      self.Mailbox["Bootstrap Configuration"],
  1228                      self.Mailbox["Standard Configuration"]]:
  1228                      self.Mailbox["Standard Configuration"]]:
  1229             self.Tree.Expand(tree)
  1229             self.Tree.Expand(tree)
  1230 
  1230 
  1231 
  1231 
  1232 #-------------------------------------------------------------------------------
  1232 #-------------------------------------------------------------------------------
  1233 #                         For Hex View Panel
  1233 #                         For Hex View Panel
  1234 #            shows EEPROM binary as hex data and characters.
  1234 #            shows EEPROM binary as hex data and characters.
  1235 #-------------------------------------------------------------------------------  
  1235 #-------------------------------------------------------------------------------
  1236 class HexView(wx.Panel):
  1236 class HexView(wx.Panel):
  1237     def __init__(self, parent, controler):
  1237     def __init__(self, parent, controler):
  1238         """
  1238         """
  1239         Constructor
  1239         Constructor
  1240         @param parent: Reference to the parent EtherCATManagementTreebook class
  1240         @param parent: Reference to the parent EtherCATManagementTreebook class
  1241         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1241         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1242         """
  1242         """
  1243         wx.Panel.__init__(self, parent, -1)
  1243         wx.Panel.__init__(self, parent, -1)
  1244         self.parent = parent
  1244         self.parent = parent
  1245         self.Controler = controler
  1245         self.Controler = controler
  1246                 
  1246 
  1247         self.HexRow = 8
  1247         self.HexRow = 8
  1248         self.HexCol = 17
  1248         self.HexCol = 17
  1249         
  1249 
  1250         self.HexViewSizer = {"view" : wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10),
  1250         self.HexViewSizer = {"view" : wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10),
  1251                              "siiButton" : wx.BoxSizer()}
  1251                              "siiButton" : wx.BoxSizer()}
  1252         self.HexViewButton = {}
  1252         self.HexViewButton = {}
  1253 
  1253 
  1254         for key, evt_handler in [("Sii Upload", self.OnButtonSiiUpload),
  1254         for key, evt_handler in [("Sii Upload", self.OnButtonSiiUpload),
  1255                                 ("Sii Download", self.OnButtonSiiDownload),
  1255                                 ("Sii Download", self.OnButtonSiiDownload),
  1256                                 ("Write to File", self.OnButtonWriteToBinFile),
  1256                                 ("Write to File", self.OnButtonWriteToBinFile),
  1257                                 ("Read from File", self.OnButtonReadFromBinFile),
  1257                                 ("Read from File", self.OnButtonReadFromBinFile),
  1258                                 ("XML to EEPROM Image", self.OnButtonXmlToEEPROMImg)]:
  1258                                 ("XML to EEPROM Image", self.OnButtonXmlToEEPROMImg)]:
  1259             self.HexViewButton[key] = wx.Button(self, -1, key) 
  1259             self.HexViewButton[key] = wx.Button(self, -1, key)
  1260             self.HexViewButton[key].Bind(wx.EVT_BUTTON, evt_handler)
  1260             self.HexViewButton[key].Bind(wx.EVT_BUTTON, evt_handler)
  1261             self.HexViewSizer["siiButton"].Add(self.HexViewButton[key])
  1261             self.HexViewSizer["siiButton"].Add(self.HexViewButton[key])
  1262 
  1262 
  1263         self.SiiBinary = self.Controler.CommonMethod.XmlToEeprom()
  1263         self.SiiBinary = self.Controler.CommonMethod.XmlToEeprom()
  1264         self.HexCode, self.HexRow, self.HexCol = self.Controler.CommonMethod.HexRead(self.SiiBinary)
  1264         self.HexCode, self.HexRow, self.HexCol = self.Controler.CommonMethod.HexRead(self.SiiBinary)
  1265         self.SiiGrid = SiiGridTable(self, self.Controler, self.HexRow, self.HexCol)
  1265         self.SiiGrid = SiiGridTable(self, self.Controler, self.HexRow, self.HexCol)
  1266         self.HexViewSizer["view"].AddMany([self.HexViewSizer["siiButton"], self.SiiGrid]) 
  1266         self.HexViewSizer["view"].AddMany([self.HexViewSizer["siiButton"], self.SiiGrid])
  1267         self.SiiGrid.CreateGrid(self.HexRow, self.HexCol)
  1267         self.SiiGrid.CreateGrid(self.HexRow, self.HexCol)
  1268         self.SetSizer(self.HexViewSizer["view"])     
  1268         self.SetSizer(self.HexViewSizer["view"])
  1269         self.HexViewSizer["view"].FitInside(self.parent.parent)
  1269         self.HexViewSizer["view"].FitInside(self.parent.parent)
  1270         self.parent.parent.FitInside()
  1270         self.parent.parent.FitInside()
  1271         self.SiiGrid.SetValue(self.HexCode)
  1271         self.SiiGrid.SetValue(self.HexCode)
  1272         self.SiiGrid.Update()
  1272         self.SiiGrid.Update()
  1273 
  1273 
  1274     def UpdateSiiGridTable(self, row, col):
  1274     def UpdateSiiGridTable(self, row, col):
  1275         """
  1275         """
  1276         Destroy existing grid and recreate
  1276         Destroy existing grid and recreate
  1277         @param row, col : Hex View grid size
  1277         @param row, col : Hex View grid size
  1278         """  
  1278         """
  1279         self.HexViewSizer["view"].Detach(self.SiiGrid)
  1279         self.HexViewSizer["view"].Detach(self.SiiGrid)
  1280         self.SiiGrid.Destroy()
  1280         self.SiiGrid.Destroy()
  1281         self.SiiGrid = SiiGridTable(self, self.Controler, row, col)
  1281         self.SiiGrid = SiiGridTable(self, self.Controler, row, col)
  1282         self.HexViewSizer["view"].Add(self.SiiGrid)
  1282         self.HexViewSizer["view"].Add(self.SiiGrid)
  1283         self.SiiGrid.CreateGrid(row, col)
  1283         self.SiiGrid.CreateGrid(row, col)
  1288     def OnButtonSiiUpload(self, event):
  1288     def OnButtonSiiUpload(self, event):
  1289         """
  1289         """
  1290         Load EEPROM data from slave and refresh Hex View grid
  1290         Load EEPROM data from slave and refresh Hex View grid
  1291         Binded to 'Sii Upload' button.
  1291         Binded to 'Sii Upload' button.
  1292         @param event : wx.EVT_BUTTON object
  1292         @param event : wx.EVT_BUTTON object
  1293         """  
  1293         """
  1294         # Check whether beremiz connected or not.
  1294         # Check whether beremiz connected or not.
  1295         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
  1295         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
  1296         if check_connect_flag:
  1296         if check_connect_flag:
  1297             # load from EEPROM data and parsing
  1297             # load from EEPROM data and parsing
  1298             self.SiiBinary = self.Controler.CommonMethod.LoadData()
  1298             self.SiiBinary = self.Controler.CommonMethod.LoadData()
  1299             self.HexCode, self.HexRow, self.HexCol = self.Controler.CommonMethod.HexRead(self.SiiBinary)
  1299             self.HexCode, self.HexRow, self.HexCol = self.Controler.CommonMethod.HexRead(self.SiiBinary)
  1300             self.UpdateSiiGridTable(self.HexRow, self.HexCol)
  1300             self.UpdateSiiGridTable(self.HexRow, self.HexCol)
  1301             self.SiiGrid.SetValue(self.HexCode)
  1301             self.SiiGrid.SetValue(self.HexCode)
  1302             self.SiiGrid.Update()
  1302             self.SiiGrid.Update()
  1303             
  1303 
  1304     def OnButtonSiiDownload(self, event):
  1304     def OnButtonSiiDownload(self, event):
  1305         """
  1305         """
  1306         Write current EEPROM data to slave and refresh data structure kept by master 
  1306         Write current EEPROM data to slave and refresh data structure kept by master
  1307         Binded to 'Sii Download' button.
  1307         Binded to 'Sii Download' button.
  1308         @param event : wx.EVT_BUTTON object
  1308         @param event : wx.EVT_BUTTON object
  1309         """  
  1309         """
  1310         # Check whether beremiz connected or not, 
  1310         # Check whether beremiz connected or not,
  1311         # and whether status is "Started" or not. 
  1311         # and whether status is "Started" or not.
  1312         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
  1312         check_connect_flag = self.Controler.CommonMethod.CheckConnect(False)
  1313         if check_connect_flag:
  1313         if check_connect_flag:
  1314             status, count = self.Controler.GetCTRoot()._connector.GetPLCstatus()
  1314             status, count = self.Controler.GetCTRoot()._connector.GetPLCstatus()
  1315             if status is not "Started":
  1315             if status is not "Started":
  1316                 self.Controler.CommonMethod.SiiWrite(self.SiiBinary)
  1316                 self.Controler.CommonMethod.SiiWrite(self.SiiBinary)
  1317                 self.Controler.CommonMethod.Rescan()
  1317                 self.Controler.CommonMethod.Rescan()
  1318         
  1318 
  1319     def OnButtonWriteToBinFile(self, event):
  1319     def OnButtonWriteToBinFile(self, event):
  1320         """ 
  1320         """
  1321         Save current EEPROM data to binary file through FileDialog
  1321         Save current EEPROM data to binary file through FileDialog
  1322         Binded to 'Write to File' button.
  1322         Binded to 'Write to File' button.
  1323         @param event : wx.EVT_BUTTON object
  1323         @param event : wx.EVT_BUTTON object
  1324         """ 
  1324         """
  1325         dialog = wx.FileDialog(self, _("Save as..."), os.getcwd(), "slave0.bin",  
  1325         dialog = wx.FileDialog(self, _("Save as..."), os.getcwd(), "slave0.bin",
  1326                                _("bin files (*.bin)|*.bin|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT)
  1326                                _("bin files (*.bin)|*.bin|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT)
  1327 
  1327 
  1328         if dialog.ShowModal() == wx.ID_OK:
  1328         if dialog.ShowModal() == wx.ID_OK:
  1329             filepath = dialog.GetPath()
  1329             filepath = dialog.GetPath()
  1330             binfile = open(filepath,"wb")
  1330             binfile = open(filepath,"wb")
  1331             binfile.write(self.SiiBinary)
  1331             binfile.write(self.SiiBinary)
  1332             binfile.close()
  1332             binfile.close()
  1333     
  1333 
  1334         dialog.Destroy()  
  1334         dialog.Destroy()
  1335     
  1335 
  1336     def OnButtonReadFromBinFile(self, event):
  1336     def OnButtonReadFromBinFile(self, event):
  1337         """
  1337         """
  1338         Load binary file through FileDialog
  1338         Load binary file through FileDialog
  1339         Binded to 'Read from File' button.
  1339         Binded to 'Read from File' button.
  1340         @param event : wx.EVT_BUTTON object
  1340         @param event : wx.EVT_BUTTON object
  1341         """
  1341         """
  1342         dialog = wx.FileDialog(self, _("Choose a binary file"), os.getcwd(), "",  
  1342         dialog = wx.FileDialog(self, _("Choose a binary file"), os.getcwd(), "",
  1343                                _("bin files (*.bin)|*.bin"), wx.OPEN)
  1343                                _("bin files (*.bin)|*.bin"), wx.OPEN)
  1344         
  1344 
  1345         if dialog.ShowModal() == wx.ID_OK:
  1345         if dialog.ShowModal() == wx.ID_OK:
  1346             filepath = dialog.GetPath()
  1346             filepath = dialog.GetPath()
  1347             
  1347 
  1348             try:
  1348             try:
  1349                 binfile = open(filepath, "rb")
  1349                 binfile = open(filepath, "rb")
  1350                 self.SiiBinary = binfile.read()
  1350                 self.SiiBinary = binfile.read()
  1351                 self.HexCode, self.HexRow, self.HexCol = self.Controler.CommonMethod.HexRead(self.SiiBinary)
  1351                 self.HexCode, self.HexRow, self.HexCol = self.Controler.CommonMethod.HexRead(self.SiiBinary)
  1352                 self.UpdateSiiGridTable(self.HexRow, self.HexCol)
  1352                 self.UpdateSiiGridTable(self.HexRow, self.HexCol)
  1353                 self.SiiGrid.SetValue(self.HexCode)
  1353                 self.SiiGrid.SetValue(self.HexCode)
  1354                 self.SiiGrid.Update()
  1354                 self.SiiGrid.Update()
  1355             except Exception:
  1355             except Exception:
  1356                 self.Controler.CommonMethod.CreateErrorDialog('The file does not exist!')
  1356                 self.Controler.CommonMethod.CreateErrorDialog('The file does not exist!')
  1357             
  1357 
  1358         dialog.Destroy()
  1358         dialog.Destroy()
  1359             
  1359 
  1360     def OnButtonXmlToEEPROMImg(self, event):
  1360     def OnButtonXmlToEEPROMImg(self, event):
  1361         """
  1361         """
  1362         Create EEPROM data based XML data that current imported
  1362         Create EEPROM data based XML data that current imported
  1363         Binded to 'XML to EEPROM' button.
  1363         Binded to 'XML to EEPROM' button.
  1364         @param event : wx.EVT_BUTTON object
  1364         @param event : wx.EVT_BUTTON object
  1370         self.SiiGrid.Update()
  1370         self.SiiGrid.Update()
  1371 
  1371 
  1372 
  1372 
  1373 #-------------------------------------------------------------------------------
  1373 #-------------------------------------------------------------------------------
  1374 #                    For Hex View grid (fill hex data)
  1374 #                    For Hex View grid (fill hex data)
  1375 #-------------------------------------------------------------------------------  
  1375 #-------------------------------------------------------------------------------
  1376 class SiiGridTable(wx.grid.Grid):  
  1376 class SiiGridTable(wx.grid.Grid):
  1377     def __init__(self, parent, controler, row, col):
  1377     def __init__(self, parent, controler, row, col):
  1378         """
  1378         """
  1379         Constructor
  1379         Constructor
  1380         @param parent: Reference to the parent HexView class
  1380         @param parent: Reference to the parent HexView class
  1381         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1381         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1382         @param row, col: Hex View grid size
  1382         @param row, col: Hex View grid size
  1383         """
  1383         """
  1384         self.parent = parent
  1384         self.parent = parent
  1385         self.Controler = controler
  1385         self.Controler = controler
  1386         self.Row = row
  1386         self.Row = row
  1387         self.Col = col    
  1387         self.Col = col
  1388         
  1388 
  1389         wx.grid.Grid.__init__(self, parent, -1, size=(830,450), 
  1389         wx.grid.Grid.__init__(self, parent, -1, size=(830,450),
  1390                               style=wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)        
  1390                               style=wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
  1391 
  1391 
  1392     def SetValue(self, value):
  1392     def SetValue(self, value):
  1393         """
  1393         """
  1394         Set data in the table
  1394         Set data in the table
  1395         @param value: EEPROM data list of which element is 1 Byte hex data
  1395         @param value: EEPROM data list of which element is 1 Byte hex data
  1401                 self.SetColLabelValue(16, "Text View")
  1401                 self.SetColLabelValue(16, "Text View")
  1402                 self.SetColSize(16, (self.GetSize().x-120)*4/20)
  1402                 self.SetColSize(16, (self.GetSize().x-120)*4/20)
  1403             else:
  1403             else:
  1404                 self.SetColLabelValue(col, '%s'%col)
  1404                 self.SetColLabelValue(col, '%s'%col)
  1405                 self.SetColSize(col, (self.GetSize().x-120)/20)
  1405                 self.SetColSize(col, (self.GetSize().x-120)/20)
  1406             
  1406 
  1407         # set data into table
  1407         # set data into table
  1408         row = col = 0
  1408         row = col = 0
  1409         for row_idx in value: 
  1409         for row_idx in value:
  1410             col = 0
  1410             col = 0
  1411             self.SetRowLabelValue(row, "0x"+"{:0>4x}".format(row*(self.Col-1)))
  1411             self.SetRowLabelValue(row, "0x"+"{:0>4x}".format(row*(self.Col-1)))
  1412             for hex in row_idx:
  1412             for hex in row_idx:
  1413                 self.SetCellValue(row, col, hex)
  1413                 self.SetCellValue(row, col, hex)
  1414                 
  1414 
  1415                 if col == 16: 
  1415                 if col == 16:
  1416                     self.SetCellAlignment(row, col, wx.ALIGN_LEFT, wx.ALIGN_CENTER)
  1416                     self.SetCellAlignment(row, col, wx.ALIGN_LEFT, wx.ALIGN_CENTER)
  1417                 else:
  1417                 else:
  1418                     self.SetCellAlignment(row, col, wx.ALIGN_CENTRE, wx.ALIGN_CENTER)
  1418                     self.SetCellAlignment(row, col, wx.ALIGN_CENTRE, wx.ALIGN_CENTER)
  1419                     
  1419 
  1420                 self.SetReadOnly(row, col, True)
  1420                 self.SetReadOnly(row, col, True)
  1421                 col = col + 1
  1421                 col = col + 1
  1422             row = row + 1
  1422             row = row + 1
  1423         
  1423 
  1424 
  1424 
  1425 #-------------------------------------------------------------------------------
  1425 #-------------------------------------------------------------------------------
  1426 #                    For Register Access Panel
  1426 #                    For Register Access Panel
  1427 #-------------------------------------------------------------------------------  
  1427 #-------------------------------------------------------------------------------
  1428 class RegisterAccessPanel(wx.Panel):
  1428 class RegisterAccessPanel(wx.Panel):
  1429     def __init__(self, parent, controler):
  1429     def __init__(self, parent, controler):
  1430         """
  1430         """
  1431 	    Constructor
  1431 	    Constructor
  1432 	    @param parent: EEPROMAccessPanel object
  1432 	    @param parent: EEPROMAccessPanel object
  1433 	    @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1433 	    @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1434 	    """
  1434 	    """
  1435         self.parent = parent
  1435         self.parent = parent
  1436         self.Controler = controler
  1436         self.Controler = controler
  1437         self.__init_data()
  1437         self.__init_data()
  1438         
  1438 
  1439         wx.Panel.__init__(self, parent, -1)
  1439         wx.Panel.__init__(self, parent, -1)
  1440         
  1440 
  1441         sizer = wx.FlexGridSizer(cols=1, hgap=20, rows=2, vgap=5)
  1441         sizer = wx.FlexGridSizer(cols=1, hgap=20, rows=2, vgap=5)
  1442         button_sizer = wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=10)
  1442         button_sizer = wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=10)
  1443         
  1443 
  1444         self.ReloadButton = wx.Button(self, -1, "Reload")
  1444         self.ReloadButton = wx.Button(self, -1, "Reload")
  1445         self.CompactViewCheckbox = wx.CheckBox(self, -1, "Compact View")        
  1445         self.CompactViewCheckbox = wx.CheckBox(self, -1, "Compact View")
  1446         self.RegisterNotebook = RegisterNotebook(self, self.Controler)
  1446         self.RegisterNotebook = RegisterNotebook(self, self.Controler)
  1447         
  1447 
  1448         button_sizer.AddMany([self.ReloadButton, self.CompactViewCheckbox])
  1448         button_sizer.AddMany([self.ReloadButton, self.CompactViewCheckbox])
  1449         sizer.AddMany([button_sizer, self.RegisterNotebook])
  1449         sizer.AddMany([button_sizer, self.RegisterNotebook])
  1450         self.SetSizer(sizer)
  1450         self.SetSizer(sizer)
  1451         
  1451 
  1452         self.ReloadButton.Bind(wx.EVT_BUTTON, self.OnReloadButton)
  1452         self.ReloadButton.Bind(wx.EVT_BUTTON, self.OnReloadButton)
  1453         self.CompactViewCheckbox.Bind(wx.EVT_CHECKBOX, self.ToggleCompactViewCheckbox)
  1453         self.CompactViewCheckbox.Bind(wx.EVT_CHECKBOX, self.ToggleCompactViewCheckbox)
  1454         
  1454 
  1455         for index in range(4):
  1455         for index in range(4):
  1456             self.RegisterNotebook.RegPage[index].MainTable.CreateGrid(self.MainRow[index], self.MainCol)
  1456             self.RegisterNotebook.RegPage[index].MainTable.CreateGrid(self.MainRow[index], self.MainCol)
  1457             self.RegisterNotebook.RegPage[index].MainTable.SetValue(self, 0, index*512, (index+1)*512)
  1457             self.RegisterNotebook.RegPage[index].MainTable.SetValue(self, 0, index*512, (index+1)*512)
  1458         
  1458 
  1459         # data default setting
  1459         # data default setting
  1460         if self.Controler.CommonMethod.RegData == "": 
  1460         if self.Controler.CommonMethod.RegData == "":
  1461             self.CompactViewCheckbox.Disable() 
  1461             self.CompactViewCheckbox.Disable()
  1462             for index in range(4): 
  1462             for index in range(4):
  1463                 self.RegisterNotebook.RegPage[index].MainTable.SetValue(self, 0, index*512, (index+1)*512)
  1463                 self.RegisterNotebook.RegPage[index].MainTable.SetValue(self, 0, index*512, (index+1)*512)
  1464         else: # If data was saved,
  1464         else: # If data was saved,
  1465             self.BasicSetData()
  1465             self.BasicSetData()
  1466             self.ParseData()
  1466             self.ParseData()
  1467             for index in range(4):
  1467             for index in range(4):
  1471         """
  1471         """
  1472 	    Declare initial data.
  1472 	    Declare initial data.
  1473 	    """
  1473 	    """
  1474         # flag for compact view
  1474         # flag for compact view
  1475         self.CompactFlag = False
  1475         self.CompactFlag = False
  1476         
  1476 
  1477         # main grid의 rows and cols
  1477         # main grid의 rows and cols
  1478         self.MainRow = [512, 512, 512, 512]
  1478         self.MainRow = [512, 512, 512, 512]
  1479         self.MainCol = 4
  1479         self.MainCol = 4
  1480         
  1480 
  1481         # main grids' data range
  1481         # main grids' data range
  1482         self.PageRange = []
  1482         self.PageRange = []
  1483         for index in range(4):
  1483         for index in range(4):
  1484             self.PageRange.append([512*index, 512*(index+1)])
  1484             self.PageRange.append([512*index, 512*(index+1)])
  1485         
  1485 
  1486         #  Previous value of register data for register description configuration
  1486         #  Previous value of register data for register description configuration
  1487         self.PreRegSpec = {"ESCType": "",
  1487         self.PreRegSpec = {"ESCType": "",
  1488                            "FMMUNumber": "",
  1488                            "FMMUNumber": "",
  1489                            "SMNumber": "",
  1489                            "SMNumber": "",
  1490                            "PDIType": ""}
  1490                            "PDIType": ""}
  1491         
  1491 
  1492     def LoadData(self):
  1492     def LoadData(self):
  1493         """
  1493         """
  1494         Get data from the register.
  1494         Get data from the register.
  1495         """
  1495         """
  1496         self.Controler.CommonMethod.RegData = ""
  1496         self.Controler.CommonMethod.RegData = ""
  1497         #ethercat reg_read
  1497         #ethercat reg_read
  1498         #ex : ethercat reg_read -p 0 0x0000 0x0001
  1498         #ex : ethercat reg_read -p 0 0x0000 0x0001
  1499         #return value : 0x11
  1499         #return value : 0x11
  1500         for index in range(4):
  1500         for index in range(4):
  1501             self.Controler.CommonMethod.RegData = self.Controler.CommonMethod.RegData + " " + self.Controler.CommonMethod.RegRead("0x"+"{:0>4x}".format(index*1024), "0x0400")
  1501             self.Controler.CommonMethod.RegData = self.Controler.CommonMethod.RegData + " " + self.Controler.CommonMethod.RegRead("0x"+"{:0>4x}".format(index*1024), "0x0400")
  1502         
  1502 
  1503         # store previous value 
  1503         # store previous value
  1504         # (ESC type, port number of FMMU, port number of SM, and PDI type))
  1504         # (ESC type, port number of FMMU, port number of SM, and PDI type))
  1505         for reg_spec in ["ESCType","FMMUNumber","SMNumber", "PDIType"]:
  1505         for reg_spec in ["ESCType","FMMUNumber","SMNumber", "PDIType"]:
  1506             self.PreRegSpec[reg_spec] = self.Controler.CommonMethod.CrtRegSpec[reg_spec]
  1506             self.PreRegSpec[reg_spec] = self.Controler.CommonMethod.CrtRegSpec[reg_spec]
  1507         
  1507 
  1508         # update registers' description 
  1508         # update registers' description
  1509         # (ESC type, port number of FMMU, port number of SM, and PDI type)
  1509         # (ESC type, port number of FMMU, port number of SM, and PDI type)
  1510         for reg_spec, address in [("ESCType", "0x0000"),
  1510         for reg_spec, address in [("ESCType", "0x0000"),
  1511                                   ("FMMUNumber", "0x0004"),
  1511                                   ("FMMUNumber", "0x0004"),
  1512                                   ("SMNumber", "0x0005"),
  1512                                   ("SMNumber", "0x0005"),
  1513                                   ("PDIType", "0x0140")]:
  1513                                   ("PDIType", "0x0140")]:
  1514             self.Controler.CommonMethod.CrtRegSpec[reg_spec] = self.Controler.CommonMethod.RegRead(address, "0x0001")
  1514             self.Controler.CommonMethod.CrtRegSpec[reg_spec] = self.Controler.CommonMethod.RegRead(address, "0x0001")
  1515                  
  1515 
  1516         # Enable compactView checkbox
  1516         # Enable compactView checkbox
  1517         self.CompactViewCheckbox.Enable()
  1517         self.CompactViewCheckbox.Enable()
  1518     
  1518 
  1519     def BasicSetData(self):
  1519     def BasicSetData(self):
  1520         """
  1520         """
  1521         Get and save the description of registers. 
  1521         Get and save the description of registers.
  1522         It's done by parsing register_information.xml.
  1522         It's done by parsing register_information.xml.
  1523         """
  1523         """
  1524         # parse the above register's value
  1524         # parse the above register's value
  1525         # If the value is 0x12, the result is 12
  1525         # If the value is 0x12, the result is 12
  1526         self.ESCType = self.Controler.CommonMethod.CrtRegSpec["ESCType"].split('x')[1]
  1526         self.ESCType = self.Controler.CommonMethod.CrtRegSpec["ESCType"].split('x')[1]
  1527         self.PDIType = self.Controler.CommonMethod.CrtRegSpec["PDIType"].split('x')[1]
  1527         self.PDIType = self.Controler.CommonMethod.CrtRegSpec["PDIType"].split('x')[1]
  1528         # If the value is 0x12, the result is 18 (It's converted to decimal value)
  1528         # If the value is 0x12, the result is 18 (It's converted to decimal value)
  1529         self.FMMUNumber = int(self.Controler.CommonMethod.CrtRegSpec["FMMUNumber"], 16)
  1529         self.FMMUNumber = int(self.Controler.CommonMethod.CrtRegSpec["FMMUNumber"], 16)
  1530         self.SMNumber = int(self.Controler.CommonMethod.CrtRegSpec["SMNumber"], 16)
  1530         self.SMNumber = int(self.Controler.CommonMethod.CrtRegSpec["SMNumber"], 16)
  1531         
  1531 
  1532         # initialize description dictionary of register main table and register sub table.
  1532         # initialize description dictionary of register main table and register sub table.
  1533         self.RegisterDescriptionDict = {}
  1533         self.RegisterDescriptionDict = {}
  1534         self.RegisterSubGridDict = {}
  1534         self.RegisterSubGridDict = {}
  1535         
  1535 
  1536         # ./EthercatMaster/register_information.xml contains register description.
  1536         # ./EthercatMaster/register_information.xml contains register description.
  1537         if wx.Platform == '__WXMSW__':
  1537         if wx.Platform == '__WXMSW__':
  1538             reg_info_file = open("../../EthercatMaster/register_information.xml", 'r')
  1538             reg_info_file = open("../../EthercatMaster/register_information.xml", 'r')
  1539         else:
  1539         else:
  1540             reg_info_file = open("./EthercatMaster/register_information.xml", 'r')
  1540             reg_info_file = open("./EthercatMaster/register_information.xml", 'r')
  1541         reg_info_tree = minidom.parse(reg_info_file)
  1541         reg_info_tree = minidom.parse(reg_info_file)
  1542         reg_info_file.close()
  1542         reg_info_file.close()
  1543         
  1543 
  1544         # parse register description
  1544         # parse register description
  1545         for register_info in reg_info_tree.childNodes:
  1545         for register_info in reg_info_tree.childNodes:
  1546             for register in register_info.childNodes:
  1546             for register in register_info.childNodes:
  1547                 if register.nodeType == reg_info_tree.ELEMENT_NODE and register.nodeName == "Register":
  1547                 if register.nodeType == reg_info_tree.ELEMENT_NODE and register.nodeName == "Register":
  1548                     # If it depends on the property(ESC type, PDI type, FMMU number, SM number)
  1548                     # If it depends on the property(ESC type, PDI type, FMMU number, SM number)
  1549                     for property, type, value in [("esc", "type", self.ESCType),
  1549                     for property, type, value in [("esc", "type", self.ESCType),
  1550                                                   ("pdi", "type", self.PDIType),
  1550                                                   ("pdi", "type", self.PDIType),
  1551                                                   ("fmmu", "number", self.FMMUNumber),
  1551                                                   ("fmmu", "number", self.FMMUNumber),
  1552                                                   ("sm", "number", self.SMNumber)]:
  1552                                                   ("sm", "number", self.SMNumber)]:
  1553                         if property in register.attributes.keys(): 
  1553                         if property in register.attributes.keys():
  1554                             if type == "type":
  1554                             if type == "type":
  1555                                 if register.attributes[property].value == value:
  1555                                 if register.attributes[property].value == value:
  1556                                     self.GetRegisterInfo(reg_info_tree, register)
  1556                                     self.GetRegisterInfo(reg_info_tree, register)
  1557                                     break
  1557                                     break
  1558                             else: # type == "number"
  1558                             else: # type == "number"
  1560                                     self.GetRegisterInfo(reg_info_tree, register)
  1560                                     self.GetRegisterInfo(reg_info_tree, register)
  1561                                     break
  1561                                     break
  1562                         else:
  1562                         else:
  1563                             self.GetRegisterInfo(reg_info_tree, register)
  1563                             self.GetRegisterInfo(reg_info_tree, register)
  1564                             break
  1564                             break
  1565                             
  1565 
  1566     def GetRegisterInfo(self, reg_info_tree, register):
  1566     def GetRegisterInfo(self, reg_info_tree, register):
  1567         """
  1567         """
  1568         Save the register's description into the dictionary.
  1568         Save the register's description into the dictionary.
  1569         reg_info_tree is based on the register_information.xml.
  1569         reg_info_tree is based on the register_information.xml.
  1570         @param reg_info_tree: XML tree
  1570         @param reg_info_tree: XML tree
  1571         @param register: register which you want to get the description
  1571         @param register: register which you want to get the description
  1572         """
  1572         """
  1573         # temporary variables for register main table idescription dictionary
  1573         # temporary variables for register main table idescription dictionary
  1574         reg_index = ""
  1574         reg_index = ""
  1575         reg_main_description = ""
  1575         reg_main_description = ""
  1576         
  1576 
  1577         for data in register.childNodes:
  1577         for data in register.childNodes:
  1578             if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Index":
  1578             if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Index":
  1579                 for index in data.childNodes:
  1579                 for index in data.childNodes:
  1580                     reg_index = index.nodeValue
  1580                     reg_index = index.nodeValue
  1581             if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Description":
  1581             if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Description":
  1582                 for description in data.childNodes:
  1582                 for description in data.childNodes:
  1583                     reg_main_description = description.nodeValue
  1583                     reg_main_description = description.nodeValue
  1584                     
  1584 
  1585             # Add description for register main table 
  1585             # Add description for register main table
  1586             if reg_index is not "" and reg_main_description is not "":
  1586             if reg_index is not "" and reg_main_description is not "":
  1587                 self.RegisterDescriptionDict[reg_index] = reg_main_description
  1587                 self.RegisterDescriptionDict[reg_index] = reg_main_description
  1588                     
  1588 
  1589             if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Details":
  1589             if data.nodeType == reg_info_tree.ELEMENT_NODE and data.nodeName == "Details":
  1590                 # declare register sub table description dictionary about this index
  1590                 # declare register sub table description dictionary about this index
  1591                 self.RegisterSubGridDict[reg_index] = []
  1591                 self.RegisterSubGridDict[reg_index] = []
  1592                 
  1592 
  1593                 for detail in data.childNodes:
  1593                 for detail in data.childNodes:
  1594                     if detail.nodeType == reg_info_tree.ELEMENT_NODE and detail.nodeName == "Detail":
  1594                     if detail.nodeType == reg_info_tree.ELEMENT_NODE and detail.nodeName == "Detail":
  1595                         # If it depends on the property(ESC type, PDI type, FMMU number, SM number)
  1595                         # If it depends on the property(ESC type, PDI type, FMMU number, SM number)
  1596                         for property, type, value in [("esc", "type", self.ESCType),
  1596                         for property, type, value in [("esc", "type", self.ESCType),
  1597                                                       ("pdi", "type", self.PDIType),
  1597                                                       ("pdi", "type", self.PDIType),
  1598                                                       ("fmmu", "number", self.FMMUNumber),
  1598                                                       ("fmmu", "number", self.FMMUNumber),
  1599                                                       ("sm", "number", self.SMNumber)]:
  1599                                                       ("sm", "number", self.SMNumber)]:
  1600                             if property in detail.attributes.keys(): 
  1600                             if property in detail.attributes.keys():
  1601                                 if type == "type":
  1601                                 if type == "type":
  1602                                     if detail.attributes[property].value == value:
  1602                                     if detail.attributes[property].value == value:
  1603                                         self.GetRegisterDetailInfo(reg_info_tree, reg_index, detail)
  1603                                         self.GetRegisterDetailInfo(reg_info_tree, reg_index, detail)
  1604                                         break
  1604                                         break
  1605                                 else: # type == "number"
  1605                                 else: # type == "number"
  1607                                         self.GetRegisterDetailInfo(reg_info_tree, reg_index, detail)
  1607                                         self.GetRegisterDetailInfo(reg_info_tree, reg_index, detail)
  1608                                         break
  1608                                         break
  1609                             else:
  1609                             else:
  1610                                 self.GetRegisterDetailInfo(reg_info_tree, reg_index, detail)
  1610                                 self.GetRegisterDetailInfo(reg_info_tree, reg_index, detail)
  1611                                 break
  1611                                 break
  1612                                           
  1612 
  1613     def GetRegisterDetailInfo(self, reg_info_tree, reg_index, detail):
  1613     def GetRegisterDetailInfo(self, reg_info_tree, reg_index, detail):
  1614         """
  1614         """
  1615         Get the resgister's detailed description(for sub table) from the reg_info_tree.
  1615         Get the resgister's detailed description(for sub table) from the reg_info_tree.
  1616         @param reg_info_tree: XML tree (register_information.xml)
  1616         @param reg_info_tree: XML tree (register_information.xml)
  1617         @param reg_index: index of the register
  1617         @param reg_index: index of the register
  1618         @param detail: description of the register
  1618         @param detail: description of the register
  1619         """
  1619         """
  1620         # temporary variables for register sub table description dictionary 
  1620         # temporary variables for register sub table description dictionary
  1621         # - It is initialized in every sub description 
  1621         # - It is initialized in every sub description
  1622         reg_bit_range = ""
  1622         reg_bit_range = ""
  1623         reg_sub_description = ""
  1623         reg_sub_description = ""
  1624         reg_enum_dictionary = {}
  1624         reg_enum_dictionary = {}
  1625         
  1625 
  1626         for detail_data in detail.childNodes:
  1626         for detail_data in detail.childNodes:
  1627             if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Range":                                            
  1627             if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Range":
  1628                 for range in detail_data.childNodes:
  1628                 for range in detail_data.childNodes:
  1629                     reg_bit_range = range.nodeValue
  1629                     reg_bit_range = range.nodeValue
  1630             if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Description":
  1630             if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Description":
  1631                 for description in detail_data.childNodes:
  1631                 for description in detail_data.childNodes:
  1632                     reg_sub_description = description.nodeValue
  1632                     reg_sub_description = description.nodeValue
  1633                     
  1633 
  1634             if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Enum":
  1634             if detail_data.nodeType == reg_info_tree.ELEMENT_NODE and detail_data.nodeName == "Enum":
  1635                 for enum in detail_data.childNodes:
  1635                 for enum in detail_data.childNodes:
  1636                     if enum.nodeType == reg_info_tree.ELEMENT_NODE and enum.nodeName == "item":
  1636                     if enum.nodeType == reg_info_tree.ELEMENT_NODE and enum.nodeName == "item":
  1637                         
  1637 
  1638                         # temporary variables for a description of each value 
  1638                         # temporary variables for a description of each value
  1639                         # For example, if the bit is 1, it is 'enabled'('On', 'True', etc.), 
  1639                         # For example, if the bit is 1, it is 'enabled'('On', 'True', etc.),
  1640                         # otherwise 'disabled'('Off', 'False', etc.). 
  1640                         # otherwise 'disabled'('Off', 'False', etc.).
  1641                         reg_sub_value = ""
  1641                         reg_sub_value = ""
  1642                         reg_sub_value_description = ""
  1642                         reg_sub_value_description = ""
  1643                         
  1643 
  1644                         for item in enum.childNodes:
  1644                         for item in enum.childNodes:
  1645                             if item.nodeType == reg_info_tree.ELEMENT_NODE and item.nodeName == "value":
  1645                             if item.nodeType == reg_info_tree.ELEMENT_NODE and item.nodeName == "value":
  1646                                 for value in item.childNodes:
  1646                                 for value in item.childNodes:
  1647                                     reg_sub_value = value.nodeValue
  1647                                     reg_sub_value = value.nodeValue
  1648                             if item.nodeType == reg_info_tree.ELEMENT_NODE and item.nodeName == "Description":
  1648                             if item.nodeType == reg_info_tree.ELEMENT_NODE and item.nodeName == "Description":
  1649                                 for description in item.childNodes:
  1649                                 for description in item.childNodes:
  1650                                     reg_sub_value_description = description.nodeValue
  1650                                     reg_sub_value_description = description.nodeValue
  1651                                     
  1651 
  1652                             # Add a description of each value to register enum dictionary
  1652                             # Add a description of each value to register enum dictionary
  1653                             if reg_sub_value is not "" and reg_sub_value_description is not "":
  1653                             if reg_sub_value is not "" and reg_sub_value_description is not "":
  1654                                 reg_enum_dictionary[reg_sub_value] = reg_sub_value_description
  1654                                 reg_enum_dictionary[reg_sub_value] = reg_sub_value_description
  1655                             
  1655 
  1656         # add a description to register sub table description dictionary
  1656         # add a description to register sub table description dictionary
  1657         if reg_bit_range is not "" and reg_sub_description is not "":
  1657         if reg_bit_range is not "" and reg_sub_description is not "":
  1658             self.RegisterSubGridDict[reg_index].append([reg_bit_range, 
  1658             self.RegisterSubGridDict[reg_index].append([reg_bit_range,
  1659                                                          reg_sub_description, reg_enum_dictionary])
  1659                                                          reg_sub_description, reg_enum_dictionary])
  1660     
  1660 
  1661     def ParseData(self):
  1661     def ParseData(self):
  1662         """
  1662         """
  1663         Transform the data into dec, hex, string, and description
  1663         Transform the data into dec, hex, string, and description
  1664         """
  1664         """
  1665         row_data = []
  1665         row_data = []
  1666         self.RegMonitorData = []
  1666         self.RegMonitorData = []
  1667         reg_word = ""
  1667         reg_word = ""
  1668         
  1668 
  1669         reg_data = self.Controler.CommonMethod.RegData.split()
  1669         reg_data = self.Controler.CommonMethod.RegData.split()
  1670         
  1670 
  1671         # loop for register(0x0000:0x0fff)
  1671         # loop for register(0x0000:0x0fff)
  1672         for address in range(0x1000):
  1672         for address in range(0x1000):
  1673             # arrange 2 Bytes of register data 
  1673             # arrange 2 Bytes of register data
  1674             reg_word = reg_data[address].split('x')[1] + reg_word
  1674             reg_word = reg_data[address].split('x')[1] + reg_word
  1675             if (address%2) == 1:
  1675             if (address%2) == 1:
  1676                 # append address
  1676                 # append address
  1677                 hex_address = "{:0>4x}".format(address-1)
  1677                 hex_address = "{:0>4x}".format(address-1)
  1678                 row_data.append(hex_address)
  1678                 row_data.append(hex_address)
  1679                 
  1679 
  1680                 # append description
  1680                 # append description
  1681                 if self.RegisterDescriptionDict.has_key(hex_address):
  1681                 if self.RegisterDescriptionDict.has_key(hex_address):
  1682                     row_data.append(self.RegisterDescriptionDict[hex_address])
  1682                     row_data.append(self.RegisterDescriptionDict[hex_address])
  1683                 else:
  1683                 else:
  1684                     row_data.append("")
  1684                     row_data.append("")
  1685                     
  1685 
  1686                 # append Decimal value
  1686                 # append Decimal value
  1687                 row_data.append(str(int(reg_word, 16)))
  1687                 row_data.append(str(int(reg_word, 16)))
  1688                 
  1688 
  1689                 # append Hex value
  1689                 # append Hex value
  1690                 row_data.append('0x'+reg_word)
  1690                 row_data.append('0x'+reg_word)
  1691                 
  1691 
  1692                 # append ASCII value
  1692                 # append ASCII value
  1693                 char_data = ""
  1693                 char_data = ""
  1694                 for iter in range(2):
  1694                 for iter in range(2):
  1695                     if int(reg_word[iter*2:iter*2+2], 16)>=32 and int(reg_word[iter*2:iter*2+2], 16)<=126:
  1695                     if int(reg_word[iter*2:iter*2+2], 16)>=32 and int(reg_word[iter*2:iter*2+2], 16)<=126:
  1696                         char_data = char_data + chr(int(reg_word[iter*2:iter*2+2], 16))
  1696                         char_data = char_data + chr(int(reg_word[iter*2:iter*2+2], 16))
  1697                     else:
  1697                     else:
  1698                         char_data = char_data + "."
  1698                         char_data = char_data + "."
  1699                 row_data.append(char_data)
  1699                 row_data.append(char_data)
  1700                 
  1700 
  1701                 self.RegMonitorData.append(row_data)
  1701                 self.RegMonitorData.append(row_data)
  1702                 reg_word = "" # initialize regWord
  1702                 reg_word = "" # initialize regWord
  1703                 row_data = []
  1703                 row_data = []
  1704     
  1704 
  1705     def OnReloadButton(self, event):
  1705     def OnReloadButton(self, event):
  1706         """
  1706         """
  1707         Handle the click event of the 'Reload' button.
  1707         Handle the click event of the 'Reload' button.
  1708         Get the data from registers again, and update the table.
  1708         Get the data from registers again, and update the table.
  1709         @param event: wx.EVT_BUTTON object
  1709         @param event: wx.EVT_BUTTON object
  1715             self.BasicSetData()
  1715             self.BasicSetData()
  1716             self.ParseData()
  1716             self.ParseData()
  1717             # set data into UI
  1717             # set data into UI
  1718             if self.CompactFlag:
  1718             if self.CompactFlag:
  1719                 self.ToggleCompactViewCheckbox(True)
  1719                 self.ToggleCompactViewCheckbox(True)
  1720             else : 
  1720             else :
  1721                 for index in range(4):
  1721                 for index in range(4):
  1722                     self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol, 
  1722                     self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
  1723                                                                          self.PageRange[index][0], self.PageRange[index][1], 
  1723                                                                          self.PageRange[index][0], self.PageRange[index][1],
  1724                                                                          self.RegMonitorData)
  1724                                                                          self.RegMonitorData)
  1725 
  1725 
  1726     def ToggleCompactViewCheckbox(self, event):
  1726     def ToggleCompactViewCheckbox(self, event):
  1727         """
  1727         """
  1728         Handles the event of the 'Compact view' check box.
  1728         Handles the event of the 'Compact view' check box.
  1729         If it's checked, show only the registers that have a description.
  1729         If it's checked, show only the registers that have a description.
  1730         If not, show all the registers.
  1730         If not, show all the registers.
  1731         @param event: wx.EVT_CHECKBOX object
  1731         @param event: wx.EVT_CHECKBOX object
  1732         """
  1732         """
  1733         
  1733 
  1734         # If "Compact View" Checkbox is True
  1734         # If "Compact View" Checkbox is True
  1735         ## 'event' is argument of this method or event of checkbox.
  1735         ## 'event' is argument of this method or event of checkbox.
  1736         if event==True or event.GetEventObject().GetValue():
  1736         if event==True or event.GetEventObject().GetValue():
  1737             self.CompactFlag = True
  1737             self.CompactFlag = True
  1738             
  1738 
  1739             reg_compact_data = []
  1739             reg_compact_data = []
  1740             page_row = [0, 0, 0, 0]
  1740             page_row = [0, 0, 0, 0]
  1741             for index in range(4):
  1741             for index in range(4):
  1742                 self.PageRange[index] = [0, 0]
  1742                 self.PageRange[index] = [0, 0]
  1743 
  1743 
  1756             for index in range(4):
  1756             for index in range(4):
  1757                 self.MainRow[index] = page_row[index]
  1757                 self.MainRow[index] = page_row[index]
  1758                 self.PageRange[index][1] = page_row[index]
  1758                 self.PageRange[index][1] = page_row[index]
  1759                 for iter in range(index):
  1759                 for iter in range(index):
  1760                     self.PageRange[index][0] += page_row[iter]
  1760                     self.PageRange[index][0] += page_row[iter]
  1761                     self.PageRange[index][1] += page_row[iter] 
  1761                     self.PageRange[index][1] += page_row[iter]
  1762                           
  1762 
  1763             # Update table
  1763             # Update table
  1764             for index in range(4):
  1764             for index in range(4):
  1765                 self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol, 
  1765                 self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
  1766                                                                       self.PageRange[index][0], self.PageRange[index][1], 
  1766                                                                       self.PageRange[index][0], self.PageRange[index][1],
  1767                                                                       reg_compact_data)
  1767                                                                       reg_compact_data)
  1768             
  1768 
  1769         # Compact View Checkbox is False    
  1769         # Compact View Checkbox is False
  1770         else:
  1770         else:
  1771             self.CompactFlag = False
  1771             self.CompactFlag = False
  1772             # Setting original rows, cols and range
  1772             # Setting original rows, cols and range
  1773             self.MainRow = [512, 512, 512, 512]
  1773             self.MainRow = [512, 512, 512, 512]
  1774             self.PageRange = []
  1774             self.PageRange = []
  1775             
  1775 
  1776             for index in range(4):
  1776             for index in range(4):
  1777                 self.PageRange.append([512*index, 512*(index+1)])
  1777                 self.PageRange.append([512*index, 512*(index+1)])
  1778             
  1778 
  1779             # Update table 
  1779             # Update table
  1780             for index in range(4):
  1780             for index in range(4):
  1781                 self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol, 
  1781                 self.RegisterNotebook.RegPage[index].UpdateMainTable(self.MainRow[index], self.MainCol,
  1782                                                                       self.PageRange[index][0], self.PageRange[index][1], 
  1782                                                                       self.PageRange[index][0], self.PageRange[index][1],
  1783                                                                       self.RegMonitorData)
  1783                                                                       self.RegMonitorData)
  1784                 
  1784 
  1785 
  1785 
  1786 #-------------------------------------------------------------------------------
  1786 #-------------------------------------------------------------------------------
  1787 #                    For Register Access Notebook (divide index range)
  1787 #                    For Register Access Notebook (divide index range)
  1788 #-------------------------------------------------------------------------------  
  1788 #-------------------------------------------------------------------------------
  1789 class RegisterNotebook(wx.Notebook):
  1789 class RegisterNotebook(wx.Notebook):
  1790     def __init__(self, parent, controler):
  1790     def __init__(self, parent, controler):
  1791         """
  1791         """
  1792         Constructor
  1792         Constructor
  1793         @param parent: RegisterAccessPanel object
  1793         @param parent: RegisterAccessPanel object
  1794         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1794         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1795         """
  1795         """
  1796         wx.Notebook.__init__(self, parent, id = -1)
  1796         wx.Notebook.__init__(self, parent, id = -1)
  1797         
  1797 
  1798         self.parent = parent
  1798         self.parent = parent
  1799         self.Controler = controler
  1799         self.Controler = controler
  1800         
  1800 
  1801         # Initialize pages
  1801         # Initialize pages
  1802         self.RegPage = []
  1802         self.RegPage = []
  1803         for iter in range(4):
  1803         for iter in range(4):
  1804             self.RegPage.append(None)
  1804             self.RegPage.append(None)
  1805         
  1805 
  1806         for index in range(4):
  1806         for index in range(4):
  1807             self.RegPage[index] = RegisterNotebookPanel(self, self.Controler, 
  1807             self.RegPage[index] = RegisterNotebookPanel(self, self.Controler,
  1808                                                     parent.MainRow[index], parent.MainCol)
  1808                                                     parent.MainRow[index], parent.MainCol)
  1809             self.AddPage(self.RegPage[index], 
  1809             self.AddPage(self.RegPage[index],
  1810                          "0x"+"{:0>4x}".format(index*1024)+" - 0x"+"{:0>4x}".format((index+1)*1024-1))
  1810                          "0x"+"{:0>4x}".format(index*1024)+" - 0x"+"{:0>4x}".format((index+1)*1024-1))
  1811         
  1811 
  1812         self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
  1812         self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
  1813         self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
  1813         self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
  1814 
  1814 
  1815     def OnPageChanged(self, event):
  1815     def OnPageChanged(self, event):
  1816         old = event.GetOldSelection()
  1816         old = event.GetOldSelection()
  1824         sel = self.GetSelection()
  1824         sel = self.GetSelection()
  1825         event.Skip()
  1825         event.Skip()
  1826 
  1826 
  1827 
  1827 
  1828 #-------------------------------------------------------------------------------
  1828 #-------------------------------------------------------------------------------
  1829 #                    For Register Access Notebook Panel 
  1829 #                    For Register Access Notebook Panel
  1830 #                  (Main UI : including main, sub table)
  1830 #                  (Main UI : including main, sub table)
  1831 #-------------------------------------------------------------------------------  
  1831 #-------------------------------------------------------------------------------
  1832 class RegisterNotebookPanel(wx.Panel):
  1832 class RegisterNotebookPanel(wx.Panel):
  1833     def __init__(self, parent, controler, row, col):
  1833     def __init__(self, parent, controler, row, col):
  1834         """
  1834         """
  1835         Constructor
  1835         Constructor
  1836         @param parent: RegisterAccessPanel object
  1836         @param parent: RegisterAccessPanel object
  1837         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1837         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1838         @param row, col: size of the table
  1838         @param row, col: size of the table
  1839     	"""
  1839     	"""
  1840         wx.Panel.__init__(self, parent, -1)
  1840         wx.Panel.__init__(self, parent, -1)
  1841         
  1841 
  1842         self.parent = parent
  1842         self.parent = parent
  1843         self.Controler = controler
  1843         self.Controler = controler
  1844         self.Row = row
  1844         self.Row = row
  1845         self.Col = col
  1845         self.Col = col
  1846         sub_row = 0
  1846         sub_row = 0
  1847         sub_col = 4
  1847         sub_col = 4
  1848         
  1848 
  1849         self.Sizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=30)
  1849         self.Sizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=30)
  1850         
  1850 
  1851         self.MainTable = RegisterMainTable(self, self.Row, self.Col, self.Controler)
  1851         self.MainTable = RegisterMainTable(self, self.Row, self.Col, self.Controler)
  1852         self.SubTable = RegisterSubTable(self, sub_row, sub_col)
  1852         self.SubTable = RegisterSubTable(self, sub_row, sub_col)
  1853         
  1853 
  1854         self.SubTable.CreateGrid(sub_row, sub_col)
  1854         self.SubTable.CreateGrid(sub_row, sub_col)
  1855         self.SubTable.SetValue(self, [])
  1855         self.SubTable.SetValue(self, [])
  1856         
  1856 
  1857         self.Sizer.AddMany([self.MainTable, self.SubTable])
  1857         self.Sizer.AddMany([self.MainTable, self.SubTable])
  1858         
  1858 
  1859         self.SetSizer(self.Sizer)
  1859         self.SetSizer(self.Sizer)
  1860      
  1860 
  1861     def UpdateMainTable(self, row, col, low_index, high_index, data):
  1861     def UpdateMainTable(self, row, col, low_index, high_index, data):
  1862         """
  1862         """
  1863         Updates main table.
  1863         Updates main table.
  1864         It's done by deleting the main table and creating it again.
  1864         It's done by deleting the main table and creating it again.
  1865         @param row, col: size of the table
  1865         @param row, col: size of the table
  1890         self.Sizer.Layout()
  1890         self.Sizer.Layout()
  1891         self.SetSizer(self.Sizer)
  1891         self.SetSizer(self.Sizer)
  1892         self.SubTable.CreateGrid(row, col)
  1892         self.SubTable.CreateGrid(row, col)
  1893         self.SubTable.SetValue(self, data)
  1893         self.SubTable.SetValue(self, data)
  1894         self.SubTable.Update()
  1894         self.SubTable.Update()
  1895         
  1895 
  1896 
  1896 
  1897 #-------------------------------------------------------------------------------
  1897 #-------------------------------------------------------------------------------
  1898 #                    For Register Access Notebook Panel (Main Table)
  1898 #                    For Register Access Notebook Panel (Main Table)
  1899 #-------------------------------------------------------------------------------  
  1899 #-------------------------------------------------------------------------------
  1900 class RegisterMainTable(wx.grid.Grid):
  1900 class RegisterMainTable(wx.grid.Grid):
  1901     def __init__(self, parent, row, col, controler):        
  1901     def __init__(self, parent, row, col, controler):
  1902         """
  1902         """
  1903 	    Constructor
  1903 	    Constructor
  1904 	    @param parent: RegisterNotebook object
  1904 	    @param parent: RegisterNotebook object
  1905 	    @param row, col: size of the table
  1905 	    @param row, col: size of the table
  1906 	    @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1906 	    @param controler: _EthercatSlaveCTN class in EthercatSlave.py
  1909         self.Data = {}
  1909         self.Data = {}
  1910         self.Row = row
  1910         self.Row = row
  1911         self.Col = col
  1911         self.Col = col
  1912         self.Controler = controler
  1912         self.Controler = controler
  1913         self.RegisterAccessPanel = self.parent.parent.parent
  1913         self.RegisterAccessPanel = self.parent.parent.parent
  1914         
  1914 
  1915         wx.grid.Grid.__init__(self, parent, -1, size=(820,300), 
  1915         wx.grid.Grid.__init__(self, parent, -1, size=(820,300),
  1916                               style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)        
  1916                               style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
  1917         
  1917 
  1918         for evt, mapping_method in [(gridlib.EVT_GRID_CELL_LEFT_CLICK, self.OnSelectCell),
  1918         for evt, mapping_method in [(gridlib.EVT_GRID_CELL_LEFT_CLICK, self.OnSelectCell),
  1919                                     (gridlib.EVT_GRID_CELL_LEFT_CLICK, self.OnSelectCell),
  1919                                     (gridlib.EVT_GRID_CELL_LEFT_CLICK, self.OnSelectCell),
  1920                                     (gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.OnRegModifyDialog)]:
  1920                                     (gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.OnRegModifyDialog)]:
  1921             self.Bind(evt, mapping_method)
  1921             self.Bind(evt, mapping_method)
  1922        
  1922 
  1923     def SetValue(self, parent, reg_monitor_data, low_index, high_index):  
  1923     def SetValue(self, parent, reg_monitor_data, low_index, high_index):
  1924         """
  1924         """
  1925 	    Set the RegMonitorData into the main table.
  1925 	    Set the RegMonitorData into the main table.
  1926 	    @param parent: RegisterNotebook object
  1926 	    @param parent: RegisterNotebook object
  1927 	    @param reg_monitor_data: data
  1927 	    @param reg_monitor_data: data
  1928 	    @param low_index: the lowest index of the page
  1928 	    @param low_index: the lowest index of the page
  1929 	    @param high_index: the highest index of the page
  1929 	    @param high_index: the highest index of the page
  1930 	    """
  1930 	    """
  1931         self.RegMonitorData = reg_monitor_data
  1931         self.RegMonitorData = reg_monitor_data
  1932         
  1932 
  1933         # set label name and size
  1933         # set label name and size
  1934         register_maintable_label = [(0, "Description"), (1, "Dec"), 
  1934         register_maintable_label = [(0, "Description"), (1, "Dec"),
  1935                                     (2, "Hex"), (3, "Char")]
  1935                                     (2, "Hex"), (3, "Char")]
  1936         
  1936 
  1937         for (index, label) in register_maintable_label:
  1937         for (index, label) in register_maintable_label:
  1938             self.SetColLabelValue(index, label)
  1938             self.SetColLabelValue(index, label)
  1939         
  1939 
  1940         self.SetColSize(0, 200)
  1940         self.SetColSize(0, 200)
  1941     
  1941 
  1942         # if reg_monitor_data is 0, it is initialization of register access.
  1942         # if reg_monitor_data is 0, it is initialization of register access.
  1943         if reg_monitor_data == 0:
  1943         if reg_monitor_data == 0:
  1944             return 0
  1944             return 0
  1945     
  1945 
  1946         # set data into UI 
  1946         # set data into UI
  1947         row = col = 0
  1947         row = col = 0
  1948         for row_index in reg_monitor_data[low_index:high_index]:
  1948         for row_index in reg_monitor_data[low_index:high_index]:
  1949             col = 0
  1949             col = 0
  1950             self.SetRowLabelValue(row, row_index[0])
  1950             self.SetRowLabelValue(row, row_index[0])
  1951             for data_index in range(4):
  1951             for data_index in range(4):
  1952                 self.SetCellValue(row, col, row_index[data_index+1])
  1952                 self.SetCellValue(row, col, row_index[data_index+1])
  1953                 self.SetCellAlignment(row, col, wx.ALIGN_CENTRE, wx.ALIGN_CENTER)
  1953                 self.SetCellAlignment(row, col, wx.ALIGN_CENTRE, wx.ALIGN_CENTER)
  1954                 self.SetReadOnly(row, col, True)
  1954                 self.SetReadOnly(row, col, True)
  1955                 col = col + 1
  1955                 col = col + 1
  1956             row = row + 1
  1956             row = row + 1
  1957     
  1957 
  1958     def OnSelectCell(self, event): 
  1958     def OnSelectCell(self, event):
  1959         """
  1959         """
  1960 	    Handles the event of the cell of the main table.
  1960 	    Handles the event of the cell of the main table.
  1961 	    @param event: gridlib object (left click)
  1961 	    @param event: gridlib object (left click)
  1962 	    """
  1962 	    """
  1963         # if reg_monitor_data is 0, it is initialization of register access.
  1963         # if reg_monitor_data is 0, it is initialization of register access.
  1964         if self.RegMonitorData == 0:
  1964         if self.RegMonitorData == 0:
  1965             event.Skip()
  1965             event.Skip()
  1966             return 0
  1966             return 0
  1967         
  1967 
  1968         sub_row = 0
  1968         sub_row = 0
  1969         sub_col = 4
  1969         sub_col = 4
  1970         
  1970 
  1971         address = self.GetRowLabelValue(event.GetRow())
  1971         address = self.GetRowLabelValue(event.GetRow())
  1972         
  1972 
  1973         reg_sub_grid_data = []
  1973         reg_sub_grid_data = []
  1974         
  1974 
  1975         BIT_RANGE, NAME, DESCRIPTIONS = range(3)
  1975         BIT_RANGE, NAME, DESCRIPTIONS = range(3)
  1976         
  1976 
  1977         # Check if this register's detail description is exist or not, 
  1977         # Check if this register's detail description is exist or not,
  1978         # and create data structure for the detail description table ; sub grid
  1978         # and create data structure for the detail description table ; sub grid
  1979         if address in self.RegisterAccessPanel.RegisterSubGridDict:
  1979         if address in self.RegisterAccessPanel.RegisterSubGridDict:
  1980             for element in self.RegisterAccessPanel.RegisterSubGridDict[address]:
  1980             for element in self.RegisterAccessPanel.RegisterSubGridDict[address]:
  1981                 row_data =[]
  1981                 row_data =[]
  1982                 row_data.append(element[BIT_RANGE])
  1982                 row_data.append(element[BIT_RANGE])
  1989                     row_data.append(element[DESCRIPTIONS][value])
  1989                     row_data.append(element[DESCRIPTIONS][value])
  1990                 else:
  1990                 else:
  1991                     row_data.append('')
  1991                     row_data.append('')
  1992                 reg_sub_grid_data.append(row_data)
  1992                 reg_sub_grid_data.append(row_data)
  1993                 sub_row = sub_row + 1
  1993                 sub_row = sub_row + 1
  1994         
  1994 
  1995         self.parent.UpdateSubTable(sub_row, sub_col, reg_sub_grid_data)
  1995         self.parent.UpdateSubTable(sub_row, sub_col, reg_sub_grid_data)
  1996         # event.Skip() updates UI of selecting cell
  1996         # event.Skip() updates UI of selecting cell
  1997         event.Skip()
  1997         event.Skip()
  1998     
  1998 
  1999     def OnRegModifyDialog(self, event):
  1999     def OnRegModifyDialog(self, event):
  2000         """
  2000         """
  2001         Handle the event of the cell of the main table.
  2001         Handle the event of the cell of the main table.
  2002         Display the window where the user modifies the value of the cell.
  2002         Display the window where the user modifies the value of the cell.
  2003         @param event: gridlib object (double click)
  2003         @param event: gridlib object (double click)
  2004 	    """
  2004 	    """
  2005         # user can enter a value in case that user double-clicked 'Dec' or 'Hex' value.
  2005         # user can enter a value in case that user double-clicked 'Dec' or 'Hex' value.
  2006         if event.GetCol() == 1 or event.GetCol() == 2:
  2006         if event.GetCol() == 1 or event.GetCol() == 2:
  2007             dlg = wx.TextEntryDialog(self, "Enter hex(0xnnnn) or dec(n) value", 
  2007             dlg = wx.TextEntryDialog(self, "Enter hex(0xnnnn) or dec(n) value",
  2008                                      "Register Modify Dialog", style = wx.OK|wx.CANCEL)
  2008                                      "Register Modify Dialog", style = wx.OK|wx.CANCEL)
  2009             
  2009 
  2010             # Setting value in initial dialog value
  2010             # Setting value in initial dialog value
  2011             start_value = self.GetCellValue(event.GetRow(), event.GetCol())
  2011             start_value = self.GetCellValue(event.GetRow(), event.GetCol())
  2012             dlg.SetValue(start_value)
  2012             dlg.SetValue(start_value)
  2013         
  2013 
  2014             if dlg.ShowModal() == wx.ID_OK:
  2014             if dlg.ShowModal() == wx.ID_OK:
  2015                 try:
  2015                 try:
  2016                     # It int(input) success, this input is dev or hex value. 
  2016                     # It int(input) success, this input is dev or hex value.
  2017                     # Otherwise, it's error, so it goes except.
  2017                     # Otherwise, it's error, so it goes except.
  2018                     int(dlg.GetValue(), 0)
  2018                     int(dlg.GetValue(), 0)
  2019 
  2019 
  2020                     # reg_write
  2020                     # reg_write
  2021                     # ex) ethercat reg_write -p 0 -t uint16 0x0000 0x0000
  2021                     # ex) ethercat reg_write -p 0 -t uint16 0x0000 0x0000
  2022                     return_val = self.Controler.CommonMethod.RegWrite('0x'+self.GetRowLabelValue(event.GetRow()), dlg.GetValue())
  2022                     return_val = self.Controler.CommonMethod.RegWrite('0x'+self.GetRowLabelValue(event.GetRow()), dlg.GetValue())
  2023 
  2023 
  2024                     if len(return_val)==0:
  2024                     if len(return_val)==0:
  2025                         # set dec
  2025                         # set dec
  2026                         self.SetCellValue(event.GetRow(), 1, str(int(dlg.GetValue(), 0))) 
  2026                         self.SetCellValue(event.GetRow(), 1, str(int(dlg.GetValue(), 0)))
  2027                         # set hex
  2027                         # set hex
  2028                         hex_data = '0x'+"{:0>4x}".format(int(dlg.GetValue(), 0))
  2028                         hex_data = '0x'+"{:0>4x}".format(int(dlg.GetValue(), 0))
  2029                         self.SetCellValue(event.GetRow(), 2, hex_data)
  2029                         self.SetCellValue(event.GetRow(), 2, hex_data)
  2030                         # set char
  2030                         # set char
  2031                         char_data = ""
  2031                         char_data = ""
  2033                         for iter in range(2):
  2033                         for iter in range(2):
  2034                             if int(hex_data[(iter+1)*2:(iter+2)*2], 16)>=32 and int(hex_data[(iter+1)*2:(iter+2)*2], 16)<=126:
  2034                             if int(hex_data[(iter+1)*2:(iter+2)*2], 16)>=32 and int(hex_data[(iter+1)*2:(iter+2)*2], 16)<=126:
  2035                                 char_data = char_data + chr(int(hex_data[(iter+1)*2:(iter+2)*2], 16))
  2035                                 char_data = char_data + chr(int(hex_data[(iter+1)*2:(iter+2)*2], 16))
  2036                             else:
  2036                             else:
  2037                                 char_data = char_data + "."
  2037                                 char_data = char_data + "."
  2038                             
  2038 
  2039                         self.SetCellValue(event.GetRow(), 3, char_data) 
  2039                         self.SetCellValue(event.GetRow(), 3, char_data)
  2040                     
  2040 
  2041                     else:
  2041                     else:
  2042                         self.Controler.CommonMethod.CreateErrorDialog('You can\'t modify it. This register is read-only or it\'s not connected.')
  2042                         self.Controler.CommonMethod.CreateErrorDialog('You can\'t modify it. This register is read-only or it\'s not connected.')
  2043                 
  2043 
  2044                 except ValueError:
  2044                 except ValueError:
  2045                     self.Controler.CommonMethod.CreateErrorDialog('You entered wrong value. You can enter dec or hex value only.')
  2045                     self.Controler.CommonMethod.CreateErrorDialog('You entered wrong value. You can enter dec or hex value only.')
  2046         
  2046 
  2047     
  2047 
  2048 #-------------------------------------------------------------------------------
  2048 #-------------------------------------------------------------------------------
  2049 #                    For Register Access Notebook Panel (Sub Table)
  2049 #                    For Register Access Notebook Panel (Sub Table)
  2050 #-------------------------------------------------------------------------------  
  2050 #-------------------------------------------------------------------------------
  2051 class RegisterSubTable(wx.grid.Grid):
  2051 class RegisterSubTable(wx.grid.Grid):
  2052     def __init__(self, parent, row, col):
  2052     def __init__(self, parent, row, col):
  2053         """
  2053         """
  2054     	 Constructor
  2054     	 Constructor
  2055     	 @param parent: RegisterNotebook object
  2055     	 @param parent: RegisterNotebook object
  2058         self.parent = parent
  2058         self.parent = parent
  2059         self.Data = {}
  2059         self.Data = {}
  2060         self.Row = row
  2060         self.Row = row
  2061         self.Col = col
  2061         self.Col = col
  2062 
  2062 
  2063         wx.grid.Grid.__init__(self, parent, -1, size=(820,150), 
  2063         wx.grid.Grid.__init__(self, parent, -1, size=(820,150),
  2064                               style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)        
  2064                               style=wx.EXPAND|wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)
  2065 
  2065 
  2066     def SetValue(self, parent, data):
  2066     def SetValue(self, parent, data):
  2067         """
  2067         """
  2068 	    Set the data into the subtable.
  2068 	    Set the data into the subtable.
  2069 	    @param parent: RegisterNotebook object
  2069 	    @param parent: RegisterNotebook object
  2070 	    @param data: data
  2070 	    @param data: data
  2071 	    """
  2071 	    """
  2072         # lset label name and size
  2072         # lset label name and size
  2073         Register_SubTable_Label = [(0, "Bits"), (1, "Name"), 
  2073         Register_SubTable_Label = [(0, "Bits"), (1, "Name"),
  2074                                     (2, "Value"), (3, "Enum")]
  2074                                     (2, "Value"), (3, "Enum")]
  2075         
  2075 
  2076         for (index, label) in Register_SubTable_Label:
  2076         for (index, label) in Register_SubTable_Label:
  2077             self.SetColLabelValue(index, label)
  2077             self.SetColLabelValue(index, label)
  2078         
  2078 
  2079         self.SetColSize(1, 200)
  2079         self.SetColSize(1, 200)
  2080         self.SetColSize(3, 200)
  2080         self.SetColSize(3, 200)
  2081             
  2081 
  2082         # set data into table
  2082         # set data into table
  2083         row = col = 0
  2083         row = col = 0
  2084         for rowData in data: 
  2084         for rowData in data:
  2085             col = 0     
  2085             col = 0
  2086             for element in rowData:
  2086             for element in rowData:
  2087                 self.SetCellValue(row, col, element)
  2087                 self.SetCellValue(row, col, element)
  2088                 self.SetCellAlignment(row, col, wx.ALIGN_CENTRE, wx.ALIGN_CENTER)
  2088                 self.SetCellAlignment(row, col, wx.ALIGN_CENTRE, wx.ALIGN_CENTER)
  2089                 self.SetReadOnly(row, col, True)
  2089                 self.SetReadOnly(row, col, True)
  2090                 col = col + 1
  2090                 col = col + 1
  2091             row = row + 1
  2091             row = row + 1
  2092                 
  2092 
  2093 
  2093 
  2094 #-------------------------------------------------------------------------------
  2094 #-------------------------------------------------------------------------------
  2095 #                    For Master State Panel
  2095 #                    For Master State Panel
  2096 #-------------------------------------------------------------------------------  
  2096 #-------------------------------------------------------------------------------
  2097 class MasterStatePanelClass(wx.Panel):
  2097 class MasterStatePanelClass(wx.Panel):
  2098     def __init__(self, parent, controler):
  2098     def __init__(self, parent, controler):
  2099         """
  2099         """
  2100         Constructor
  2100         Constructor
  2101         @param parent: wx.ScrollWindow object
  2101         @param parent: wx.ScrollWindow object
  2102         @Param controler: _EthercatSlaveCTN class in EthercatSlave.py
  2102         @Param controler: _EthercatSlaveCTN class in EthercatSlave.py
  2103         """
  2103         """
  2104         wx.Panel.__init__(self, parent, -1, (0, 0), 
  2104         wx.Panel.__init__(self, parent, -1, (0, 0),
  2105                           size=wx.DefaultSize, style = wx.SUNKEN_BORDER)
  2105                           size=wx.DefaultSize, style = wx.SUNKEN_BORDER)
  2106         self.Controler = controler
  2106         self.Controler = controler
  2107         self.parent = parent
  2107         self.parent = parent
  2108         self.StaticBox = {}
  2108         self.StaticBox = {}
  2109         self.StaticText = {}
  2109         self.StaticText = {}
  2110         self.TextCtrl = {}
  2110         self.TextCtrl = {}
  2111           
  2111 
  2112         # ----------------------- Main Sizer and Update Button --------------------------------------------
  2112         # ----------------------- Main Sizer and Update Button --------------------------------------------
  2113         self.MasterStateSizer = {"main" : wx.BoxSizer(wx.VERTICAL)}
  2113         self.MasterStateSizer = {"main" : wx.BoxSizer(wx.VERTICAL)}
  2114         for key, attr in [
  2114         for key, attr in [
  2115             ("innerMain",           [1, 10, 2, 10]),
  2115             ("innerMain",           [1, 10, 2, 10]),
  2116             ("innerTopHalf",        [2, 10, 1, 10]),
  2116             ("innerTopHalf",        [2, 10, 1, 10]),
  2121             self.MasterStateSizer[key] = wx.FlexGridSizer(cols=attr[0], hgap=attr[1], rows=attr[2], vgap=attr[3])
  2121             self.MasterStateSizer[key] = wx.FlexGridSizer(cols=attr[0], hgap=attr[1], rows=attr[2], vgap=attr[3])
  2122 
  2122 
  2123 
  2123 
  2124         self.UpdateButton = wx.Button(self, label=_('Update'))
  2124         self.UpdateButton = wx.Button(self, label=_('Update'))
  2125         self.UpdateButton.Bind(wx.EVT_BUTTON, self.OnButtonClick)
  2125         self.UpdateButton.Bind(wx.EVT_BUTTON, self.OnButtonClick)
  2126        
  2126 
  2127         for key, label in [                
  2127         for key, label in [
  2128             ('masterState', 'EtherCAT Master State'),
  2128             ('masterState', 'EtherCAT Master State'),
  2129             ('deviceInfo', 'Ethernet Network Card Information'),
  2129             ('deviceInfo', 'Ethernet Network Card Information'),
  2130             ('frameInfo', 'Network Frame Information')]:
  2130             ('frameInfo', 'Network Frame Information')]:
  2131             self.StaticBox[key] = wx.StaticBox(self, label=_(label))
  2131             self.StaticBox[key] = wx.StaticBox(self, label=_(label))
  2132             self.MasterStateSizer[key] = wx.StaticBoxSizer(self.StaticBox[key])
  2132             self.MasterStateSizer[key] = wx.StaticBoxSizer(self.StaticBox[key])
  2133         
  2133 
  2134         
  2134 
  2135         # ----------------------- Master State -----------------------------------------------------------
  2135         # ----------------------- Master State -----------------------------------------------------------
  2136         for key, label in [
  2136         for key, label in [
  2137             ('Phase', 'Phase:'),
  2137             ('Phase', 'Phase:'),
  2138             ('Active', 'Active:'),
  2138             ('Active', 'Active:'),
  2139             ('Slaves', 'Slave Count:')]:
  2139             ('Slaves', 'Slave Count:')]:
  2140             self.StaticText[key] = wx.StaticText(self, label=_(label))
  2140             self.StaticText[key] = wx.StaticText(self, label=_(label))
  2141             self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
  2141             self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
  2142             self.MasterStateSizer['innerMasterState'].AddMany([self.StaticText[key], self.TextCtrl[key]])    
  2142             self.MasterStateSizer['innerMasterState'].AddMany([self.StaticText[key], self.TextCtrl[key]])
  2143         
  2143 
  2144         self.MasterStateSizer['masterState'].AddSizer(self.MasterStateSizer['innerMasterState'])
  2144         self.MasterStateSizer['masterState'].AddSizer(self.MasterStateSizer['innerMasterState'])
  2145         
  2145 
  2146         # ----------------------- Ethernet Network Card Information --------------------------------------- 
  2146         # ----------------------- Ethernet Network Card Information ---------------------------------------
  2147         for key, label in [
  2147         for key, label in [
  2148             ('Main', 'MAC Address:'),
  2148             ('Main', 'MAC Address:'),
  2149             ('Link', 'Link State:'),
  2149             ('Link', 'Link State:'),
  2150             ('Tx frames', 'Tx Frames:'),
  2150             ('Tx frames', 'Tx Frames:'),
  2151             ('Rx frames', 'Rx Frames:'),
  2151             ('Rx frames', 'Rx Frames:'),
  2152             ('Lost frames', 'Lost Frames:')]:
  2152             ('Lost frames', 'Lost Frames:')]:
  2153             self.StaticText[key] = wx.StaticText(self, label=_(label))
  2153             self.StaticText[key] = wx.StaticText(self, label=_(label))
  2154             self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
  2154             self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
  2155             self.MasterStateSizer['innerDeviceInfo'].AddMany([self.StaticText[key], self.TextCtrl[key]])
  2155             self.MasterStateSizer['innerDeviceInfo'].AddMany([self.StaticText[key], self.TextCtrl[key]])
  2156         
  2156 
  2157         self.MasterStateSizer['deviceInfo'].AddSizer(self.MasterStateSizer['innerDeviceInfo'])
  2157         self.MasterStateSizer['deviceInfo'].AddSizer(self.MasterStateSizer['innerDeviceInfo'])
  2158         
  2158 
  2159         # ----------------------- Network Frame Information -----------------------------------------------
  2159         # ----------------------- Network Frame Information -----------------------------------------------
  2160         for key, label in [
  2160         for key, label in [
  2161             ('Tx frame rate [1/s]', 'Tx Frame Rate [1/s]:'), 
  2161             ('Tx frame rate [1/s]', 'Tx Frame Rate [1/s]:'),
  2162             ('Rx frame rate [1/s]', 'Tx Rate [kByte/s]:'), 
  2162             ('Rx frame rate [1/s]', 'Tx Rate [kByte/s]:'),
  2163             ('Loss rate [1/s]', 'Loss Rate [1/s]:'),
  2163             ('Loss rate [1/s]', 'Loss Rate [1/s]:'),
  2164             ('Frame loss [%]', 'Frame Loss [%]:')]:
  2164             ('Frame loss [%]', 'Frame Loss [%]:')]:
  2165             self.StaticText[key] = wx.StaticText(self, label=_(label))
  2165             self.StaticText[key] = wx.StaticText(self, label=_(label))
  2166             self.MasterStateSizer['innerFrameInfo'].Add(self.StaticText[key])
  2166             self.MasterStateSizer['innerFrameInfo'].Add(self.StaticText[key])
  2167             self.TextCtrl[key] = {} 
  2167             self.TextCtrl[key] = {}
  2168             for index in ['0', '1', '2']:                
  2168             for index in ['0', '1', '2']:
  2169                 self.TextCtrl[key][index] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
  2169                 self.TextCtrl[key][index] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
  2170                 self.MasterStateSizer['innerFrameInfo'].Add(self.TextCtrl[key][index])
  2170                 self.MasterStateSizer['innerFrameInfo'].Add(self.TextCtrl[key][index])
  2171         
  2171 
  2172         self.MasterStateSizer['frameInfo'].AddSizer(self.MasterStateSizer['innerFrameInfo'])
  2172         self.MasterStateSizer['frameInfo'].AddSizer(self.MasterStateSizer['innerFrameInfo'])
  2173         
  2173 
  2174         # --------------------------------- Main Sizer ----------------------------------------------------
  2174         # --------------------------------- Main Sizer ----------------------------------------------------
  2175         for key, sub, in [
  2175         for key, sub, in [
  2176             ('innerTopHalf', [
  2176             ('innerTopHalf', [
  2177                     'masterState', 'deviceInfo']),
  2177                     'masterState', 'deviceInfo']),
  2178             ('innerBottomHalf', [
  2178             ('innerBottomHalf', [
  2182             for key2 in sub:
  2182             for key2 in sub:
  2183                 self.MasterStateSizer[key].AddSizer(self.MasterStateSizer[key2])
  2183                 self.MasterStateSizer[key].AddSizer(self.MasterStateSizer[key2])
  2184 
  2184 
  2185         self.MasterStateSizer['main'].AddSizer(self.UpdateButton)
  2185         self.MasterStateSizer['main'].AddSizer(self.UpdateButton)
  2186         self.MasterStateSizer['main'].AddSizer(self.MasterStateSizer['innerMain'])
  2186         self.MasterStateSizer['main'].AddSizer(self.MasterStateSizer['innerMain'])
  2187         
  2187 
  2188         self.SetSizer(self.MasterStateSizer['main'])
  2188         self.SetSizer(self.MasterStateSizer['main'])
  2189 
  2189 
  2190     def OnButtonClick(self, event):
  2190     def OnButtonClick(self, event):
  2191         """
  2191         """
  2192         Handle the event of the 'Update' button.
  2192         Handle the event of the 'Update' button.