Calculation Server
The Calculation Server, or Calc Server, is a useful tool for adding additional context to your historical tag data. System administrators use the the Calc Server to create new calculated tags that are derived from a series of expressions.
These expressions can be created using various tag values from both the historical archive or from Virtual Views, as well as use any metadata associated with those tag records. In addition to basic NCalc functions, OPC Foundation aggregates as well as custom Canary functions are provided.
Based on the configuration of the calculated tag, new calculated values can be scheduled to occur periodically (e.g., every 30 seconds, every 4 hours, once per day, etc.) or when one or more tags contained within the expression(s) experience a value change.
Once a calculated tag has been defined, it can then be written to the Canary Historian, either as a single tag or as part of an asset type. When applied to an asset type, all associated asset instances will receive the new calculated tag.
The Calculation Server writes tags to the Historian using the Sender/Receiver service, thus following the same data flow as tags that are being logged using Canary Data Collectors.
Additionally, the tag may be backfilled using the existing historical records in the Canary Historian. The action of backfilling provides immediate validation of the calculation and has proven to be very useful.
Examples of Calculated Tags
There are many different ways you can use calculated tags and many types of calculations. Here are a few common calculation types.
Single tag transformations
Completes a data transformation of a single tag value. For instance, converting a temperature from Celsius to Fahrenheit.
Multiple tag expressions
Using data from more than one tag to create a new tag value; such as using two pressure tags to calculate an average pressure.
Conditional statements
Creates an output based on the condition of another tag or tag group using logic statements. This could be as simple as 'If the line is running and temperature is less than 212, output a FALSE, otherwise output TRUE'. Multiple nested logic statements may be used, as may other tag transformations and/or calculations.
Statistical calculations
Multiple functions are provided that allow calculations to be made that output maximums, minimums, means, standard deviations, variances, and other standard statistical calculations. These calculations can be run over specific time frames and have many configurable settings.
Time since or time remaining
Allows for a value to be output that determines the amount of time that has passed since or until a point in time. This output can then be used in other calculations. For instance, if the shift started when the process status tag equaled TRUE, you can calculate the amount of time since the shift started and then use that as a variable in other calculations.
Writing Expressions
The functions available within the Calculation Server can be categorized in three different ways:
 Standard OPC Foundation aggregates
 NCALC functions and operators
 Custom functions developed by Canary
OPC Foundation Aggregates
For most aggregates, the expression syntax is simply:
FunctionName('[TagPath]','Duration')
Duration can be expressed in various ways using the each of the following syntax:
 Now  represents current time; used often for rolling calculations 'Now1h' or 'Now5 minutes'
 Second(s) or s  typically used to represent a period of time '30s' or '30 seconds'
 Minute(s) or m  typically used to represent a period of time '5m' or '30 minutes'
 Hour(s) or h  typically used to represent a period of time '8h' or '1 hour'
 Day(s) or d  typically used to represent a period of time '1d' or '7 days'
 Today  midnight of the current day; can be combined with other syntax 'Today+8h' arrives at 08:00:00 of the current day
 Yesterday  midnight of the previous day; can be combined with other syntax 'Yesterday+10h' arrives at 10:00:00 of the previous day
 Day of Week – midnight of the day specified; ‘Monday’ or ‘Saturday’; can be combined with other syntax 'Monday+8h' arrives at the previous Monday at 08:00:00
 Week(s)  midnight on Sunday of current week; can be combined with other syntax 'Week1d' would shift to midnight of Saturday
 Month(s)  midnight of the first day of the current month; can be combined with other syntax 'Today3months' arrives at today's day of the month shifted three months prior
 Year(s)  midnight of the first day of the current year; can be combined with other syntax 'Year3 months + 1h' arrives 01:00:00 on October 1st of the previous year
 Date – a precise date; ‘3/1/2021’ or ‘February 21, 2021’
 Time – a precise time; ‘3/1/2021 10:00AM’ or ’10:00AM’
 Variable  time can be based off the variable of another expression
