Skip to content

Commit

Permalink
Tickit 0.4.1 (#78)
Browse files Browse the repository at this point in the history
Update the device adapters to support the latest release of tickit.
  • Loading branch information
abbiemery authored Aug 8, 2023
1 parent 1b1f686 commit 5689639
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 151 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ classifiers = [
]
description = "Devices for tickit, an event-based device simulation framework"
dependencies = [
"tickit==0.3",
"tickit>=0.4.1",
"typing_extensions",
"softioc",
"pydantic>1",
Expand Down
16 changes: 14 additions & 2 deletions src/tickit_devices/cryostream/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import pydantic.v1.dataclasses
from tickit.adapters.io import TcpIo
from tickit.core.adapter import AdapterContainer
from tickit.core.components.component import Component, ComponentConfig
from tickit.core.components.device_simulation import DeviceSimulation

Expand All @@ -13,8 +15,18 @@ class Cryostream(ComponentConfig):
port: int = 25565

def __call__(self) -> Component: # noqa: D102
device = CryostreamDevice()
adapters = [
AdapterContainer(
CryostreamAdapter(device),
TcpIo(
self.host,
self.port,
),
)
]
return DeviceSimulation(
name=self.name,
device=CryostreamDevice(),
adapters=[CryostreamAdapter(host=self.host, port=self.port)],
device=device,
adapters=adapters,
)
31 changes: 6 additions & 25 deletions src/tickit_devices/cryostream/cryostream.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
import struct
from typing import AsyncIterable, TypedDict

from tickit.adapters.composed import ComposedAdapter
from tickit.adapters.interpreters.command import CommandInterpreter, RegexCommand
from tickit.adapters.servers.tcp import TcpServer
from tickit.adapters.specifications import RegexCommand
from tickit.adapters.tcp import CommandAdapter
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.byte_format import ByteFormat

from tickit_devices.cryostream.base import CryostreamBase
from tickit_devices.cryostream.states import PhaseIds
Expand Down Expand Up @@ -57,31 +55,14 @@ def update(self, time: SimTime, inputs: Inputs) -> DeviceUpdate[Outputs]:
return DeviceUpdate(self.Outputs(temperature=self.gas_temp), None)


class CryostreamAdapter(ComposedAdapter[bytes]):
class CryostreamAdapter(CommandAdapter):
"""A Cryostream TCP adapter which sends regular status packets and can set modes."""

device: CryostreamDevice

def __init__(
self,
host: str = "localhost",
port: int = 25565,
) -> None:
"""A CryostreamAdapter constructor which instantiates a TcpServer with host and
port.
Args:
device (Device): The device which this adapter is attached to
raise_interrupt (Callable): A callback to request that the device is
updated immediately.
host (Optional[str]): The host address of the TcpServer. Defaults to
"localhost".
port (Optional[int]): The bound port of the TcpServer. Defaults to 25565.
"""
super().__init__(
TcpServer(format=ByteFormat(b"%b"), host=host, port=port),
CommandInterpreter(),
)
def __init__(self, device: CryostreamDevice) -> None:
super().__init__()
self.device = device

async def on_connect(self) -> AsyncIterable[bytes]:
"""A method which continiously yields status packets.
Expand Down
26 changes: 21 additions & 5 deletions src/tickit_devices/eiger/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import pydantic.v1.dataclasses
from tickit.adapters.io import HttpIo, ZeroMqPushIo
from tickit.core.adapter import AdapterContainer
from tickit.core.components.component import Component, ComponentConfig
from tickit.core.components.device_simulation import DeviceSimulation

Expand All @@ -16,11 +18,25 @@ class Eiger(ComponentConfig):
zmq_port: int = 9999

def __call__(self) -> Component: # noqa: D102
device = EigerDevice()
adapters = [
AdapterContainer(
EigerRESTAdapter(device),
HttpIo(
self.host,
self.port,
),
),
AdapterContainer(
EigerZMQAdapter(device),
ZeroMqPushIo(
self.zmq_host,
self.zmq_port,
),
),
]
return DeviceSimulation(
name=self.name,
device=EigerDevice(),
adapters=[
EigerRESTAdapter(host=self.host, port=self.port),
EigerZMQAdapter(host=self.zmq_host, port=self.zmq_port),
],
device=device,
adapters=adapters,
)
17 changes: 12 additions & 5 deletions src/tickit_devices/eiger/eiger_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

from aiohttp import web
from apischema import serialize
from tickit.adapters.httpadapter import HttpAdapter
from tickit.adapters.interpreters.endpoints.http_endpoint import HttpEndpoint
from tickit.adapters.zeromq.push_adapter import ZeroMqPushAdapter
from tickit.adapters.http import HttpAdapter
from tickit.adapters.specifications import HttpEndpoint
from tickit.adapters.zmq import ZeroMqPushAdapter

from tickit_devices.eiger.eiger import EigerDevice
from tickit_devices.eiger.eiger_schema import SequenceComplete, Value, construct_value
Expand All @@ -24,6 +24,9 @@ class EigerRESTAdapter(HttpAdapter):

device: EigerDevice

def __init__(self, device: EigerDevice) -> None:
self.device = device

@HttpEndpoint.get(f"/{DETECTOR_API}" + "/config/{parameter_name}")
async def get_config(self, request: web.Request) -> web.Response:
"""A HTTP Endpoint for requesting configuration variables from the Eiger.
Expand Down Expand Up @@ -189,7 +192,7 @@ async def trigger_eiger(self, request: web.Request) -> web.Response:
LOGGER.debug("Triggering Eiger")
await self.device.trigger()

await self.raise_interrupt()
await self.interrupt()
await self.device.finished_aquisition.wait()

return web.json_response(serialize(SequenceComplete(4)))
Expand Down Expand Up @@ -421,7 +424,11 @@ class EigerZMQAdapter(ZeroMqPushAdapter):

device: EigerDevice

def __init__(self, device: EigerDevice) -> None:
super().__init__()
self.device = device

def after_update(self) -> None:
"""Updates IOC values immediately following a device update."""
buffered_data = self.device.stream.consume_data()
self.send_message_sequence_soon([list(buffered_data)])
self.add_message_to_stream([list(buffered_data)])
20 changes: 16 additions & 4 deletions src/tickit_devices/femto/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import pydantic.v1.dataclasses
from tickit.adapters.io import EpicsIo
from tickit.core.adapter import AdapterContainer
from tickit.core.components.component import Component, ComponentConfig
from tickit.core.components.device_simulation import DeviceSimulation

Expand All @@ -16,12 +18,22 @@ class Femto(ComponentConfig):
ioc_name: str = "FEMTO"

def __call__(self) -> Component: # noqa: D102
device = FemtoDevice(
initial_gain=self.initial_gain, initial_current=self.initial_current
)
adapters = [
AdapterContainer(
FemtoAdapter(device),
EpicsIo(
self.ioc_name,
self.db_file,
),
)
]
return DeviceSimulation(
name=self.name,
device=FemtoDevice(
initial_gain=self.initial_gain, initial_current=self.initial_current
),
adapters=[FemtoAdapter(ioc_name=self.ioc_name, db_file=self.db_file)],
device=device,
adapters=adapters,
)


Expand Down
13 changes: 9 additions & 4 deletions src/tickit_devices/femto/femto.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import TypedDict

from softioc import builder
from tickit.adapters.epicsadapter import EpicsAdapter
from tickit.adapters.epics import EpicsAdapter
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime

Expand All @@ -28,8 +28,9 @@ def __init__(
initial_current (Optional[float]): The input signal current. \
Defaults to 0.0.
"""
self.gain: float = initial_gain
self._current: float = initial_current
self.gain = initial_gain
self._current = initial_current
self._output_current = initial_current * initial_gain

def set_gain(self, gain: float) -> None:
"""Sets a new amplified difference between the input and output signals.
Expand Down Expand Up @@ -89,14 +90,18 @@ class FemtoAdapter(EpicsAdapter):

device: FemtoDevice

def __init__(self, device: FemtoDevice) -> None:
super().__init__()
self.device = device

async def callback(self, value) -> None:
"""Device callback function.
Args:
value (float): The value to set the gain to.
"""
self.device.set_gain(value)
await self.raise_interrupt()
await self.interrupt()

def on_db_load(self) -> None:
"""Customises records that have been loaded in to suit the simulation."""
Expand Down
20 changes: 16 additions & 4 deletions src/tickit_devices/pneumatic/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import pydantic.v1.dataclasses
from tickit.adapters.io import EpicsIo
from tickit.core.adapter import AdapterContainer
from tickit.core.components.component import Component, ComponentConfig
from tickit.core.components.device_simulation import DeviceSimulation

Expand All @@ -15,10 +17,20 @@ class Pneumatic(ComponentConfig):
ioc_name: str = "PNEUMATIC"

def __call__(self) -> Component: # noqa: D102
device = PneumaticDevice(
initial_speed=self.initial_speed, initial_state=self.initial_state
)
adapters = [
AdapterContainer(
PneumaticAdapter(device),
EpicsIo(
self.ioc_name,
self.db_file,
),
)
]
return DeviceSimulation(
name=self.name,
device=PneumaticDevice(
initial_speed=self.initial_speed, initial_state=self.initial_state
),
adapters=[PneumaticAdapter(ioc_name=self.ioc_name, db_file=self.db_file)],
device=device,
adapters=adapters,
)
8 changes: 6 additions & 2 deletions src/tickit_devices/pneumatic/pneumatic.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import TypedDict

from softioc import builder
from tickit.adapters.epicsadapter import EpicsAdapter
from tickit.adapters.epics import EpicsAdapter
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime

Expand Down Expand Up @@ -82,14 +82,18 @@ class PneumaticAdapter(EpicsAdapter):

device: PneumaticDevice

def __init__(self, device: PneumaticDevice) -> None:
super().__init__()
self.device = device

async def callback(self, value) -> None:
"""Set the state of the device and await a response.
Args:
value (bool): The value to set the state to.
"""
self.device.set_state()
await self.raise_interrupt()
await self.interrupt()

def on_db_load(self):
"""Adds a record of the current state to the mapping of interrupting records."""
Expand Down
Loading

0 comments on commit 5689639

Please sign in to comment.