Skip to content

Commit 268540f

Browse files
committed
Update to pvi 0.8.1
Update to pass PV prefix into EPICS backend so that it can be included on Signals.
1 parent 792eae1 commit 268540f

File tree

4 files changed

+34
-30
lines changed

4 files changed

+34
-30
lines changed

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ description = "Control system agnostic framework for building Device support in
1313
dependencies = [
1414
"numpy",
1515
"pydantic",
16-
"pvi~=0.7.1",
16+
"pvi~=0.8.1",
1717
"softioc",
1818
]
1919
dynamic = ["version"]

src/fastcs/backends/epics/backend.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66

77

88
class EpicsBackend:
9-
def __init__(self, mapping: Mapping):
9+
def __init__(self, mapping: Mapping, pv_prefix: str = "MY-DEVICE-PREFIX"):
1010
self._mapping = mapping
11+
self._pv_prefix = pv_prefix
1112

1213
def create_docs(self, options: EpicsDocsOptions | None = None) -> None:
1314
docs = EpicsDocs(self._mapping)
1415
docs.create_docs(options)
1516

1617
def create_gui(self, options: EpicsGUIOptions | None = None) -> None:
17-
gui = EpicsGUI(self._mapping)
18+
gui = EpicsGUI(self._mapping, self._pv_prefix)
1819
gui.create_gui(options)
1920

2021
def get_ioc(self) -> EpicsIOC:
21-
return EpicsIOC(self._mapping)
22+
return EpicsIOC(self._mapping, self._pv_prefix)

src/fastcs/backends/epics/gui.py

+26-24
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pvi._format.dls import DLSFormatter
66
from pvi.device import (
77
LED,
8-
CheckBox,
8+
ButtonPanel,
99
Component,
1010
Device,
1111
Grid,
@@ -19,6 +19,7 @@
1919
TextFormat,
2020
TextRead,
2121
TextWrite,
22+
ToggleButton,
2223
Tree,
2324
WriteWidget,
2425
)
@@ -42,18 +43,16 @@ class EpicsGUIOptions:
4243

4344

4445
class EpicsGUI:
45-
def __init__(self, mapping: Mapping) -> None:
46+
def __init__(self, mapping: Mapping, pv_prefix: str) -> None:
4647
self._mapping = mapping
48+
self._pv_prefix = pv_prefix
4749

48-
@staticmethod
49-
def _get_pv(attr_path: str, name: str):
50+
def _get_pv(self, attr_path: str, name: str):
5051
if attr_path:
5152
attr_path = ":" + attr_path
5253
attr_path += ":"
5354

54-
pv = attr_path.upper() + name.title().replace("_", "")
55-
56-
return pv
55+
return f"{self._pv_prefix}{attr_path.upper()}{name.title().replace('_', '')}"
5756

5857
@staticmethod
5958
def _get_read_widget(datatype: DataType) -> ReadWidget:
@@ -71,43 +70,46 @@ def _get_read_widget(datatype: DataType) -> ReadWidget:
7170
def _get_write_widget(datatype: DataType) -> WriteWidget:
7271
match datatype:
7372
case Bool():
74-
return CheckBox()
73+
return ToggleButton()
7574
case Int() | Float():
7675
return TextWrite()
7776
case String():
7877
return TextWrite(format=TextFormat.string)
7978
case _:
8079
raise FastCSException(f"Unsupported type {type(datatype)}: {datatype}")
8180

82-
@classmethod
83-
def _get_attribute_component(cls, attr_path: str, name: str, attribute: Attribute):
84-
pv = cls._get_pv(attr_path, name)
81+
def _get_attribute_component(self, attr_path: str, name: str, attribute: Attribute):
82+
pv = self._get_pv(attr_path, name)
8583
name = name.title().replace("_", "")
8684

8785
match attribute:
8886
case AttrRW():
89-
read_widget = cls._get_read_widget(attribute.datatype)
90-
write_widget = cls._get_write_widget(attribute.datatype)
87+
read_widget = self._get_read_widget(attribute.datatype)
88+
write_widget = self._get_write_widget(attribute.datatype)
9189
return SignalRW(
9290
name=name,
93-
pv=pv,
94-
widget=write_widget,
91+
write_pv=pv,
92+
write_widget=write_widget,
9593
read_pv=pv + "_RBV",
9694
read_widget=read_widget,
9795
)
9896
case AttrR():
99-
read_widget = cls._get_read_widget(attribute.datatype)
100-
return SignalR(name=name, pv=pv, widget=read_widget)
97+
read_widget = self._get_read_widget(attribute.datatype)
98+
return SignalR(name=name, read_pv=pv, read_widget=read_widget)
10199
case AttrW():
102-
write_widget = cls._get_write_widget(attribute.datatype)
103-
return SignalW(name=name, pv=pv, widget=TextWrite())
100+
write_widget = self._get_write_widget(attribute.datatype)
101+
return SignalW(name=name, write_pv=pv, write_widget=TextWrite())
104102

105-
@classmethod
106-
def _get_command_component(cls, attr_path: str, name: str):
107-
pv = cls._get_pv(attr_path, name)
103+
def _get_command_component(self, attr_path: str, name: str):
104+
pv = self._get_pv(attr_path, name)
108105
name = name.title().replace("_", "")
109106

110-
return SignalX(name=name, pv=pv, value="1")
107+
return SignalX(
108+
name=name,
109+
write_pv=pv,
110+
value="1",
111+
write_widget=ButtonPanel(actions={name: "1"}),
112+
)
111113

112114
def create_gui(self, options: EpicsGUIOptions | None = None) -> None:
113115
if options is None:
@@ -136,7 +138,7 @@ def create_gui(self, options: EpicsGUIOptions | None = None) -> None:
136138

137139
device = Device(label="Simple Device", children=components)
138140

139-
formatter.format(device, "MY-DEVICE-PREFIX", options.output_path)
141+
formatter.format(device, options.output_path)
140142

141143
def extract_mapping_components(self, mapping: SingleMapping) -> list[Component]:
142144
components: Tree[Component] = []

src/fastcs/backends/epics/ioc.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,9 @@ def _create_and_link_command_pvs(mapping: Mapping) -> None:
113113

114114

115115
class EpicsIOC:
116-
def __init__(self, mapping: Mapping):
116+
def __init__(self, mapping: Mapping, pv_prefix: str):
117117
self._mapping = mapping
118+
self._pv_prefix = pv_prefix
118119

119120
def run(self, options: EpicsIOCOptions | None = None) -> None:
120121
if options is None:
@@ -125,7 +126,7 @@ def run(self, options: EpicsIOCOptions | None = None) -> None:
125126
backend = Backend(self._mapping, dispatcher.loop)
126127

127128
# Set the record prefix
128-
builder.SetDeviceName("MY-DEVICE-PREFIX")
129+
builder.SetDeviceName(self._pv_prefix)
129130

130131
_create_and_link_attribute_pvs(self._mapping)
131132

0 commit comments

Comments
 (0)