SVGHMI : watchdog is now taking an initial and interval duration as CTN fields. svghmi
authorEdouard Tisserant
Thu, 23 Jan 2020 11:22:09 +0100
branchsvghmi
changeset 2831 6c9cfdbe94dc
parent 2830 15d7bd79d9e8
child 2832 e9ba4dee6ffb
SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
svghmi/svghmi.py
svghmi/svghmi_server.py
tests/svghmi/plc.xml
tests/svghmi/svghmi_0@svghmi/confnode.xml
--- a/svghmi/svghmi.py	Tue Jan 21 13:55:03 2020 +0100
+++ b/svghmi/svghmi.py	Thu Jan 23 11:22:09 2020 +0100
@@ -374,6 +374,8 @@
           <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:complexType>
       </xsd:element>
     </xsd:schema>
@@ -511,22 +513,42 @@
         runtimefile_path = os.path.join(buildpath, "runtime_svghmi1_%s.py" % location_str)
         runtimefile = open(runtimefile_path, 'w')
         runtimefile.write("""
-# TODO : multi
-def watchdog_trigger():
+# TODO : multiple watchdog (one for each svghmi instance)
+def svghmi_watchdog_trigger():
     {svghmi_cmds[Watchdog]}
 
+svghmi_watchdog = None
+
 def _runtime_svghmi1_{location}_start():
-    svghmi_root.putChild('{view_name}', NoCacheFile('{xhtml}', defaultType='application/xhtml+xml'))
+    global svghmi_watchdog
+    svghmi_root.putChild(
+        '{view_name}',
+        NoCacheFile('{xhtml}',
+        defaultType='application/xhtml+xml'))
+
     {svghmi_cmds[Start]}
 
+    svghmi_watchdog = Watchdog(
+        {watchdog_initial}, 
+        {watchdog_interval}, 
+        svghmi_watchdog_trigger)
+
 def _runtime_svghmi1_{location}_stop():
+    global svghmi_watchdog
+    if svghmi_watchdog is not None:
+        svghmi_watchdog.cancel()
+        svghmi_watchdog = None
+
     svghmi_root.delEntity('{view_name}')
     {svghmi_cmds[Stop]}
 
         """.format(location=location_str,
                    xhtml=target_fname,
                    view_name=view_name,
-                   svghmi_cmds=svghmi_cmds))
+                   svghmi_cmds=svghmi_cmds,
+                   watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"],
+                   watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
+                   ))
 
         runtimefile.close()
 
--- a/svghmi/svghmi_server.py	Tue Jan 21 13:55:03 2020 +0100
+++ b/svghmi/svghmi_server.py	Thu Jan 23 11:22:09 2020 +0100
@@ -78,17 +78,20 @@
         return 0
 
 class Watchdog(object):
-    def __init__(self, initial_timeout, callback):
+    def __init__(self, initial_timeout, interval, callback):
         self._callback = callback
         self.lock = RLock()
         self.initial_timeout = initial_timeout
+        self.interval = interval
         self.callback = callback
         with self.lock:
             self._start()
 
-    def _start(self):
-        self.timer = Timer(self.initial_timeout, self.trigger)
-        self.timer.start()
+    def _start(self, rearm=False):
+        duration = self.interval if rearm else self.initial_timeout
+        if duration:
+            self.timer = Timer(duration, self.trigger)
+            self.timer.start()
 
     def _stop(self):
         if self.timer is not None:
@@ -102,7 +105,7 @@
     def feed(self):
         with self.lock:
             self._stop()
-            self._start()
+            self._start(rearm=True)
 
     def trigger(self):
         self._callback()
@@ -162,7 +165,7 @@
 
 # Called by PLCObject at start
 def _runtime_svghmi0_start():
-    global svghmi_listener, svghmi_root, svghmi_send_thread, svghmi_watchdog
+    global svghmi_listener, svghmi_root, svghmi_send_thread
 
     svghmi_root = Resource()
     svghmi_root.putChild("ws", WebSocketResource(HMIWebSocketServerFactory()))
@@ -173,15 +176,10 @@
     svghmi_send_thread = Thread(target=SendThreadProc, name="SVGHMI Send")
     svghmi_send_thread.start()
 
-    svghmi_watchdog = Watchdog(5, watchdog_trigger)
 
 # Called by PLCObject at stop
 def _runtime_svghmi0_stop():
-    global svghmi_listener, svghmi_root, svghmi_send_thread, svghmi_session, svghmi_watchdog
-
-    if svghmi_watchdog is not None:
-        svghmi_watchdog.cancel()
-        svghmi_watchdog = None
+    global svghmi_listener, svghmi_root, svghmi_send_thread, svghmi_session
 
     if svghmi_session is not None:
         svghmi_session.close()
--- a/tests/svghmi/plc.xml	Tue Jan 21 13:55:03 2020 +0100
+++ b/tests/svghmi/plc.xml	Thu Jan 23 11:22:09 2020 +0100
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='utf-8'?>
 <project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201">
   <fileHeader companyName="Unknown" productName="Unnamed" productVersion="1" creationDateTime="2019-08-06T14:23:42"/>
-  <contentHeader name="Unnamed" modificationDateTime="2020-01-15T09:34:34">
+  <contentHeader name="Unnamed" modificationDateTime="2020-01-23T11:01:29">
     <coordinateInfo>
       <fbd>
         <scaling x="5" y="5"/>
--- a/tests/svghmi/svghmi_0@svghmi/confnode.xml	Tue Jan 21 13:55:03 2020 +0100
+++ b/tests/svghmi/svghmi_0@svghmi/confnode.xml	Thu Jan 23 11:22:09 2020 +0100
@@ -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="xdg-open http://127.0.0.1:{port}/{name}" OnStop="echo Closing {name}"/>
+<SVGHMI xmlns:xsd="http://www.w3.org/2001/XMLSchema" OnWatchdog="echo Watchdog for {name} !" OnStart="xdg-open http://127.0.0.1:{port}/{name}" OnStop="echo Closing {name}" WatchdogInitial="10" WatchdogInterval="5"/>