--- a/Beremiz.py Fri Jan 09 17:08:31 2009 +0100
+++ b/Beremiz.py Wed Jan 14 16:41:14 2009 +0100
@@ -416,18 +416,10 @@
self._init_ctrls(parent)
self.Log = LogPseudoFile(self.LogConsole)
-
- # create temporary directory for runtime working directory
- self.local_runtime_tmpdir = tempfile.mkdtemp()
- # choose an arbitrary random port for runtime
- self.runtime_port = int(random.random() * 1000) + 61131
- # launch local runtime
- self.local_runtime = ProcessLogger(self.Log,
- "\"%s\" \"%s\" -p %s -i localhost -x 0 %s"%(sys.executable,
- Bpath("Beremiz_service.py"),
- self.runtime_port,
- self.local_runtime_tmpdir),
- no_gui=False)
+
+ self.local_runtime = None
+ self.runtime_port = None
+ self.local_runtime_tmpdir = None
# Add beremiz's icon in top left corner of the frame
self.SetIcon(wx.Icon(Bpath( "images", "brz.ico"), wx.BITMAP_TYPE_ICO))
@@ -437,7 +429,7 @@
self.PluginInfos = {}
if projectOpen:
- self.PluginRoot = PluginsRoot(self, self.Log, self.runtime_port)
+ self.PluginRoot = PluginsRoot(self, self.Log)
self.PluginRoot.LoadProject(projectOpen, buildpath)
self.RefreshAll()
else:
@@ -445,6 +437,30 @@
self.RefreshMainMenu()
+ def StartLocalRuntime(self, taskbaricon = True):
+ if self.local_runtime is None or self.local_runtime.finished:
+ # create temporary directory for runtime working directory
+ self.local_runtime_tmpdir = tempfile.mkdtemp()
+ # choose an arbitrary random port for runtime
+ self.runtime_port = int(random.random() * 1000) + 61131
+ # launch local runtime
+ self.local_runtime = ProcessLogger(self.Log,
+ "\"%s\" \"%s\" -p %s -i localhost %s %s"%(sys.executable,
+ Bpath("Beremiz_service.py"),
+ self.runtime_port,
+ {False : "-x 0", True :"-x 1"}[taskbaricon],
+ self.local_runtime_tmpdir),
+ no_gui=False)
+ self.local_runtime.spin(timeout=500, keyword = "working", kill_it = False)
+ return self.runtime_port
+
+ def KillLocalRuntime(self):
+ if self.local_runtime is not None:
+ # shutdown local runtime
+ self.local_runtime.kill(gently=False)
+ # clear temp dir
+ shutil.rmtree(self.local_runtime_tmpdir)
+
def OnOpenWidgetInspector(self, evt):
# Activate the widget inspection tool
from wx.lib.inspection import InspectionTool
@@ -492,11 +508,8 @@
event.Veto()
return
- # shutdown local runtime
- self.local_runtime.kill(gently=False)
- # clear temp dir
- shutil.rmtree(self.local_runtime_tmpdir)
-
+ self.KillLocalRuntime()
+
event.Skip()
def OnMoveWindow(self, event):
--- a/Beremiz_service.py Fri Jan 09 17:08:31 2009 +0100
+++ b/Beremiz_service.py Wed Jan 14 16:41:14 2009 +0100
@@ -215,6 +215,7 @@
message.Destroy()
return
self.EndModal(wx.ID_OK)
+ event.Skip()
def GetValue(self):
return self.GetSizer().GetItem(1).GetWindow().GetValue()
@@ -222,21 +223,24 @@
def SetTests(self, tests):
self.Tests = tests
- class DemoTaskBarIcon(wx.TaskBarIcon):
+ class BeremizTaskBarIcon(wx.TaskBarIcon):
TBMENU_CHANGE_NAME = wx.NewId()
TBMENU_CHANGE_PORT = wx.NewId()
TBMENU_CHANGE_INTERFACE = wx.NewId()
+ TBMENU_LIVE_SHELL = wx.NewId()
TBMENU_CHANGE_WD = wx.NewId()
TBMENU_QUIT = wx.NewId()
def __init__(self, pyroserver):
wx.TaskBarIcon.__init__(self)
+ self.pyroserver = pyroserver
# Set the image
self.UpdateIcon(None)
# bind some events
self.Bind(wx.EVT_MENU, self.OnTaskBarChangeName, id=self.TBMENU_CHANGE_NAME)
self.Bind(wx.EVT_MENU, self.OnTaskBarChangeInterface, id=self.TBMENU_CHANGE_INTERFACE)
+ self.Bind(wx.EVT_MENU, self.OnTaskBarLiveShell, id=self.TBMENU_LIVE_SHELL)
self.Bind(wx.EVT_MENU, self.OnTaskBarChangePort, id=self.TBMENU_CHANGE_PORT)
self.Bind(wx.EVT_MENU, self.OnTaskBarChangeWorkingDir, id=self.TBMENU_CHANGE_WD)
self.Bind(wx.EVT_MENU, self.OnTaskBarQuit, id=self.TBMENU_QUIT)
@@ -251,6 +255,7 @@
menu = wx.Menu()
menu.Append(self.TBMENU_CHANGE_NAME, "Change Name")
menu.Append(self.TBMENU_CHANGE_INTERFACE, "Change IP of interface to bind")
+ menu.Append(self.TBMENU_LIVE_SHELL, "Launch a live Python shell")
menu.Append(self.TBMENU_CHANGE_PORT, "Change Port Number")
menu.AppendSeparator()
menu.Append(self.TBMENU_CHANGE_WD, "Change working directory")
@@ -276,34 +281,47 @@
( lambda ip :len([x for x in ip.split(".") if 0 <= int(x) <= 255]) == 4, "Ip is not valid!")
])
if dlg.ShowModal() == wx.ID_OK:
- pyroserver.ip = dlg.GetValue()
- pyroserver.Stop()
+ self.pyroserver.ip = dlg.GetValue()
+ self.pyroserver.Stop()
+ evt.Skip()
def OnTaskBarChangePort(self,evt):
dlg = ParamsEntryDialog(None, "Enter a port number ", defaultValue=str(pyroserver.port))
dlg.SetTests([(UnicodeType.isdigit, "Port number must be an integer!"), (lambda port : 0 <= int(port) <= 65535 , "Port number must be 0 <= port <= 65535!")])
if dlg.ShowModal() == wx.ID_OK:
- pyroserver.port = int(dlg.GetValue())
- pyroserver.Stop()
-
+ self.pyroserver.port = int(dlg.GetValue())
+ self.pyroserver.Stop()
+ evt.Skip()
def OnTaskBarChangeWorkingDir(self,evt):
dlg = wx.DirDialog(None, "Choose a working directory ", pyroserver.workdir, wx.DD_NEW_DIR_BUTTON)
if dlg.ShowModal() == wx.ID_OK:
- pyroserver.workdir = dlg.GetPath()
- pyroserver.Stop()
+ self.pyroserver.workdir = dlg.GetPath()
+ self.pyroserver.Stop()
+ evt.Skip()
def OnTaskBarChangeName(self,evt):
dlg = ParamsEntryDialog(None, "Enter a name ", defaultValue=pyroserver.name)
dlg.SetTests([(lambda name : len(name) is not 0 , "Name must not be null!")])
if dlg.ShowModal() == wx.ID_OK:
- pyroserver.name = dlg.GetValue()
- pyroserver.Restart()
-
+ self.pyroserver.name = dlg.GetValue()
+ self.pyroserver.Restart()
+ evt.Skip()
+
+ def OnTaskBarLiveShell(self,evt):
+ if self.pyroserver.plcobj is not None and self.pyroserver.plcobj.python_threads_vars is not None:
+ from wx import py
+ frame = py.shell.ShellFrame(locals=self.pyroserver.plcobj.python_threads_vars)
+ frame.Show()
+ else:
+ wx.MessageBox("No runnning PLC","Error")
+ evt.Skip()
+
def OnTaskBarQuit(self,evt):
pyroserver.Quit()
self.RemoveIcon()
wx.GetApp().ExitMainLoop()
+ evt.Skip()
def UpdateIcon(self, plcstatus):
if plcstatus is "Started" :
@@ -376,7 +394,7 @@
if havewx:
app=wx.App(redirect=False)
- taskbar_instance = DemoTaskBarIcon(pyroserver)
+ taskbar_instance = BeremizTaskBarIcon(pyroserver)
def statuschange(status):
wx.CallAfter(taskbar_instance.UpdateIcon,status)
pyro_thread=Thread(target=pyroserver.Loop, args=[statuschange])
--- a/connectors/__init__.py Fri Jan 09 17:08:31 2009 +0100
+++ b/connectors/__init__.py Wed Jan 14 16:41:14 2009 +0100
@@ -39,9 +39,12 @@
factoryname = servicetype + "_connector_factory"
return getattr(connectormodule, factoryname)(uri, pluginsroot)
elif servicetype == "LOCAL":
+ #handle incompatibility with tray icon and svgui...
+ no_poisoned_plugin = pluginsroot.GetChildByType("svgui") is None
+ runtime_port = pluginsroot.AppFrame.StartLocalRuntime(taskbaricon = no_poisoned_plugin)
import PYRO
return PYRO.PYRO_connector_factory(
- "PYRO://127.0.0.1:"+str(pluginsroot.runtime_port),
+ "PYRO://127.0.0.1:"+str(runtime_port),
pluginsroot)
else :
return None
--- a/plugger.py Fri Jan 09 17:08:31 2009 +0100
+++ b/plugger.py Wed Jan 14 16:41:14 2009 +0100
@@ -313,6 +313,12 @@
else:
return self
+ def GetChildByType(self, TypeName):
+ if TypeName:
+ return self._GetChildBySomething("PlugType", TypeName)
+ else:
+ return self
+
def GetChildByIECLocation(self, Location):
if Location:
return self._GetChildBySomething("IEC_Channel", Location)
@@ -668,10 +674,9 @@
</xsd:schema>
"""
- def __init__(self, frame, logger, runtime_port):
+ def __init__(self, frame, logger):
PLCControler.__init__(self)
- self.runtime_port = runtime_port
self.MandatoryParams = None
self.AppFrame = frame
self.logger = logger
--- a/runtime/PLCObject.py Fri Jan 09 17:08:31 2009 +0100
+++ b/runtime/PLCObject.py Wed Jan 14 16:41:14 2009 +0100
@@ -51,6 +51,7 @@
self._FreePLC()
self.daemon = daemon
self.statuschange = statuschange
+ self.python_threads_vars = None
# Get the last transfered PLC if connector must be restart
try:
@@ -174,28 +175,29 @@
def PythonThreadProc(self):
print "PythonThreadProc started"
- my_globs = globals().copy()
+ self.python_threads_vars = globals().copy()
pyfile = os.path.join(self.workingdir, "runtime.py")
if os.path.exists(pyfile):
# TODO handle exceptions in runtime.py
# pyfile may redefine _runtime_cleanup
# or even call _PythonThreadProc itself.
- execfile(pyfile, my_globs)
+ execfile(pyfile, self.python_threads_vars)
res,cmd = "None","None"
while self.PLCStatus == "Started":
- print "_PythonIterator(", res, ")",
+ #print "_PythonIterator(", res, ")",
cmd = self._PythonIterator(res)
- print " -> ", cmd
+ #print " -> ", cmd
if cmd is None:
break
try :
- res = str(eval(cmd,my_globs))
+ res = str(eval(cmd,self.python_threads_vars))
except Exception,e:
res = "#EXCEPTION : "+str(e)
print res
print "PythonThreadProc interrupted"
- if my_globs.get("_runtime_cleanup",None) is not None:
- my_globs["_runtime_cleanup"]()
+ if self.python_threads_vars.get("_runtime_cleanup",None) is not None:
+ self.python_threads_vars["_runtime_cleanup"]()
+ self.python_threads_vars = None
print "PythonThreadProc cleaned up"
def StartPLC(self, debug=False):
--- a/targets/Linux/__init__.py Fri Jan 09 17:08:31 2009 +0100
+++ b/targets/Linux/__init__.py Wed Jan 14 16:41:14 2009 +0100
@@ -2,4 +2,5 @@
class Linux_target(toolchain_gcc):
extension = ".so"
- CustomLDFLAGS = ["-shared", "-lrt"]
+ def getBuilderLDFLAGS(self):
+ return toolchain_gcc.getBuilderLDFLAGS(self) + ["-shared", "-lrt"]
--- a/targets/Linux/plc_Linux_main.c Fri Jan 09 17:08:31 2009 +0100
+++ b/targets/Linux/plc_Linux_main.c Wed Jan 14 16:41:14 2009 +0100
@@ -141,12 +141,14 @@
void suspendDebug(void)
{
+ __DEBUG = 0;
/* Prevent PLC to enter debug code */
pthread_mutex_lock(&debug_mutex);
}
void resumeDebug(void)
{
+ __DEBUG = 1;
/* Let PLC enter debug code */
pthread_mutex_unlock(&debug_mutex);
}
--- a/targets/Win32/__init__.py Fri Jan 09 17:08:31 2009 +0100
+++ b/targets/Win32/__init__.py Wed Jan 14 16:41:14 2009 +0100
@@ -2,7 +2,8 @@
class Win32_target(toolchain_gcc):
extension = ".dll"
- CustomLDFLAGS = ["-shared",
+ def getBuilderLDFLAGS(self):
+ return toolchain_gcc.getBuilderLDFLAGS(self) + ["-shared",
"-Wl,--export-all-symbols",
"-Wl,--enable-auto-import",
"-Wl,--whole-archive",
--- a/targets/Win32/plc_Win32_main.c Fri Jan 09 17:08:31 2009 +0100
+++ b/targets/Win32/plc_Win32_main.c Wed Jan 14 16:41:14 2009 +0100
@@ -188,12 +188,14 @@
void suspendDebug()
{
+ __DEBUG = 0;
/* Prevent PLC to enter debug code */
WaitForSingleObject(debug_sem, INFINITE);
}
void resumeDebug()
{
+ __DEBUG = 1;
/* Let PLC enter debug code */
ReleaseSemaphore(debug_sem, 1, NULL);
}
--- a/targets/toolchain_gcc.py Fri Jan 09 17:08:31 2009 +0100
+++ b/targets/toolchain_gcc.py Wed Jan 14 16:41:14 2009 +0100
@@ -19,6 +19,19 @@
self.md5key = None
self.srcmd5 = {}
+ def getBuilderLDFLAGS(self):
+ """
+ Returns list of builder specific CFLAGS
+ """
+ return [self.PuginsRootInstance.BeremizRoot.getTargetType().getcontent()["value"].getCFLAGS()]
+
+ def getBuilderCFLAGS(self):
+ """
+ Returns list of builder specific LDFLAGS
+ """
+ return self.PuginsRootInstance.LDFLAGS + \
+ [self.PuginsRootInstance.BeremizRoot.getTargetType().getcontent()["value"].getLDFLAGS()]
+
def GetBinaryCode(self):
try:
return open(self.exe_path, "rb").read()
@@ -67,9 +80,9 @@
# Retrieve toolchain user parameters
toolchain_params = self.PuginsRootInstance.BeremizRoot.getTargetType().getcontent()["value"]
self.compiler = toolchain_params.getCompiler()
- self._CFLAGS = toolchain_params.getCFLAGS()
self.linker = toolchain_params.getLinker()
- self._LDFLAGS = toolchain_params.getLDFLAGS()
+
+ Builder_CFLAGS = ' '.join(self.getBuilderCFLAGS())
######### GENERATE OBJECT FILES ########################################
obns = []
@@ -98,7 +111,7 @@
status, result, err_result = ProcessLogger(
self.logger,
"\"%s\" -c \"%s\" -o \"%s\" %s %s"%
- (self.compiler, CFile, objectfilename, self._CFLAGS, CFLAGS)
+ (self.compiler, CFile, objectfilename, Builder_CFLAGS, CFLAGS)
).spin()
if status :
@@ -117,7 +130,7 @@
# Generate list .o files
listobjstring = '"' + '" "'.join(objs) + '"'
- ALLldflags = ' '.join(self.CustomLDFLAGS+self.PuginsRootInstance.LDFLAGS+[self._LDFLAGS])
+ ALLldflags = ' '.join(self.getBuilderLDFLAGS())
self.logger.write(" [CC] " + ' '.join(obns)+" -> " + self.exe + "\n")