Use asyncio
in an IOC
Creating an IOC shows how to create a pythonSoftIOC using the
Using the cothread Library
library. This page shows how to create one using asyncio
See also
What are the differences between asyncio and cothread? for the differences and why you would use one over the other
Example 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)
dispatcher(update)
# 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 pass this coroutine to the dispatcher
, which will execute it in the
dispatcher’s own event loop and not in the main event loop. It also provides some logging
if exceptions occur.
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
aioca
module. It provides await
-able implementations of caget
,
caput
, etc. See that module for more information.