--- a/svghmi/svghmi.py Thu Jul 01 14:33:14 2021 +0200
+++ b/svghmi/svghmi.py Mon Jul 05 10:51:02 2021 +0200
@@ -279,11 +279,15 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="SVGHMI">
- <xsd:attribute name="OnStart" type="xsd:string" use="optional"/>
- <xsd:attribute name="OnStop" type="xsd:string" use="optional"/>
- <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional"/>
- <xsd:attribute name="WatchdogInitial" type="xsd:integer" use="optional"/>
- <xsd:attribute name="WatchdogInterval" type="xsd:integer" use="optional"/>
+ <xsd:attribute name="OnStart" type="xsd:string" use="optional" default="chromium {url}"/> + <xsd:attribute name="OnStop" type="xsd:string" use="optional" default="echo 'please close chromium window at {url}'"/> + <xsd:attribute name="EnableWatchdog" type="xsd:boolean" use="optional" default="false"/> + <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional" default="chromium {url}"/> + <xsd:attribute name="WatchdogInitial" type="xsd:integer" use="optional" default="30"/> + <xsd:attribute name="WatchdogInterval" type="xsd:integer" use="optional" default="5"/> + <xsd:attribute name="Port" type="xsd:integer" use="optional" default="8008"/> + <xsd:attribute name="Interface" type="xsd:string" use="optional" default="localhost"/> + <xsd:attribute name="Path" type="xsd:string" use="optional" default=""/> @@ -532,50 +536,96 @@
res += ((target_fname, open(target_path, "rb")),)
+ port = self.GetParamsAttributes("SVGHMI.Port")["value"] + interface = self.GetParamsAttributes("SVGHMI.Interface")["value"] + path = self.GetParamsAttributes("SVGHMI.Path")["value"].format(name=view_name) + enable_watchdog = self.GetParamsAttributes("SVGHMI.EnableWatchdog")["value"] + url="http://"+interface+("" if port==80 else (":"+str(port)) + ) + (("/"+path) if path else "" + ) + ("#watchdog" if enable_watchdog else "") for thing in ["Start", "Stop", "Watchdog"]:
given_command = self.GetParamsAttributes("SVGHMI.On"+thing)["value"]
- repr(shlex.split(given_command.format(port="8008", name=view_name))) +
+ repr(shlex.split(given_command.format( ")") if given_command else "pass # no command given"
runtimefile_path = os.path.join(buildpath, "runtime_%s_svghmi_.py" % location_str)
runtimefile = open(runtimefile_path, 'w')
# TODO : multiple watchdog (one for each svghmi instance)
-def svghmi_watchdog_trigger():
+def svghmi_{location}_watchdog_trigger(): def _runtime_{location}_svghmi_start():
+ global svghmi_watchdog, svghmi_servers + srv = svghmi_servers.get("{interface}:{port}", None) + svghmi_root, svghmi_listener, path_list = srv + if '{path}' in path_list: + raise Exception("SVGHMI {view_name}: path {path} already used on {interface}:{port}") + svghmi_root = Resource() + svghmi_root.putChild("ws", WebSocketResource(HMIWebSocketServerFactory())) + svghmi_listener = reactor.listenTCP({port}, Site(svghmi_root), interface='{interface}') + svghmi_servers["{interface}:{port}"] = (svghmi_root, svghmi_listener, path_list)
- defaultType='application/xhtml+xml'))
+ defaultType='application/xhtml+xml')) + path_list.append("{path}") - svghmi_watchdog = Watchdog(
- svghmi_watchdog_trigger)
+ if svghmi_watchdog is None: + svghmi_watchdog = Watchdog( + svghmi_{location}_watchdog_trigger) + raise Exception("SVGHMI {view_name}: only one watchdog allowed") def _runtime_{location}_svghmi_stop():
+ global svghmi_watchdog, svghmi_servers if svghmi_watchdog is not None:
- svghmi_root.delEntity('{view_name}')
+ svghmi_root, svghmi_listener, path_list = svghmi_servers["{interface}:{port}"] + svghmi_root.delEntity('{path}') + path_list.remove('{path}') + svghmi_root.delEntity("ws") + svghmi_listener.stopListening() + svghmi_servers.pop("{interface}:{port}") """.format(location=location_str,
+ enable_watchdog = enable_watchdog, watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"],
watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
--- a/svghmi/svghmi_server.py Thu Jul 01 14:33:14 2021 +0200
+++ b/svghmi/svghmi_server.py Mon Jul 05 10:51:02 2021 +0200
@@ -142,8 +142,7 @@
class HMIWebSocketServerFactory(WebSocketServerFactory):
svghmi_send_thread = None
@@ -165,19 +164,14 @@
# this happens when finishing
- print("SVGHMI watchdog trigger")
+def AddPathToSVGHMIServers(path, factory): + for k,v in svghmi_servers.iteritems(): + svghmi_root, svghmi_listener, path_list = v + svghmi_root.putChild(path, factory()) # Called by PLCObject at start
def _runtime_00_svghmi_start():
- global svghmi_listener, svghmi_root, svghmi_send_thread
- svghmi_root = Resource()
- svghmi_root.putChild("ws", WebSocketResource(HMIWebSocketServerFactory()))
- svghmi_listener = reactor.listenTCP(8008, Site(svghmi_root), interface='localhost')
+ global svghmi_send_thread # start a thread that call the C part of SVGHMI
svghmi_send_thread = Thread(target=SendThreadProc, name="SVGHMI Send")
@@ -186,14 +180,10 @@
# Called by PLCObject at stop
def _runtime_00_svghmi_stop():
- global svghmi_listener, svghmi_root, svghmi_send_thread, svghmi_session
+ global svghmi_send_thread, svghmi_session if svghmi_session is not None:
- svghmi_root.delEntity("ws")
- svghmi_listener.stopListening()
# plc cleanup calls svghmi_(locstring)_cleanup and unlocks send thread
svghmi_send_thread.join()
svghmi_send_thread = None
--- a/tests/svghmi/py_ext_0@py_ext/pyfile.xml Thu Jul 01 14:33:14 2021 +0200
+++ b/tests/svghmi/py_ext_0@py_ext/pyfile.xml Mon Jul 05 10:51:02 2021 +0200
@@ -87,7 +87,7 @@
-svghmi_root.putChild("alarms", AlarmJsonResource())
+AddPathToSVGHMIServers("alarms", AlarmJsonResource) --- a/tests/svghmi/svghmi_0@svghmi/confnode.xml Thu Jul 01 14:33:14 2021 +0200
+++ b/tests/svghmi/svghmi_0@svghmi/confnode.xml Mon Jul 05 10:51:02 2021 +0200
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='utf-8'?>
-<SVGHMI xmlns:xsd="http://www.w3.org/2001/XMLSchema" OnWatchdog="echo Watchdog for {name} !" OnStart="chromium http://127.0.0.1:{port}/{name}" OnStop="echo Closing {name}" WatchdogInitial="10" WatchdogInterval="5"/>
+<SVGHMI xmlns:xsd="http://www.w3.org/2001/XMLSchema" OnWatchdog="echo Watchdog for {name} !" WatchdogInitial="10" WatchdogInterval="5" EnableWatchdog="true" Path="{name}"/>