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 |
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), |
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 |
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 |
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 |
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 |
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 = "" |
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', [ |