public static DataValue SlopedInterpolate(DateTime timestamp, DataValue earlyBound, DataValue lateBound)
{
try
{
// can't interpolate if no start bound.
if (StatusCode.IsBad(earlyBound.StatusCode))
{
return new DataValue(Variant.Null, StatusCodes.BadNoData, timestamp, timestamp);
}
// revert to stepped if no end bound.
if (StatusCode.IsBad(lateBound.StatusCode))
{
DataValue dataValue2 = SteppedInterpolate(timestamp, earlyBound);
if (StatusCode.IsNotBad(dataValue2.StatusCode))
{
dataValue2.StatusCode = dataValue2.StatusCode.SetCodeBits(StatusCodes.UncertainDataSubNormal);
}
return dataValue2;
}
// convert to doubles.
double earlyValue = CastToDouble(earlyBound);
double lateValue = CastToDouble(lateBound);
// do interpolation.
double range = (lateBound.SourceTimestamp - earlyBound.SourceTimestamp).TotalMilliseconds;
double slope = (lateValue - earlyValue) / range;
double calculatedValue = slope * (timestamp - earlyBound.SourceTimestamp).TotalMilliseconds + earlyValue;
// convert back to original type.
DataValue dataValue = new DataValue();
dataValue.WrappedValue = CastToOriginalType(calculatedValue, earlyBound);
dataValue.SourceTimestamp = timestamp;
dataValue.ServerTimestamp = timestamp;
dataValue.StatusCode = StatusCodes.Good;
// update status code.
if (StatusCode.IsNotGood(earlyBound.StatusCode) || StatusCode.IsNotGood(lateBound.StatusCode))
{
dataValue.StatusCode = StatusCodes.UncertainDataSubNormal;
}
dataValue.StatusCode = dataValue.StatusCode.SetAggregateBits(AggregateBits.Interpolated);
return dataValue;
}
// exception occurs on data conversion errors.
catch (Exception)
{
return new DataValue(Variant.Null, StatusCodes.BadTypeMismatch, timestamp, timestamp);
}
}