
com.cosylab.epics.caj.cas.util.examples.CounterProcessVariable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jca Show documentation
Show all versions of jca Show documentation
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