epicsdev_ps_caen_fastps 0.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Electron-Ion Collider
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,5 @@
1
+ Metadata-Version: 2.5
2
+ Name: epicsdev_ps_caen_fastps
3
+ Version: 0.0.2
4
+ Summary: EPICS PVAccess server for CAEN FAST-PS power supplies
5
+ License-File: LICENSE
@@ -0,0 +1,99 @@
1
+ # epicsdev_ps_caen_fastps
2
+
3
+ EPICS PVAccess server for CAEN FAST-PS power supplies, implemented with `epicsdev`.
4
+
5
+ Main server module: [caen_fastps/__main__.py](caen_fastps/__main__.py)
6
+ IOC reference DB: [ioc/fastps.db](ioc/fastps.db)
7
+ Phoebus screen generator: [opi/generate_screen.py](screens/generate_screen.py)
8
+ - Main server module: [epicsdev_ps_caen_fastps/__main__.py](epicsdev_ps_caen_fastps/__main__.py)
9
+ - IOC reference DB: [docs/fastps.db](docs/fastps.db)
10
+ - Phoebus screen generator: [opi/generate_opi.py](opi/generate_opi.py)
11
+
12
+ ## Features
13
+
14
+ - TCP remote control interface to FAST-PS (default port `10001`)
15
+ - PV set modeled after the IOC records in [docs/fastps.db](docs/fastps.db)
16
+ - Setpoint control with optional ramping:
17
+ - `Voltage`, `Current`, `RampEnable`
18
+ - Output and diagnostic readback:
19
+ - `OutputVoltage`, `OutputCurrent`, `GroundCurrent`, `DCLinkVoltage`, `HeatsinkTemp`
20
+ - Status and state control:
21
+ - `StatusMSB`, `StatusLSB`, `StatusReset`, `Enable`, `RegulationMode`, `Upmode`
22
+ - Ramp-rate control:
23
+ - `RampRateV`, `RampRateI`
24
+ - Device identity and inferred limits:
25
+ - `Model`, `Version`, `Limits`
26
+ - Generic command passthrough:
27
+ - `instrCmdS`, `instrCmdR`
28
+
29
+ ## FAST-PS protocol mapping
30
+
31
+ Implemented command families:
32
+
33
+ - `VER`
34
+ - `MON`, `MOFF`
35
+ - `LOOP`, `LOOP ?`
36
+ - `MWV`, `MWV ?`, `MWVR`
37
+ - `MWI`, `MWI ?`, `MWIR`
38
+ - `MRESET`
39
+ - `MST`
40
+ - `UPMODE:?`, `UPMODE:<mode>`
41
+ - `MSRV:?`, `MSRV:<value>`
42
+ - `MSRI:?`, `MSRI:<value>`
43
+ - `MRV`, `MRI`, `MGC`, `MRP`, `MRT`
44
+
45
+ ## Requirements
46
+
47
+ - Python 3.10+
48
+ - `epicsdev` and its runtime dependencies (including `p4p`)
49
+ - Network access to the CAEN FAST-PS device
50
+
51
+ ## Run
52
+
53
+ From this project directory:
54
+
55
+ - `python -m epicsdev_ps_caen_fastps`
56
+
57
+ Useful arguments:
58
+
59
+ - `--host` FAST-PS IP/hostname (default: `130.199.104.57`)
60
+ - `--port` TCP port (default: `10001`)
61
+ - `--timeout` socket timeout in seconds (default: `2.0`)
62
+ - `-d, --device` PV prefix device root (default: `caen_fastps`)
63
+ - `-i, --index` PV prefix index (default: `0`)
64
+ - `-v` increase verbosity (`-vv` for more)
65
+ - `-a, --autosave` enable autosave with optional directory
66
+ - `-c, --recall` disable restoring autosaved values on startup
67
+
68
+ Example:
69
+
70
+ - `python -m epicsdev_ps_caen_fastps --host 130.199.104.57 -d caen_fastps:`
71
+
72
+ Default PV prefix:
73
+
74
+ - `caen_fastps0:`
75
+
76
+ ## Generate a Phoebus screen
77
+
78
+ Generate `.bob` OPI file:
79
+
80
+ - `python generate_opi.py -t FAST-PS pva://caen_fastps:0:`
81
+
82
+ Options:
83
+
84
+ - `-t, --title` screen title
85
+ - `prefix` PV prefix macro/value (default: `$(DEV):`)
86
+
87
+ Output:
88
+
89
+ - [opi/caen_fastps.bob](opi/caen_fastps.bob)
90
+
91
+ ## Screenshot
92
+
93
+ - [docs/opi_caen_fastps.jpg](docs/opi_caen_fastps.jpg)
94
+
95
+ ## Notes
96
+
97
+ - The server uses common `epicsdev` control PVs such as `server`, `sleep`, `status`, and `HEARTBEAT`.
98
+ - `Enable` is synchronized from bit 0 of `StatusLSB` during polling.
99
+ - For unsupported/custom diagnostics, use `instrCmdS` and read the reply from `instrCmdR`.
@@ -0,0 +1,283 @@
1
+
2
+ record(bo, "$(P)$(R)RegulationMode")
3
+ {
4
+ field(DESC, "Selects between voltage/current reg")
5
+ field(DTYP, "stream")
6
+ field(OUT, "@fastps.proto setRegulationMode L0")
7
+ field(ZNAM, "V")
8
+ field(ONAM, "I")
9
+ }
10
+
11
+ record(ao, "$(P)$(R)Voltage")
12
+ {
13
+ field(DESC, "Voltage control (in V reg mode)")
14
+ field(DTYP, "stream")
15
+ field(EGU, "V")
16
+ field(OUT, "@fastps.proto setVoltage($(P)$(R)) L0")
17
+ field(PREC, "5")
18
+ }
19
+
20
+ record(ao, "$(P)$(R)Current")
21
+ {
22
+ field(DESC, "Current control (in V reg mode)")
23
+ field(DTYP, "stream")
24
+ field(EGU, "A")
25
+ field(OUT, "@fastps.proto setCurrent($(P)$(R)) L0")
26
+ field(PREC, "5")
27
+ }
28
+
29
+ record(bo, "$(P)$(R)StatusReset")
30
+ {
31
+ field(DESC, "Reset status register/clear faults")
32
+ field(DTYP, "stream")
33
+ field(OUT, "@fastps.proto resetStatus L0")
34
+ }
35
+
36
+ record(bo, "$(P)$(R)RampEnable")
37
+ {
38
+ field(DESC, "Enables/disables ramping to setpoint")
39
+ field(ZNAM, "Off")
40
+ field(ONAM, "On")
41
+ field(DOL, "0")
42
+ field(PINI, "YES")
43
+ }
44
+
45
+ ################################################################################
46
+ record(bi, "$(P)$(R)ReadbackPoll_")
47
+ {
48
+ field(DESC, "Head of readback chain")
49
+ field(FLNK, "$(P)$(R)OutputVoltage")
50
+ field(PINI, "YES")
51
+ field(INP, "0")
52
+ field(SCAN, "1 second")
53
+ }
54
+
55
+ record(ai, "$(P)$(R)OutputVoltage")
56
+ {
57
+ field(DESC, "Output voltage")
58
+ field(DTYP, "stream")
59
+ field(EGU, "V")
60
+ field(FLNK, "$(P)$(R)OutputCurrent")
61
+ field(INP, "@fastps.proto getOutputVoltage L0")
62
+ field(PREC, "5")
63
+ }
64
+
65
+ record(ai, "$(P)$(R)OutputCurrent")
66
+ {
67
+ field(DESC, "Output current")
68
+ field(DTYP, "stream")
69
+ field(EGU, "A")
70
+ field(FLNK, "$(P)$(R)GroundCurrent")
71
+ field(INP, "@fastps.proto getOutputCurrent L0")
72
+ field(PREC, "5")
73
+ }
74
+
75
+ record(ai, "$(P)$(R)GroundCurrent")
76
+ {
77
+ field(DESC, "Ground current")
78
+ field(DTYP, "stream")
79
+ field(EGU, "A")
80
+ field(FLNK, "$(P)$(R)DCLinkVoltage")
81
+ field(INP, "@fastps.proto getGroundCurrent L0")
82
+ field(PREC, "3")
83
+ }
84
+
85
+ record(ai, "$(P)$(R)DCLinkVoltage")
86
+ {
87
+ field(DESC, "DC Link voltage")
88
+ field(DTYP, "stream")
89
+ field(EGU, "V")
90
+ field(FLNK, "$(P)$(R)HeatsinkTemp")
91
+ field(INP, "@fastps.proto getDCLinkVoltage L0")
92
+ field(PREC, "2")
93
+ }
94
+
95
+ record(ai, "$(P)$(R)HeatsinkTemp")
96
+ {
97
+ field(DESC, "Heatsink temperature")
98
+ field(DTYP, "stream")
99
+ field(EGU, "deg C")
100
+ field(FLNK, "$(P)$(R)StatusMSB")
101
+ field(INP, "@fastps.proto getTemperature L0")
102
+ field(PREC, "2")
103
+ }
104
+
105
+ record(mbbiDirect, "$(P)$(R)StatusMSB")
106
+ {
107
+ field(DESC, "Status MSB")
108
+ field(DTYP, "stream")
109
+ field(FLNK, "$(P)$(R)StatusLSB")
110
+ field(INP, "@fastps.proto getStatusMSB L0")
111
+ }
112
+
113
+ record(mbbiDirect, "$(P)$(R)StatusLSB")
114
+ {
115
+ field(DESC, "Status LSB")
116
+ field(DTYP, "stream")
117
+ field(FLNK, "$(P)$(R)Limits")
118
+ field(INP, "@fastps.proto getStatusLSB L0")
119
+ }
120
+
121
+ record (aai, "$(P)$(R)Limits")
122
+ {
123
+ field(DESC, "Limits")
124
+ field(DTYP, "stream")
125
+
126
+ field(FTVL, "FLOAT")
127
+ field(NELM, "4")
128
+ field(INP, "@fastps.proto getLimits L0")
129
+ field(FLNK, "$(P)$(R)LimitMinV")
130
+ }
131
+
132
+ record (ai, "$(P)$(R)LimitMinV")
133
+ {
134
+ field(DESC, "Low limit of voltage")
135
+ field(DTYP, "stream")
136
+ field(EGU, "V")
137
+ field(FLNK, "$(P)$(R)LimitMaxV")
138
+ field(INP, "@fastps.proto getMinV L0")
139
+ }
140
+
141
+ record (ai, "$(P)$(R)LimitMaxV")
142
+ {
143
+ field(DESC, "High limit of voltage")
144
+ field(DTYP, "stream")
145
+ field(EGU, "V")
146
+ field(FLNK, "$(P)$(R)LimitMinI")
147
+ field(INP, "@fastps.proto getMaxV L0")
148
+ }
149
+
150
+ record (ai, "$(P)$(R)LimitMinI")
151
+ {
152
+ field(DESC, "Low limit of current")
153
+ field(DTYP, "stream")
154
+ field(EGU, "A")
155
+ field(FLNK, "$(P)$(R)LimitMaxI")
156
+ field(INP, "@fastps.proto getMinI L0")
157
+ }
158
+
159
+ record (ai, "$(P)$(R)LimitMaxI")
160
+ {
161
+ field(DESC, "High limit of current")
162
+ field(DTYP, "stream")
163
+ field(EGU, "A")
164
+ field(FLNK, "$(P)$(R)LimitMinV_")
165
+ field(INP, "@fastps.proto getMaxI L0")
166
+ }
167
+
168
+ record (calcout, "$(P)$(R)LimitMinV_")
169
+ {
170
+ field(DESC, "Low limit for Voltage")
171
+ field(INPA, "$(P)$(R)LimitMinV")
172
+ field(CALC, "A")
173
+ field(OUT, "$(P)$(R)Voltage.LOPR")
174
+ field(FLNK, "$(P)$(R)LimitMinVOutput_")
175
+ }
176
+
177
+ record (calcout, "$(P)$(R)LimitMinVOutput_")
178
+ {
179
+ field(DESC, "Low limit for output Voltage")
180
+ field(INPA, "$(P)$(R)LimitMinV")
181
+ field(CALC, "A")
182
+ field(OUT, "$(P)$(R)OutputVoltage.LOPR")
183
+ field(FLNK, "$(P)$(R)LimitMaxV_")
184
+ }
185
+
186
+ record (calcout, "$(P)$(R)LimitMaxV_")
187
+ {
188
+ field(DESC, "High limit for Voltage")
189
+ field(INPA, "$(P)$(R)LimitMaxV")
190
+ field(CALC, "A")
191
+ field(OUT, "$(P)$(R)Voltage.HOPR")
192
+ field(FLNK, "$(P)$(R)LimitMaxVOutput_")
193
+ }
194
+
195
+ record (calcout, "$(P)$(R)LimitMaxVOutput_")
196
+ {
197
+ field(DESC, "High limit for output Voltage")
198
+ field(INPA, "$(P)$(R)LimitMaxV")
199
+ field(CALC, "A")
200
+ field(OUT, "$(P)$(R)OutputVoltage.HOPR")
201
+ field(FLNK, "$(P)$(R)LimitMinI_")
202
+ }
203
+
204
+ record (calcout, "$(P)$(R)LimitMinI_")
205
+ {
206
+ field(DESC, "Low limit for Current")
207
+ field(INPA, "$(P)$(R)LimitMinI")
208
+ field(CALC, "A")
209
+ field(OUT, "$(P)$(R)Current.LOPR")
210
+ field(FLNK, "$(P)$(R)LimitMinIOutput_")
211
+ }
212
+
213
+ record (calcout, "$(P)$(R)LimitMinIOutput_")
214
+ {
215
+ field(DESC, "Low limit for output Current")
216
+ field(INPA, "$(P)$(R)LimitMinI")
217
+ field(CALC, "A")
218
+ field(OUT, "$(P)$(R)OutputCurrent.LOPR")
219
+ field(FLNK, "$(P)$(R)LimitMaxI_")
220
+ }
221
+
222
+ record (calcout, "$(P)$(R)LimitMaxI_")
223
+ {
224
+ field(DESC, "High limit for Current")
225
+ field(INPA, "$(P)$(R)LimitMaxI")
226
+ field(CALC, "A")
227
+ field(OUT, "$(P)$(R)Current.HOPR")
228
+ field(FLNK, "$(P)$(R)LimitMaxIOutput_")
229
+ }
230
+
231
+ record (calcout, "$(P)$(R)LimitMaxIOutput_")
232
+ {
233
+ field(DESC, "High limit for output Current")
234
+ field(INPA, "$(P)$(R)LimitMaxI")
235
+ field(CALC, "A")
236
+ field(OUT, "$(P)$(R)OutputCurrent.HOPR")
237
+ field(FLNK, "$(P)$(R)Model")
238
+ }
239
+
240
+ record (stringin, "$(P)$(R)Model")
241
+ {
242
+ field(DESC, "Model")
243
+ field(DTYP, "stream")
244
+ field(INP, "@fastps.proto getModel L0")
245
+ field(FLNK, "$(P)$(R)Version")
246
+ }
247
+
248
+ record (stringin, "$(P)$(R)Version")
249
+ {
250
+ field(DESC, "Version")
251
+ field(DTYP, "stream")
252
+ field(INP, "@fastps.proto getVersion L0")
253
+ field(FLNK, "$(P)$(R)_EnableInit")
254
+ }
255
+
256
+ record(mbbiDirect, "$(P)$(R)_EnableInit")
257
+ {
258
+ field(DESC, "Initialization for Enable")
259
+ field(DTYP, "stream")
260
+ field(PINI, "YES")
261
+ field(INP, "@fastps.proto getStatusLSB L0")
262
+ field(FLNK, "$(P)$(R)_EnableInitCalc")
263
+ }
264
+
265
+ record(calcout, "$(P)$(R)_EnableInitCalc")
266
+ {
267
+ field(DESC, "Initialization for Enable")
268
+ field(INPA, "$(P)$(R)StatusLSB")
269
+ field(CALC, "A & 0x1")
270
+ field(OUT, "$(P)$(R)Enable.VAL")
271
+ }
272
+
273
+ record(bo, "$(P)$(R)Enable")
274
+ {
275
+ field(DESC, "Turn supply off/on")
276
+ field(DTYP, "stream")
277
+ field(OUT, "@fastps.proto setEnable L0")
278
+ field(ZNAM, "Off")
279
+ field(ONAM, "On")
280
+ # the field gets initialized from status, clear UDF
281
+ field(STAT, "NO_ALARM")
282
+ field(SEVR, "NO_ALARM")
283
+ }
@@ -0,0 +1,4 @@
1
+ ## Initial prompt for caen_fastps
2
+ Add code to implement EPICS PVAccess server, using epicsdev module.
3
+ Use programming manual at docs/'Remote Control Manual Rev3.1.pdf'.
4
+ Create PVs similar to ones, described in IOC db file ioc/fastps.db