Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,29 @@
"name": "Eiger IOC",
"type": "debugpy",
"request": "launch",
"module": "fastcs_eiger",
"justMyCode": false,
"console": "integratedTerminal",
"module": "fastcs_eiger",
"args": [
"ioc",
"EIGER",
]
"run",
"${workspaceFolder:fastcs-eiger}/src/fastcs_eiger/fastcs-eiger.yaml",
"--log-level",
"TRACE",
],
"console": "integratedTerminal",
},
{
"name": "Eiger Odin IOC",
"type": "debugpy",
"request": "launch",
"module": "fastcs_eiger",
"justMyCode": false,
"console": "integratedTerminal",
"module": "fastcs_eiger",
"args": [
"ioc",
"EIGER",
"--odin-ip",
"127.0.0.1",
]
"run",
"${workspaceFolder:fastcs-eiger}/src/fastcs_eiger/fastcs-eiger-odin.yaml",
"--log-level",
"TRACE",
],
"console": "integratedTerminal",
},
{
"name": "Eiger Asyncio",
Expand All @@ -37,7 +39,9 @@
"module": "fastcs_eiger",
"justMyCode": false,
"console": "integratedTerminal",
"args": ["asyncio"]
"args": [
"asyncio"
]
},
{
"name": "Debug Unit Test",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ classifiers = [
description = "Eiger control system integration with FastCS"
dependencies = [
"aiohttp",
"fastcs-odin~=0.9.0",
"fastcs-odin @ git+https://github.com/DiamondLightSource/fastcs-odin.git@update_to_fastcs_0.14.0",
"numpy",
"pillow",
"typer",
Expand Down
88 changes: 4 additions & 84 deletions src/fastcs_eiger/__main__.py
Original file line number Diff line number Diff line change
@@ -1,88 +1,8 @@
from pathlib import Path
from typing import Optional

import softioc.pvlog # noqa: F401
import typer
from fastcs.connections import IPConnectionSettings
from fastcs.launch import FastCS
from fastcs.logging import LogLevel, configure_logging, intercept_std_logger
from fastcs.transports.epics import EpicsGUIOptions, EpicsIOCOptions
from fastcs.transports.epics.ca.transport import EpicsCATransport
from fastcs.launch import launch

from fastcs_eiger import __version__
from fastcs_eiger.controllers.eiger_controller import EigerController
from fastcs_eiger.controllers.odin.eiger_odin_controller import EigerOdinController
from fastcs_eiger.eiger_parameter import EigerAPIVersion

__all__ = ["main"]


app = typer.Typer()


def version_callback(value: bool):
if value:
typer.echo(__version__)
raise typer.Exit()


@app.callback()
def main(
# TODO: typer does not support `bool | None` yet
# https://github.com/tiangolo/typer/issues/533
version: Optional[bool] = typer.Option( # noqa
None,
"--version",
callback=version_callback,
is_eager=True,
help="Print the version and exit",
),
):
pass


OPI_PATH = Path("/epics/opi")


@app.command()
def ioc(
pv_prefix: str = typer.Argument(),
ip: str = typer.Option("127.0.0.1", help="IP address of Eiger detector"),
port: int = typer.Option(8081, help="Port of Eiger HTTP server"),
api_version: EigerAPIVersion = typer.Option("1.8.0", help="Version of Eiger API"), # noqa: B008
odin_ip: str | None = typer.Option(None, help="IP address of odin control server"),
odin_port: int = typer.Option(8888, help="Port of odin control server"),
log_level: LogLevel = LogLevel.TRACE,
):
ui_path = OPI_PATH if OPI_PATH.is_dir() else Path.cwd() / "opi"

configure_logging(log_level)
intercept_std_logger("root")

if odin_ip is None:
controller = EigerController(
connection_settings=IPConnectionSettings(ip=ip, port=port),
api_version=api_version,
)
else:
controller = EigerOdinController(
detector_connection_settings=IPConnectionSettings(ip=ip, port=port),
odin_connection_settings=IPConnectionSettings(ip=odin_ip, port=odin_port),
api_version=api_version,
)

transports = [
EpicsCATransport(
epicsca=EpicsIOCOptions(pv_prefix=pv_prefix),
gui=EpicsGUIOptions(
output_path=ui_path / "eiger.bob", title=f"Eiger - {pv_prefix}"
),
),
]
launcher = FastCS(controller, transports)
launcher.run()

from .controllers.eiger_controller import EigerController
from .controllers.odin.eiger_odin_controller import EigerOdinController

# test with: python -m fastcs_eiger
if __name__ == "__main__":
app()
launch(controller_classes=[EigerController, EigerOdinController], version=__version__)
17 changes: 11 additions & 6 deletions src/fastcs_eiger/controllers/eiger_controller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
from collections.abc import Coroutine
from dataclasses import dataclass

from fastcs.attributes import AttrR, AttrRW
from fastcs.connections import IPConnectionSettings
Expand All @@ -18,6 +19,12 @@
COMMAND_GROUP = "Command"


@dataclass
class EigerControllerSettings:
connection_settings: IPConnectionSettings
api_version: EigerAPIVersion


class EigerController(Controller):
"""Root controller for Eiger detectors

Expand All @@ -37,16 +44,14 @@ class EigerController(Controller):
group=COMMAND_GROUP,
)

def __init__(
self, connection_settings: IPConnectionSettings, api_version: EigerAPIVersion
) -> None:
def __init__(self, settings: EigerControllerSettings) -> None:
super().__init__()
self.connection_settings = connection_settings
self.connection_settings = settings.connection_settings

self.connection = HTTPConnection(connection_settings)
self.connection = HTTPConnection(settings.connection_settings)
self._parameter_update_lock = asyncio.Lock()
self.queue = asyncio.Queue()
self._api_version: EigerAPIVersion = api_version
self._api_version: EigerAPIVersion = settings.api_version

async def initialise(self) -> None:
"""Create attributes by introspecting detector.
Expand Down
29 changes: 19 additions & 10 deletions src/fastcs_eiger/controllers/odin/eiger_odin_controller.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import asyncio
from dataclasses import dataclass

from fastcs.attributes import AttrRW
from fastcs.connections import IPConnectionSettings
from fastcs.datatypes import Bool, Int
from fastcs.methods import command
from fastcs_odin.controllers.odin_controller import OdinControllerSettings

from fastcs_eiger.controllers.eiger_controller import COMMAND_GROUP, EigerController
from fastcs_eiger.controllers.eiger_controller import (
COMMAND_GROUP,
EigerController,
EigerControllerSettings,
)
from fastcs_eiger.controllers.odin.odin_controller import OdinController
from fastcs_eiger.eiger_parameter import EigerAPIVersion


@dataclass
class EigerOdinControllerSettings(EigerControllerSettings):
odin_connection_settings: IPConnectionSettings


class EigerOdinController(EigerController):
Expand All @@ -21,15 +31,14 @@ class EigerOdinController(EigerController):
)
enable_vds_creation = AttrRW(Bool())

def __init__(
self,
detector_connection_settings: IPConnectionSettings,
odin_connection_settings: IPConnectionSettings,
api_version: EigerAPIVersion,
) -> None:
super().__init__(detector_connection_settings, api_version)
def __init__(self, settings: EigerOdinControllerSettings) -> None:
super().__init__(
EigerControllerSettings(settings.connection_settings, settings.api_version)
)

self.OD = OdinController(odin_connection_settings)
self.OD = OdinController(
OdinControllerSettings(settings.odin_connection_settings)
)

async def initialise(self) -> None:
"""Initialise eiger controller and odin controller"""
Expand Down
16 changes: 16 additions & 0 deletions src/fastcs_eiger/fastcs-eiger-odin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# yaml-language-server: $schema=schema.json
controllers:
- id: EIGER
type: fastcs_eiger.EigerOdinController
connection_settings:
ip: "localhost"
port: 8081
odin_connection_settings:
ip: "localhost"
port: 8888
api_version: "1.8.0"
transport:
- epicsca: {}
gui:
title: "Eiger - EIGER"
output_dir: ./opi/
13 changes: 13 additions & 0 deletions src/fastcs_eiger/fastcs-eiger.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# yaml-language-server: $schema=schema.json
controllers:
- id: EIGER
type: fastcs_eiger.EigerController
connection_settings:
ip: "localhost"
port: 8081
api_version: "1.8.0"
transport:
- epicsca: {}
gui:
title: "Eiger - EIGER"
output_dir: ./opi/
Loading
Loading