def validate_ioc_test_func( self, device_name, record_func, child_conn, validate_pass: bool): """Start the IOC with the specified validate method""" builder.SetDeviceName(device_name) kwarg = {} if record_func in [builder.WaveformIn, builder.WaveformOut]: kwarg = {"length": WAVEFORM_LENGTH} # Must specify when no value kwarg["validate"] = ( self.validate_always_pass if validate_pass else self.validate_always_fail ) record_func("VALIDATE-RECORD", **kwarg) dispatcher = asyncio_dispatcher.AsyncioDispatcher() builder.LoadDatabase() softioc.iocInit(dispatcher) child_conn.send("R") # Keep process alive while main thread runs CAGET if child_conn.poll(TIMEOUT): val = child_conn.recv() assert val == "D", "Did not receive expected Done character"
def none_value_test_func(self, record_func, queue): """Start the IOC and catch the expected exception""" kwarg = {} if record_func in [builder.WaveformIn, builder.WaveformOut]: kwarg = {"length": WAVEFORM_LENGTH} # Must specify when no value record = record_func("SOME-NAME", **kwarg) log("CHILD: About to start IOC") dispatcher = asyncio_dispatcher.AsyncioDispatcher() builder.LoadDatabase() softioc.iocInit(dispatcher) log("CHILD: Soft IOC started, about to .set(None)") try: record.set(None) log("CHILD: Uh-OH! No exception thrown when setting None!") except Exception as e: log("CHILD: Putting exception into queue %s", e) queue.put(e) else: log("CHILD: No exception raised when using None as value!") queue.put(Exception("FAIL: No exception raised during .set()"))
def on_update_test_func( self, device_name, record_func, conn, always_update ): builder.SetDeviceName(device_name) li = builder.longIn("ON-UPDATE-COUNTER-RECORD", initial_value=0) def on_update_func(new_val): """Increments li record each time main out record receives caput""" li.set(li.get() + 1) kwarg = {} if record_func is builder.WaveformOut: kwarg = {"length": WAVEFORM_LENGTH} # Must specify when no value record_func( "ON-UPDATE-RECORD", on_update=on_update_func, always_update=always_update, **kwarg) def on_update_done(_): conn.send("C") # "Complete" # Put to the action record after we've done all other Puts, so we know # all the callbacks have finished processing builder.Action("ON-UPDATE-DONE", on_update=on_update_done) dispatcher = asyncio_dispatcher.AsyncioDispatcher() builder.LoadDatabase() softioc.iocInit(dispatcher) conn.send("R") # "Ready" log("CHILD: Sent R over Connection to Parent") # Keep process alive while main thread runs CAGET if conn.poll(TIMEOUT): val = conn.recv() assert val == "D", "Did not receive expected Done character" log("CHILD: Received exit command, child exiting")
def blocking_test_func(self, device_name, conn): builder.SetDeviceName(device_name) count_rec = builder.longIn("BLOCKING-COUNTER", initial_value=0) async def blocking_update_func(new_val): """A function that will block for some time""" log("CHILD: blocking_update_func starting") await asyncio.sleep(0.5) log("CHILD: Finished sleep!") completed_count = count_rec.get() + 1 count_rec.set(completed_count) log( "CHILD: blocking_update_func finished, completed ", completed_count ) builder.longOut( "BLOCKING-REC", on_update=blocking_update_func, always_update=True, blocking=True ) dispatcher = asyncio_dispatcher.AsyncioDispatcher() builder.LoadDatabase() softioc.iocInit(dispatcher) conn.send("R") # "Ready" log("CHILD: Sent R over Connection to Parent") # Keep process alive while main thread runs CAGET if conn.poll(TIMEOUT): val = conn.recv() assert val == "D", "Did not receive expected Done character" log("CHILD: Received exit command, child exiting")
def main(): if "-v" in sys.argv: logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT) sys.argv.remove("-v") else: logging.basicConfig(level=logging.INFO, format=LOG_FORMAT) # Determine the ring mode if sys.argv[1:]: ring_mode = sys.argv[1] else: try: ring_mode = str(os.environ["RINGMODE"]) except KeyError: try: value = caget("SR-CS-RING-01:MODE", format=2) ring_mode = value.enums[int(value)] except ca_nothing: ring_mode = "DIAD" # Create PVs. server = atip_server.ATIPServer( ring_mode, DATADIR / "limits.csv", DATADIR / "feedback.csv", DATADIR / "mirrored.csv", DATADIR / "tunefb.csv", ) # Add special case out record for SOFB to write to. builder.SetDeviceName("CS-CS-MSTAT-01") builder.aOut("FBHEART", initial_value=10) # Start the IOC. builder.LoadDatabase() softioc.iocInit() server.monitor_mirrored_pvs() server.setup_tune_feedback() softioc.interactive_ioc(globals())
def target_function(self): while True: if self.flag.is_set() is True: pass # Create PVs. pvs1 = ['PV-{0}-PC-01'.format(i + 1) for i in range(4000)] pvs2 = ['PV-{0}-PC-02'.format(i + 1) for i in range(4000)] # Create 4000 aIn and 4000 aOut records without background thread running. print("Without thread:") start = time.time() svr = server.ATIPServer(pvs1) print(' Total time: {0}'.format(time.time() - start)) # Start background thread th = thread_test() # Create 4000 aIn and 4000 aOut records with background thread running. print("With thread:") start = time.time() svr = server.ATIPServer(pvs2) print(' Total time: {0}'.format(time.time() - start)) # Start the IOC. builder.LoadDatabase() softioc.iocInit() softioc.interactive_ioc(globals())
def run_ioc(record_configurations: list, conn, set_enum, get_enum): """Creates a record and starts the IOC. `initial_value` will be set on the record at different times based on the `set_enum` parameter.""" builder.SetDeviceName(DEVICE_NAME) records: List[RecordWrapper] = [] # Create records from the given list for configuration in record_configurations: kwarg = {} ( record_name, creation_func, initial_value, expected_value, expected_type, ) = configuration if set_enum == SetValueEnum.INITIAL_VALUE: kwarg["initial_value"] = initial_value elif creation_func in [builder.WaveformIn, builder.WaveformOut]: kwarg["length"] = WAVEFORM_LENGTH # Must specify when no value # Related to this issue: # https://github.com/dls-controls/pythonSoftIOC/issues/37 out_rec = creation_func(record_name, **kwarg) if set_enum == SetValueEnum.SET_BEFORE_INIT: out_rec.set(initial_value) records.append(out_rec) dispatcher = asyncio_dispatcher.AsyncioDispatcher() builder.LoadDatabase() softioc.iocInit(dispatcher) conn.send("R") # "Ready" # Record list and record config list should always be in line for record, configuration in zip(records, record_configurations): ( record_name, creation_func, initial_value, expected_value, expected_type, ) = configuration if set_enum == SetValueEnum.SET_AFTER_INIT: record.set(initial_value) for record in records: if get_enum == GetValueEnum.GET: conn.send(record.get()) # Some tests do a caput and require another .get() if set_enum == SetValueEnum.CAPUT: if conn.poll(TIMEOUT): val = conn.recv() if val == "G": conn.send(record.get()) else: pytest.fail(f"Received unexpected character {val}") # Keep process alive while main thread works. # This is most applicable to CAGET tests. while (True): if conn.poll(TIMEOUT): val = conn.recv() if val == "D": # "Done" break
# Simple example script for building an example soft IOC. import versions import cothread from softioc import softioc, builder, pvlog from testing import * softioc.devIocStats('TS-DI-TEST-01') builder.LoadDatabase() softioc.iocInit() softioc.interactive_ioc(globals())
# Import the basic framework components. from softioc import softioc, builder, asyncio_dispatcher import asyncio # Create an asyncio dispatcher, the event loop is now running dispatcher = asyncio_dispatcher.AsyncioDispatcher() # Set the record prefix builder.SetDeviceName("MY-DEVICE-PREFIX") # Create some records ai = builder.aIn('AI', initial_value=5) ao = builder.aOut('AO', initial_value=12.45, always_update=True, on_update=lambda v: ai.set(v)) # Boilerplate get the IOC started builder.LoadDatabase() softioc.iocInit(dispatcher) # Start processes required to be run after iocInit async def update(): while True: ai.set(ai.get() + 1) await asyncio.sleep(1) asyncio.run_coroutine_threadsafe(update(), dispatcher.loop) # Finally leave the IOC running with an interactive shell. softioc.interactive_ioc(globals())
t_ao = builder.aOut('ALARM', on_update=callback) async def on_update_name_callback(value, name): print(name, "value", value) builder.longOut( "NAME-CALLBACK", initial_value = 3, always_update=True, on_update_name=on_update_name_callback, blocking=True ) # Run the IOC builder.LoadDatabase() softioc.iocInit(asyncio_dispatcher.AsyncioDispatcher()) conn.send("R") # "Ready" # Make sure coverage is written on epicsExit from pytest_cov.embed import cleanup sys._run_exitfuncs = cleanup select_and_recv(conn, "D") # "Done" # Attempt to ensure all buffers flushed - C code (from `import pvlog`) # may not be affected by these calls... sys.stdout.flush() sys.stderr.flush() conn.send("D") # "Done"