--- a/Beremiz_service.py Sat Dec 09 01:03:43 2023 +0100
+++ b/Beremiz_service.py Wed Jan 17 22:09:32 2024 +0100
@@ -36,7 +36,7 @@
from functools import partial
-from runtime.PyroServer import PyroServer
+from runtime.eRPCServer import eRPCServer as RPCServer from runtime.xenomai import TryPreloadXenomai
from runtime import LogMessageAndException
from runtime import PlcStatus
@@ -270,12 +270,12 @@
TBMENU_CHANGE_INTERFACE = wx.NewIdRef()
TBMENU_LIVE_SHELL = wx.NewIdRef()
TBMENU_WXINSPECTOR = wx.NewIdRef()
- TBMENU_CHANGE_WD = wx.NewIdRef()
+ # TBMENU_CHANGE_WD = wx.NewIdRef() TBMENU_QUIT = wx.NewIdRef()
- def __init__(self, pyroserver):
+ def __init__(self, rpc_server): wx.adv.TaskBarIcon.__init__(self)
- self.pyroserver = pyroserver
+ self.rpc_server = rpc_server @@ -287,7 +287,7 @@
self.Bind(wx.EVT_MENU, self.OnTaskBarLiveShell, id=self.TBMENU_LIVE_SHELL)
self.Bind(wx.EVT_MENU, self.OnTaskBarWXInspector, id=self.TBMENU_WXINSPECTOR)
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.OnTaskBarChangeWorkingDir, id=self.TBMENU_CHANGE_WD) self.Bind(wx.EVT_MENU, self.OnTaskBarQuit, id=self.TBMENU_QUIT)
def CreatePopupMenu(self):
@@ -304,7 +304,7 @@
menu.Append(self.TBMENU_CHANGE_NAME, _("Change Name"))
menu.Append(self.TBMENU_CHANGE_INTERFACE, _("Change IP of interface to bind"))
menu.Append(self.TBMENU_CHANGE_PORT, _("Change Port Number"))
- menu.Append(self.TBMENU_CHANGE_WD, _("Change working directory"))
+ # menu.Append(self.TBMENU_CHANGE_WD, _("Change working directory")) menu.Append(self.TBMENU_LIVE_SHELL, _("Launch a live Python shell"))
menu.Append(self.TBMENU_WXINSPECTOR, _("Launch WX GUI inspector"))
@@ -332,37 +332,37 @@
runtime.GetPLCObjectSingleton().StopPLC()
def OnTaskBarChangeInterface(self, evt):
- ip_addr = self.pyroserver.ip_addr
+ ip_addr = self.rpc_server.ip_addr ip_addr = '' if ip_addr is None else ip_addr
dlg = ParamsEntryDialog(None, _("Enter the IP of the interface to bind"), defaultValue=ip_addr)
dlg.SetTests([(re.compile(r'\d{1,3}(?:\.\d{1,3}){3}$').match, _("IP is not valid!")),
(lambda x:len([x for x in x.split(".") if 0 <= int(x) <= 255]) == 4,
if dlg.ShowModal() == wx.ID_OK:
- self.pyroserver.ip_addr = dlg.GetValue()
- self.pyroserver.Restart()
+ self.rpc_server.ip_addr = dlg.GetValue() + self.rpc_server.Restart() def OnTaskBarChangePort(self, evt):
- dlg = ParamsEntryDialog(None, _("Enter a port number "), defaultValue=str(self.pyroserver.port))
+ dlg = ParamsEntryDialog(None, _("Enter a port number "), defaultValue=str(self.rpc_server.port)) dlg.SetTests([(str.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:
- self.pyroserver.port = int(dlg.GetValue())
- self.pyroserver.Restart()
+ self.rpc_server.port = int(dlg.GetValue()) + self.rpc_server.Restart() - def OnTaskBarChangeWorkingDir(self, evt):
- dlg = wx.DirDialog(None, _("Choose a working directory "), self.pyroserver.workdir, wx.DD_NEW_DIR_BUTTON)
- if dlg.ShowModal() == wx.ID_OK:
- self.pyroserver.workdir = dlg.GetPath()
- self.pyroserver.Restart()
+ # def OnTaskBarChangeWorkingDir(self, evt): + # dlg = wx.DirDialog(None, _("Choose a working directory "), self.rpc_server.workdir, wx.DD_NEW_DIR_BUTTON) + # if dlg.ShowModal() == wx.ID_OK: + # self.rpc_server.workdir = dlg.GetPath() + # self.rpc_server.Restart() def OnTaskBarChangeName(self, evt):
- _servicename = self.pyroserver.servicename
+ _servicename = self.rpc_server.servicename _servicename = '' if _servicename is None else _servicename
dlg = ParamsEntryDialog(None, _("Enter a name "), defaultValue=_servicename)
dlg.SetTests([(lambda name: len(name) != 0, _("Name must not be null!"))])
if dlg.ShowModal() == wx.ID_OK:
- self.pyroserver.servicename = dlg.GetValue()
- self.pyroserver.Restart()
+ self.rpc_server.servicename = dlg.GetValue() + self.rpc_server.Restart() def _LiveShellLocals(self):
return {"locals": runtime.GetPLCObjectSingleton().python_runtime_vars}
@@ -383,7 +383,7 @@
def OnTaskBarQuit(self, evt):
if wx.Platform == '__WXMSW__':
- Thread(target=self.pyroserver.Quit).start()
+ Thread(target=self.rpc_server.Quit).start() wx.CallAfter(wx.GetApp().ExitMainLoop)
@@ -513,10 +513,10 @@
runtime.CreatePLCObjectSingleton(
WorkingDir, argv, statuschange, evaluator, pyruntimevars)
-pyroserver = PyroServer(servicename, interface, port)
+rpc_server = RPCServer(servicename, interface, port) - taskbar_instance = BeremizTaskBarIcon(pyroserver)
+ taskbar_instance = BeremizTaskBarIcon(rpc_server) @@ -533,28 +533,28 @@
LogMessageAndException(_("WAMP client startup failed. "))
+rpc_server_thread = None - RPC through pyro/wamp/UI may lead to delegation to Worker,
+ RPC through rpc/wamp/UI may lead to delegation to Worker, then this function ensures that Worker is already
- created when pyro starts
+ created when rpc starts - global pyro_thread, pyroserver
+ global rpc_server_thread, rpc_server - pyro_thread_started = Lock()
- pyro_thread_started.acquire()
- pyro_thread = Thread(target=pyroserver.PyroLoop,
- kwargs=dict(when_ready=pyro_thread_started.release),
+ rpc_thread_started = Lock() + rpc_thread_started.acquire() + rpc_server_thread = Thread(target=rpc_server.Loop, + kwargs=dict(when_ready=rpc_thread_started.release),
+ rpc_server_thread.start() - # Wait for pyro thread to be effective
- pyro_thread_started.acquire()
+ # Wait for rpc thread to be effective + rpc_thread_started.acquire() - pyroserver.PrintServerInfo()
+ rpc_server.PrintServerInfo() # Beremiz IDE detects LOCAL:// runtime is ready by looking
# for self.workdir in the daemon's stdout.
@@ -616,8 +616,8 @@
+rpc_server_thread.join() plcobj = runtime.GetPLCObjectSingleton()
--- a/connectors/__init__.py Sat Dec 09 01:03:43 2023 +0100
+++ b/connectors/__init__.py Wed Jan 17 22:09:32 2024 +0100
@@ -31,7 +31,7 @@
from os import listdir, path
from connectors.ConnectorBase import ConnectorBase
-connectors_packages = ["PYRO"]
+connectors_packages = ["ERPC", "WAMP"] def _GetLocalConnectorClassFactory(name):
@@ -71,38 +71,13 @@
_scheme = uri.split("://")[0].upper()
- # commented code to enable for MDNS:// support
- # _scheme, location = uri.split("://")
- # _scheme = _scheme.upper()
- # pyro connection to local runtime
+ # ERPC connection to local runtime # started on demand, listening on random port
runtime_port = confnodesroot.StartLocalRuntime()
- uri = f"PYRO://{LocalHost}:{runtime_port}"
- # commented code to enable for MDNS:// support
- # elif _scheme == "MDNS":
- # from zeroconf import Zeroconf
- # i = r.get_service_info(zeroconf_service_type, location)
- # raise Exception("'%s' not found" % location)
- # ip = str(socket.inet_ntoa(i.address))
- # newlocation = ip + ':' + port
- # confnodesroot.logger.write(_("'{a1}' is located at {a2}\n").format(a1=location, a2=newlocation))
- # location = newlocation
- # # not a bug, but a workaround against obvious downgrade attack
- # confnodesroot.logger.write_error(_("MDNS resolution failure for '%s'\n") % location)
- # confnodesroot.logger.write_error(traceback.format_exc())
+ uri = f"ERPC://{LocalHost}:{runtime_port}" elif _scheme in connectors:
@@ -111,18 +86,9 @@
- # import module according to uri type and get connector specific baseclass
- # first call to import the module,
- # then call with parameters to create the class
- connector_specific_class = connectors[scheme]()(uri, confnodesroot)
- if connector_specific_class is None:
- # new class inheriting from generic and specific connector base classes
- return type(_scheme + "_connector",
- (ConnectorBase, connector_specific_class), {})()
+ return (connectors[scheme] + (uri, confnodesroot)) # creates object def EditorClassFromScheme(scheme):