For aggregates with a unique syntax, that syntax is listed in the 'Additional Information' section.
OPC Standard Aggregates  Basic Definition  Additional Information 
Count  Retrieves the number of raw values over the interval.  A user may want to know how many values have been returned in a given period of time as opposed to what the values were. 
CountInStateZero/NonZero  Retrieves the number of times a Boolean or numeric value was in a zero or nonzero state. 
Can be used to track how many times a piece of equipment was turned on or off. 
DeltaBounds  Retrieves the difference between the StartBound and EndBound value in a given interval. 
This is a good aggregate for tags that return progressively increasing/decreasing data. 
DurationBad  Retrieves the total duration of time in the interval during which the data outputs continuous bad quality scores without interruption.  The DurationGood and DurationBad tags save users from having to trend their data to find out how long field devices ran without issue. These two aggregates can be useful when troubleshooting field devices. Returns a value in milliseconds. 
DurationGood  Retrieves the total duration of time in the interval during which the data outputs continuous good quality scores without interruption.  The DurationGood and DurationBad tags save users from having to trend their data to find out how long field devices ran without issue. These two aggregates can be useful when troubleshooting field devices. Returns a value in milliseconds. 
DurationInStateZero/NonZero  Retrieves the time a Boolean or numeric was in a zero or nonzero state using Simple Bounding Values. 
Returns a value in milliseconds. 
EndBound  EndBound  Retrieves the last value in the interval using Simple Bounding Values.  The last value in the interval can be used in the DeltaBound equation to determine the difference between the last and first values recorded to understand the 'spread' of the data. 
IEEERemainder  Returns the remainder resulting from the division of a specified number by another specified number  The IEEE prefix of the function name refers to the technical standard for floating point arithmetic established in 1985 by the Institute of Electronic and Electrical (IEEE) engineers. SYNTAX: IEEERemainder('x','y') 
Interpolative  At the beginning of each interval, retrieve the calculated values from the data points on either side of the requested timestamp.  This aggregate can take an unevenly spaced set of raw values and approximate that data at regular intervals. 
Max  Returns the larger of two specified numbers  This aggregate is especially helpful when comparing expressions, the end value of an expression can be represented by a variable. Two variables can be entered for the Max aggregate. SYNTAX: Max('x','y') 
Max2  Returns the larger of two specified numbers using Simple Bounding Values.  The maximum value of an interval can be a good indicator of Asset health in some situations. 
Minimum  Returns the larger of two specified numbers  This aggregate is especially helpful when comparing expressions, the end value of an expression can be represented by a variable. Two variables can be entered for the Min aggregate. SYNTAX: Min('x','y') 
Minimum2  Retrieves the minimum value in the interval including the Simple Bounding values  The minimum value of an interval can be a good indicator of Asset health in some situations. 
NumberOfTransitions  Retrieves the number of changes between zero and nonzero that a Boolean or numeric value experienced in the interval  This can be useful for determining when a value went from zero to a nonzero number, it is useful to track the activity or lackthereof of certain processes. 
PercentBad  Retrieves the percentage of data (0  100) in the interval which has a Bad status code.  This function tells the user how much of the data from the specified interval can be trusted. This can be used with the WorstQuality2 aggregate to find out how untrustworthy the data is. 
PercentGood  Retrieves the percentage of data (0  100) in the interval which has a Good status code.  This function tells the user how trustworthy a batch of data is. 
Range2  Returns the difference between the Minimum2 and Maximum2 values.  This function is useful for finding out how spread apart the data is. In contrast to the Range function, the Range2 function finds the range of Simple Bounding Values as opposed to interpolated values. 
StandardDeviationPopulation / Sample  Retrieves the standard deviation for the interval for a complete population (n) which includes Simple Bounding values  Standard deviation is used to measure the dispersion of data values in a given interval. This is for the statistical analysis of all values in an interval whereas StandardDeviationSample calculates only a portion of the data in an interval. 
StartBound  StartBound  Retrieves the first value in the interval using Simple Bounding values.  The first value in the interval can be used in the DeltaBound equation to determine the difference between the last and first values recorded to understand the 'spread' of the data. 
TimeAverage2  Retrieves the time weighted average data over the interval using Simple Bounding values.  The TimeAverage2 aggregate is different from the original TimeAverage because it calculates an average of raw data values as opposed to interpolated values. 
Total2, TotalPerMinute, TotalPerHour, TotalPer24Hours  Retrieves the total (time integral in seconds/minutes/hours/days) of the data over the interval using Simple Bounding values  Total2 = TimeAverage2 x ProcessingInterval of good data in seconds. The ProcessingInterval is the timespan for which derived values are produced based on a specified Aggregate. 
VariancePopulation  Retrieve the variance for the interval as calculated by the StandardDeviationPopulation which includes Simple Bounding values.  This function is useful for finding out how spread apart the data is. 
VarianceSample  Retrieves the variance for the interval as calculated by the StandardDeviationSample  Variance is the average squared deviation from the mean. This aggregate is applied to the values returned by StandardDeviationSample. 
WorstQuality2  Retrieves the worst status code of data in the interval including the Simple Bounding values  The usefulness of this aggregate depends on the capabilities of the OPC Server, some OPC Servers are capable of returning nuanced and precise Bad Quality values that yield important diagnostic information while others only give a simple Bad Quality value. 
NCalc Functions
Standard NCalc functions that are also used in popular software like Microsoft Excel.
Microsoft Functions  Basic Definition  Additional Information 
Absolute Value  Returns the absolute value of a specified number.  This aggregate is useful to add to expressions where the distance from zero is more important than the real number. This can be used in more complicated expressions to avoid dealing with negative numbers. 
And 
Evaluates an array of expressions and returns true if all expressions are true.  To use a real use case as an example, this aggregate can be used with the 'If' function and applied to several diagnostic tags to easily monitor the state of many Assets. With this Aggregate, users no longer have to comb through each Asset to look up the info for each diagnostic tag and decipher what that value means. This saves time and energy. SYNTAX: And([tag1] = 1, [tag2] = 1, [tagN} = 1) 
Average  Retrieve the average value of the data over the interval.  The most basic measurement that is a building block of much more complicated expressions. An average or mean gives a the general overview of many data points. 
Ceiling  Returns the smallest integer greater to or equal than the specified number.  Also called rounding towards positive infinity, this function is useful for rounding decimal numbers up to the next integer away from zero. Ceiling is similar to but not to be confused with truncate or floor. 
Floor  Retrieves the largest integer less than or equal to the specified number  Sometimes called rounding towards negative infinity, this is a way to get rid of decimal places by rounding down. Not to be confused with truncating, the floor function rounds towards negative infinity. 
Functions of Trigonometry  Returns the cos, sin, tan, abs, and  Functions such as cos, sine, tan, and abs are trigonometric functions that will not be explained here. 
If  Returns a value based on a condition  The 'if' statement is an extremely versatile aggregate. SYNTAX: if(3 % 2 = 1, 'value is true', 'value is false') 
In  Returns whether an element is in a set of values. in(element, x value, y value, z value,...) 
This can be used to determine whether a value equals one of several values. So if you had a tag '[tag1]' you could it to find out if it equals one or more specified numbers For example: "in([tag1], 5, 7, 10, 15)" . This expression will return true if [tag1] equals any of 5, 7, 10, or 15. While similar to the 'Switch' function, this is different because it returns a true or false instead of a userdefined string or value. SYNTAX: in(1 + 1, 1, 2, 3) 
Log and Log10  Returns the logarithm of the specified base.  Logarithmic expressions are used for advanced statistical analysis. 
Or  Evaluates an Array of values and returns true if at least one is true. 
The OR function is a logical function to test multiple conditions at the same time. OR returns either TRUE or FALSE. For example, to test A1 for either "x" or "y", use =OR(A1="x",A1="y"). Its useful for checking the validity of certain things. SYNTAX: Or([tag1] = 1, [tag2] = 1, [tagN] = 1) 
Sqrt  Returns the square root of a specified number  The square root of a tag value is valuable for more advanced statistical functions such as variance. SYNTAX: Sqrt(4) 
Switch  Select an output value based on which match contains the same value as the compare key.  The Switch aggregate can be used to convert status codes into a human readable format. Instead of reading the value and resorting to the status codex to find the meaning of the value, the switch aggregate will return a string that explains what is happening. SYNTAX: Switch(compareKey, match1, value1 [,match2,value2]... [,defaultValue]) Any number of matches and values are allowed, but each match needs a value and viceversa. For each of the parameters in the function, any expression is allowed. You can use constant values, aggregates, variables, tag values, etc. Example: "Switch ([localhost.Testing.Tag1], 1,[localhost.Testing.Tag2], var1 + 2, [localhost.Testing.Tag3], [localhost.Testing.Tag4])" Where Tag2 is the output when Tag1 is equal to 1, Tag 3 is the output when Tag1 is equal to var1 + 2, and Tag4 is the default value that is output when none of the other conditions are met. 
Truncate  Calculates the integral part of a number  This function discards the long decimal values of a number, leaving only the whole number. Sometimes the additional decimal precision is not necessary. 
Round  Rounds a value to the nearest integer or specified number of decimal places  This aggregate has unique syntax as well. SYNTAX: Round('x', Number Of Decimal Places to Round to ') For Example: Round('3.222','3') Output: '3' 
Pow  Returns a number raised to the specified power.  The term 'power' refers to how many times a number is multiplied by itself. SYNTAX: Pow(3,2) Output = 9 
Custom Functions
The following have been built by Canary to address typical historian based analytics.
Canary Functions  Basic Definition  Additional Information 
AssetInstanceCount  Returns the total number of asset instances of the specified type under a source path.  This tag keeps the admin from tediously counting what could be dozens of assets. This aggregate is helpful for operations that are constantly taking Assets online and offline. SYNTAX: AssetInstanceCount(string sourcePath, string assetType) 
DeltaTotalCount  Retrieves the total delta (change) of values for an accumulation tag that resets periodically.  The DeltaTotalCount aggregate returns the total positive increase of the value over an interval, ignoring any decreases. Some tags increase, then decrease, then increase some more, then decrease. The DeltaTotalCount reveals the total increase across a specified time period. 
DurationSinceLastTVQ  Retrieve the time in milliseconds since a tag has received an update.  This aggregate returns the time since the last updated value, not the last updated timestamp. This can be used to indicate whether the settings of a logging session must be changed for a specific tag. SYNTAX: DurationSinceLastTVQ (string tagPath[, bool ignoreBadValueChanges]) If ignoreBadValueChanges is set to true, it changes the behavior of the function so that bad or NoData quality TVQs do not reset the duration and instead only set the output quality to uncertain. Additionally, it keeps the function from resetting the duration because of an uncertain quality. 
NoOutput  Does not output tag values.  The NoOutput function can be used in conjunction with an 'If' function to return nothing when another tag returns a specific value. For example, a user could write the value of Tag2 only when Tag1 is true. When Tag1 is false it won't output anything, not even a NoData TVQ, so if you look at it in Axiom it will look like a flat line. 
Property  Retrieves the value of a tag property.  The only function that deals with Metadata properties, this returns the value entered for the specified property of tag. Metadata values can be changed within a tag's logging session. This will return text and numbers. SYNTAX: Property(string tagName, string propertyName) 
Quality  Retrieves the latest quality for a tag.  The value of this tag depends on the capabilities of the OPC Server or data source that is writing data to the tag. SYNTAX: Quality(string tagName) 
ResettingAnchoredInterval  Calculates an aggregate with an interval that continues to grow over a length of time, and then resets after a certain duration.  This function is typically used in conjunction with others. A target interval is specified, and as the calculation runs the actual interval that is used to calculate the aggregate continually grows until it reaches the target interval. At that point the aggregate interval resets back to zero and then continues to grow until it reaches the target again and so on. SYNTAX: ResettingAnchoredInterval(string aggregateName, string tagName, string resetInterval, [string resetOffset]) 
Rollup  Calculates a sum, count, average, or min/max of all like tags in every Asset. Unlike normal aggregates, the Rollup interfaces with the Virtual Views service.  Typically, Assets within a Virtual have the same type of tags. For example, every Pump Asset in a View may have a speed tag. A rollup can be used in conjunction with other aggregates to create a calculated tag that yields information about the state/health of many Assets. SYNTAX: Rollup (String sourcePath, string operation, string assetType, string rollupTag) Operation: SUM, COUNT, AVERAGE, MINIMUM, 
SetOutputQuality  Sets the output tag value quality.  This is useful is overwrite the default quality code set by some OPC Servers. Furthermore, some functions require the 'Good' quality to work properly, such as TimeAverage2. SetOutputQuality can guarantee that tags prone to the occasional uncertain or bad quality, can still be compatible with other functions in a multistep expression. SYNTAX: SetOutputQuality(quality) For most use cases, the quality will be set to 'Good'. 
TagIfExists  Returns the value of the tag if it exists, otherwise returns the fallback value.  This aggregate is useful to when dealing with many Assets and the Admin does not remember if a particular tag resides in many Assets or just one. This is helpful when creating more complicated expressions that require many tags. Use the TagIfExists to allow the calculation to run without error even if an incorrect or nonexistent tag name was entered. SYNTAX: TagIfExists (string tagName, fallbackValue) fallbackValue can be a number or a string but can't be a tag, an aggregate, or a variable. 
4 replies

Is possible to create a custom calculation like (tag1*const1+tag2+tag3*tag4)/(const2+tag5)?