Skip to content

Commit 77189df

Browse files
Add GUI code to tutorial snippets (#164)
1 parent a281942 commit 77189df

File tree

10 files changed

+295
-180
lines changed

10 files changed

+295
-180
lines changed

docs/snippets/static05.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1+
from pathlib import Path
2+
13
from fastcs.attributes import AttrR
2-
from fastcs.connections import IPConnection, IPConnectionSettings
34
from fastcs.controller import Controller
45
from fastcs.datatypes import String
56
from fastcs.launch import FastCS
6-
from fastcs.transport.epics.ca.options import EpicsCAOptions
7+
from fastcs.transport.epics.ca.options import EpicsCAOptions, EpicsGUIOptions
78
from fastcs.transport.epics.options import EpicsIOCOptions
89

910

1011
class TemperatureController(Controller):
1112
device_id = AttrR(String())
1213

13-
def __init__(self, settings: IPConnectionSettings):
14-
super().__init__()
15-
16-
self._ip_settings = settings
17-
self.connection = IPConnection()
18-
19-
async def connect(self):
20-
await self.connection.connect(self._ip_settings)
2114

15+
gui_options = EpicsGUIOptions(
16+
output_path=Path(".") / "demo.bob", title="Demo Temperature Controller"
17+
)
18+
epics_options = EpicsCAOptions(
19+
gui=gui_options,
20+
ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"),
21+
)
22+
fastcs = FastCS(TemperatureController(), [epics_options])
2223

23-
epics_options = EpicsCAOptions(ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"))
24-
connection_settings = IPConnectionSettings("localhost", 25565)
25-
fastcs = FastCS(TemperatureController(connection_settings), [epics_options])
24+
fastcs.create_gui()
2625

2726
# fastcs.run() # Commented as this will block

docs/snippets/static06.py

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,16 @@
1-
from __future__ import annotations
1+
from pathlib import Path
22

3-
from dataclasses import dataclass
4-
5-
from fastcs.attributes import AttrHandlerR, AttrR
3+
from fastcs.attributes import AttrR
64
from fastcs.connections import IPConnection, IPConnectionSettings
7-
from fastcs.controller import BaseController, Controller
5+
from fastcs.controller import Controller
86
from fastcs.datatypes import String
97
from fastcs.launch import FastCS
108
from fastcs.transport.epics.ca.options import EpicsCAOptions
11-
from fastcs.transport.epics.options import EpicsIOCOptions
12-
13-
14-
@dataclass
15-
class IDUpdater(AttrHandlerR):
16-
update_period: float | None = 0.2
17-
_controller: TemperatureController | None = None
18-
19-
async def initialise(self, controller: BaseController):
20-
assert isinstance(controller, TemperatureController)
21-
self._controller = controller
22-
23-
@property
24-
def controller(self) -> TemperatureController:
25-
if self._controller is None:
26-
raise RuntimeError("Handler not initialised")
27-
28-
return self._controller
29-
30-
async def update(self, attr: AttrR):
31-
response = await self.controller.connection.send_query("ID?\r\n")
32-
value = response.strip("\r\n")
33-
34-
await attr.set(value)
9+
from fastcs.transport.epics.options import EpicsGUIOptions, EpicsIOCOptions
3510

3611

3712
class TemperatureController(Controller):
38-
device_id = AttrR(String(), handler=IDUpdater())
13+
device_id = AttrR(String())
3914

4015
def __init__(self, settings: IPConnectionSettings):
4116
super().__init__()
@@ -47,8 +22,16 @@ async def connect(self):
4722
await self.connection.connect(self._ip_settings)
4823

4924

50-
epics_options = EpicsCAOptions(ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"))
25+
gui_options = EpicsGUIOptions(
26+
output_path=Path(".") / "demo.bob", title="Demo Temperature Controller"
27+
)
28+
epics_options = EpicsCAOptions(
29+
gui=gui_options,
30+
ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"),
31+
)
5132
connection_settings = IPConnectionSettings("localhost", 25565)
5233
fastcs = FastCS(TemperatureController(connection_settings), [epics_options])
5334

35+
fastcs.create_gui()
36+
5437
# fastcs.run() # Commented as this will block

docs/snippets/static07.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
from __future__ import annotations
22

33
from dataclasses import dataclass
4+
from pathlib import Path
45

56
from fastcs.attributes import AttrHandlerR, AttrR
67
from fastcs.connections import IPConnection, IPConnectionSettings
78
from fastcs.controller import BaseController, Controller
8-
from fastcs.datatypes import Float, String
9+
from fastcs.datatypes import String
910
from fastcs.launch import FastCS
1011
from fastcs.transport.epics.ca.options import EpicsCAOptions
11-
from fastcs.transport.epics.options import EpicsIOCOptions
12+
from fastcs.transport.epics.options import EpicsGUIOptions, EpicsIOCOptions
1213

1314

1415
@dataclass
15-
class TemperatureControllerUpdater(AttrHandlerR):
16-
command_name: str
16+
class IDUpdater(AttrHandlerR):
1717
update_period: float | None = 0.2
1818
_controller: TemperatureController | None = None
1919

@@ -29,17 +29,14 @@ def controller(self) -> TemperatureController:
2929
return self._controller
3030

3131
async def update(self, attr: AttrR):
32-
response = await self.controller.connection.send_query(
33-
f"{self.command_name}?\r\n"
34-
)
32+
response = await self.controller.connection.send_query("ID?\r\n")
3533
value = response.strip("\r\n")
3634

37-
await attr.set(attr.dtype(value))
35+
await attr.set(value)
3836

3937

4038
class TemperatureController(Controller):
41-
device_id = AttrR(String(), handler=TemperatureControllerUpdater("ID"))
42-
power = AttrR(Float(), handler=TemperatureControllerUpdater("P"))
39+
device_id = AttrR(String(), handler=IDUpdater())
4340

4441
def __init__(self, settings: IPConnectionSettings):
4542
super().__init__()
@@ -51,8 +48,16 @@ async def connect(self):
5148
await self.connection.connect(self._ip_settings)
5249

5350

54-
epics_options = EpicsCAOptions(ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"))
51+
gui_options = EpicsGUIOptions(
52+
output_path=Path(".") / "demo.bob", title="Demo Temperature Controller"
53+
)
54+
epics_options = EpicsCAOptions(
55+
gui=gui_options,
56+
ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"),
57+
)
5558
connection_settings = IPConnectionSettings("localhost", 25565)
5659
fastcs = FastCS(TemperatureController(connection_settings), [epics_options])
5760

61+
fastcs.create_gui()
62+
5863
# fastcs.run() # Commented as this will block

docs/snippets/static08.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
from __future__ import annotations
22

33
from dataclasses import dataclass
4-
from typing import Any
4+
from pathlib import Path
55

6-
from fastcs.attributes import AttrHandlerRW, AttrR, AttrRW, AttrW
6+
from fastcs.attributes import AttrHandlerR, AttrR
77
from fastcs.connections import IPConnection, IPConnectionSettings
88
from fastcs.controller import BaseController, Controller
99
from fastcs.datatypes import Float, String
1010
from fastcs.launch import FastCS
1111
from fastcs.transport.epics.ca.options import EpicsCAOptions
12-
from fastcs.transport.epics.options import EpicsIOCOptions
12+
from fastcs.transport.epics.options import EpicsGUIOptions, EpicsIOCOptions
1313

1414

1515
@dataclass
16-
class TemperatureControllerHandler(AttrHandlerRW):
16+
class TemperatureControllerUpdater(AttrHandlerR):
1717
command_name: str
1818
update_period: float | None = 0.2
1919
_controller: TemperatureController | None = None
@@ -37,16 +37,10 @@ async def update(self, attr: AttrR):
3737

3838
await attr.set(attr.dtype(value))
3939

40-
async def put(self, attr: AttrW, value: Any):
41-
await self.controller.connection.send_command(
42-
f"{self.command_name}={value}\r\n"
43-
)
44-
4540

4641
class TemperatureController(Controller):
47-
device_id = AttrR(String(), handler=TemperatureControllerHandler("ID"))
48-
power = AttrR(Float(), handler=TemperatureControllerHandler("P"))
49-
ramp_rate = AttrRW(Float(), handler=TemperatureControllerHandler("R"))
42+
device_id = AttrR(String(), handler=TemperatureControllerUpdater("ID"))
43+
power = AttrR(Float(), handler=TemperatureControllerUpdater("P"))
5044

5145
def __init__(self, settings: IPConnectionSettings):
5246
super().__init__()
@@ -58,8 +52,16 @@ async def connect(self):
5852
await self.connection.connect(self._ip_settings)
5953

6054

61-
epics_options = EpicsCAOptions(ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"))
55+
gui_options = EpicsGUIOptions(
56+
output_path=Path(".") / "demo.bob", title="Demo Temperature Controller"
57+
)
58+
epics_options = EpicsCAOptions(
59+
gui=gui_options,
60+
ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"),
61+
)
6262
connection_settings = IPConnectionSettings("localhost", 25565)
6363
fastcs = FastCS(TemperatureController(connection_settings), [epics_options])
6464

65+
fastcs.create_gui()
66+
6567
# fastcs.run() # Commented as this will block

docs/snippets/static09.py

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,74 @@
11
from __future__ import annotations
22

33
from dataclasses import dataclass
4+
from pathlib import Path
45
from typing import Any
56

67
from fastcs.attributes import AttrHandlerRW, AttrR, AttrRW, AttrW
78
from fastcs.connections import IPConnection, IPConnectionSettings
8-
from fastcs.controller import BaseController, Controller, SubController
9-
from fastcs.datatypes import Float, Int, String
9+
from fastcs.controller import BaseController, Controller
10+
from fastcs.datatypes import Float, String
1011
from fastcs.launch import FastCS
1112
from fastcs.transport.epics.ca.options import EpicsCAOptions
12-
from fastcs.transport.epics.options import EpicsIOCOptions
13+
from fastcs.transport.epics.options import EpicsGUIOptions, EpicsIOCOptions
1314

1415

1516
@dataclass
1617
class TemperatureControllerHandler(AttrHandlerRW):
1718
command_name: str
1819
update_period: float | None = 0.2
19-
_controller: TemperatureController | TemperatureRampController | None = None
20+
_controller: TemperatureController | None = None
2021

2122
async def initialise(self, controller: BaseController):
22-
assert isinstance(controller, TemperatureController | TemperatureRampController)
23+
assert isinstance(controller, TemperatureController)
2324
self._controller = controller
2425

2526
@property
26-
def controller(self) -> TemperatureController | TemperatureRampController:
27+
def controller(self) -> TemperatureController:
2728
if self._controller is None:
2829
raise RuntimeError("Handler not initialised")
2930

3031
return self._controller
3132

3233
async def update(self, attr: AttrR):
3334
response = await self.controller.connection.send_query(
34-
f"{self.command_name}{self.controller.suffix}?\r\n"
35+
f"{self.command_name}?\r\n"
3536
)
3637
value = response.strip("\r\n")
3738

3839
await attr.set(attr.dtype(value))
3940

4041
async def put(self, attr: AttrW, value: Any):
4142
await self.controller.connection.send_command(
42-
f"{self.command_name}{self.controller.suffix}={value}\r\n"
43+
f"{self.command_name}={attr.dtype(value)}\r\n"
4344
)
4445

4546

46-
class TemperatureRampController(SubController):
47-
start = AttrRW(Int(), handler=TemperatureControllerHandler("S"))
48-
end = AttrRW(Int(), handler=TemperatureControllerHandler("E"))
49-
50-
def __init__(self, index: int, connection: IPConnection):
51-
self.suffix = f"{index:02d}"
52-
53-
super().__init__(f"Ramp{self.suffix}")
54-
55-
self.connection = connection
56-
57-
5847
class TemperatureController(Controller):
5948
device_id = AttrR(String(), handler=TemperatureControllerHandler("ID"))
6049
power = AttrR(Float(), handler=TemperatureControllerHandler("P"))
6150
ramp_rate = AttrRW(Float(), handler=TemperatureControllerHandler("R"))
6251

63-
suffix = ""
64-
65-
def __init__(self, ramp_count: int, settings: IPConnectionSettings):
52+
def __init__(self, settings: IPConnectionSettings):
6653
super().__init__()
6754

6855
self._ip_settings = settings
6956
self.connection = IPConnection()
7057

71-
self._ramp_controllers: list[TemperatureRampController] = []
72-
for idx in range(1, ramp_count + 1):
73-
ramp_controller = TemperatureRampController(idx, self.connection)
74-
self._ramp_controllers.append(ramp_controller)
75-
self.register_sub_controller(f"R{idx}", ramp_controller)
76-
7758
async def connect(self):
7859
await self.connection.connect(self._ip_settings)
7960

8061

81-
epics_options = EpicsCAOptions(ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"))
62+
gui_options = EpicsGUIOptions(
63+
output_path=Path(".") / "demo.bob", title="Demo Temperature Controller"
64+
)
65+
epics_options = EpicsCAOptions(
66+
gui=gui_options,
67+
ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"),
68+
)
8269
connection_settings = IPConnectionSettings("localhost", 25565)
83-
fastcs = FastCS(TemperatureController(4, connection_settings), [epics_options])
70+
fastcs = FastCS(TemperatureController(connection_settings), [epics_options])
71+
72+
fastcs.create_gui()
8473

8574
# fastcs.run() # Commented as this will block

docs/snippets/static10.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
from __future__ import annotations
22

3-
import enum
43
from dataclasses import dataclass
4+
from pathlib import Path
55
from typing import Any
66

77
from fastcs.attributes import AttrHandlerRW, AttrR, AttrRW, AttrW
88
from fastcs.connections import IPConnection, IPConnectionSettings
99
from fastcs.controller import BaseController, Controller, SubController
10-
from fastcs.datatypes import Enum, Float, Int, String
10+
from fastcs.datatypes import Float, Int, String
1111
from fastcs.launch import FastCS
1212
from fastcs.transport.epics.ca.options import EpicsCAOptions
13-
from fastcs.transport.epics.options import EpicsIOCOptions
13+
from fastcs.transport.epics.options import EpicsGUIOptions, EpicsIOCOptions
1414

1515

1616
@dataclass
@@ -40,19 +40,13 @@ async def update(self, attr: AttrR):
4040

4141
async def put(self, attr: AttrW, value: Any):
4242
await self.controller.connection.send_command(
43-
f"{self.command_name}{self.controller.suffix}={value}\r\n"
43+
f"{self.command_name}{self.controller.suffix}={attr.dtype(value)}\r\n"
4444
)
4545

4646

47-
class OnOffEnum(enum.StrEnum):
48-
Off = "0"
49-
On = "1"
50-
51-
5247
class TemperatureRampController(SubController):
5348
start = AttrRW(Int(), handler=TemperatureControllerHandler("S"))
5449
end = AttrRW(Int(), handler=TemperatureControllerHandler("E"))
55-
enabled = AttrRW(Enum(OnOffEnum), handler=TemperatureControllerHandler("N"))
5650

5751
def __init__(self, index: int, connection: IPConnection):
5852
self.suffix = f"{index:02d}"
@@ -85,8 +79,16 @@ async def connect(self):
8579
await self.connection.connect(self._ip_settings)
8680

8781

88-
epics_options = EpicsCAOptions(ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"))
82+
gui_options = EpicsGUIOptions(
83+
output_path=Path(".") / "demo.bob", title="Demo Temperature Controller"
84+
)
85+
epics_options = EpicsCAOptions(
86+
gui=gui_options,
87+
ca_ioc=EpicsIOCOptions(pv_prefix="DEMO"),
88+
)
8989
connection_settings = IPConnectionSettings("localhost", 25565)
9090
fastcs = FastCS(TemperatureController(4, connection_settings), [epics_options])
9191

92+
fastcs.create_gui()
93+
9294
# fastcs.run() # Commented as this will block

0 commit comments

Comments
 (0)