-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
IOC singleton for EpicsAdapter (#66)
Module for IOC management, used by all `EpicsAdapter`s. Share a single channel access context
- Loading branch information
1 parent
3141025
commit 215582f
Showing
7 changed files
with
130 additions
and
17 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
- tickit.devices.pneumatic.Pneumatic: | ||
name: filter1 | ||
inputs: {} | ||
initial_speed: 0.5 | ||
initial_state: False | ||
ioc_name: PNEUMATIC | ||
db_file: tickit/devices/pneumatic/db_files/filter1.db | ||
- tickit.devices.sink.Sink: | ||
name: contr_sink | ||
inputs: | ||
input: filter1:output | ||
- tickit.devices.femto.Current: | ||
name: current_device | ||
inputs: {} | ||
callback_period: 1000000000 | ||
- tickit.devices.femto.Femto: | ||
name: femto | ||
inputs: | ||
input: current_device:output | ||
initial_gain: 2.5 | ||
initial_current: 0.0 | ||
db_file: tickit/devices/femto/record.db | ||
ioc_name: FEMTO |
Empty file.
File renamed without changes.
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,28 @@ | ||
import asyncio | ||
|
||
import pytest | ||
from aioca import caget, caput | ||
|
||
|
||
@pytest.mark.asyncio | ||
@pytest.mark.parametrize( | ||
"tickit_process", ["examples/configs/multi-ioc.yaml"], indirect=True | ||
) | ||
async def test_femto_system(tickit_process): | ||
assert (await caget("FEMTO:GAIN_RBV")) == 2.5 | ||
current = await caget("FEMTO:CURRENT") | ||
assert 100 * 2.5 <= current < 200 * 2.5 | ||
await caput("FEMTO:GAIN", 0.01) | ||
await asyncio.sleep(0.5) | ||
assert (await caget("FEMTO:GAIN_RBV")) == 0.01 | ||
current = await caget("FEMTO:CURRENT") | ||
assert 100 * 0.01 <= current < 200 * 0.01 | ||
|
||
async def toggle(expected: bool): | ||
assert (await caget("PNEUMATIC:FILTER_RBV")) != expected | ||
await caput("PNEUMATIC:FILTER", expected) | ||
await asyncio.sleep(0.8) | ||
assert (await caget("PNEUMATIC:FILTER_RBV")) == expected | ||
|
||
await toggle(True) | ||
await toggle(False) |
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,3 @@ | ||
from .adapter import EpicsAdapter, InputRecord, OutputRecord | ||
|
||
__all__ = ["EpicsAdapter", "InputRecord", "OutputRecord"] |
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,67 @@ | ||
import asyncio | ||
import itertools | ||
import logging | ||
from typing import Set | ||
|
||
from softioc import asyncio_dispatcher, builder, softioc | ||
|
||
LOGGER = logging.getLogger(__name__) | ||
|
||
#: Name for the global Tickit IOC, will prefix some meta PVs. | ||
_TICKIT_IOC_NAME: str = "TICKIT_IOC" | ||
|
||
#: Ids of all adapters currently registered but not ready. | ||
_REGISTERED_ADAPTER_IDS: Set[int] = set() | ||
|
||
#: Iterator of unique IDs for new adapters | ||
_ID_COUNTER: itertools.count = itertools.count() | ||
|
||
|
||
def register_adapter() -> int: | ||
"""Register a new adapter that may be creating records for the process-wide IOC. | ||
The IOC will not be initialized until all registered adapters have notified that | ||
they are ready. | ||
Returns: | ||
int: A unique ID for this adapter to use when notifiying that it is ready. | ||
""" | ||
adapter_id = next(_ID_COUNTER) | ||
LOGGER.debug(f"New IOC adapter registering with ID: {adapter_id}") | ||
_REGISTERED_ADAPTER_IDS.add(adapter_id) | ||
return adapter_id | ||
|
||
|
||
def notify_adapter_ready(adapter_id: int) -> None: | ||
"""Notify the builder that a particular adpater has made all the records it needs to. | ||
Once all registered adapters have notified, the IOC will start. | ||
Args: | ||
adapter_id (int): Unique ID of the adapter | ||
""" | ||
_REGISTERED_ADAPTER_IDS.remove(adapter_id) | ||
LOGGER.debug(f"IOC adapter #{adapter_id} reports ready") | ||
if not _REGISTERED_ADAPTER_IDS: | ||
LOGGER.debug("All registered adapters are ready, starting IOC") | ||
_build_and_run_ioc() | ||
|
||
|
||
def _build_and_run_ioc() -> None: | ||
"""Build an EPICS python soft IOC for the adapter.""" | ||
LOGGER.debug("Initializing database") | ||
|
||
# Records become immutable after this point | ||
builder.SetDeviceName(_TICKIT_IOC_NAME) | ||
softioc.devIocStats(_TICKIT_IOC_NAME) | ||
builder.LoadDatabase() | ||
|
||
LOGGER.debug("Starting IOC") | ||
event_loop = asyncio.get_event_loop() | ||
dispatcher = asyncio_dispatcher.AsyncioDispatcher(event_loop) | ||
softioc.iocInit(dispatcher) | ||
# dbl directly prints out all record names, so we have to check | ||
# the log level in order to only do it in DEBUG. | ||
if LOGGER.level <= logging.DEBUG: | ||
softioc.dbl() | ||
LOGGER.debug("IOC started") |