diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/FormulaItem.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/FormulaItem.java index fdc3404ed5..2ee6b747e8 100644 --- a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/FormulaItem.java +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/FormulaItem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010-2019 Oak Ridge National Laboratory. + * Copyright (c) 2010-2022 Oak Ridge National Laboratory. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -75,7 +75,7 @@ public class FormulaItem extends ModelItem /** Samples of the formula, computed from inputs. * Access must lock samples */ - private final PlotSampleArray samples = new PlotSampleArray(); + private final FormulaSamples samples = new FormulaSamples(); /** Initialize formula * @param name Name of the Formula item @@ -285,6 +285,7 @@ else if (org.phoebus.core.vtypes.VTypeHelper.getTimestamp(values[i]).compareTo(t { logger.log(Level.WARNING, "Error computing " + this, ex); } + // Update PlotSamples samples.set(result); } diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/FormulaSamples.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/FormulaSamples.java new file mode 100644 index 0000000000..48a310e2a4 --- /dev/null +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/FormulaSamples.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2022 Oak Ridge National Laboratory. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + ******************************************************************************/ +package org.csstudio.trends.databrowser3.model; + +import java.time.Instant; + +import org.epics.vtype.AlarmSeverity; +import org.phoebus.archive.vtype.VTypeHelper; + +/** Samples of a {@link FormulaItem}. + + *

If the last sample is valid, it's + * extended to 'now' assuming no new data means + * that the last value is still valid. + * + * @author Kay Kasemir + */ +public class FormulaSamples extends PlotSampleArray +{ + /** @return Sample count, includes the last sample extended to 'now' */ + @Override + public int size() + { + final int raw = super.size(); + if (raw <= 0) + return raw; + final PlotSample last = get(raw-1); + if (org.phoebus.core.vtypes.VTypeHelper.getSeverity(last.getVType()) == AlarmSeverity.UNDEFINED) + return raw; + // Last sample is valid, so it should still apply 'now' + return raw+1; + } + + /** @param index 0... size()-1 + * @return Sample from historic or live sample subsection + */ + @Override + public PlotSample get(final int index) + { + final int raw_count = super.size(); + if (index < raw_count) + return super.get(index); + // Last sample is valid, so it should still apply 'now' + final PlotSample sample = super.get(raw_count-1); + if (Instant.now().compareTo(sample.getPosition()) < 0) + return sample; + else + return new PlotSample(sample.getSource(), VTypeHelper.transformTimestampToNow(sample.getVType())); + } +} diff --git a/core/pv/src/test/java/org/phoebus/pv/FormulaTest.java b/core/pv/src/test/java/org/phoebus/pv/FormulaTest.java index 9e8ed5334d..493f9c50fb 100644 --- a/core/pv/src/test/java/org/phoebus/pv/FormulaTest.java +++ b/core/pv/src/test/java/org/phoebus/pv/FormulaTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020-2021 Oak Ridge National Laboratory. + * Copyright (c) 2020-2022 Oak Ridge National Laboratory. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -223,4 +223,44 @@ public void raceDemo() throws Exception // With plain but real PV, often get the initial value right away. assertEquals(2, updates.get()); } + + @Test + public void testUpdatingVsConstant() throws Exception + { + // Formula with input that changes + { + final PV pv = PVPool.getPV("=`sim://sine`"); + final CountDownLatch updates = new CountDownLatch(1); + final Disposable sub = pv.onValueEvent().subscribe(value -> + { + System.out.println(pv.getName() + " = " + value); + if (! PV.isDisconnected(value)) + updates.countDown(); + }); + + final boolean got_value = updates.await(5, TimeUnit.SECONDS); + sub.dispose(); + PVPool.releasePV(pv); + + assertTrue(got_value); + } + + // Try again with local PV that does not change + { + final PV pv = PVPool.getPV("=`loc://constant(42)`"); + final CountDownLatch updates = new CountDownLatch(1); + final Disposable sub = pv.onValueEvent().subscribe(value -> + { + System.out.println(pv.getName() + " = " + value); + if (! PV.isDisconnected(value)) + updates.countDown(); + }); + + final boolean got_value = updates.await(5, TimeUnit.SECONDS); + sub.dispose(); + PVPool.releasePV(pv); + + assertTrue(got_value); + } + } }