]> jspc29.x-matter.uni-frankfurt.de Git - mvd_epics.git/commitdiff
DASH: Use CA monitor w/ callbacks
authorOle Artz <ole.artz@t-online.de>
Mon, 14 Aug 2017 09:50:48 +0000 (11:50 +0200)
committerOle Artz <ole.artz@t-online.de>
Mon, 14 Aug 2017 09:50:48 +0000 (11:50 +0200)
Instead of our own thread continuously polling the PVs
we now use the built-in CA *monitor* capabilities to
be informed about PV status changes (connected/disconnected,
value change) via callback functions.

python_suite/dashboard/dashboard.py

index 38d98375029fdccba4f6b8d7ae813931a9db3bce..5c3b2427343c9ce245d32527ed5c12ce7816e31f 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-import json, threading
+import json, threading, time
 import epics
 
 from bottle import route, run, static_file
@@ -9,12 +9,44 @@ from bottle import jinja2_view as view
 CONFIG = None
 PVS = {}
 
-def update_values():
+def cb_connection_change(**kwargs):
     global CONFIG
+
+    if kwargs['conn']:
+        pass
+        # We are now connected
+        def fetch_ctrlvars():
+            #print("Started thread for ", kwargs['pvname'])
+            #start = time.time()
+            p = PVS[kwargs['pvname']]
+            p.get_ctrlvars()
+            #end = time.time()
+            #print("Finished thread for ", kwargs['pvname'], " in ", end-start, " s. Unit: ", p.units)
+            #for group in CONFIG['groups']:
+            #    for pv in group['PVs']:
+            #        if pv['name'] != kwargs['pvname']: continue
+            #        pv['unit'] = p.units or ''
+        tid = threading.Thread(target=fetch_ctrlvars)
+        tid.daemon = True
+        tid.start()
+        return
+
+    # Otherwise: we are disconnected from the IOC!
     for group in CONFIG['groups']:
         for pv in group['PVs']:
-            p = PVS[pv['name']]
-            p.get_ctrlvars()
+            if pv['name'] != kwargs['pvname']: continue
+
+            pv['value'] = '- disconnected -'
+            pv['unit'] = ''
+            pv['classes'] = 'disconnected'
+
+
+def cb_value_update(**kwargs):
+    global CONFIG
+    for group in CONFIG['groups']:
+        for pv in group['PVs']:
+            if pv['name'] != kwargs['pvname']: continue
+
             class_map = {
               epics.NO_ALARM :      "",
               epics.MINOR_ALARM :   "minor_alarm",
@@ -22,20 +54,21 @@ def update_values():
               epics.INVALID_ALARM : "invalid_alarm",
               None : "disconnected",
             }
-            pv['classes'] = class_map[p.severity]
-            if 'enum' in p.type:
-                pv['value'] = p.char_value
+            pv['classes'] = class_map[kwargs['severity']]
+            #print(kwargs['pvname'], kwargs['type'])
+            #print(kwargs)
+            if 'enum' in kwargs['type']:
+                if type(kwargs['char_value']) is bytes:
+                     pv['value'] = kwargs['char_value'].decode('ascii')
+                else:
+                     pv['value'] = kwargs['char_value']
             else:
-                pv['value'] = p.value
+                pv['value'] = kwargs['value']
             if pv['value'] is None: pv['value'] = '- disconnected -'
-            pv['unit'] = p.units or ''
+            pv['unit'] = kwargs['units'] or ''
             if pv['value'] == 'OFF': pv['value'] = '- OFF -'
             if pv['value'] == 'ON': pv['value'] = '- ON -'
 
-def update_values_continuous():
-    while True:
-        update_values()
-
 @route('/')
 @view('pv_overview.jinja2')
 def index():
@@ -74,14 +107,10 @@ def main():
 
     for group in CONFIG['groups']:
         for pv in group['PVs']:
-            PVS[pv['name']] = epics.PV(pv['name'], auto_monitor=True)
-            pv['value'] = 'Undefined'
+            pv['value'] = '- disconnected (initial) -'
             pv['unit'] = ''
-            pv['classes'] = ''
-
-    uvt = threading.Thread(target=update_values_continuous)
-    uvt.daemon = True
-    uvt.start()
+            pv['classes'] = 'disconnected'
+            PVS[pv['name']] = epics.PV(pv['name'], auto_monitor=True, form='ctrl', callback=cb_value_update, connection_callback=cb_connection_change)
 
     run(host=args.host, port=args.port, debug=args.debug)