From 87e723982848c550e6d4f82e682564d48a64468a Mon Sep 17 00:00:00 2001 From: Gary Yendell Date: Thu, 27 Nov 2025 11:35:57 +0000 Subject: [PATCH] Add monitor waveform --- src/fastcs_eiger/__main__.py | 8 +++++-- .../controllers/eiger_monitor_controller.py | 24 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/fastcs_eiger/__main__.py b/src/fastcs_eiger/__main__.py index dada0e8..5c7e129 100644 --- a/src/fastcs_eiger/__main__.py +++ b/src/fastcs_eiger/__main__.py @@ -7,6 +7,7 @@ from fastcs.logging import LogLevel, configure_logging from fastcs.transports.epics import EpicsGUIOptions, EpicsIOCOptions from fastcs.transports.epics.ca.transport import EpicsCATransport +from fastcs.transports.epics.pva.transport import EpicsPVATransport from fastcs_eiger import __version__ from fastcs_eiger.controllers.eiger_controller import EigerController @@ -66,12 +67,15 @@ def ioc( ) transports = [ - EpicsCATransport( - epicsca=EpicsIOCOptions(pv_prefix=pv_prefix), + EpicsPVATransport( + epicspva=EpicsIOCOptions(pv_prefix=pv_prefix), gui=EpicsGUIOptions( output_path=ui_path / "eiger.bob", title=f"Eiger - {pv_prefix}" ), ), + EpicsCATransport( + epicsca=EpicsIOCOptions(pv_prefix=pv_prefix), + ), ] launcher = FastCS(controller, transports) launcher.run() diff --git a/src/fastcs_eiger/controllers/eiger_monitor_controller.py b/src/fastcs_eiger/controllers/eiger_monitor_controller.py index 3479620..c52971d 100644 --- a/src/fastcs_eiger/controllers/eiger_monitor_controller.py +++ b/src/fastcs_eiger/controllers/eiger_monitor_controller.py @@ -1,25 +1,37 @@ from io import BytesIO import numpy as np +from fastcs.attributes import AttrR +from fastcs.datatypes import Waveform from fastcs.methods import scan from PIL import Image from fastcs_eiger.controllers.eiger_subsystem_controller import EigerSubsystemController +DEFAULT_IMAGE_SHAPE = (5000, 5000) +DEFAULT_IMAGE = np.array(range(np.prod(DEFAULT_IMAGE_SHAPE)), dtype=np.uint32).reshape( + *DEFAULT_IMAGE_SHAPE +) + class EigerMonitorController(EigerSubsystemController): _subsystem = "monitor" + image = AttrR( + Waveform(np.uint32, shape=DEFAULT_IMAGE_SHAPE), initial_value=DEFAULT_IMAGE + ) + line = AttrR(Waveform(np.float64, shape=(10,)), initial_value=np.sin(np.arange(10))) + @scan(1) async def handle_monitor(self): """Poll monitor images to display.""" + if (image := await self._read_monitor_image()) is not None: + await self.image.update(image) + + async def _read_monitor_image(self) -> np.ndarray | None: response, image_bytes = await self.connection.get_bytes( "monitor/api/1.8.0/images/next" ) - if response.status != 200: - return - else: - image = Image.open(BytesIO(image_bytes)) - # TODO: Populate waveform PV to display as image, once supported in PVI - print(np.array(image)) + if response.status == 200: + return np.array(Image.open(BytesIO(image_bytes)).getdata())