
com.cosylab.epics.caj.cas.util.examples.CounterProcessVariable Maven / Gradle / Ivy
Go to download
JCA is an EPICS Channel Access library for Java. For more information concerning EPICS or Channel Access please refer to the <a href="http://www.aps.anl.gov/epics">EPICS Web pages</a> or read the <a href="http://www.aps.anl.gov/epics/base/R3-14/8-docs/CAref.html">Channel Access manual (3.14)</a>.
<p>This module also includes CAJ, A 100% pure Java implementation of the EPICS Channel Access library.</p>
/*
* Copyright (c) 2004 by Cosylab
*
* The full license specifying the redistribution, modification, usage and other
* rights and obligations is included with the distribution of this project in
* the file "LICENSE-CAJ". If the license is not included visit Cosylab web site,
* .
*
* THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND, NOT EVEN THE
* IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, ASSUMES
* _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE RESULTING FROM THE USE, MODIFICATION,
* OR REDISTRIBUTION OF THIS SOFTWARE.
*/
package com.cosylab.epics.caj.cas.util.examples;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.cosylab.epics.caj.cas.handlers.AbstractCASResponseHandler;
import com.cosylab.epics.caj.cas.util.NumericProcessVariable;
import gov.aps.jca.CAException;
import gov.aps.jca.CAStatus;
import gov.aps.jca.Monitor;
import gov.aps.jca.cas.ProcessVariableEventCallback;
import gov.aps.jca.cas.ProcessVariableReadCallback;
import gov.aps.jca.cas.ProcessVariableWriteCallback;
import gov.aps.jca.dbr.DBR;
import gov.aps.jca.dbr.DBRType;
import gov.aps.jca.dbr.DBR_Int;
import gov.aps.jca.dbr.DBR_TIME_Int;
import gov.aps.jca.dbr.GR;
import gov.aps.jca.dbr.Severity;
import gov.aps.jca.dbr.Status;
import gov.aps.jca.dbr.TIME;
import gov.aps.jca.dbr.TimeStamp;
/**
* Example implementation of process variable - counter.
* Counter starts counting at startValue
incrementing by incrementValue
every periodInMS
milliseconds.
* When counter value riches envValue
counter is reset to startValue
.
* Implementation also triggers alarms (seting status and severity) regarding to set warning and alarm limits.
* @author msekoranja
*/
public class CounterProcessVariable extends NumericProcessVariable implements Runnable {
// Get Logger
private static final Logger logger = Logger.getLogger(CounterProcessVariable.class.getName());
/**
* Counter start value.
*/
protected int startValue;
/**
* Counter end (stop) value.
*/
protected int endValue;
/**
* Increment value (counter stepping).
*/
protected int incrementValue;
/**
* Period between value increments.
*/
protected int periodInMS;
/**
* Lower warning value.
*/
protected Number lowerWarningValue;
/**
* Upper warning value.
*/
protected Number upperWarningValue;
/**
* Lower alarm value.
*/
protected Number lowerAlarmValue;
/**
* Upper alarm value.
*/
protected Number upperAlarmValue;
/**
* Lower display value (= start value).
*/
protected Number lowerDisplayValue;
/**
* Upper display value (= end value).
*/
protected Number upperDisplayValue;
/**
* Lower control value (= start value).
*/
protected Number lowerControlValue;
/**
* Upper control value (= end value).
*/
protected Number upperControlValue;
/**
* Counter value.
*/
protected int value;
/**
* Timestamp of last value change.
*/
protected TimeStamp timestamp;
/**
* Value status.
*/
protected Status status;
/**
* Value status severity.
*/
protected Severity severity;
/**
* Construct a counter PV instance.
* @param name PV name.
* @param eventCallback event callback, where to report value change events.
* @param startValue counter start value, where to start counting.
* @param endValue counter end value, where to stop counting.
* @param incrementValue counter increment value, count steps.
* @param periodInMS period in milliseconds between two increments.
* @param lowerWarningValue lower warning limit value.
* @param upperWarningValue upper warning limit value.
* @param lowerAlarmValue lower alarm limit value.
* @param upperAlarmValue upper alarm limit value.
*/
public CounterProcessVariable(String name,
ProcessVariableEventCallback eventCallback,
int startValue, int endValue, int incrementValue, int periodInMS,
int lowerWarningValue, int upperWarningValue,
int lowerAlarmValue, int upperAlarmValue) {
super(name, eventCallback);
this.startValue = startValue;
this.endValue = endValue;
this.incrementValue = incrementValue;
this.periodInMS = periodInMS;
this.lowerWarningValue = new Integer(lowerWarningValue);
this.upperWarningValue = new Integer(upperWarningValue);
this.lowerAlarmValue = new Integer(lowerAlarmValue);
this.upperAlarmValue = new Integer(upperAlarmValue);
this.lowerControlValue = new Integer(startValue);
this.upperControlValue = new Integer(endValue);
this.lowerDisplayValue = lowerControlValue;
this.upperDisplayValue = upperControlValue;
initialize();
}
/**
* Initialize PV.
* Sets initial counter state and spawns a counter thread.
*/
protected void initialize()
{
value = startValue;
timestamp = new TimeStamp();
checkForAlarms();
Thread thread = new Thread(this, getName() + " counter");
thread.setDaemon(true);
thread.start();
}
/**
* Checks for alarms (sets status
and severity
).
*/
protected void checkForAlarms() {
severity = Severity.MINOR_ALARM;
if (value >= upperAlarmValue.intValue())
status = Status.HIHI_ALARM;
else if (value >= upperWarningValue.intValue())
status = Status.HIGH_ALARM;
else if (value <= lowerAlarmValue.intValue())
status = Status.LOLO_ALARM;
else if (value <= lowerWarningValue.intValue())
status = Status.LOW_ALARM;
else
{
status = Status.NO_ALARM;
severity = Severity.NO_ALARM;
}
}
/**
* Return DBRType.INT
type as native type.
* @see gov.aps.jca.cas.ProcessVariable#getType()
*/
public DBRType getType() {
return DBRType.INT;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getLowerAlarmLimit()
*/
public Number getLowerAlarmLimit() {
return lowerAlarmValue;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getLowerCtrlLimit()
*/
public Number getLowerCtrlLimit() {
return lowerControlValue;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getLowerDispLimit()
*/
public Number getLowerDispLimit() {
return lowerDisplayValue;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getLowerWarningLimit()
*/
public Number getLowerWarningLimit() {
return lowerWarningValue;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getUnits()
*/
public String getUnits() {
return GR.EMPTYUNIT;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getUpperAlarmLimit()
*/
public Number getUpperAlarmLimit() {
return upperAlarmValue;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getUpperCtrlLimit()
*/
public Number getUpperCtrlLimit() {
return upperControlValue;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getUpperDispLimit()
*/
public Number getUpperDispLimit() {
return upperDisplayValue;
}
/**
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#getUpperWarningLimit()
*/
public Number getUpperWarningLimit() {
return upperWarningValue;
}
/**
* Read value.
* DBR is already filled-in by com.cosylab.epics.caj.cas.util.NumericProcessVariable#read()
method.
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#readValue(gov.aps.jca.dbr.DBR, gov.aps.jca.cas.ProcessVariableReadCallback)
*/
protected synchronized CAStatus readValue(DBR value,
ProcessVariableReadCallback asyncReadCallback) throws CAException {
// it is always at least DBR_TIME_Int DBR
DBR_TIME_Int timeDBR = (DBR_TIME_Int)value;
// set status and time
fillInStatusAndTime(timeDBR);
// set scalar value
timeDBR.getIntValue()[0] = this.value;
// return read completion status
return CAStatus.NORMAL;
}
/**
* Fill-in status and time to DBR.
* @param timeDBR DBR to fill-in.
*/
protected void fillInStatusAndTime(TIME timeDBR)
{
// set status and severity
timeDBR.setStatus(status);
timeDBR.setSeverity(severity);
// set timestamp
timeDBR.setTimeStamp(timestamp);
}
/**
* Write value.
* @see com.cosylab.epics.caj.cas.util.NumericProcessVariable#writeValue(gov.aps.jca.dbr.DBR, gov.aps.jca.cas.ProcessVariableWriteCallback)
*/
protected synchronized CAStatus writeValue(DBR value,
ProcessVariableWriteCallback asyncWriteCallback) throws CAException {
// it is always at least DBR_Int DBR
DBR_Int intDBR = (DBR_Int)value;
// check value
int val = intDBR.getIntValue()[0];
if (val < startValue || val > endValue)
return CAStatus.PUTFAIL;
// set value, status and alarm
this.value = val;
timestamp = new TimeStamp();
checkForAlarms();
// post event if there is an interest
if (interest)
{
// set event mask
int mask = Monitor.VALUE | Monitor.LOG;
if (status != Status.NO_ALARM)
mask |= Monitor.ALARM;
// create and fill-in DBR
DBR monitorDBR = AbstractCASResponseHandler.createDBRforReading(this);
((DBR_Int)monitorDBR).getIntValue()[0] = this.value;
fillInDBR(monitorDBR);
fillInStatusAndTime((TIME)monitorDBR);
// port event
eventCallback.postEvent(mask, monitorDBR);
}
return CAStatus.NORMAL;
}
/**
* Couting (external trigger) is done in this separate thread.
* @see java.lang.Runnable#run()
*/
public void run() {
// initialize DBR for writting
final DBR_Int valueHolder = new DBR_Int(1);
final int[] valueArray = valueHolder.getIntValue();
while (!Thread.interrupted())
{
try {
Thread.sleep(periodInMS);
} catch (InterruptedException e) {
break;
}
synchronized (this)
{
// calculate new value
int newValue = value + incrementValue;
if (newValue > endValue)
newValue = startValue;
// set value to DBR
valueArray[0] = newValue;
// write to PV
try {
write(valueHolder, null);
} catch (CAException e) {
logger.log(Level.SEVERE, "", e);
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy