Common Mistakes
- Calculated Input with formula that returns Nothing in the code path.
- No null check when referencing previous values - previous value is always null during first calculation. This need to be handled in code explicitly if the formula involves previous values.
- Source input not logging - Calculated input is using the logging frequency of the inputs it references to align the data points. Currently it will not work if one of the referenced inputs is set to not logging.
Examples
Cumulative total of multiple inputs from different sites
Return Outposts.SiteA.Inputs.Counter1.Value + Outposts.SiteB.Inputs.Counter1.Value + Outposts.SiteC.Inputs.Counter1.Value
Cumulative total of pulse Counter 1 input
Return Inputs.Counter 1.Value + If(PreviousValue.HasValue, PreviousValue.Value, 0)
Cumulative total of Counter 1 input over 24 hours from 9AM and resets daily at 9AM
Dim myInput As Input = Inputs.Counter 1
Dim preDate As Date? = myInput.PreviousLogTime
Dim curDate As Date = myInput.LogTime
If curDate.Hour = 9 AndAlso preDate.HasValue Andalso (preDate.Value.Hour <> 9 OrElse preDate.Value.Year <> curDate.Year OrElse preDate.Value.Month <> curDate.Month OrElse preDate.Value.Day <> curDate.Day) Then
'Reset accumulated data at 9 AM every day
Return myInput.Value
Else
Return myInput.Value + If(PreviousValue.HasValue, PreviousValue.Value, 0)
End If
Filter data from 9AM to 5:45PM only; show no data outside this period
Dim myInput As System.DateTime = Inputs.Counter 1.LogTime
If (myInput.Hour >= 9 And myInput.Hour <= 17.75)
Return Inputs.Counter 1.Value
End if
Return Nothing
Cumulative total of Counter 1 input over the month and resets monthly
Dim myInput As Input = Inputs.Counter 1
Dim preDate As Date? = myInput.PreviousLogTime
Dim curDate As Date = myInput.LogTime
If curDate.Day = 1 AndAlso preDate.HasValue Andalso (preDate.Value.Day <> 1 OrElse preDate.Value.Month <> curDate.Month OrElse preDate.Value.Year <> curDate.Year ) Then
'Reset accumulated data at 1st every month
Return myInput.Value
Else
Return myInput.Value + If(PreviousValue.HasValue, PreviousValue.Value, 0)
End If
Filter data from 9AM to 5:45PM only; show no data outside this period
Dim myInput As System.DateTime = Inputs.Counter 1.LogTime
If (myInput.Hour >= 9 And myInput.Hour <= 17.75)
Return Inputs.Counter 1.Value
End if
Return Nothing
Cumulative total of Counter 1 input over the year and resets yearly
Dim myInput As Input = Inputs.Counter 1
Dim preDate As Date? = myInput.PreviousLogTime
Dim curDate As Date = myInput.LogTime
If curDate.Month = 1 AndAlso preDate.HasValue Andalso preDate.Value.Month <> 1 AndAlso preDate.Value.Year <> curDate.Year Then
'Reset accumulated data at turn of the year
Return myInput.Value
Else
Return myInput.Value + If(PreviousValue.HasValue, PreviousValue.Value, 0)
End If
Create Flow Rate (unit/s)
If Inputs.Flow.PreviousValue.HasValue Then
Return (Inputs.Flow.Value - Inputs.Flow.PreviousValue) / Inputs.Flow.LogTime.Subtract(Inputs.Flow.PreviousLogTime).TotalSeconds
End If
Return 0
Create Flow Rate (unit/min)
If Inputs.Flow.PreviousValue.HasValue Then
Return (Inputs.Flow.Value - Inputs.Flow.PreviousValue) / Inputs.Flow.LogTime.Subtract(Inputs.Flow.PreviousLogTime).TotalMinutes
End If
Return 0
Remove steps and spikes from a series
'Remove spikes and step jumps that are bigger than a specified fraction of the input.
Dim RAW As Input = Inputs.Air Pressure
'Linear scaling of RAW input
Dim Scale As Double = 10
'Fraction of RAW input at which step would be removed
Dim StepSizeCutoff As Double = 0.9
Dim RAW_v As Double = RAW.Value * Scale
If PreviousValue.HasValue AndAlso RAW.Previousvalue.HasValue Then
Dim RAW_pv As Double = RAW.Previousvalue * Scale
'Extract previous adjusted RAW value from CI result
Dim pav As Double = PreviousValue
If (RAW_v < pav * StepSizeCutoff) Or (RAW_v > pav * (2 - StepSizeCutoff)) Then
Dim diff As Double = System.Math.Abs(Decimal.Parse(RAW_v - RAW_pv))
If diff < RAW_pv * (1 - StepSizeCutoff) Then
pav = pav + (RAW_v - RAW_pv)
End If
RAW_v = pav
End If
End If
Return RAW_v
Calculate the height of a liquid using two external pressure sensor inputs (air & liquid)
'Linear offset in mm
Const Offset_mm As Double = 0
'Inputs for air and water pressures; set next constants to scale these to the correct unit of measures
Dim airPressureRaw = Inputs.MAC - BaroTROLL (0-30psi)
Dim liquidPressureRaw = Inputs.MAS - LevelTROLL 400 (0-30psi)
'Factors to convert raw pressure values to Pascal (Pa/mmHg = 133.322; Pa/H2O = 9.80665; Pa/PSI = 6894.76; Pa/Atm = 101325)
Const airPressureRawToPa As Double = 133.322
Const liquidPressureRawToPa As Double = 6894.76
'The pressure offset of the sensors in Pascal; if the reported value is lower than it should be then the offset is negative
Const airPressureOffset_Pa As Double = -101325
Const liquidPressureOffset_Pa As Double = 0
'Factor to convert height in mm to the desired unit (ft/mm = 0.00328084; in/mm = 0.0393701)
Const outputScaling_mmToUnit As Double = 0.00328084
'Density of liquid being measured as kg/m^3 (water = 998)
Const density As Double = 998
'Convert everything to Pascal
Dim airPressure_Pa as Double = airPressureRaw.Value * airPressureRawToPa
Dim liquidPressure_Pa as Double = liquidPressureRaw.Value * liquidPressureRawToPa
'Liquid height = (pressure of liquid - pressure of air) / (density * acceleration of gravity) ; [Pa / (kg/m^3 * m/s^2) = m]; Pa = kg/m.s^2
Dim liquidHeight_mm As Double = ((((liquidPressure_Pa - liquidPressureOffset_Pa) - (airPressure_Pa - airPressureOffset_Pa)) / (density * 9.80665))) * 1000 + Offset_mm
Return liquidHeight_mm * outputScaling_mmToUnit