Metrics

Metrics are calculations that take place at a regular interval, normally every 10 or 30 minutes.

These can calculate statistics and performance quality measures, which in turn can be shown on schematics and graphs.

They can have an hourly, daily or monthly reporting period, but the calculations can be made every hour to provide interim data.

They are used to perform complex calculations (written in Phi), which analyse the data from assets and data pools.

When creating a scheduled calculation:

  • it must be defined in the context of a single Schema (i.e. for assets or data pools of a single type)
  • you can define the reporting period (hourly, daily, monthly or yearly)
  • you can define how often it runs (hourly or daily).

If the metric runs more frequently than the reporting period, then it compiles interim data whenever the reporting period is not complete.

Context and time periods

A metric has to belong to a Schema, i.e. a "type of thing". Because of this, you will find metrics inside a Schema.

The possible reporting periods are: monthly; daily; and hourly.

For example, if you have a data pool called a Room, you might want to have a metric that calculates the number of times some activity takes place in each Room, each day.

If you have a hierarchy with Rooms inside Areas, and Areas inside Locations, you can show the Room-level metrics when viewing an Area or a Location (on a schematic or floor-plan, and on graphs).

How to create a metric

To create a metric, go into a Schema and look for Metrics. Click on "+ New metric" to add one.

Once editing the metric, give it a name, and set the reporting period. The reporting period is important because the variables fromTimestamp and toTimestamp will be set to correspond to this period each time the calculation is run. 

(If the metric is asked to "reprocess" data from the past, these variables will be set temporarily to correspond to the start and end of each period (e.g. each day etc.) in the past.)

Variables available

fromTimestamp

The timestamp at the start of the reporting period. (E.g. If the reporting period is monthly, it would be midnight 00:00:00 at the start of the first day of the calendar month.)

It's inclusive, i.e. you need to use greater-than-or-equal (>=).

toTimestamp

The timestamp at the end of this period. (E.g. if this was a monthly calculation, it would be a fraction before midnight at the end of the month.

Note that fromTimestamp includes the time at the beginning of the period, but toTimestamp excludes the time at the end of the period (think of it running until 1 millisecond before the end of the period). If comparing times against these, you should use >= fromTimestamp, but < toTimestamp.

There is also access to:

assetId

which is the id of the current asset (or data pool).

Functions

The following functions are available to use in your Phi code in metrics.

getTimestamp(description[, timestamp])

This works as in other Phi code.

getHistoricValue(key, timestamp[, nodeId])

This works as in other Phi code, Passing nodeId you can get the value of a specific node other than the current node.

There are some functions to get minimum and maximum values:

getMinValue(key, fromTimestamp, toTimestamp[, nodeIds])

getMaxValue(key, fromTimestamp, toTimestamp[, nodeIds])

getAllChildIds([schema[, nodeId]])

This gives you all of the children of the current node. Passing schema you can filter by a specific schema. Passing nodeId  or an array nodeIds you can get the child IDs of a different node or nodes from the current one.

getImmediateChildIds([schema[, nodeId]])

This gives you the immediate children of the current asset. Passing schema you can filter by a specific schema. Passing nodeId you can get the child IDs of a different node from the current one.

query(fromTimestamp, toTimestamp[, nodeIds])

This returns a cursor of results that you can loop through using a for () loop.

getMetricValue(key, fromTimestamp[, nodeId])

Gets a metric from another pre-existing metric, where key is the textual field key of the metric at the time fromTimestamp. Passing nodeId you can get the child IDs of a different node from the current one.

Query Example

You want to read all values from the current reporting period (e.g. if the reporting period is daily, when it would be today since the start of the day, or a complete day once the day is over).

Imagine you have some data pools whose schema ID is SCHEMA_ID, and that have a metric called some_count, and at the hierarchy level above them there is another data pool. You want a metric that calculates the sum total_count of some_count each day:

SCHEMA_ID = 2
total_count = 0
assets = getImmediateChildIds(SCHEMA_ID)
dump(assets) # Only for debugging, will show the array of asset IDs in a dry run

for (asset in assets) {
    dump(getMetricValue('some_count', fromTimestamp, asset)) # Again just for debugging
    total_count += getMetricValue('some_count', fromTimestamp, asset)
}
dump(total_count)

setValue('total_count', total_count) # This stores the metric value in the database

The last line of a calculation normally includes setValue(), which is necessary to store the calculated value in the database after each run.