-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from dls-controls/documentation_update
Docs re-write, including for asyncio support
- Loading branch information
Showing
15 changed files
with
240 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# 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()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Import the basic framework components. | ||
from softioc import softioc, builder | ||
import cothread | ||
|
||
# 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() | ||
|
||
# Start processes required to be run after iocInit | ||
def update(): | ||
while True: | ||
ai.set(ai.get() + 1) | ||
cothread.Sleep(1) | ||
|
||
cothread.Spawn(update) | ||
|
||
# Finally leave the IOC running with an interactive shell. | ||
softioc.interactive_ioc(globals()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from softioc import softioc | ||
from cothread.catools import caget, caput, camonitor | ||
|
||
print(caget("MY-DEVICE-PREFIX:AI")) | ||
print(caget("MY-DEVICE-PREFIX:AO")) | ||
print(caput("MY-DEVICE-PREFIX:AO", "999")) | ||
print(caget("MY-DEVICE-PREFIX:AO")) | ||
|
||
softioc.interactive_ioc(globals()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
Create a Publishable IOC | ||
======================== | ||
|
||
As seen in `../tutorials/creating-an-ioc`, a single Python script can be an IOC. | ||
It is also possible (and the most common situation) to have an entire Python module | ||
comprising an IOC. This guide explains both, as well as how to publish an IOC within | ||
the DLS environment. | ||
|
||
Single File IOC | ||
---------------- | ||
An IOC that is entirely contained within a single Python source file can be used as an | ||
IOC inside DLS simply by adding this shebang line:: | ||
|
||
#!/dls_sw/prod/python3/RHEL7-x86_64/softioc/3.0b2/prefix/bin/pythonIoc | ||
|
||
|
||
IOC entry point for a module | ||
------------------------------ | ||
If your IOC is more complicated than one file, it is recommended to write a python | ||
module (including docs/tests/etc.). The Panda Blocks Client will be an example of | ||
this. | ||
|
||
|
||
Make an IOC publishable at DLS | ||
------------------------------ | ||
To make the IOC publishable, a makefile is required: | ||
|
||
``Makefile`` | ||
This file is necessary in order to run ``dls-release.py``, and needs to have | ||
both ``install`` and ``clean`` targets, but doesn't need to actually do | ||
anything. Thus the following content for this file is enough:: | ||
|
||
install: | ||
clean: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
Read data from an IOC | ||
====================== | ||
|
||
This guide explains how to read data from an IOC in a separate Python program. | ||
|
||
.. note:: | ||
Please ensure your firewall allows both TCP and UDP traffic on ports 5064 and 5065. | ||
These are used by EPICS for channel access to the PVs. | ||
|
||
|
||
To start, run the `cothread` IOC from `../tutorials/creating-an-ioc` or the | ||
`asyncio` IOC from `use-asyncio-in-an-ioc` and leave it running at the | ||
interactive shell. | ||
|
||
We will read data from that IOC using this script: | ||
|
||
.. literalinclude:: ../examples/example_read_from_ioc.py | ||
|
||
.. note:: | ||
You may see warnings regarding the missing "caRepeater" program. This is an EPICS tool | ||
that is used to track when PVs start and stop. It is not required for this simple example, | ||
and so the warning can be ignored. | ||
|
||
From the interactive command line you can now use the ``caget`` and ``caput`` functions to operate on | ||
the PVs exposed in the IOC. Another interesting command to try is:: | ||
|
||
camonitor("MY-DEVICE-PREFIX:AI", lambda val: print(val)) | ||
|
||
|
||
You should observe the value of ``AI`` being printed out, once per second, every time the PV value | ||
updates. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,33 @@ | ||
Use `asyncio` in an IOC | ||
======================= | ||
|
||
Write about the differences creating an IOC using `AsyncioDispatcher` | ||
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 `../tutorials/creating-an-ioc` | ||
|
||
.. literalinclude:: ../examples/example_asyncio_ioc.py | ||
|
||
|
||
The ``dispatcher`` is created and passed to :func:`~softioc.softioc.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 `../tutorials/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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.