--- a/LPCBeremiz.py Tue Feb 07 19:14:10 2012 +0100
+++ b/LPCBeremiz.py Sat Feb 11 00:02:02 2012 +0100
@@ -60,6 +60,8 @@
from Beremiz import *
from plugger import PluginsRoot, PlugTemplate, opjimg, connectors
+from plugins.canfestival import RootClass as CanOpenRootClass
+from plugins.canfestival.canfestival import _SlavePlug, _NodeListPlug, NodeManager
from plcopen.structures import LOCATIONDATATYPES
from PLCControler import LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP,\
LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
@@ -188,6 +190,9 @@
return self.VariableLocationTree
raise KeyError, "Only 'children' key is available"
+ def PlugEnabled(self):
+ return None
+
def SetIcon(self, icon):
self.Icon = icon
@@ -355,6 +360,93 @@
return [(Gen_Module_path, matiec_flags)],"",True
#-------------------------------------------------------------------------------
+# LPC CanFestival Plugin Class
+#-------------------------------------------------------------------------------
+
+DEFAULT_SETTINGS = {
+ "CAN_Baudrate": "125K",
+ "Slave_NodeId": 2,
+ "Master_NodeId": 1,
+}
+
+class LPCCanOpenSlave(_SlavePlug):
+ XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:element name="CanFestivalSlaveNode">
+ <xsd:complexType>
+ <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="optional" default="%(CAN_Baudrate)s"/>
+ <xsd:attribute name="NodeId" type="xsd:string" use="optional" default="%(Slave_NodeId)d"/>
+ <xsd:attribute name="Sync_Align" type="xsd:integer" use="optional" default="0"/>
+ <xsd:attribute name="Sync_Align_Ratio" use="optional" default="50">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:integer">
+ <xsd:minInclusive value="1"/>
+ <xsd:maxInclusive value="99"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ """ % DEFAULT_SETTINGS
+
+ def __init__(self):
+ # TODO change netname when name change
+ NodeManager.__init__(self)
+ odfilepath = self.GetSlaveODPath()
+ if(os.path.isfile(odfilepath)):
+ self.OpenFileInCurrent(odfilepath)
+ else:
+ self.CreateNewNode("SlaveNode", # Name - will be changed at build time
+ 0x00, # NodeID - will be changed at build time
+ "slave", # Type
+ "", # description
+ "None", # profile
+ "", # prfile filepath
+ "heartbeat", # NMT
+ []) # options
+ self.OnPlugSave()
+
+ def GetCanDevice(self):
+ return str(self.BaseParams.getIEC_Channel())
+
+class LPCCanOpenMaster(_NodeListPlug):
+ XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:element name="CanFestivalNode">
+ <xsd:complexType>
+ <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="optional" default="%(CAN_Baudrate)s"/>
+ <xsd:attribute name="NodeId" type="xsd:string" use="optional" default="%(Master_NodeId)d"/>
+ <xsd:attribute name="Sync_TPDOs" type="xsd:boolean" use="optional" default="true"/>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ """ % DEFAULT_SETTINGS
+
+ def GetCanDevice(self):
+ return str(self.BaseParams.getIEC_Channel())
+
+class LPCCanOpen(CanOpenRootClass):
+ XSD = None
+ PlugChildsTypes = [("CanOpenNode",LPCCanOpenMaster, "CanOpen Master"),
+ ("CanOpenSlave",LPCCanOpenSlave, "CanOpen Slave")]
+
+ def GetCanDriver(self):
+ return ""
+
+ def LoadChilds(self):
+ PlugTemplate.LoadChilds(self)
+
+ if self.GetChildByName("Master") is None:
+ master = self.PlugAddChild("Master", "CanOpenNode", 0)
+ master.BaseParams.setEnabled(False)
+
+ if self.GetChildByName("Slave") is None:
+ slave = self.PlugAddChild("Slave", "CanOpenSlave", 1)
+ slave.BaseParams.setEnabled(False)
+
+
+#-------------------------------------------------------------------------------
# LPCPluginsRoot Class
#-------------------------------------------------------------------------------
@@ -411,7 +503,7 @@
PluginsRoot.__init__(self, frame, logger)
- self.PlugChildsTypes += [("LPCBus", LPCBus, "LPC bus")]
+ self.PlugChildsTypes += [("LPCBus", LPCBus, "LPC bus"), ("CanOpen", LPCCanOpen, "CanOpen bus")]
self.PlugType = "LPC"
self.OnlineMode = "OFF"
@@ -590,6 +682,11 @@
#Load and init all the childs
self.LoadChilds()
+ if self.GetChildByName("CanOpen") is None:
+ canopen = self.PlugAddChild("CanOpen", "CanOpen", 0)
+ canopen.BaseParams.setEnabled(False)
+ canopen.LoadChilds()
+
if self.PlugTestModified():
self.SaveProject()
@@ -1043,9 +1140,12 @@
self.PluginTreeSizer.AddWindow(leftwindow, 0, border=0, flag=wx.GROW)
+ leftwindowvsizer = wx.BoxSizer(wx.VERTICAL)
+ leftwindow.SetSizer(leftwindowvsizer)
+
leftwindowsizer = wx.BoxSizer(wx.HORIZONTAL)
- leftwindow.SetSizer(leftwindowsizer)
-
+ leftwindowvsizer.AddSizer(leftwindowsizer, 0, border=0, flag=0)
+
st = wx.StaticText(leftwindow, -1)
st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
st.SetLabel(plugin.GetFullIEC_Channel())
@@ -1105,9 +1205,7 @@
st.SetLabel(plugin.MandatoryParams[1].getName())
leftwindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
- rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
- rightwindow.SetBackgroundColour(bkgdclr)
-
+ rightwindow = self.GenerateParamsPanel(plugin, bkgdclr)
self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW)
self.PluginInfos[plugin]["left"] = leftwindow
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/canfestival/NetworkEditor.py Sat Feb 11 00:02:02 2012 +0100
@@ -0,0 +1,122 @@
+import os, sys
+base_folder = os.path.split(sys.path[0])[0]
+CanFestivalPath = os.path.join(base_folder, "CanFestival-3")
+
+import wx
+
+from subindextable import EditingPanel
+from networkedit import NetworkEditorTemplate
+from controls import EditorPanel
+
+[ID_NETWORKEDITOR,
+] = [wx.NewId() for _init_ctrls in range(1)]
+
+[ID_NETWORKEDITORPLUGINMENUADDSLAVE, ID_NETWORKEDITORPLUGINMENUREMOVESLAVE,
+ ID_NETWORKEDITORPLUGINMENUMASTER,
+] = [wx.NewId() for _init_coll_PluginMenu_Items in range(3)]
+
+[ID_NETWORKEDITORMASTERMENUNODEINFOS, ID_NETWORKEDITORMASTERMENUDS301PROFILE,
+ ID_NETWORKEDITORMASTERMENUDS302PROFILE, ID_NETWORKEDITORMASTERMENUDSOTHERPROFILE,
+ ID_NETWORKEDITORMASTERMENUADD,
+] = [wx.NewId() for _init_coll_MasterMenu_Items in range(5)]
+
+[ID_NETWORKEDITORADDMENUSDOSERVER, ID_NETWORKEDITORADDMENUSDOCLIENT,
+ ID_NETWORKEDITORADDMENUPDOTRANSMIT, ID_NETWORKEDITORADDMENUPDORECEIVE,
+ ID_NETWORKEDITORADDMENUMAPVARIABLE, ID_NETWORKEDITORADDMENUUSERTYPE,
+] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
+
+class NetworkEditor(EditorPanel, NetworkEditorTemplate):
+
+ ID = ID_NETWORKEDITOR
+
+ def _init_coll_MainSizer_Items(self, parent):
+ parent.AddWindow(self.NetworkNodes, 0, border=5, flag=wx.GROW|wx.ALL)
+
+ def _init_coll_MainSizer_Growables(self, parent):
+ parent.AddGrowableCol(0)
+ parent.AddGrowableRow(0)
+
+ def _init_sizers(self):
+ self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=1, vgap=0)
+
+ self._init_coll_MainSizer_Items(self.MainSizer)
+ self._init_coll_MainSizer_Growables(self.MainSizer)
+
+ self.Editor.SetSizer(self.MainSizer)
+
+ def _init_Editor(self, prnt):
+ self.Editor = wx.Panel(id=-1, parent=prnt, pos=wx.Point(0, 0),
+ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
+
+ NetworkEditorTemplate._init_ctrls(self, self.Editor)
+
+ self._init_sizers()
+
+ def __init__(self, parent, controler, window):
+ EditorPanel.__init__(self, parent, "", window, controler)
+ NetworkEditorTemplate.__init__(self, controler, window, False)
+
+ img = wx.Bitmap(os.path.join(CanFestivalPath, "objdictgen", "networkedit.png"), wx.BITMAP_TYPE_PNG).ConvertToImage()
+ self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16)))
+
+ self.RefreshNetworkNodes()
+ self.RefreshBufferState()
+
+ def __del__(self):
+ self.Controler.OnCloseEditor(self)
+
+ def GetPluginMenuItems(self):
+ add_menu = [(wx.ITEM_NORMAL, (_('SDO Server'), ID_NETWORKEDITORADDMENUSDOSERVER, '', self.OnAddSDOServerMenu)),
+ (wx.ITEM_NORMAL, (_('SDO Client'), ID_NETWORKEDITORADDMENUSDOCLIENT, '', self.OnAddSDOClientMenu)),
+ (wx.ITEM_NORMAL, (_('PDO Transmit'), ID_NETWORKEDITORADDMENUPDOTRANSMIT, '', self.OnAddPDOTransmitMenu)),
+ (wx.ITEM_NORMAL, (_('PDO Receive'), ID_NETWORKEDITORADDMENUPDORECEIVE, '', self.OnAddPDOReceiveMenu)),
+ (wx.ITEM_NORMAL, (_('Map Variable'), ID_NETWORKEDITORADDMENUMAPVARIABLE, '', self.OnAddMapVariableMenu)),
+ (wx.ITEM_NORMAL, (_('User Type'), ID_NETWORKEDITORADDMENUUSERTYPE, '', self.OnAddUserTypeMenu))]
+
+ profile = self.Manager.GetCurrentProfileName()
+ if profile not in ("None", "DS-301"):
+ other_profile_text = _("%s Profile") % profile
+ add_menu.append((wx.ITEM_SEPARATOR, None))
+ for text, indexes in self.Manager.GetCurrentSpecificMenu():
+ add_menu.append((wx.ITEM_NORMAL, (text, wx.NewId(), '', self.GetProfileCallBack(text))))
+ else:
+ other_profile_text = _('Other Profile')
+
+ master_menu = [(wx.ITEM_NORMAL, (_('Node infos'), ID_NETWORKEDITORMASTERMENUNODEINFOS, '', self.OnNodeInfosMenu)),
+ (wx.ITEM_NORMAL, (_('DS-301 Profile'), ID_NETWORKEDITORMASTERMENUDS301PROFILE, '', self.OnCommunicationMenu)),
+ (wx.ITEM_NORMAL, (_('DS-302 Profile'), ID_NETWORKEDITORMASTERMENUDS302PROFILE, '', self.OnOtherCommunicationMenu)),
+ (wx.ITEM_NORMAL, (other_profile_text, ID_NETWORKEDITORMASTERMENUDSOTHERPROFILE, '', self.OnEditProfileMenu)),
+ (wx.ITEM_SEPARATOR, None),
+ (add_menu, (_('Add'), ID_NETWORKEDITORMASTERMENUADD))]
+
+ return [(wx.ITEM_NORMAL, (_('Add slave'), ID_NETWORKEDITORPLUGINMENUADDSLAVE, '', self.OnAddSlaveMenu)),
+ (wx.ITEM_NORMAL, (_('Remove slave'), ID_NETWORKEDITORPLUGINMENUREMOVESLAVE, '', self.OnRemoveSlaveMenu)),
+ (wx.ITEM_SEPARATOR, None),
+ (master_menu, (_('Master'), ID_NETWORKEDITORPLUGINMENUMASTER))]
+
+ def RefreshMainMenu(self):
+ pass
+
+ def RefreshPluginMenu(self, plugin_menu):
+ plugin_menu.Enable(ID_NETWORKEDITORPLUGINMENUMASTER, self.NetworkNodes.GetSelection() == 0)
+
+ def GetTitle(self):
+ fullname = self.Controler.PlugFullName()
+ if not self.Manager.CurrentIsSaved():
+ return "~%s~" % fullname
+ return fullname
+
+ def RefreshView(self):
+ self.RefreshCurrentIndexList()
+
+ def RefreshBufferState(self):
+ NetworkEditorTemplate.RefreshBufferState(self)
+ self.ParentWindow.RefreshTitle()
+ self.ParentWindow.RefreshFileMenu()
+ self.ParentWindow.RefreshEditMenu()
+ self.ParentWindow.RefreshPageTitles()
+
+ def OnNodeSelectedChanged(self, event):
+ NetworkEditorTemplate.OnNodeSelectedChanged(self, event)
+ wx.CallAfter(self.ParentWindow.RefreshPluginMenu)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/canfestival/SlaveEditor.py Sat Feb 11 00:02:02 2012 +0100
@@ -0,0 +1,83 @@
+import os, sys
+base_folder = os.path.split(sys.path[0])[0]
+CanFestivalPath = os.path.join(base_folder, "CanFestival-3")
+
+import wx
+
+from subindextable import EditingPanel
+from nodeeditor import NodeEditorTemplate
+from controls import EditorPanel
+
+[ID_SLAVEEDITORPLUGINMENUNODEINFOS, ID_SLAVEEDITORPLUGINMENUDS301PROFILE,
+ ID_SLAVEEDITORPLUGINMENUDS302PROFILE, ID_SLAVEEDITORPLUGINMENUDSOTHERPROFILE,
+ ID_SLAVEEDITORPLUGINMENUADD,
+] = [wx.NewId() for _init_coll_PluginMenu_Items in range(5)]
+
+[ID_SLAVEEDITORADDMENUSDOSERVER, ID_SLAVEEDITORADDMENUSDOCLIENT,
+ ID_SLAVEEDITORADDMENUPDOTRANSMIT, ID_SLAVEEDITORADDMENUPDORECEIVE,
+ ID_SLAVEEDITORADDMENUMAPVARIABLE, ID_SLAVEEDITORADDMENUUSERTYPE,
+] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
+
+class SlaveEditor(EditorPanel, NodeEditorTemplate):
+
+ def _init_Editor(self, prnt):
+ self.Editor = EditingPanel(prnt, self, self.Controler, self.Editable)
+
+ def __init__(self, parent, controler, window, editable=True):
+ self.Editable = editable
+ EditorPanel.__init__(self, parent, "", window, controler)
+ NodeEditorTemplate.__init__(self, controler, window, False)
+
+ img = wx.Bitmap(os.path.join(CanFestivalPath, "objdictgen", "networkedit.png"), wx.BITMAP_TYPE_PNG).ConvertToImage()
+ self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16)))
+
+ def __del__(self):
+ self.Controler.OnCloseEditor(self)
+
+ def GetPluginMenuItems(self):
+ if self.Editable:
+ add_menu = [(wx.ITEM_NORMAL, (_('SDO Server'), ID_SLAVEEDITORADDMENUSDOSERVER, '', self.OnAddSDOServerMenu)),
+ (wx.ITEM_NORMAL, (_('SDO Client'), ID_SLAVEEDITORADDMENUSDOCLIENT, '', self.OnAddSDOClientMenu)),
+ (wx.ITEM_NORMAL, (_('PDO Transmit'), ID_SLAVEEDITORADDMENUPDOTRANSMIT, '', self.OnAddPDOTransmitMenu)),
+ (wx.ITEM_NORMAL, (_('PDO Receive'), ID_SLAVEEDITORADDMENUPDORECEIVE, '', self.OnAddPDOReceiveMenu)),
+ (wx.ITEM_NORMAL, (_('Map Variable'), ID_SLAVEEDITORADDMENUMAPVARIABLE, '', self.OnAddMapVariableMenu)),
+ (wx.ITEM_NORMAL, (_('User Type'), ID_SLAVEEDITORADDMENUUSERTYPE, '', self.OnAddUserTypeMenu))]
+
+ profile = self.Controler.GetCurrentProfileName()
+ if profile not in ("None", "DS-301"):
+ other_profile_text = _("%s Profile") % profile
+ add_menu.append((wx.ITEM_SEPARATOR, None))
+ for text, indexes in self.Manager.GetCurrentSpecificMenu():
+ add_menu.append((wx.ITEM_NORMAL, (text, wx.NewId(), '', self.GetProfileCallBack(text))))
+ else:
+ other_profile_text = _('Other Profile')
+
+ return [(wx.ITEM_NORMAL, (_('Node infos'), ID_SLAVEEDITORPLUGINMENUNODEINFOS, '', self.OnNodeInfosMenu)),
+ (wx.ITEM_NORMAL, (_('DS-301 Profile'), ID_SLAVEEDITORPLUGINMENUDS301PROFILE, '', self.OnCommunicationMenu)),
+ (wx.ITEM_NORMAL, (_('DS-302 Profile'), ID_SLAVEEDITORPLUGINMENUDS302PROFILE, '', self.OnOtherCommunicationMenu)),
+ (wx.ITEM_NORMAL, (other_profile_text, ID_SLAVEEDITORPLUGINMENUDSOTHERPROFILE, '', self.OnEditProfileMenu)),
+ (wx.ITEM_SEPARATOR, None),
+ (add_menu, (_('Add'), ID_SLAVEEDITORPLUGINMENUADD))]
+ return []
+
+ def RefreshPluginMenu(self, plugin_menu):
+ plugin_menu.Enable(ID_SLAVEEDITORPLUGINMENUDSOTHERPROFILE, False)
+
+ def GetTitle(self):
+ fullname = self.Controler.PlugFullName()
+ if not self.Controler.CurrentIsSaved():
+ return "~%s~" % fullname
+ return fullname
+
+ def RefreshView(self):
+ self.Editor.RefreshIndexList()
+
+ def RefreshCurrentIndexList(self):
+ self.RefreshView()
+
+ def RefreshBufferState(self):
+ self.ParentWindow.RefreshTitle()
+ self.ParentWindow.RefreshFileMenu()
+ self.ParentWindow.RefreshEditMenu()
+ self.ParentWindow.RefreshPageTitles()
+
--- a/plugins/canfestival/canfestival.py Tue Feb 07 19:14:10 2012 +0100
+++ b/plugins/canfestival/canfestival.py Sat Feb 11 00:02:02 2012 +0100
@@ -13,6 +13,9 @@
from commondialogs import CreateNodeDialog
import wx
+from SlaveEditor import SlaveEditor
+from NetworkEditor import NetworkEditor
+
from gnosis.xml.pickle import *
from gnosis.xml.pickle.util import setParanoia
setParanoia(0)
@@ -59,9 +62,8 @@
</xsd:element>
</xsd:schema>
""" % DEFAULT_SETTINGS
-
- def GetSlaveODPath(self):
- return os.path.join(self.PlugPath(), 'slave.od')
+
+ EditorType = SlaveEditor
def __init__(self):
# TODO change netname when name change
@@ -97,34 +99,18 @@
"heartbeat", # NMT
[]) # options
dialog.Destroy()
- _View = None
+ self.OnPlugSave()
+
+ def GetSlaveODPath(self):
+ return os.path.join(self.PlugPath(), 'slave.od')
+
+ def GetCanDevice(self):
+ return self.CanFestivalSlaveNode.getCan_Device()
+
def _OpenView(self):
- if not self._View:
- open_objdictedit = True
- has_permissions = self.GetPlugRoot().CheckProjectPathPerm()
- if not has_permissions:
- dialog = wx.MessageDialog(self.GetPlugRoot().AppFrame,
- _("You don't have write permissions.\nOpen ObjDictEdit anyway ?"),
- _("Open ObjDictEdit"),
- wx.YES_NO|wx.ICON_QUESTION)
- open_objdictedit = dialog.ShowModal() == wx.ID_YES
- dialog.Destroy()
- if open_objdictedit:
- def _onclose():
- self._View = None
- if has_permissions:
- def _onsave():
- self.GetPlugRoot().SaveProject()
- else:
- def _onsave():
- pass
-
- self._View = objdictedit(self.GetPlugRoot().AppFrame, self)
- # TODO redefine BusId when IEC channel change
- self._View.SetBusId(self.GetCurrentLocation())
- self._View._onclose = _onclose
- self._View._onsave = _onsave
- self._View.Show()
+ PlugTemplate._OpenView(self)
+ if self._View is not None:
+ self._View.SetBusId(self.GetCurrentLocation())
PluginMethods = [
{"bitmap" : os.path.join("images", "NetworkEdit"),
@@ -143,6 +129,15 @@
def OnPlugSave(self):
return self.SaveCurrentInFile(self.GetSlaveODPath())
+ def SetParamsAttribute(self, path, value):
+ result = PlugTemplate.SetParamsAttribute(self, path, value)
+
+ # Filter IEC_Channel and Name, that have specific behavior
+ if path == "BaseParams.IEC_Channel" and self._View is not None:
+ self._View.SetBusId(self.GetCurrentLocation())
+
+ return result
+
def PlugGenerate_C(self, buildpath, locations):
"""
Generate C code
@@ -173,10 +168,38 @@
raise Exception, res
return [(Gen_OD_path,local_canfestival_config.getCFLAGS(CanFestivalPath))],"",False
+ def LoadPrevious(self):
+ self.LoadCurrentPrevious()
+
+ def LoadNext(self):
+ self.LoadCurrentNext()
+
+ def GetBufferState(self):
+ return self.GetCurrentBufferState()
+
#--------------------------------------------------
# MASTER
#--------------------------------------------------
+class MiniNodeManager(NodeManager):
+
+ def __init__(self, parent, filepath, fullname):
+ NodeManager.__init__(self)
+
+ self.OpenFileInCurrent(filepath)
+
+ self.Parent = parent
+ self.Fullname = fullname
+
+ def OnCloseEditor(self, view):
+ self.Parent.OnCloseEditor(view)
+
+ def PlugFullName(self):
+ return self.Fullname
+
+ def GetBufferState(self):
+ return self.GetCurrentBufferState()
+
class _NodeListPlug(NodeList):
XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
@@ -190,56 +213,61 @@
</xsd:element>
</xsd:schema>
""" % DEFAULT_SETTINGS
-
+
+ EditorType = NetworkEditor
+
def __init__(self):
manager = NodeManager()
- # TODO change netname when name change
- NodeList.__init__(self, manager, self.BaseParams.getName())
+ NodeList.__init__(self, manager)
self.LoadProject(self.PlugPath())
-
- _View = None
+ self.SetNetworkName(self.BaseParams.getName())
+
+ def GetCanDevice(self):
+ return self.CanFestivalNode.getCan_Device()
+
+ def SetParamsAttribute(self, path, value):
+ result = PlugTemplate.SetParamsAttribute(self, path, value)
+
+ # Filter IEC_Channel and Name, that have specific behavior
+ if path == "BaseParams.IEC_Channel" and self._View is not None:
+ self._View.SetBusId(self.GetCurrentLocation())
+ elif path == "BaseParams.Name":
+ self.SetNetworkName(value)
+
+ return result
+
def _OpenView(self):
- if not self._View:
- open_networkedit = True
- has_permissions = self.GetPlugRoot().CheckProjectPathPerm()
- if not has_permissions:
- dialog = wx.MessageDialog(self.GetPlugRoot().AppFrame,
- _("You don't have write permissions.\nOpen NetworkEdit anyway ?"),
- _("Open NetworkEdit"),
- wx.YES_NO|wx.ICON_QUESTION)
- open_networkedit = dialog.ShowModal() == wx.ID_YES
- dialog.Destroy()
- if open_networkedit:
- def _onclose():
- self._View = None
- if has_permissions:
- def _onsave():
- self.GetPlugRoot().SaveProject()
- else:
- def _onsave():
- pass
- self._View = networkedit(self.GetPlugRoot().AppFrame, self)
- # TODO redefine BusId when IEC channel change
- self._View.SetBusId(self.GetCurrentLocation())
- self._View._onclose = _onclose
- self._View._onsave = _onsave
- self._View.Show()
-
+ PlugTemplate._OpenView(self)
+ if self._View is not None:
+ self._View.SetBusId(self.GetCurrentLocation())
+
+ _GeneratedView = None
def _ShowMasterGenerated(self):
- buildpath = self._getBuildPath()
- # Eventually create build dir
- if not os.path.exists(buildpath):
- self.GetPlugRoot().logger.write_error(_("Error: No PLC built\n"))
- return
-
- masterpath = os.path.join(buildpath, "MasterGenerated.od")
- if not os.path.exists(masterpath):
- self.GetPlugRoot().logger.write_error(_("Error: No Master generated\n"))
- return
-
- new_dialog = objdictedit(None, filesOpen=[masterpath])
- new_dialog.Show()
-
+ if self._GeneratedView is None:
+ buildpath = self._getBuildPath()
+ # Eventually create build dir
+ if not os.path.exists(buildpath):
+ self.GetPlugRoot().logger.write_error(_("Error: No PLC built\n"))
+ return
+
+ masterpath = os.path.join(buildpath, "MasterGenerated.od")
+ if not os.path.exists(masterpath):
+ self.GetPlugRoot().logger.write_error(_("Error: No Master generated\n"))
+ return
+
+ app_frame = self.GetPlugRoot().AppFrame
+
+ manager = MiniNodeManager(self, masterpath, self.PlugFullName() + ".generated_master")
+ self._GeneratedView = SlaveEditor(app_frame.TabsOpened, manager, app_frame, False)
+
+ app_frame.EditProjectElement(self._GeneratedView, "MasterGenerated")
+
+ def _CloseGenerateView(self):
+ if self._GeneratedView is not None:
+ app_frame = self.GetPlugRoot().AppFrame
+ if app_frame is not None:
+ app_frame.DeletePage(self._GeneratedView)
+
PluginMethods = [
{"bitmap" : os.path.join("images", "NetworkEdit"),
"name" : _("Edit network"),
@@ -250,10 +278,16 @@
"tooltip" : _("Show Master generated by config_utils"),
"method" : "_ShowMasterGenerated"}
]
+
+ def OnCloseEditor(self, view):
+ PlugTemplate.OnCloseEditor(self, view)
+ if self._GeneratedView == view:
+ self._GeneratedView = None
def OnPlugClose(self):
- if self._View:
- self._View.Close()
+ PlugTemplate.OnPlugClose(self)
+ self._CloseGenerateView()
+ return True
def PlugTestModified(self):
return self.ChangesToSave or self.HasChanged()
@@ -275,6 +309,7 @@
}, ...]
@return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
"""
+ self._CloseGenerateView()
current_location = self.GetCurrentLocation()
# define a unique name for the generated C file
prefix = "_".join(map(str, current_location))
@@ -295,6 +330,15 @@
return [(Gen_OD_path,local_canfestival_config.getCFLAGS(CanFestivalPath))],"",False
+ def LoadPrevious(self):
+ self.Manager.LoadCurrentPrevious()
+
+ def LoadNext(self):
+ self.Manager.LoadCurrentNext()
+
+ def GetBufferState(self):
+ return self.Manager.GetCurrentBufferState()
+
class RootClass:
XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
@@ -317,14 +361,22 @@
if child["name"] == "CAN_Driver":
DLL_LIST= getattr(local_canfestival_config,"DLL_LIST",None)
if DLL_LIST is not None:
- child["type"] = DLL_LIST
- return infos
+ child["type"] = DLL_LIST
return infos
-
+
+ def GetCanDriver(self):
+ can_driver = self.CanFestivalInstance.getCAN_Driver()
+ if sys.platform == 'win32':
+ if self.CanFestivalInstance.getDebug_mode() and os.path.isfile(os.path.join("%s"%(can_driver + '_DEBUG.dll'))):
+ can_driver += '_DEBUG.dll'
+ else:
+ can_driver += '.dll'
+ return can_driver
+
def PlugGenerate_C(self, buildpath, locations):
format_dict = {"locstr" : "_".join(map(str,self.GetCurrentLocation())),
- "candriver" : self.CanFestivalInstance.getCAN_Driver(),
+ "candriver" : self.GetCanDriver(),
"nodes_includes" : "",
"board_decls" : "",
"nodes_init" : "",
@@ -357,29 +409,34 @@
# initialize and declare node boot status variables for post_SlaveBootup lookup
SlaveIDs = child.GetSlaveIDs()
- for id in SlaveIDs:
+ if len(SlaveIDs) == 0:
+ # define post_SlaveBootup lookup functions
format_dict["slavebootups"] += (
- "int %s_slave_%d_booted = 0;\n"%(nodename, id))
- # define post_SlaveBootup lookup functions
- format_dict["slavebootups"] += (
- "static void %s_post_SlaveBootup(CO_Data* d, UNS8 nodeId){\n"%(nodename)+
- " switch(nodeId){\n")
- # one case per declared node, mark node as booted
- for id in SlaveIDs:
+ "static void %s_post_SlaveBootup(CO_Data* d, UNS8 nodeId){}\n"%(nodename))
+ else:
+ for id in SlaveIDs:
+ format_dict["slavebootups"] += (
+ "int %s_slave_%d_booted = 0;\n"%(nodename, id))
+ # define post_SlaveBootup lookup functions
format_dict["slavebootups"] += (
- " case %d:\n"%(id)+
- " %s_slave_%d_booted = 1;\n"%(nodename, id)+
- " break;\n")
- format_dict["slavebootups"] += (
- " default:\n"+
- " break;\n"+
- " }\n"+
- " if( ")
- # expression to test if all declared nodes booted
- format_dict["slavebootups"] += " && ".join(["%s_slave_%d_booted"%(nodename, id) for id in SlaveIDs])
- format_dict["slavebootups"] += " )\n" + (
- " Master_post_SlaveBootup(d,nodeId);\n"+
- "}\n")
+ "static void %s_post_SlaveBootup(CO_Data* d, UNS8 nodeId){\n"%(nodename)+
+ " switch(nodeId){\n")
+ # one case per declared node, mark node as booted
+ for id in SlaveIDs:
+ format_dict["slavebootups"] += (
+ " case %d:\n"%(id)+
+ " %s_slave_%d_booted = 1;\n"%(nodename, id)+
+ " break;\n")
+ format_dict["slavebootups"] += (
+ " default:\n"+
+ " break;\n"+
+ " }\n"+
+ " if( ")
+ # expression to test if all declared nodes booted
+ format_dict["slavebootups"] += " && ".join(["%s_slave_%d_booted"%(nodename, id) for id in SlaveIDs])
+ format_dict["slavebootups"] += " )\n" + (
+ " Master_post_SlaveBootup(d,nodeId);\n"+
+ "}\n")
# register previously declared func as post_SlaveBootup callback for that node
format_dict["slavebootup_register"] += (
"%s_Data.post_SlaveBootup = %s_post_SlaveBootup;\n"%(nodename,nodename))
@@ -409,16 +466,11 @@
# Declare CAN channels according user filled config
format_dict["board_decls"] += 'BOARD_DECL(%s, "%s", "%s")\n'%(
nodename,
- child_data.getCAN_Device(),
+ child.GetCanDevice(),
child_data.getCAN_Baudrate())
format_dict["nodes_open"] += 'NODE_OPEN(%s)\n '%(nodename)
format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n '%(nodename)
- format_dict["nodes_stop"] += 'NODE_STOP(%s)\n '%(nodename)
- if sys.platform == 'win32':
- if self.CanFestivalInstance.getDebug_mode() and os.path.isfile(os.path.join("%s"%(format_dict["candriver"] + '_DEBUG.dll'))):
- format_dict["candriver"] += '_DEBUG.dll'
- else:
- format_dict["candriver"] += '.dll'
+ format_dict["nodes_stop"] += 'NODE_STOP(%s)\n '%(nodename)
filename = os.path.join(os.path.split(__file__)[0],"cf_runtime.c")
cf_main = open(filename).read() % format_dict