Hello!
I’m pretty confused as to why I can’t get the IVOA/IVOV fields to work as expected on a simple calcout record, could someone please help me?
The goal is to have a more robust ‘power’ status PV for use in some CS-Studio (Phoebus) pages using a combination of two PVs; a calcout to generate the state, and an mbbi to represent it. Everything I want it to do works just fine EXCEPT
that I can’t seem to get the calcout to respect the ‘InValid Output Action’ (IVOA) setting: “Set output to IVOV” where IVOV is “5”.
I’m currently just testing this with dummy PVs, but no matter what I do, the calcout just never seems to respect my IVOA/IVOV definitions. I’ve tried commenting out one of the dummy PVs that’s being used as an input, and, as seen in the
example below, I’ve tried making one of the inputs ‘INVALID’ by setting it’s .OSV to ‘INVALID’... but it isn’t working like I expected it to.
I’m running EPICS 3.15.8.
Unless I missed something, I see no issues being presented in the outputs from my IOCs ‘make distclean all’ or startup script.
The spelling I’m using is exactly the same as what I see in my /usr/lib/epics/dbd/menuIvoa.dbd.
Below, I’ve included the relevant .db/.tmpl code, comments and all, and the live output of some PVs/fields below. It’s got to be something simple that I’m missing, but I’m just not seeing it. Any help would be greatly appreciated!
Thanks so much!
-Dan
```
# ==========================================================================================
# IOC .db file defining calcout & mbbi records for PWR_LED (multi_state_led)
# (Running EPICS 3.15.8)
# ==========================================================================================
#
# SUBSTITUTION MACROS:
# file "PWR_LED.tmpl"
# { pattern {SYS, SUB, DEV, DEVPS, INST, SIG}
# {"REA", "TEST", "DH", "PSD", "DNNNN", "I"}
# }
#
# CALCOUT Logic:
# If _ON_RSTS_==1:
# mbbi := {1: 'On'}
# If ILK_RSTS==1:
# mbbi := {2: 'Interlocked'}
# If IN_USE==1 && CSET != 0:
# mbbi := {3: 'Off (CSET != 0)'}
# If _ON_RSTS_==0:
# mbbi := {0: 'Off'}
# If neither of the above conditions are met, or either of the calcout INP fields are INVALID/disconnected:
# mbbi := {4: 'Invalid'}
#
#
# LED States*:
# state[0]: value = '0', label = '', color = 'off'
# state[1]: value = '1', label = '✔', color = 'normal' # On
# state[2]: value = '2', label = '✖', color = 'major' # Interlocked
# state[3]: value = '3', label = '', color = 'off' # Border will indicate MINOR alarm (orange)
# state[4]: value = '4', label = '', color = 'gray' # Not currently possible
# state[5]: value = '5', label = '?', color = 'invalid' # Calcout has an invalid/disconnected input
#
# [*] Short labels; limited space w/ circular LED. 'color' values match those in opscodex/etc/default_config.json; see opscodex docs for how to set widget states with these values.
#
# ------------------------------------------------------------------------------------------
# CALCULATE STATE
# ------------------------------------------------------------------------------------------
record(calcout, "_$(SYS)_$(SUB):$(DEV)_$(INST):PWR_LED"){
field(DESC, "Calculates 'Power State'")
field(DTYP, "Soft Channel")
field(PINI, "YES")
field(INPA, "$(SYS)_$(SUB):$(DEVPS)_$(INST):ON_RSTS CP MS") # (bo) {0: 'Off', 1: 'On'}
field(INPB, "$(SYS)_$(SUB):$(DEV)_$(INST):IN_USE CP MS") # (bo) {0: 'Not In Use', 1: 'In Use'}
field(INPC, "$(SYS)_$(SUB):$(DEVPS)_$(INST):ILK_RSTS CP MS") # (bi) {0: 'Ok', 1: 'Interlocked'}
field(INPD, "$(SYS)_$(SUB):$(DEVPS)_$(INST):$(SIG)_CSET CP MS") # (ao) (Setpoint)
field(INPE, "$(SYS)_$(SUB):$(DEVPS)_$(INST):$(SIG)_RD CP MS") # (ai) (Readback) (only included to help capture invalid/disconnected states)
field(CALC, "A==1?1:C==1?2:(B==1 && D!=0)?3:A==0?0:5")
field(DOPT, "Use CALC") # Default
field(OOPT, "Every Time") # Default (Might change to "On Change")
field(IVOV, "5")
field(IVOA, "Set output to IVOV")
field(OUT, "$(SYS)_$(SUB):$(DEV)_$(INST):PWR_LED PP")
}
# ------------------------------------------------------------------------------------------
# STATUS PV
# ------------------------------------------------------------------------------------------
# Intended for use by multi_state_led widgets in .bob files; not initially designed for use in an alarm server.
# See comments at top-of-file for how LED States are displayed.
record(mbbi, "$(SYS)_$(SUB):$(DEV)_$(INST):PWR_LED"){
field(DESC, "Status for Power LED")
field(DTYP, "Soft Channel")
field(SCAN, "Passive")
field(INP, "_$(SYS)_$(SUB):$(DEV)_$(INST):PWR_LED") # (calcout) (including as INP allows inspection of derivation via EPICS PV Tree)
field(ZRST, "Off")
field(ONST, "On")
field(TWST, "Interlocked")
field(THST, "Off (CSET != 0)") # LED.state[3] uses same 'off' color as state[0]
field(THSV, "MINOR") # LED border will indicate 'MINOR' alarm. (Device should be turned back on, the setpoint should be zeroed, or IN_USE should be set to False)
field(FRST, "Section not In Use") # state[4] isn't possible with how the calcout above is currently written.
field(FVST, "Invalid")
}
```
# ==========================================================================================
# LIVE PV Data relating to the mbbi & calcout records created by the above .db file
# ==========================================================================================
# mbbi record to be used by multi_state_led widget
# ------------------------------------------------------------------------------------------
#NAME, READING, STATUS
REA_TEST:DH_DNNNN:PWR_LED Off
REA_TEST:DH_DNNNN:PWR_LED.RVAL 0.000
REA_TEST:DH_DNNNN:PWR_LED.INP _REA_TEST:DH_DNNNN:PWR_LED NPP NMS
REA_TEST:DH_DNNNN:PWR_LED.DTYP Soft Channel
REA_TEST:DH_DNNNN:PWR_LED.SCAN Passive
REA_TEST:DH_DNNNN:PWR_LED.ZRST Off
REA_TEST:DH_DNNNN:PWR_LED.ONST On
REA_TEST:DH_DNNNN:PWR_LED.TWST Interlocked
REA_TEST:DH_DNNNN:PWR_LED.THST Off (CSET != 0)
REA_TEST:DH_DNNNN:PWR_LED.FRST Section not In Use
REA_TEST:DH_DNNNN:PWR_LED.FVST Invalid
# ------------------------------------------------------------------------------------------
# calcout record that sets state of mbbi record
# ------------------------------------------------------------------------------------------
#NAME, READING, STATUS
_REA_TEST:DH_DNNNN:PWR_LED 0 LINK
_REA_TEST:DH_DNNNN:PWR_LED.SEVR INVALID LINK
_REA_TEST:DH_DNNNN:PWR_LED.OUT REA_TEST:DH_DNNNN:PWR_LED PP NMS LINK
_REA_TEST:DH_DNNNN:PWR_LED.DTYP Soft Channel LINK
_REA_TEST:DH_DNNNN:PWR_LED.SCAN Passive LINK
_REA_TEST:DH_DNNNN:PWR_LED.IVOA Set output to IVOV LINK
_REA_TEST:DH_DNNNN:PWR_LED.IVOV 5.000 LINK
_REA_TEST:DH_DNNNN:PWR_LED.DOPT Use CALC LINK
_REA_TEST:DH_DNNNN:PWR_LED.OOPT Every Time LINK
# INPUTS
_REA_TEST:DH_DNNNN:PWR_LED.INPA REA_TEST:PSD_DNNNN:ON_RSTS CP MS LINK
_REA_TEST:DH_DNNNN:PWR_LED.A 0.000 LINK
REA_TEST:PSD_DNNNN:ON_RSTS 0
_REA_TEST:DH_DNNNN:PWR_LED.INPB REA_TEST:DH_DNNNN:IN_USE CP MS LINK
_REA_TEST:DH_DNNNN:PWR_LED.B 1.000 LINK
REA_TEST:DH_DNNNN:IN_USE.RVAL 1.000 STATE
# * More IN_USE PV values in next section
_REA_TEST:DH_DNNNN:PWR_LED.INPC REA_TEST:PSD_DNNNN:ILK_RSTS CP MS LINK
_REA_TEST:DH_DNNNN:PWR_LED.C 0.000 LINK
REA_TEST:PSD_DNNNN:ILK_RSTS Ok
_REA_TEST:DH_DNNNN:PWR_LED.INPD REA_TEST:PSD_DNNNN:I_CSET CP MS LINK
_REA_TEST:DH_DNNNN:PWR_LED.D 0.000 LINK
REA_TEST:PSD_DNNNN:I_CSET 0
_REA_TEST:DH_DNNNN:PWR_LED.INPE REA_TEST:PSD_DNNNN:I_RD CP MS LINK
_REA_TEST:DH_DNNNN:PWR_LED.E 0.000 LINK
REA_TEST:PSD_DNNNN:I_RD 0
# CALC
_REA_TEST:DH_DNNNN:PWR_LED.CALC A==1?1:C==1?2:(B==1 && D!=0)?3:A==0?0:5 LINK
# ------------------------------------------------------------------------------------------
# bo record being used to test 'INVALID'
# ------------------------------------------------------------------------------------------
#NAME, READING, STATUS
REA_TEST:DH_DNNNN:IN_USE.RVAL 1.000 STATE
REA_TEST:DH_DNNNN:IN_USE.VAL In Use STATE
REA_TEST:DH_DNNNN:IN_USE.SEVR INVALID STATE
REA_TEST:DH_DNNNN:IN_USE.DTYP Soft Channel STATE
REA_TEST:DH_DNNNN:IN_USE.ZSV NO_ALARM STATE
REA_TEST:DH_DNNNN:IN_USE.OSV INVALID STATE
# ----------------------------------------- End of example -------------------------------------------------
+++++++++++++++++++++++++++++
Dan Crisp
FRIB @ Michigan State
SIEA HMI & IOCs
+++++++++++++++++++++++++++++