Skip to content

Commit dd1eab3

Browse files
committed
additional, more-complicated example
1 parent c7284a0 commit dd1eab3

3 files changed

Lines changed: 160 additions & 1 deletion

File tree

iocBoot/11-Sequencer/monitor.lua

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
-- monitor.lua
2+
--
3+
-- Voltage monitor sequencer -- demonstrates condition functions,
4+
-- action callbacks, unconditional transitions, event flags, and
5+
-- the "exit" state.
6+
--
7+
-- The monitor watches a voltage PV and sets an alarm PV when the
8+
-- voltage exceeds a high threshold. The alarm clears when the
9+
-- voltage drops below a low threshold (hysteresis). The monitor
10+
-- can be stopped externally via a named event flag.
11+
12+
local seq = require("seq")
13+
local db = require("db")
14+
local epics = require("epics")
15+
local event = require("event")
16+
17+
-- Create records
18+
db.record("ao", P .. "voltage") { VAL = "0", PREC = "2" }
19+
db.record("bo", P .. "alarm") { ZNAM = "OK", ONAM = "ALARM" }
20+
21+
-- PV objects
22+
local voltage = epics.pv(P .. "voltage")
23+
local alarm = epics.pv(P .. "alarm")
24+
25+
-- Named event flag for external stop signal
26+
local stop = event.flag("stopMonitor")
27+
28+
-- Thresholds with hysteresis
29+
local HI = 8.0
30+
local LO = 3.0
31+
32+
local prog = seq.program("voltageMonitor")
33+
34+
-- Initial setup: unconditional transition to normal
35+
prog:state("init", {
36+
seq.when() {
37+
action = function()
38+
alarm.VAL = 0
39+
print("Monitor: started (HI=" .. HI .. " LO=" .. LO .. ")")
40+
end,
41+
next = "normal",
42+
},
43+
})
44+
45+
-- Normal state: watch for voltage exceeding the high threshold
46+
prog:state("normal", {
47+
seq.when(function() return voltage.VAL > HI end) {
48+
action = function()
49+
alarm.VAL = 1
50+
print("Monitor: ALARM (voltage " .. voltage.VAL .. " > " .. HI .. ")")
51+
end,
52+
next = "alarm",
53+
},
54+
55+
seq.when(function() return stop:test() end) {
56+
action = function() print("Monitor: stopped") end,
57+
next = "exit",
58+
},
59+
60+
seq.when(seq.delay(0.1)) {
61+
next = "normal",
62+
},
63+
})
64+
65+
-- Alarm state: watch for voltage dropping below the low threshold
66+
prog:state("alarm", {
67+
seq.when(function() return voltage.VAL < LO end) {
68+
action = function()
69+
alarm.VAL = 0
70+
print("Monitor: OK (voltage " .. voltage.VAL .. " < " .. LO .. ")")
71+
end,
72+
next = "normal",
73+
},
74+
75+
seq.when(function() return stop:test() end) {
76+
action = function() print("Monitor: stopped") end,
77+
next = "exit",
78+
},
79+
80+
seq.when(seq.delay(0.1)) {
81+
next = "alarm",
82+
},
83+
})
84+
85+
seq.register(prog)

iocBoot/11-Sequencer/st.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,10 @@ osi = require("osi")
2828

2929
for i = 1, 20 do
3030
osi.sleep(1.0)
31-
do r = epics.get("lua:red"); y = epics.get("lua:yellow"); g = epics.get("lua:green"); print(string.format(" Red: %d Yellow: %d Green: %d", r, y, g)) end
31+
do
32+
r = epics.get("lua:red");
33+
y = epics.get("lua:yellow");
34+
g = epics.get("lua:green");
35+
print(string.format(" Red: %d Yellow: %d Green: %d", r, y, g))
36+
end
3237
end
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
-- Sequencer Library Example IOC -- Voltage Monitor
2+
--
3+
-- Demonstrates seq library transitions with condition functions,
4+
-- action callbacks, unconditional transitions, event flags, and
5+
-- the "exit" state.
6+
--
7+
-- Run with: ../../bin/<arch>/testLuaShell st_monitor.lua
8+
9+
dbLoadDatabase("../../dbd/testLuaShell.dbd")
10+
testLuaShell_registerRecordDeviceDriver(pdbbase)
11+
12+
luaAddModule("../..")
13+
14+
luaLoadFile("monitor.lua", {P="lua:"})
15+
16+
iocInit()
17+
18+
epics = require("epics")
19+
event = require("event")
20+
osi = require("osi")
21+
22+
-- Wait for sequencer to start
23+
osi.sleep(0.5)
24+
25+
--
26+
--
27+
-- === Drive voltage above the high threshold (8.0) ===
28+
-- Expected: Monitor prints "ALARM" and alarm PV changes to 1
29+
30+
epics.put("lua:voltage", 10.0)
31+
osi.sleep(0.5)
32+
-- Expected: 1
33+
epics.get("lua:alarm")
34+
35+
--
36+
--
37+
-- === Drive voltage below the low threshold (3.0) ===
38+
-- Expected: Monitor prints "OK" and alarm PV changes to 0
39+
40+
epics.put("lua:voltage", 1.0)
41+
osi.sleep(0.5)
42+
-- Expected: 0
43+
epics.get("lua:alarm")
44+
45+
--
46+
--
47+
-- === Voltage in the hysteresis band (between 3.0 and 8.0) ===
48+
-- Expected: alarm stays in its current state (0 = OK)
49+
50+
epics.put("lua:voltage", 5.0)
51+
osi.sleep(0.5)
52+
-- Expected: 0 (still OK, hasn't crossed HI threshold)
53+
epics.get("lua:alarm")
54+
55+
--
56+
--
57+
-- === Drive above threshold again ===
58+
59+
epics.put("lua:voltage", 9.0)
60+
osi.sleep(0.5)
61+
-- Expected: 1
62+
epics.get("lua:alarm")
63+
64+
--
65+
--
66+
-- === Stop the monitor via named event flag ===
67+
68+
event.flag("stopMonitor"):set()
69+
osi.sleep(0.5)

0 commit comments

Comments
 (0)