/******************************************************************************* * Copyright (c) 2010 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.epics.archiverappliance.engine.model; import java.sql.Timestamp; import org.apache.log4j.Logger; import org.epics.archiverappliance.Writer; import org.epics.archiverappliance.config.ArchDBRTypes; import org.epics.archiverappliance.config.ConfigService; import org.epics.archiverappliance.data.DBRTimeEvent; /** * An ArchiveChannel that stores each incoming value that differs from the * previous sample by some 'delta'. * * @author Kay Kasemir */ @SuppressWarnings("nls") public class DeltaArchiveChannel extends ArchiveChannel { private static final Logger logger = Logger.getLogger(DeltaArchiveChannel.class); /** 'Delta' for value change */ final private double delta; /** Estimated period of change in seconds */ final private double period_estimate; /** * @param name * Name of the channel (PV) * @param writer   * @param enablement * How channel affects its groups * @param buffer_capacity * Size of sample buffer * @param last_timeestamp   * @param period_estimate * Estimated change period [seconds] * @param delta * Value changes ≥ this value will be stored * @param configservice ConfigService * @param archdbrtype ArchDBRTypeS * @param controlPVname   * @param commandThreadID   * @param usePVAccess   * @throws Exception * On error in PV setup */ public DeltaArchiveChannel(final String name, final Writer writer, final Enablement enablement, final int buffer_capacity, final Timestamp last_timeestamp, final double period_estimate, final double delta, final ConfigService configservice, final ArchDBRTypes archdbrtype, final String controlPVname, final int commandThreadID, final boolean usePVAccess) throws Exception { super(name, writer, enablement, buffer_capacity, last_timeestamp, configservice, archdbrtype, controlPVname, commandThreadID, usePVAccess); this.delta = delta; this.period_estimate = period_estimate; } @Override public String getMechanism() { return "on delta [" + PeriodFormat.formatSeconds(period_estimate) + ", " + delta + "]"; } /** Attempt to add each new value to the buffer. */ @Override protected boolean handleNewValue(final DBRTimeEvent timeevent) { try { if (super.handleNewValue(timeevent)) { // Activator.getLogger().log(Level.FINE, // "Wrote first sample for {0}: {1}", new Object[] { getName(), // value }); return true; } } catch (Exception e1) { // logger.error("Exception handing new value", e1); } if (isEnabled() && isBeyondDelta(timeevent)) { // Activator.getLogger().log(Level.FINE, // "Wrote sample for {0}: {1}", new Object[] { getName(), value }); try { addValueToBuffer(timeevent); } catch (Exception e) { // logger.error("exception in handleNewValue", e); } return true; } return false; } /** * @param timeevent * DBRTimeEvent * @return <code>true</code> if this value is beyond 'delta' from the last * value */ private boolean isBeyondDelta(final DBRTimeEvent timeevent) { final double number = ValueUtil.getDouble(timeevent.getSampleValue()); // Archive NaN, Inf'ty if (Double.isNaN(number)) return true; double previous; synchronized (this) { // Anything to compare against? if (lastDBRTimeEvent == null) return true; previous = ValueUtil.getDouble(timeevent.getSampleValue()); } return Math.abs(previous - number) >= delta; } }