# HG changeset patch # User Edouard Tisserant # Date 1625475062 -7200 # Node ID 5d174cdf4d988af641f1254e92ff98a4b9f2b480 # Parent d22782b9591f3194595371731de7d7901bee8428 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling. diff -r d22782b9591f -r 5d174cdf4d98 svghmi/svghmi.py --- 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 @@ - - - - - + + + + + + + + + @@ -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 "") + svghmi_cmds = {} for thing in ["Start", "Stop", "Watchdog"]: given_command = self.GetParamsAttributes("SVGHMI.On"+thing)["value"] svghmi_cmds[thing] = ( "Popen(" + - repr(shlex.split(given_command.format(port="8008", name=view_name))) + + repr(shlex.split(given_command.format( + port=port, + name=view_name, + url=url))) + ")") 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') runtimefile.write(""" # TODO : multiple watchdog (one for each svghmi instance) -def svghmi_watchdog_trigger(): +def svghmi_{location}_watchdog_trigger(): {svghmi_cmds[Watchdog]} svghmi_watchdog = None def _runtime_{location}_svghmi_start(): - global svghmi_watchdog + global svghmi_watchdog, svghmi_servers + + srv = svghmi_servers.get("{interface}:{port}", None) + if srv is not 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}") + else: + svghmi_root = Resource() + svghmi_root.putChild("ws", WebSocketResource(HMIWebSocketServerFactory())) + + svghmi_listener = reactor.listenTCP({port}, Site(svghmi_root), interface='{interface}') + path_list = [] + svghmi_servers["{interface}:{port}"] = (svghmi_root, svghmi_listener, path_list) + svghmi_root.putChild( - '{view_name}', + '{path}', NoCacheFile('{xhtml}', - defaultType='application/xhtml+xml')) + defaultType='application/xhtml+xml')) + + path_list.append("{path}") {svghmi_cmds[Start]} - svghmi_watchdog = Watchdog( - {watchdog_initial}, - {watchdog_interval}, - svghmi_watchdog_trigger) + if {enable_watchdog}: + if svghmi_watchdog is None: + svghmi_watchdog = Watchdog( + {watchdog_initial}, + {watchdog_interval}, + svghmi_{location}_watchdog_trigger) + else: + raise Exception("SVGHMI {view_name}: only one watchdog allowed") + def _runtime_{location}_svghmi_stop(): - global svghmi_watchdog + global svghmi_watchdog, svghmi_servers + if svghmi_watchdog is not None: svghmi_watchdog.cancel() svghmi_watchdog = None - svghmi_root.delEntity('{view_name}') + svghmi_root, svghmi_listener, path_list = svghmi_servers["{interface}:{port}"] + svghmi_root.delEntity('{path}') + + path_list.remove('{path}') + + if len(path_list)==0: + svghmi_root.delEntity("ws") + svghmi_listener.stopListening() + svghmi_servers.pop("{interface}:{port}") + {svghmi_cmds[Stop]} """.format(location=location_str, xhtml=target_fname, view_name=view_name, svghmi_cmds=svghmi_cmds, + port = port, + interface = interface, + path = path, + enable_watchdog = enable_watchdog, watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"], watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"], )) diff -r d22782b9591f -r 5d174cdf4d98 svghmi/svghmi_server.py --- 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): protocol = HMIProtocol -svghmi_root = None -svghmi_listener = None +svghmi_servers = {} svghmi_send_thread = None def SendThreadProc(): @@ -165,19 +164,14 @@ # this happens when finishing break - -def watchdog_trigger(): - 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_session.close() - svghmi_root.delEntity("ws") - svghmi_root = None - svghmi_listener.stopListening() - svghmi_listener = None # plc cleanup calls svghmi_(locstring)_cleanup and unlocks send thread svghmi_send_thread.join() svghmi_send_thread = None diff -r d22782b9591f -r 5d174cdf4d98 tests/svghmi/py_ext_0@py_ext/pyfile.xml --- 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 @@ diff -r d22782b9591f -r 5d174cdf4d98 tests/svghmi/svghmi_0@svghmi/confnode.xml --- 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 @@ - +