C3 AI Documentation Home

Eval Method in Metrics

The ExpressionEngineFunction#eval method can be used to enforce and override parameters on the evaluation of a metric: such as, interval, start date, and end date.

The ExpressionEngineFunction#eval method forces the evaluation of an input expression at a specified grain. If the result is a time series dataset, then before executing eval, the time series is rolled up from the specified grain to query grain using the aggregationFunction specified. The start and end are the dates from and to which this function eval is executed.

Example

Consider a metric that can calculate the total energy cost for a light bulb. The light bulb has the energy consumption and the energy price data at a quarter hour granularity from "2018-01-01T00:00:00" until "2018-01-01T02:30:00".

In this example, the following values were measured over time:

  • [1, 2, 3, 3, 2, 1, 1, 2, 3, 1] for energy consumption and
  • [1, 2, 1, 1, 2, 2, 2, 1, 1, 2] for energy price,

Energy consumption use case

Consider a metric EnergyCost with the expression EnergyConsumption * EnergyPrice, a problem occurs if the metric is evaluated at intervals greater than 'QUARTER_HOUR'.

AssumeEnergyCost at the HOUR is evaluated at intervals from "2018-01-01T00:00:00" until "2018-01-01T02:00:00". The result is the sum of the EnergyConsumption for that hour multiplied by the average of the EnergyPrice for that hour:

[(1 + 2 + 3 + 3) * ((1 + 2 + 1 + 1) / 4), ((2 + 1 + 1 + 2) * ((2 + 2 + 2 + 1) / 4))] -> [(9 * 1.25), (6 * 1.75)] -> [11.25, 10.5]

The problem each EnergyConsumption value must be weighted by its corresponding EnergyPrice value. Hence this metric must always be evaluated at the 'QUARTER_HOUR' interval.

Solution

A solution is to rewrite EnergyCost to have the expression sum(eval('QUARTER_HOUR', (EnergyConsumption * EnergyPrice))).

Next, evaluate EnergyCost at the HOUR interval from "2018-01-01T00:00:00" until "2018-01-01T02:00:00", it then evaluates this way:

[((1 * 1) + (2 * 2) + (3 * 1) + (3 * 1)), ((2 * 2)+ (1 * 2) + (1 * 2) + (2 * 1))] -> [(1 + 4 + 3 + 3), (4 + 2 + 2 + 2)] -> [14, 10]

Using start parameter

Consider another metric that calculates the total energy cost to date for the light bulb, a metric TotalEnergyCostToDate with expression rolling('SUM', EnergyCost).

Evaluating this metric on the HOUR interval from "2018-01-01T00:00:00" until "2018-01-01T02:00:00", the resulting value is correct because since evaluating from the initial point in time there is data.

[11, (11 + 10)] -> [11, 21]

However, if evaluating from "2018-01-01T01:00:00" until "2018-01-01T03:00:00" the result is:

[10, 10 + 5] -> [10, 15], when in fact it should be [11 + 10, 11 + 10 + 5] -> [24, 29].

The start parameter for eval must be utilized. Modifying TotalEnergyCostToDate to the following expression:

sum(eval('QUARTER_HOUR', rolling('SUM', (EnergyConsumption * EnergyPrice)), dateTime('2018-01-01T00:00:00')))

Evaluating with this new definition from a start date that is after the first data point, it can still evaluate from the beginning, and then take the result in the queried time.

Evaluating TotalEnergyCostToDate from "2018-01-01T01:00:00" until "2018-01-01T03:00:00" results in:

[11, 11 + 10, 11 + 10 + 5] -> [11, 21, 26] -> [21, 26]

Note that if you query from an earlier start than the one specified in eval, it can output 0 with missing equal to 100 for the entire period before the start in eval.

See also

Was this page helpful?