package org.yamcs.parameter;
import java.util.List;
import java.util.Optional;
import org.yamcs.protobuf.Mdb.AlarmLevelType;
import org.yamcs.protobuf.Mdb.AlarmRange;
import org.yamcs.protobuf.Pvalue.AcquisitionStatus;
import org.yamcs.protobuf.Pvalue.MonitoringResult;
import org.yamcs.protobuf.Pvalue.RangeCondition;
import org.yamcs.protobuf.Yamcs.NamedObjectId;
import org.yamcs.utils.TimeEncoding;
import org.yamcs.utils.ValueUtility;
import org.yamcs.xtce.FloatRange;
import org.yamcs.xtce.Parameter;
import org.yamcs.xtce.ParameterEntry;
/**
* Holds the value of a parameter
*
*/
public class ParameterValue {
//the definition of the parameter may be null if we do not have a reference to an XtceDB object
// this could happen if the ParameterValue is extracted from the ParameterArchive
private Parameter def;
private final String paramFqn;
ParameterEntry entry;
int absoluteBitOffset, bitSize;
private Value rawValue;
private Value engValue;
private long acquisitionTime = TimeEncoding.INVALID_INSTANT;
private long generationTime;
private long expirationTime = TimeEncoding.INVALID_INSTANT;
//use this singleton as a default status
ParameterStatus status = ParameterStatus.NOMINAL;
/**
* Creates a parameter value for a parameter which has critical or warning range associated
* @param def the parameter definition
*/
public ParameterValue(Parameter def) {
this.def = def;
paramFqn = def.getQualifiedName();
}
public ParameterValue(String fqn) {
this.def = null;
this.paramFqn = fqn;
}
public int getAbsoluteBitOffset() {
return absoluteBitOffset;
}
public void setAbsoluteBitOffset(int absoluteBitOffset) {
this.absoluteBitOffset = absoluteBitOffset;
}
public int getBitSize() {
return bitSize;
}
public void setBitSize(int bitSize) {
this.bitSize = bitSize;
}
public void setParameterEntry(ParameterEntry entry) {
this.entry = entry;
}
public ParameterEntry getParameterEntry() {
return entry;
}
public void setAcquisitionTime(long instant) {
acquisitionTime=instant;
}
public void setGenerationTime(long instant) {
generationTime=instant;
}
public Value getEngValue() {
return engValue;
}
public Value getRawValue() {
return rawValue;
}
public void setParameter(Parameter p) {
this.def = p;
}
/**
* Retrieve the parameter definition for this parameter value
* @return parameter definition
*/
public Parameter getParameter() {
return def;
}
public String getParameterQualifiedNamed() {
return paramFqn;
}
public long getGenerationTime() {
return generationTime;
}
public long getAcquisitionTime() {
return acquisitionTime;
}
public void setRawValue(Value rv) {
this.rawValue=rv;
}
public void setRawValue(byte[] b) {
rawValue = new BinaryValue(b);
}
public void setRawValue(float f) {
rawValue = new FloatValue(f);
}
public void setRawValue(double d) {
rawValue = new DoubleValue(d);
}
public void setRawValue(boolean b) {
rawValue = new BooleanValue(b);
}
public void setRawValue(String s) {
rawValue = new StringValue(s);
}
public void setRawSignedInteger(int x) {
rawValue = new SInt32Value(x);
}
public void setRawUnsignedInteger(int x) {
rawValue = new UInt32Value(x);
}
public void setRawSignedLong(long x) {
rawValue = new SInt64Value(x);
}
public void setRawUnsignedLong(long x) {
rawValue = new UInt64Value(x);
}
public void setStringValue(String s) {
engValue = new StringValue(s);
}
public void setBinaryValue(byte[] v) {
engValue = new BinaryValue(v);
}
public void setBooleanValue(boolean b) {
engValue = new BooleanValue(b);
}
public void setDoubleValue(double v) {
engValue = new DoubleValue(v);
}
public void setFloatValue(float v) {
engValue = new FloatValue(v);
}
public void setSignedIntegerValue(int v) {
engValue = new SInt32Value(v);
}
public void setUnsignedIntegerValue(int v) {
engValue = new UInt32Value(v);
}
public void setSignedLongValue(long v) {
engValue = new SInt64Value(v);
}
public void setUnsignedLongValue(long v) {
engValue = new UInt64Value(v);
}
public void setEngineeringValue(Value ev) {
this.engValue=ev;
}
public void setExpirationTime(long et) {
this.expirationTime = et;
}
public long getExpirationTime() {
return expirationTime;
}
public void setEngValue(Value engValue) {
this.engValue = engValue;
}
// *********** parameter status
private void changeNominalStatus() {
if(status == ParameterStatus.NOMINAL) {
status = new ParameterStatus();
}
}
public void setWatchRange(FloatRange range) {
changeNominalStatus();
status.setWatchRange(range);
}
public void setWarningRange(FloatRange range) {
changeNominalStatus();
status.setWarningRange(range);
}
public void setDistressRange(FloatRange range) {
changeNominalStatus();
status.setDistressRange(range);
}
public void setCriticalRange(FloatRange range) {
changeNominalStatus();
status.setCriticalRange(range);
}
public void setSevereRange(FloatRange range) {
changeNominalStatus();
status.setSevereRange(range);
}
public void setMonitoringResult(MonitoringResult m) {
changeNominalStatus();
status.setMonitoringResult(m);
}
public void setDeltaMonitoringResult(MonitoringResult m) {
changeNominalStatus();
status.setDeltaMonitoringResult(m);
}
public void setRangeCondition(RangeCondition rangeCondition) {
changeNominalStatus();
status.setRangeCondition(rangeCondition);
}
public void setProcessingStatus(boolean p) {
if(status.getProcessingStatus()!=p) {
changeNominalStatus();
}
status.setProcessingStatus(p);
}
public void setAcquisitionStatus(AcquisitionStatus a) {
if(status.getAcquisitionStatus()!=a) {
changeNominalStatus();
}
status.setAcquisitionStatus(a);
}
public FloatRange getDistressRange() {
return status.getDistressRange();
}
public FloatRange getWatchRange() {
return status.getWatchRange();
}
public FloatRange getCriticalRange() {
return status.getCriticalRange();
}
public FloatRange getWarningRange() {
return status.getWarningRange();
}
public FloatRange getSevereRange() {
return status.getSevereRange();
}
public MonitoringResult getMonitoringResult() {
return status.getMonitoringResult();
}
public RangeCondition getRangeCondition() {
return status.getRangeCondition();
}
public AcquisitionStatus getAcquisitionStatus() {
return status.getAcquisitionStatus();
}
public boolean getProcessingStatus() {
return status.getProcessingStatus();
}
public MonitoringResult getDeltaMonitoringResult() {
return status.getDeltaMonitoringResult();
}
/**
* Convert a PV to a ProtobufPV
*
* @param id - the parameter identifier
* @param withUtc - if true - set the UTC string times
* @return the created ProtobufPV
*/
public org.yamcs.protobuf.Pvalue.ParameterValue toProtobufParameterValue(Optional<NamedObjectId> id, boolean withUtc) {
org.yamcs.protobuf.Pvalue.ParameterValue.Builder gpvb=org.yamcs.protobuf.Pvalue.ParameterValue.newBuilder()
.setAcquisitionStatus(getAcquisitionStatus())
.setGenerationTime(getGenerationTime())
.setProcessingStatus(getProcessingStatus());
if(id.isPresent()) {
gpvb.setId(id.get());
}
if(acquisitionTime!=TimeEncoding.INVALID_INSTANT) {
gpvb.setAcquisitionTime(acquisitionTime);
if(withUtc) {
gpvb.setAcquisitionTimeUTC(TimeEncoding.toString(getAcquisitionTime()));
}
}
if(engValue!=null) {
gpvb.setEngValue(ValueUtility.toGbp(engValue));
}
if(getMonitoringResult()!=null) {
gpvb.setMonitoringResult(getMonitoringResult());
}
if(getRangeCondition()!=null) {
gpvb.setRangeCondition(getRangeCondition());
}
if(withUtc) {
gpvb.setGenerationTimeUTC(TimeEncoding.toString(getGenerationTime()));
}
if(expirationTime!=TimeEncoding.INVALID_INSTANT) {
gpvb.setExpirationTime(expirationTime);
if(withUtc) {
gpvb.setExpirationTimeUTC(TimeEncoding.toString(expirationTime));
}
}
if (getWatchRange() != null) {
gpvb.addAlarmRange(toGpbAlarmRange(AlarmLevelType.WATCH, getWatchRange()));
}
if (getWarningRange() != null) {
gpvb.addAlarmRange(toGpbAlarmRange(AlarmLevelType.WARNING, getWarningRange()));
}
if (getDistressRange() != null) {
gpvb.addAlarmRange(toGpbAlarmRange(AlarmLevelType.DISTRESS, getDistressRange()));
}
if (getCriticalRange() != null) {
gpvb.addAlarmRange(toGpbAlarmRange(AlarmLevelType.CRITICAL, getCriticalRange()));
}
if (getSevereRange()!=null) {
gpvb.addAlarmRange(toGpbAlarmRange(AlarmLevelType.SEVERE, getSevereRange()));
}
if(rawValue!=null) {
gpvb.setRawValue(ValueUtility.toGbp(rawValue));
}
return gpvb.build();
}
public org.yamcs.protobuf.Pvalue.ParameterValue toGpb(NamedObjectId id) {
Optional<NamedObjectId> optionalId = Optional.ofNullable(id);
return toProtobufParameterValue(optionalId, true);
}
private static AlarmRange toGpbAlarmRange(AlarmLevelType gpbLevel, FloatRange floatRange) {
AlarmRange.Builder rangeb = AlarmRange.newBuilder();
rangeb.setLevel(gpbLevel);
if (Double.isFinite(floatRange.getMinInclusive()))
rangeb.setMinInclusive(floatRange.getMinInclusive());
if (Double.isFinite(floatRange.getMaxInclusive()))
rangeb.setMaxInclusive(floatRange.getMaxInclusive());
return rangeb.build();
}
public static ParameterValue fromGpb(String fqn, org.yamcs.protobuf.Pvalue.ParameterValue gpv) {
ParameterValue pv = new ParameterValue(fqn);
copyTo(gpv, pv);
return pv;
}
public static ParameterValue fromGpb(Parameter pdef, org.yamcs.protobuf.Pvalue.ParameterValue gpv) {
ParameterValue pv = new ParameterValue(pdef);
copyTo(gpv, pv);
return pv;
}
private static void copyTo(org.yamcs.protobuf.Pvalue.ParameterValue gpv, ParameterValue pv) {
pv.setAcquisitionStatus(gpv.getAcquisitionStatus());
pv.setEngineeringValue(ValueUtility.fromGpb(gpv.getEngValue()));
if(gpv.hasAcquisitionTime()) {
pv.setAcquisitionTime(gpv.getAcquisitionTime());
}
if(gpv.hasExpirationTime()) {
pv.setExpirationTime(gpv.getExpirationTime());
}
if(gpv.hasGenerationTime()) {
pv.setGenerationTime(gpv.getGenerationTime());
}
if(gpv.hasMonitoringResult())
pv.setMonitoringResult(gpv.getMonitoringResult());
if(gpv.hasRangeCondition())
pv.setRangeCondition(gpv.getRangeCondition());
if(gpv.hasProcessingStatus()) {
pv.setProcessingStatus(gpv.getProcessingStatus());
}
if(gpv.hasRawValue()) {
pv.setRawValue(ValueUtility.fromGpb(gpv.getRawValue()));
}
}
public void addAlarmRanges(List<AlarmRange> alarmRangeList) {
for(AlarmRange ar: alarmRangeList) {
switch(ar.getLevel()){
case WATCH:
setWatchRange(fromGbpAlarmRange(ar));
break;
case WARNING:
setWarningRange(fromGbpAlarmRange(ar));
break;
case DISTRESS:
setDistressRange(fromGbpAlarmRange(ar));
break;
case CRITICAL:
setCriticalRange(fromGbpAlarmRange(ar));
break;
case SEVERE:
setSevereRange(fromGbpAlarmRange(ar));
break;
case NORMAL: //never used
}
}
}
public boolean hasAcquisitionTime() {
return acquisitionTime != TimeEncoding.INVALID_INSTANT;
}
private FloatRange fromGbpAlarmRange(AlarmRange ar) {
double minInclusive = ar.hasMinInclusive()?ar.getMinInclusive():Double.NEGATIVE_INFINITY;
double maxInclusive = ar.hasMaxInclusive()?ar.getMaxInclusive():Double.POSITIVE_INFINITY;
return new FloatRange(minInclusive, maxInclusive);
}
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append("name: ");
if(def!=null) {
sb.append(def.getName());
} else {
sb.append(paramFqn);
}
if(rawValue!=null) {
sb.append(" rawValue: {").append(rawValue.toString()).append("}");
}
if(engValue!=null) {
sb.append(" engValue: {").append(engValue.toString()).append("}");
}
return sb.toString();
}
}