Source code for fastcs.transports.epics.pva.transport
import asyncio
from dataclasses import dataclass, field
from typing import ClassVar
from pydantic import ConfigDict
from fastcs.controllers import ControllerAPI
from fastcs.logging import logger
from fastcs.transports.epics import (
EpicsDocsOptions,
EpicsGUIOptions,
EpicsPVAOptions,
)
from fastcs.transports.epics.emission import emit_docs_files, emit_gui_files
from fastcs.transports.epics.pva.gui import PvaEpicsGUI
from fastcs.transports.epics.pva.util import validate_pva_id
from fastcs.transports.epics.util import pv_prefix_from_path
from fastcs.transports.transport import Transport
from .ioc import P4PIOC
[docs]
@dataclass
class EpicsPVATransport(Transport):
"""PV access transport."""
__pydantic_config__: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
epicspva: EpicsPVAOptions = field(default_factory=EpicsPVAOptions)
"""PVA-specific options. Currently empty; present as the YAML discriminator."""
docs: EpicsDocsOptions | None = None
gui: EpicsGUIOptions | None = None
def connect(
self,
controller_apis: list[ControllerAPI],
loop: asyncio.AbstractEventLoop,
) -> None:
for api in controller_apis:
validate_pva_id(api)
self._controller_apis = controller_apis
self._pv_prefixes = [pv_prefix_from_path(api.path) for api in controller_apis]
self._ioc = P4PIOC(controller_apis)
if self.docs is not None:
emit_docs_files(controller_apis, self.docs)
if self.gui is not None:
emit_gui_files(controller_apis, self.gui, PvaEpicsGUI)
[docs]
async def serve(self) -> None:
"""Serve `ControllerAPI` over EPICS PVAccess"""
logger.info("Running IOC", pv_prefixes=self._pv_prefixes)
await self._ioc.run()
def __repr__(self):
return f"EpicsPVATransport({self._pv_prefixes})"