diff --git a/core/formula/src/main/java/org/csstudio/apputil/formula/enums/IndexOfFunction.java b/core/formula/src/main/java/org/csstudio/apputil/formula/enums/IndexOfFunction.java index e0a3e00a79..c7cccf4498 100644 --- a/core/formula/src/main/java/org/csstudio/apputil/formula/enums/IndexOfFunction.java +++ b/core/formula/src/main/java/org/csstudio/apputil/formula/enums/IndexOfFunction.java @@ -1,8 +1,10 @@ package org.csstudio.apputil.formula.enums; import org.csstudio.apputil.formula.spi.FormulaFunction; +import org.epics.vtype.Alarm; import org.epics.vtype.Display; import org.epics.vtype.Time; +import org.epics.vtype.VDouble; import org.epics.vtype.VEnum; import org.epics.vtype.VInt; import org.epics.vtype.VType; @@ -52,6 +54,18 @@ public VType compute(VType... args) throws Exception Display.none()); } else { + if (args[0] instanceof VDouble) + { + final VDouble v = (VDouble)args[0]; + if (v.getValue().isNaN() && + (v.getAlarm() == Alarm.none() || v.getAlarm() == Alarm.disconnected())) + { + // Connection has not yet been made to the PV + // so don't throw an exception yet + return args[0]; + } + } + // Otherwise throw exception throw new Exception("Function " + getName() + " requires an enum argument " + Arrays.toString(args)); } diff --git a/core/formula/src/test/java/org/csstudio/apputil/formula/FormulaUnitTest.java b/core/formula/src/test/java/org/csstudio/apputil/formula/FormulaUnitTest.java index 34fadd7872..5ce412dd28 100644 --- a/core/formula/src/test/java/org/csstudio/apputil/formula/FormulaUnitTest.java +++ b/core/formula/src/test/java/org/csstudio/apputil/formula/FormulaUnitTest.java @@ -7,11 +7,16 @@ ******************************************************************************/ package org.csstudio.apputil.formula; +import org.csstudio.apputil.formula.enums.IndexOfFunction; + import org.epics.vtype.Alarm; import org.epics.vtype.AlarmSeverity; import org.epics.vtype.AlarmStatus; +import org.epics.vtype.Display; import org.epics.vtype.Time; +import org.epics.vtype.VDouble; import org.epics.vtype.VString; +import org.epics.vtype.VType; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.phoebus.core.vtypes.VTypeHelper; @@ -293,6 +298,31 @@ public void testSPI() throws Exception { } } + @Test + public void testEnums() throws Exception { + Formula f = new Formula("enumOf(1, arrayOf(1,2,3), arrayOf(\"a\",\"b\",\"c\"))"); + assertEquals("b", VTypeHelper.toString(f.eval())); + + f = new Formula("indexOf(enumOf(1, arrayOf(1,2,3), arrayOf(\"a\",\"b\",\"c\")))"); + assertEquals(1, VTypeHelper.toDouble(f.eval())); + + // Exception is thrown + IndexOfFunction indexFunc = new IndexOfFunction(); + try { + indexFunc.compute(VDouble.of(3.2, Alarm.none(), Time.now(), Display.none())); + } catch (Exception ex) { + assertTrue(ex.getMessage().contains("Function indexOf requires an enum argument")); + } + + // Disconnected or not set values should not throw an exception + // and should return the same input. + VType input = VDouble.of(Double.NaN, Alarm.none(), Time.now(), Display.none()); + assertEquals(indexFunc.compute(input), input); + + input = VDouble.of(Double.NaN, Alarm.disconnected(), Time.now(), Display.none()); + assertEquals(indexFunc.compute(input), input); + } + @Test public void testVariableDetermination() throws Exception { Formula f = new Formula("RFQ_Vac:Pump2:Pressure < 10", true);