From 30523fe7e74106f4af89b3924f5fb296612fbce9 Mon Sep 17 00:00:00 2001 From: "v.stadnytskyi@gmail.com" Date: Tue, 8 Oct 2019 18:03:27 -0400 Subject: [PATCH] x --- caproto_sandbox/io_device_client_simple.py | 4 +- .../io_device_server_one_thread.py | 87 +++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 caproto_sandbox/io_device_server_one_thread.py diff --git a/caproto_sandbox/io_device_client_simple.py b/caproto_sandbox/io_device_client_simple.py index 5a28d9c..680502b 100644 --- a/caproto_sandbox/io_device_client_simple.py +++ b/caproto_sandbox/io_device_client_simple.py @@ -11,7 +11,7 @@ from pdb import pm import epics from numpy import nan -default_prefix='io_device:' +default_prefix='io_device_single:' ctx = Context() ca_img,ca_t1,ca_t2 = ctx.get_pvs(default_prefix+'image',default_prefix+'t1',default_prefix+'t2') @@ -22,12 +22,14 @@ def pyepics_for_loop(): + print('img,img.shape,img.max(),img.mean(),t1.get(),t2.get()') for i in range(4): img = image.get(timeout = 20) print(img,img.shape,img.max(),img.mean(),t1.get(),t2.get()) sleep(1) def caproto_for_loop(): + print('img,img.shape,img.max(),img.mean(),ca_t2.read().data[0]') for i in range(4): img = ca_img.read().data print(img,img.shape,img.max(),img.mean(),ca_t2.read().data[0]) diff --git a/caproto_sandbox/io_device_server_one_thread.py b/caproto_sandbox/io_device_server_one_thread.py new file mode 100644 index 0000000..d97b920 --- /dev/null +++ b/caproto_sandbox/io_device_server_one_thread.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +import termios +import fcntl +import sys +import os +import threading +import atexit +from time import time,sleep +from datetime import datetime + +from caproto.server import pvproperty, PVGroup, ioc_arg_parser, run +from numpy import zeros, random +image_shape = (3960,3960) +class Device(object): + dt = 1.0 + + def start_io_interrupt_monitor(self,new_value_callback): + ''' + This function monitors the terminal it was run in for keystrokes. + On each keystroke, it calls new_value_callback with the given keystroke. + + This is used to simulate the concept of an I/O Interrupt-style signal from + the EPICS world. Those signals depend on hardware to tell EPICS when new + values are available to be read by way of interrupts - whereas we use + callbacks here. + ''' + while True: + date_time = datetime.fromtimestamp(time()) + t = time()#date_time.strftime("%m/%d/%Y, %H:%M:%S.%f") + image = random.randint(0,256,image_shape).flatten() + date_time = datetime.fromtimestamp(time()) + t = time()#date_time.strftime("%m/%d/%Y, %H:%M:%S.%f") + new_value_callback({'t2':t,'image':image,'t1':t}) + #print('image in device:',image.mean(),image.max(),image.min()) + sleep(self.dt) + + +class IOInterruptIOC(PVGroup): + t1 = pvproperty(value=2.0) + dt = pvproperty(value=0.9, dtype = float, precision = 3) + t2 = pvproperty(value=2.0) + arr = zeros(image_shape) + f_arr = arr.flatten() + image = pvproperty(value = f_arr, dtype = float) + + # NOTE the decorator used here: + #@dt1.startup + #async def dt1(self, instance, async_lib): + + #@dt2.startup + #async def dt2(self, instance, async_lib): + + @t1.startup + async def t1(self, instance, async_lib): + # This method will be called when the server starts up. + print('* t1 method called at server startup') + queue = async_lib.ThreadsafeQueue() + + # Start a separate thread that monitors keyboard input, telling it to + # put new values into our async-friendly queue + thread = threading.Thread(target=device.start_io_interrupt_monitor, + daemon=True, + kwargs=dict(new_value_callback=queue.put)) + device.dt = 0.99 + thread.start() + + # Loop and grab items from the queue one at a time + while True: + value = await queue.async_get() + if 't1' in list(value.keys()): + await self.t1.write(value['t1']) + if 'image' in list(value.keys()): + await self.image.write(value['image']) + if 't2' in list(value.keys()): + await self.t2.write(value['t2']) + + +device = Device() + +if __name__ == '__main__': + ioc_options, run_options = ioc_arg_parser( + default_prefix='io_device_single:', + desc='Run an IOC that updates via I/O interrupt on key-press events.') + + ioc = IOInterruptIOC(**ioc_options) + print(ioc.image) + run(ioc.pvdb, **run_options)