Use asyncio
in an IOC¶
There are two libraries available for asynchronous operations in PythonIOC:
cothread
and asyncio
. This guide shows how to use the latter in
an IOC.
Note
This page only explains the differences between using cothread
and asyncio
.
For more thorough explanation of the IOC itself see Creating an IOC
# 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())
The dispatcher
is created and passed to iocInit()
. This is what
allows the use of asyncio
functions in this IOC. It contains a new event loop to handle
this.
The async update
function will increment the value of ai
once per second,
sleeping that coroutine between updates.
Note that we run this coroutine in the loop
of the dispatcher
, and not in the
main event loop.
This IOC will, like the one in Creating an IOC, leave an interactive
shell open. The values of the PVs can be queried using the methods defined in the
softioc.softioc
module.
Asynchronous Channel Access¶
PVs can be retrieved externally from a PV in an asynchronous manner by using the :py`aioca` module.
It provides await
-able implementations of caget
, caput
, etc. See that module for more information.