# HG changeset patch # User laurent # Date 1329871162 -3600 # Node ID ae8fecf082a163b36731b430a210bef2f3e6ac9f # Parent 1c64b84c06098e26549c67350e01c35c0ba5563e Adding support for MCL diff -r 1c64b84c0609 -r ae8fecf082a1 etherlab/ConfigEditor.py --- a/etherlab/ConfigEditor.py Thu Feb 16 18:40:13 2012 +0100 +++ b/etherlab/ConfigEditor.py Wed Feb 22 01:39:22 2012 +0100 @@ -145,20 +145,16 @@ grid.SetCellTextColour(row, col, highlight_colours[1]) self.ResizeRow(grid, row) -[ID_SLAVEPANEL, ID_SLAVEPANELTYPELABEL, - ID_SLAVEPANELTYPE, ID_SLAVEPANELTYPEBROWSE, - ID_SLAVEPANELALIASLABEL, ID_SLAVEPANELALIAS, - ID_SLAVEPANELPOSLABEL, ID_SLAVEPANELPOS, - ID_SLAVEPANELSLAVEINFOSSTATICBOX, ID_SLAVEPANELVENDORLABEL, - ID_SLAVEPANELVENDOR, ID_SLAVEPANELPRODUCTCODELABEL, - ID_SLAVEPANELPRODUCTCODE, ID_SLAVEPANELREVISIONNUMBERLABEL, - ID_SLAVEPANELREVISIONNUMBER, ID_SLAVEPANELPHYSICSLABEL, - ID_SLAVEPANELPHYSICS, ID_SLAVEPANELSYNCMANAGERSLABEL, - ID_SLAVEPANELSYNCMANAGERSGRID, ID_SLAVEPANELVARIABLESLABEL, - ID_SLAVEPANELVARIABLESGRID, -] = [wx.NewId() for _init_ctrls in range(21)] - -class SlavePanel(wx.Panel): +[ID_SLAVEINFOSPANEL, ID_SLAVEINFOSPANELVENDORLABEL, + ID_SLAVEINFOSPANELVENDOR, ID_SLAVEINFOSPANELPRODUCTCODELABEL, + ID_SLAVEINFOSPANELPRODUCTCODE, ID_SLAVEINFOSPANELREVISIONNUMBERLABEL, + ID_SLAVEINFOSPANELREVISIONNUMBER, ID_SLAVEINFOSPANELPHYSICSLABEL, + ID_SLAVEINFOSPANELPHYSICS, ID_SLAVEINFOSPANELSYNCMANAGERSLABEL, + ID_SLAVEINFOSPANELSYNCMANAGERSGRID, ID_SLAVEINFOSPANELVARIABLESLABEL, + ID_SLAVEINFOSPANELVARIABLESGRID, +] = [wx.NewId() for _init_ctrls in range(13)] + +class SlaveInfosPanel(wx.Panel): if wx.VERSION < (2, 6, 0): def Bind(self, event, function, id = None): @@ -168,43 +164,14 @@ event(self, function) def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.PositionSizer, 0, border=5, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.SlaveInfosBoxSizer, 0, border=5, flag=wx.GROW|wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT) - + parent.AddSizer(self.SlaveInfosDetailsSizer, 0, border=5, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW) + parent.AddWindow(self.SyncManagersLabel, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.GROW) + parent.AddWindow(self.SyncManagersGrid, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.GROW) + parent.AddWindow(self.VariablesLabel, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.GROW) + parent.AddWindow(self.VariablesGrid, 0, border=5, flag=wx.BOTTOM|wx.LEFT|wx.RIGHT|wx.GROW) + def _init_coll_MainSizer_Growables(self, parent): parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_coll_PositionSizer_Items(self, parent): - parent.AddWindow(self.TypeLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) - parent.AddSizer(self.TypeSizer, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.AliasLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) - parent.AddWindow(self.Alias, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.PosLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) - parent.AddWindow(self.Pos, 0, border=0, flag=wx.GROW) - - def _init_coll_PositionSizer_Growables(self, parent): - parent.AddGrowableCol(1) - parent.AddGrowableCol(3) - parent.AddGrowableCol(5) - parent.AddGrowableRow(0) - - def _init_coll_TypeSizer_Items(self, parent): - parent.AddWindow(self.Type, 1, border=0, flag=0) - parent.AddWindow(self.TypeBrowse, 0, border=0, flag=0) - - def _init_coll_SlaveInfosBoxSizer_Items(self, parent): - parent.AddSizer(self.SlaveInfosSizer, 1, border=5, flag=wx.GROW|wx.ALL) - - def _init_coll_SlaveInfosSizer_Items(self, parent): - parent.AddSizer(self.SlaveInfosDetailsSizer, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.SyncManagersLabel, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.SyncManagersGrid, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.VariablesLabel, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wx.GROW) - - def _init_coll_SlaveInfosSizer_Growables(self, parent): - parent.AddGrowableCol(0) parent.AddGrowableRow(2, 1) parent.AddGrowableRow(4, 2) @@ -223,110 +190,65 @@ parent.AddGrowableCol(3) def _init_sizers(self): - self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - self.PositionSizer = wx.FlexGridSizer(cols=6, hgap=5, rows=1, vgap=0) - self.TypeSizer = wx.BoxSizer(wx.HORIZONTAL) - self.SlaveInfosBoxSizer = wx.StaticBoxSizer(self.SlaveInfosStaticBox, wx.VERTICAL) - self.SlaveInfosSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5) + self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5) self.SlaveInfosDetailsSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=2, vgap=5) self._init_coll_MainSizer_Growables(self.MainSizer) self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_PositionSizer_Growables(self.PositionSizer) - self._init_coll_PositionSizer_Items(self.PositionSizer) - self._init_coll_TypeSizer_Items(self.TypeSizer) - self._init_coll_SlaveInfosBoxSizer_Items(self.SlaveInfosBoxSizer) - self._init_coll_SlaveInfosSizer_Growables(self.SlaveInfosSizer) - self._init_coll_SlaveInfosSizer_Items(self.SlaveInfosSizer) self._init_coll_SlaveInfosDetailsSizer_Growables(self.SlaveInfosDetailsSizer) self._init_coll_SlaveInfosDetailsSizer_Items(self.SlaveInfosDetailsSizer) self.SetSizer(self.MainSizer) - + def _init_ctrls(self, prnt): - wx.Panel.__init__(self, id=ID_SLAVEPANEL, name='SlavePanel', parent=prnt, + wx.Panel.__init__(self, id=ID_SLAVEINFOSPANEL, name='SlavePanel', parent=prnt, size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - self.TypeLabel = wx.StaticText(id=ID_SLAVEPANELTYPELABEL, - label=_('Type:'), name='TypeLabel', parent=self, - pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - - self.Type = wx.TextCtrl(id=ID_SLAVEPANELTYPE, value='', - name='Type', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.TE_READONLY) - - self.TypeBrowse = wx.Button(id=ID_SLAVEPANELTYPEBROWSE, label='...', - name='TypeBrowse', parent=self, pos=wx.Point(0, 0), - size=wx.Size(30, 24), style=0) - self.Bind(wx.EVT_BUTTON, self.OnTypeBrowseClick, id=ID_SLAVEPANELTYPEBROWSE) - - self.AliasLabel = wx.StaticText(id=ID_SLAVEPANELALIASLABEL, - label=_('Alias:'), name='AliasLabel', parent=self, - pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - - self.Alias = wx.SpinCtrl(id=ID_SLAVEPANELALIAS, - name='Alias', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) - self.Bind(wx.EVT_SPINCTRL, self.OnAliasChanged, id=ID_SLAVEPANELALIAS) - - self.PosLabel = wx.StaticText(id=ID_SLAVEPANELPOSLABEL, - label=_('Position:'), name='PositionLabel', parent=self, - pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - - self.Pos = wx.SpinCtrl(id=ID_SLAVEPANELPOS, - name='Pos', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) - self.Bind(wx.EVT_SPINCTRL, self.OnPositionChanged, id=ID_SLAVEPANELPOS) - - self.SlaveInfosStaticBox = wx.StaticBox(id=ID_SLAVEPANELSLAVEINFOSSTATICBOX, - label=_('Slave infos:'), name='SlaveInfosStaticBox', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) - - self.VendorLabel = wx.StaticText(id=ID_SLAVEPANELVENDORLABEL, + self.VendorLabel = wx.StaticText(id=ID_SLAVEINFOSPANELVENDORLABEL, label=_('Vendor:'), name='VendorLabel', parent=self, pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - self.Vendor = wx.TextCtrl(id=ID_SLAVEPANELVENDOR, value='', + self.Vendor = wx.TextCtrl(id=ID_SLAVEINFOSPANELVENDOR, value='', name='Vendor', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.TE_READONLY) - self.ProductCodeLabel = wx.StaticText(id=ID_SLAVEPANELPRODUCTCODELABEL, + self.ProductCodeLabel = wx.StaticText(id=ID_SLAVEINFOSPANELPRODUCTCODELABEL, label=_('Product code:'), name='ProductCodeLabel', parent=self, pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - self.ProductCode = wx.TextCtrl(id=ID_SLAVEPANELPRODUCTCODE, value='', + self.ProductCode = wx.TextCtrl(id=ID_SLAVEINFOSPANELPRODUCTCODE, value='', name='ProductCode', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.TE_READONLY) - self.RevisionNumberLabel = wx.StaticText(id=ID_SLAVEPANELREVISIONNUMBERLABEL, + self.RevisionNumberLabel = wx.StaticText(id=ID_SLAVEINFOSPANELREVISIONNUMBERLABEL, label=_('Revision number:'), name='RevisionNumberLabel', parent=self, pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - self.RevisionNumber = wx.TextCtrl(id=ID_SLAVEPANELREVISIONNUMBER, value='', + self.RevisionNumber = wx.TextCtrl(id=ID_SLAVEINFOSPANELREVISIONNUMBER, value='', name='RevisionNumber', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.TE_READONLY) - self.PhysicsLabel = wx.StaticText(id=ID_SLAVEPANELPHYSICSLABEL, + self.PhysicsLabel = wx.StaticText(id=ID_SLAVEINFOSPANELPHYSICSLABEL, label=_('Physics:'), name='PhysicsLabel', parent=self, pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - self.Physics = wx.TextCtrl(id=ID_SLAVEPANELPHYSICS, value='', + self.Physics = wx.TextCtrl(id=ID_SLAVEINFOSPANELPHYSICS, value='', name='Physics', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.TE_READONLY) - self.SyncManagersLabel = wx.StaticText(id=ID_SLAVEPANELSYNCMANAGERSLABEL, + self.SyncManagersLabel = wx.StaticText(id=ID_SLAVEINFOSPANELSYNCMANAGERSLABEL, label=_('Sync managers:'), name='SyncManagersLabel', parent=self, pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - self.SyncManagersGrid = CustomGrid(id=ID_SLAVEPANELSYNCMANAGERSGRID, + self.SyncManagersGrid = CustomGrid(id=ID_SLAVEINFOSPANELSYNCMANAGERSGRID, name='SyncManagersGrid', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=wx.VSCROLL) - self.VariablesLabel = wx.StaticText(id=ID_SLAVEPANELVARIABLESLABEL, + self.VariablesLabel = wx.StaticText(id=ID_SLAVEINFOSPANELVARIABLESLABEL, label=_('Variable entries:'), name='VariablesLabel', parent=self, pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - self.VariablesGrid = CustomGrid(id=ID_SLAVEPANELVARIABLESGRID, + self.VariablesGrid = CustomGrid(id=ID_SLAVEINFOSPANELVARIABLESGRID, name='VariablesGrid', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=wx.VSCROLL) if wx.VERSION >= (2, 5, 0): @@ -335,13 +257,11 @@ wx.grid.EVT_GRID_CELL_LEFT_CLICK(self.VariablesGrid, self.OnVariablesGridCellLeftClick) self._init_sizers() - - def __init__(self, parent, controler, window, slave): + + def __init__(self, parent, controler): self._init_ctrls(parent) self.Controler = controler - self.ParentWindow = window - self.Slave = slave self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames()) self.SyncManagersGrid.SetTable(self.SyncManagersTable) @@ -369,27 +289,9 @@ self.VariablesGrid.SetColAttr(col, attr) self.VariablesGrid.SetColMinimalWidth(col, self.VariablesGridColSizes[col]) self.VariablesGrid.AutoSizeColumn(col, False) - - self.RefreshView() - - def GetSlaveTitle(self): - type_infos = self.Controler.GetSlaveType(self.Slave) - return "%s (%d:%d)" % (type_infos["device_type"], self.Slave[0], self.Slave[1]) - - def GetSlave(self): - return self.Slave - - def SetSlave(self, slave): - if self.Slave != slave: - self.Slave = slave - self.RefreshView() - - def RefreshView(self): - self.Alias.SetValue(self.Slave[0]) - self.Pos.SetValue(self.Slave[1]) - slave_infos = self.Controler.GetSlaveInfos(self.Slave) + + def SetSlaveInfos(self, slave_infos): if slave_infos is not None: - self.Type.SetValue(slave_infos["device_type"]) self.Vendor.SetValue(slave_infos["vendor"]) self.ProductCode.SetValue(slave_infos["product_code"]) self.RevisionNumber.SetValue(slave_infos["revision_number"]) @@ -399,49 +301,14 @@ self.VariablesTable.SetData(slave_infos["entries"]) self.VariablesTable.ResetView(self.VariablesGrid) else: - type_infos = self.Controler.GetSlaveType(self.Slave) - self.Type.SetValue(type_infos["device_type"]) - - def OnAliasChanged(self, event): - alias = self.Alias.GetValue() - if alias != self.Slave[0]: - result = self.Controler.SetSlavePos(self.Slave[:2], alias = alias) - if result is not None: - message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - wx.CallAfter(self.ParentWindow.RefreshView, (alias, self.Slave[1])) - wx.CallAfter(self.ParentWindow.RefreshParentWindow) - event.Skip() - - def OnPositionChanged(self, event): - position = self.Pos.GetValue() - if position != self.Slave[1]: - result = self.Controler.SetSlavePos(self.Slave, position = position) - if result is not None: - message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - wx.CallAfter(self.ParentWindow.RefreshView, (self.Slave[0], position)) - wx.CallAfter(self.ParentWindow.RefreshParentWindow) - event.Skip() - - def OnTypeBrowseClick(self, event): - dialog = SlaveTypeChoiceDialog(self, self.Controler, self.Controler.GetSlaveType(self.Slave)) - if dialog.ShowModal() == wx.ID_OK: - result = self.Controler.SetSlaveType(self.Slave, dialog.GetType()) - if result is not None: - message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - wx.CallAfter(self.RefreshView) - wx.CallAfter(self.ParentWindow.RefreshSlaveNodesTitles) - wx.CallAfter(self.ParentWindow.RefreshParentWindow) - dialog.Destroy() - event.Skip() + self.Vendor.SetValue("") + self.ProductCode.SetValue("") + self.RevisionNumber.SetValue("") + self.Physics.SetValue("") + self.SyncManagersTable.SetData([]) + self.SyncManagersTable.ResetView(self.SyncManagersGrid) + self.VariablesTable.SetData([]) + self.VariablesTable.ResetView(self.VariablesGrid) def OnVariablesGridCellLeftClick(self, event): row = event.GetRow() @@ -468,9 +335,184 @@ event.Skip() -[ID_CONFIGEDITOR, ID_CONFIGEDITORADDSLAVEBUTTON, - ID_CONFIGEDITORDELETESLAVEBUTTON, ID_CONFIGEDITORSLAVENODES, -] = [wx.NewId() for _init_ctrls in range(4)] +[ID_SLAVEPANEL, ID_SLAVEPANELTYPELABEL, + ID_SLAVEPANELTYPE, ID_SLAVEPANELTYPEBROWSE, + ID_SLAVEPANELALIASLABEL, ID_SLAVEPANELALIAS, + ID_SLAVEPANELPOSLABEL, ID_SLAVEPANELPOS, + ID_SLAVEPANELSLAVEINFOSSTATICBOX, +] = [wx.NewId() for _init_ctrls in range(9)] + +class SlavePanel(wx.Panel): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.PositionSizer, 0, border=5, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.SlaveInfosBoxSizer, 0, border=5, flag=wx.GROW|wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT) + + def _init_coll_MainSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_coll_PositionSizer_Items(self, parent): + parent.AddWindow(self.TypeLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) + parent.AddSizer(self.TypeSizer, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.AliasLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) + parent.AddWindow(self.Alias, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.PosLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) + parent.AddWindow(self.Pos, 0, border=0, flag=wx.GROW) + + def _init_coll_PositionSizer_Growables(self, parent): + parent.AddGrowableCol(1) + parent.AddGrowableCol(3) + parent.AddGrowableCol(5) + parent.AddGrowableRow(0) + + def _init_coll_TypeSizer_Items(self, parent): + parent.AddWindow(self.Type, 1, border=0, flag=0) + parent.AddWindow(self.TypeBrowse, 0, border=0, flag=0) + + def _init_coll_SlaveInfosBoxSizer_Items(self, parent): + parent.AddWindow(self.SlaveInfosPanel, 1, border=0, flag=wx.GROW) + + def _init_sizers(self): + self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + self.PositionSizer = wx.FlexGridSizer(cols=6, hgap=5, rows=1, vgap=0) + self.TypeSizer = wx.BoxSizer(wx.HORIZONTAL) + self.SlaveInfosBoxSizer = wx.StaticBoxSizer(self.SlaveInfosStaticBox, wx.VERTICAL) + + self._init_coll_MainSizer_Growables(self.MainSizer) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_PositionSizer_Growables(self.PositionSizer) + self._init_coll_PositionSizer_Items(self.PositionSizer) + self._init_coll_TypeSizer_Items(self.TypeSizer) + self._init_coll_SlaveInfosBoxSizer_Items(self.SlaveInfosBoxSizer) + + self.SetSizer(self.MainSizer) + + def _init_ctrls(self, prnt): + wx.Panel.__init__(self, id=ID_SLAVEPANEL, name='SlavePanel', parent=prnt, + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.TypeLabel = wx.StaticText(id=ID_SLAVEPANELTYPELABEL, + label=_('Type:'), name='TypeLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.Type = wx.TextCtrl(id=ID_SLAVEPANELTYPE, value='', + name='Type', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.TE_READONLY) + + self.TypeBrowse = wx.Button(id=ID_SLAVEPANELTYPEBROWSE, label='...', + name='TypeBrowse', parent=self, pos=wx.Point(0, 0), + size=wx.Size(30, 24), style=0) + self.Bind(wx.EVT_BUTTON, self.OnTypeBrowseClick, id=ID_SLAVEPANELTYPEBROWSE) + + self.AliasLabel = wx.StaticText(id=ID_SLAVEPANELALIASLABEL, + label=_('Alias:'), name='AliasLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.Alias = wx.SpinCtrl(id=ID_SLAVEPANELALIAS, + name='Alias', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) + self.Bind(wx.EVT_SPINCTRL, self.OnAliasChanged, id=ID_SLAVEPANELALIAS) + + self.PosLabel = wx.StaticText(id=ID_SLAVEPANELPOSLABEL, + label=_('Position:'), name='PositionLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.Pos = wx.SpinCtrl(id=ID_SLAVEPANELPOS, + name='Pos', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) + self.Bind(wx.EVT_SPINCTRL, self.OnPositionChanged, id=ID_SLAVEPANELPOS) + + self.SlaveInfosStaticBox = wx.StaticBox(id=ID_SLAVEPANELSLAVEINFOSSTATICBOX, + label=_('Slave infos:'), name='SlaveInfosStaticBox', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) + + self.SlaveInfosPanel = SlaveInfosPanel(self, self.Controler) + + self._init_sizers() + + def __init__(self, parent, controler, window, slave): + self.Controler = controler + self.ParentWindow = window + self.Slave = slave + + self._init_ctrls(parent) + + self.RefreshView() + + def GetSlaveTitle(self): + type_infos = self.Controler.GetSlaveType(self.Slave) + return "%s (%d:%d)" % (type_infos["device_type"], self.Slave[0], self.Slave[1]) + + def GetSlave(self): + return self.Slave + + def SetSlave(self, slave): + if self.Slave != slave: + self.Slave = slave + self.RefreshView() + + def RefreshView(self): + self.Alias.SetValue(self.Slave[0]) + self.Pos.SetValue(self.Slave[1]) + slave_infos = self.Controler.GetSlaveInfos(self.Slave) + if slave_infos is not None: + self.Type.SetValue(slave_infos["device_type"]) + else: + type_infos = self.Controler.GetSlaveType(self.Slave) + self.Type.SetValue(type_infos["device_type"]) + self.SlaveInfosPanel.SetSlaveInfos(slave_infos) + + def OnAliasChanged(self, event): + alias = self.Alias.GetValue() + if alias != self.Slave[0]: + result = self.Controler.SetSlavePos(self.Slave[:2], alias = alias) + if result is not None: + message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + wx.CallAfter(self.ParentWindow.RefreshView, (alias, self.Slave[1])) + wx.CallAfter(self.ParentWindow.RefreshParentWindow) + event.Skip() + + def OnPositionChanged(self, event): + position = self.Pos.GetValue() + if position != self.Slave[1]: + result = self.Controler.SetSlavePos(self.Slave, position = position) + if result is not None: + message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + wx.CallAfter(self.ParentWindow.RefreshView, (self.Slave[0], position)) + wx.CallAfter(self.ParentWindow.RefreshParentWindow) + event.Skip() + + def OnTypeBrowseClick(self, event): + dialog = SlaveTypeChoiceDialog(self, self.Controler, self.Controler.GetSlaveType(self.Slave)) + if dialog.ShowModal() == wx.ID_OK: + result = self.Controler.SetSlaveType(self.Slave, dialog.GetType()) + if result is not None: + message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + wx.CallAfter(self.RefreshView) + wx.CallAfter(self.ParentWindow.RefreshSlaveNodesTitles) + wx.CallAfter(self.ParentWindow.RefreshParentWindow) + dialog.Destroy() + event.Skip() + +[ID_CONFIGEDITOR, ID_CONFIGEDITORSLAVENODES, +] = [wx.NewId() for _init_ctrls in range(2)] [ID_CONFIGEDITORPLUGINMENUADDSLAVE, ID_CONFIGEDITORPLUGINMENUDELETESLAVE, ] = [wx.NewId() for _init_coll_PluginMenu_Items in range(2)] @@ -586,4 +628,33 @@ if self.Controler.RemoveSlave(panel.GetSlave()[:2]): self.RefreshParentWindow() wx.CallAfter(self.RefreshView) - \ No newline at end of file + + +[ID_DS402NODEEDITOR, +] = [wx.NewId() for _init_ctrls in range(1)] + +class DS402NodeEditor(EditorPanel): + + ID = ID_DS402NODEEDITOR + + def _init_Editor(self, prnt): + self.Editor = SlaveInfosPanel(prnt, self.Controler) + + def __init__(self, parent, controler, window): + EditorPanel.__init__(self, parent, "", window, controler) + + img = wx.Bitmap(self.Controler.GetIconPath("Cfile.png"), wx.BITMAP_TYPE_PNG).ConvertToImage() + self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16))) + + def __del__(self): + self.Controler.OnCloseEditor(self) + + def GetTitle(self): + return self.Controler.PlugFullName() + + def GetBufferState(self): + return False, False + + def RefreshView(self): + self.Editor.SetSlaveInfos(self.Controler.GetSlaveInfos()) + \ No newline at end of file diff -r 1c64b84c0609 -r ae8fecf082a1 etherlab/etherlab.py --- a/etherlab/etherlab.py Thu Feb 16 18:40:13 2012 +0100 +++ b/etherlab/etherlab.py Wed Feb 22 01:39:22 2012 +0100 @@ -7,7 +7,7 @@ from xmlclass import * from plugger import PlugTemplate from PLCControler import UndoBuffer, LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY -from ConfigEditor import ConfigEditor, ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE +from ConfigEditor import ConfigEditor, DS402NodeEditor, ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE #-------------------------------------------------- # Ethercat DS402 Node @@ -15,8 +15,10 @@ NODE_VARIABLES = [ ("ControlWord", 0x6040, 0x00, "UINT", "Q"), + ("TargetPosition", 0x607a, 0x00, "DINT", "Q"), ("StatusWord", 0x6041, 0x00, "UINT", "I"), ("ModesOfOperationDisplay", 0x06061, 0x00, "SINT", "I"), + ("ActualPosition", 0x6064, 0x00, "DINT", "I"), ("ErrorCode", 0x603f, 0x00, "UINT", "I"), ] @@ -30,6 +32,13 @@ """ + EditorType = DS402NodeEditor + + def ExtractHexDecValue(self, value): + return ExtractHexDecValue(value) + + def GetSizeOfType(self, type): + return TYPECONVERSION.get(self.GetPlugRoot().GetBaseType(type), None) def _GetChildBySomething(self, something, toks): return self @@ -57,7 +66,7 @@ """ return self.PlugParent.GetCurrentLocation() + (self.BaseParams.getIEC_Channel(), 0) - def GetSlaveInfos(self): + def GetSlaveTypeInfos(self): slave_type = self.EtherlabDS402Slave.getNode_Type() for module_type, vendor_id, product_code, revision_number in self.PlugParent.GetModulesByProfile(402): @@ -69,17 +78,40 @@ return None + def GetSlaveInfos(self): + slave_typeinfos = self.GetSlaveTypeInfos() + if slave_typeinfos is not None: + device = self.PlugParent.GetModuleInfos(slave_typeinfos) + if device is not None: + infos = slave_typeinfos.copy() + entries = device.GetEntriesList() + entries_list = entries.items() + entries_list.sort() + infos.update({"physics": device.getPhysics(), + "sync_managers": device.GetSyncManagers(), + "entries": [entry[1] for entry in entries_list]}) + return infos + return None + def GetVariableLocationTree(self): - slave_infos = self.GetSlaveInfos() + slave_typeinfos = self.GetSlaveTypeInfos() vars = [] - if slave_infos is not None: - vars = self.PlugParent.GetDeviceLocationTree(self.GetCurrentLocation(), slave_infos) + if slave_typeinfos is not None: + vars = self.PlugParent.GetDeviceLocationTree(self.GetCurrentLocation(), slave_typeinfos) return {"name": self.BaseParams.getName(), "type": LOCATION_PLUGIN, "location": self.GetFullIEC_Channel(), "children": vars} + PluginMethods = [ + {"bitmap" : os.path.join("images", "EditCfile"), + "name" : _("Edit Node"), + "tooltip" : _("Edit Node"), + "method" : "_OpenView"}, + ] + + def PlugGenerate_C(self, buildpath, locations): """ Generate C code @@ -99,65 +131,53 @@ slave_pos = current_location[-2:] - slave_infos = self.GetSlaveInfos() + slave_typeinfos = self.GetSlaveTypeInfos() device = None - if slave_infos is not None: - device = self.PlugParent.GetModuleInfos(slave_infos) + if slave_typeinfos is not None: + device = self.PlugParent.GetModuleInfos(slave_typeinfos) if device is None: raise (ValueError, _("No information found for DS402 node \"%s\" at location %s!") % ( - slave_infos["device_type"], ".".join(current_location))) + slave_typeinfos["device_type"], ".".join(current_location))) - slave_idx = self.PlugParent.FileGenerator.DeclareSlave(slave_pos, slave_infos) + self.PlugParent.FileGenerator.DeclareSlave(slave_pos, slave_typeinfos) plc_ds402node_filepath = os.path.join(os.path.split(__file__)[0], "plc_ds402node.c") plc_ds402node_file = open(plc_ds402node_filepath, 'r') plc_ds402node_code = plc_ds402node_file.read() plc_ds402node_file.close() + from plugins.motion import Headers + str_completion = { "location": location_str, - "MCL_includes": "", - "located_variables_declaration": [], + "MCL_headers": Headers, + "extern_located_variables_declaration": [], "entry_variables": [], - "extern_pdo_entry_configuration": [], - "retrieve_variables": [], - "publish_variables": [], + "init_entry_variables": [], } - variables = {} for variable in NODE_VARIABLES: var_infos = dict(zip(["name", "index", "subindex", "var_type", "dir"], variable)) var_infos["location"] = location_str - var_infos["slave"] = slave_idx var_infos["var_size"] = self.PlugParent.GetSizeOfType(var_infos["var_type"]) var_infos["var_name"] = "__%(dir)s%(var_size)s%(location)s_%(index)d_%(subindex)d" % var_infos - var_infos["real_var"] = "__DS402Node_%(location)s.%(name)s" % var_infos - var_infos.update(slave_infos) - variables[(var_infos["index"], var_infos["subindex"])] = var_infos["name"] - - str_completion["entry_variables"].append(" IEC_%(var_type)s %(name)s;" % var_infos) - - ConfigureVariable(var_infos, str_completion) - - str_completion["extern_pdo_entry_configuration"].append( - "extern unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % var_infos) - - if var_infos["var_type"] == "BOOL": - str_completion["extern_pdo_entry_configuration"].append( - "extern unsigned int slave%(slave)d_%(index).4x_%(subindex).2x_bit;" % var_infos) + str_completion["extern_located_variables_declaration"].append( + "IEC_%(var_type)s *%(var_name)s;" % var_infos) + str_completion["entry_variables"].append( + " IEC_%(var_type)s *%(name)s;" % var_infos) + str_completion["init_entry_variables"].append( + " __DS402Node_%(location)s.%(name)s = %(var_name)s;" % var_infos) self.PlugParent.FileGenerator.DeclareVariable( slave_pos, var_infos["index"], var_infos["subindex"], - var_infos["var_type"], var_infos["dir"], var_infos["var_name"], False) - - for element in ["located_variables_declaration", + var_infos["var_type"], var_infos["dir"], var_infos["var_name"]) + + for element in ["extern_located_variables_declaration", "entry_variables", - "extern_pdo_entry_configuration", - "retrieve_variables", - "publish_variables"]: + "init_entry_variables"]: str_completion[element] = "\n".join(str_completion[element]) Gen_DS402Nodefile_path = os.path.join(buildpath, "ds402node_%s.c"%location_str) @@ -165,12 +185,6 @@ ds402nodefile.write(plc_ds402node_code % str_completion) ds402nodefile.close() - for location in locations: - loc = location["LOC"][len(current_location):] - if variables.get(loc, None) is None: - self.PlugParent.FileGenerator.DeclareVariable( - slave_pos, loc[0], loc[1], location["IEC_TYPE"], location["DIR"], location["NAME"]) - return [(Gen_DS402Nodefile_path, '"-I%s"'%os.path.abspath(self.GetPlugRoot().GetIECLibPath()))],"",True @@ -598,14 +612,23 @@ if entry_infos["data_type"] is None: raise ValueError, _("Type of location \"%s\" not yet supported!") % entry_infos["var_name"] - if not entry_infos.has_key("real_var"): - entry_infos["real_var"] = "beremiz" + entry_infos["var_name"] - str_completion["located_variables_declaration"].append( - "IEC_%(var_type)s %(real_var)s;" % entry_infos) - str_completion["located_variables_declaration"].append( - "IEC_%(var_type)s *%(var_name)s = &%(real_var)s;" % entry_infos) + entry_infos["real_var"] = "beremiz" + entry_infos["var_name"] + str_completion["located_variables_declaration"].extend( + ["IEC_%(var_type)s %(real_var)s;" % entry_infos, + "IEC_%(var_type)s *%(var_name)s = &%(real_var)s;" % entry_infos]) + + str_completion["used_pdo_entry_offset_variables_declaration"].append( + "unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos) if entry_infos["data_type"] == "BIT": + str_completion["used_pdo_entry_offset_variables_declaration"].append( + "unsigned int slave%(slave)d_%(index).4x_%(subindex).2x_bit;" % entry_infos) + + str_completion["used_pdo_entry_configuration"].append( + (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, " + + "0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x, " + + "&slave%(slave)d_%(index).4x_%(subindex).2x_bit},") % entry_infos) + if entry_infos["dir"] == "I": str_completion["retrieve_variables"].append( (" %(real_var)s = EC_READ_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " + @@ -616,6 +639,10 @@ "slave%(slave)d_%(index).4x_%(subindex).2x_bit, %(real_var)s);") % entry_infos) else: + str_completion["used_pdo_entry_configuration"].append( + (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, " + + "%(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x},") % entry_infos) + if entry_infos["dir"] == "I": str_completion["retrieve_variables"].append( (" %(real_var)s = EC_READ_%(data_type)s(domain1_pd + " + @@ -625,25 +652,6 @@ (" EC_WRITE_%(data_type)s(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " + "%(real_var)s);") % entry_infos) -def ConfigurePDO(entry_infos, str_completion): - str_completion["used_pdo_entry_offset_variables_declaration"].append( - "unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos) - - if entry_infos["var_type"] == "BOOL": - str_completion["used_pdo_entry_offset_variables_declaration"].append( - "unsigned int slave%(slave)d_%(index).4x_%(subindex).2x_bit;" % entry_infos) - - str_completion["used_pdo_entry_configuration"].append( - (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, " + - "0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x, " + - "&slave%(slave)d_%(index).4x_%(subindex).2x_bit},") % entry_infos) - - else: - - str_completion["used_pdo_entry_configuration"].append( - (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, " + - "%(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x},") % entry_infos) - class _EthercatCFileGenerator: def __init__(self, controler): @@ -660,14 +668,13 @@ self.Slaves.sort() return self.Slaves.index((slave_identifier, slave)) - def DeclareVariable(self, slave_identifier, index, subindex, iec_type, dir, name, configure=True): + def DeclareVariable(self, slave_identifier, index, subindex, iec_type, dir, name): slave_variables = self.UsedVariables.setdefault(slave_identifier, {}) entry_infos = slave_variables.get((index, subindex), None) if entry_infos is None: slave_variables[(index, subindex)] = { "infos": (iec_type, dir, name), - "configure": configure, "mapped": False} elif entry_infos["infos"] != (iec_type, dir, name): raise ValueError, _("Definition conflict for location \"%s\"") % name @@ -764,6 +771,7 @@ sync_managers.append(sync_manager_infos) pdos_index = [] + excluded_pdos = [] for only_mandatory in [True, False]: for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] + [(pdo, "Outputs") for pdo in device.getRxPdo()]): @@ -777,6 +785,9 @@ pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) pdos_index.append(pdo_index) + if pdo_index in excluded_pdos: + continue + entries_infos = [] for entry in entries: @@ -805,11 +816,14 @@ entry_infos["dir"] == "Q" and pdo_type != "Outputs"): raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"] - if entry_declaration["configure"]: - ConfigureVariable(entry_infos, str_completion) - ConfigurePDO(entry_infos, str_completion) - + ConfigureVariable(entry_infos, str_completion) + if pdo_needed: + for excluded in pdo.getExclude(): + excluded_index = ExtractHexDecValue(excluded.getcontent()) + if excluded_index not in excluded_pdos: + excluded_pdos.append(excluded_index) + sm = pdo.getSm() if sm is None: for sm_idx, sync_manager in enumerate(sync_managers): @@ -874,9 +888,7 @@ if not dynamic_pdos.has_key(pdo_type): raise ValueError, _("No Sync manager defined for %s!") % pdo_type - if entry_declaration["configure"]: - ConfigureVariable(entry_infos, str_completion) - ConfigurePDO(entry_infos, str_completion) + ConfigureVariable(entry_infos, str_completion) if len(dynamic_pdos[pdo_type]["pdos"]) > 0: pdo = dynamic_pdos[pdo_type]["pdos"][0] diff -r 1c64b84c0609 -r ae8fecf082a1 etherlab/plc_ds402node.c --- a/etherlab/plc_ds402node.c Thu Feb 16 18:40:13 2012 +0100 +++ b/etherlab/plc_ds402node.c Wed Feb 22 01:39:22 2012 +0100 @@ -11,10 +11,14 @@ #include "iec_std_lib.h" #endif -%(MCL_includes)s +IEC_INT beremiz__IW%(location)s_0; +IEC_INT *__IW%(location)s_0 = &beremiz__IW%(location)s_0; + +%(MCL_headers)s IEC_UINT __InactiveMask = 0x4f; IEC_UINT __ActiveMask = 0x6f; +IEC_UINT __PowerMask = 0x10; typedef enum { __Unknown, @@ -31,17 +35,17 @@ typedef struct { %(entry_variables)s __DS402NodeState state; + axis_s* axis; } __DS402Node; static __DS402Node __DS402Node_%(location)s; -%(located_variables_declaration)s - -extern uint8_t *domain1_pd; -%(extern_pdo_entry_configuration)s +%(extern_located_variables_declaration)s int __init_%(location)s() { +%(init_entry_variables)s; +*__IW%(location)s_0 = __MK_AllocAxis(&(__DS402Node_%(location)s.axis)); return 0; } @@ -51,11 +55,8 @@ void __retrieve_%(location)s() { - IEC_UINT statusword_inactive = __DS402Node_%(location)s.StatusWord & __InactiveMask; - IEC_UINT statusword_active = __DS402Node_%(location)s.StatusWord & __ActiveMask; - - // DS402 input entries extraction -%(retrieve_variables)s + IEC_UINT statusword_inactive = *(__DS402Node_%(location)s.StatusWord) & __InactiveMask; + IEC_UINT statusword_active = *(__DS402Node_%(location)s.StatusWord) & __ActiveMask; // DS402 node state computation __DS402Node_%(location)s.state = __Unknown; @@ -95,35 +96,40 @@ return; } + __DS402Node_%(location)s.axis->PowerFeedback = __DS402Node_%(location)s.state != __OperationEnabled; + __DS402Node_%(location)s.axis->ActualPosition = (IEC_REAL)(*(__DS402Node_%(location)s.ActualPosition)) * __DS402Node_%(location)s.axis->RatioDenominator / __DS402Node_%(location)s.axis->RatioNumerator; + + __MK_UpdateAxis(*__IW%(location)s_0); } void __publish_%(location)s() { + __MK_ComputeAxis(*__IW%(location)s_0); + + IEC_BOOL power = ((*(__DS402Node_%(location)s.StatusWord) & __PowerMask) > 0) && __DS402Node_%(location)s.axis->Power; + // DS402 node state transition computation switch (__DS402Node_%(location)s.state) { case __SwitchOnDisabled: - __DS402Node_%(location)s.ControlWord = (__DS402Node_%(location)s.ControlWord & ~0x87) | 0x06; + *(__DS402Node_%(location)s.ControlWord) = (*(__DS402Node_%(location)s.ControlWord) & ~0x87) | 0x06; break; case __ReadyToSwitchOn: - __DS402Node_%(location)s.ControlWord = (__DS402Node_%(location)s.ControlWord & ~0x8f) | 0x07; - break; + case __OperationEnabled: + if (!power) { + *(__DS402Node_%(location)s.ControlWord) = (*(__DS402Node_%(location)s.ControlWord) & ~0x8f) | 0x07; + break; + } case __SwitchedOn: - // if (POWER) { - // __DS402Node_%(location)s.ControlWord = (__DS402Node_%(location)s.ControlWord & ~0x8f) | 0x0f; - // } - break; - case __OperationEnabled: - // if (!POWER) { - // __DS402Node_%(location)s.ControlWord = (__DS402Node_%(location)s.ControlWord & ~0x8f) | 0x07; - // } + if (power) { + *(__DS402Node_%(location)s.ControlWord) = (*(__DS402Node_%(location)s.ControlWord) & ~0x8f) | 0x0f; + } break; case __Fault: - __DS402Node_%(location)s.ControlWord = (__DS402Node_%(location)s.ControlWord & ~0x8f) | 0x80; + *(__DS402Node_%(location)s.ControlWord) = (*(__DS402Node_%(location)s.ControlWord) & ~0x8f) | 0x80; break; default: break; } - // DS402 output entries setting -%(publish_variables)s + *(__DS402Node_%(location)s.TargetPosition) = (IEC_DINT)(__DS402Node_%(location)s.axis->PositionSetPoint * __DS402Node_%(location)s.axis->RatioNumerator / __DS402Node_%(location)s.axis->RatioDenominator); }