How to handle the case when end is null in a TSDecl metric

#1

I’ve a SimpleMetric defined as follows:

{
    "id": "CanComputeGeneralHotWaterConsumptions_Facility",
    "name": "CanComputeGeneralHotWaterConsumptions",
    "description": "Check wheter 'srv24' or 'srv26' is available for the given site.",
    "srcType": "Facility",
    "path": "site.denormChildFacilities.servicePoints",
    "tsDecl": {
      "data": "services",
      "value": "1",
      "treatment" : "PREVIOUS",
      "start" : "start",
      "end": "end"
      "filter" : "serviceOffering.id == 'srv24' || serviceOffering.id == 'srv26'"
    },
    "unit": {
      "id": "dimensionless"
    }
}

The problem is that if my Service has only a start date and no end date (i.e. end is null), the evaluation result is all missing.

On the other hand, if I remove the end expression from the tsDecl the metric evaluation seems to work, i.e. i have data!

How I could use end in the tsDecl?

0 Likes

#2

I’ve endup using this expression:

"tsDecl": {
   "end": "!empty(end)? end : start + period(1, interval())",
},
1 Like

#3

This seems to do the trick for what I am looking for - if end == null then treat it as the end of time. But this kind of seems like a bug in the ExpressionEngine… shouldn’t this show up as end == start + 1 interval?

0 Likes

#4

@scott.kruyswyk If I understand you correctly, you are suggesting the default behavior should be end = start + period(1,interval()) ? why would it be start + 1 interval() and not n intervals. I would argue it is safer to treat the value as null and report missing rather than choosing the default in this case to make sure the user knows about the missing data

0 Likes

#5

@rohit.sureka right, what I want is for if end == null then that value should be carried forward indefinitely.

A bit of context: I have a metric that is looking at a TimedIntervalValueHistory field, defined as follows:

{
    "id": "BooleanMetric_MyType",
    "name": "BooleanMetric",
    "srcType": "MyType",
    "path": "somePath",
    "tsDecl": {
      "data": "timedIntervalValueField",
      "treatment": "LATEST",
      "start": "start",
      "end": "end",
      "value" : "1",
      "transform": "fillMissing(this, 0)"
    }
}

If I were to create one of these TimedIntervalValueHistory objects with a start but no end defined, the metric returns 0. I’ve tried playing with treatment but had no success getting the metric to show up as 0 before start and then 1 for all time afterwards.

However, when I took @bachr’s suggestion and set the metric to:

{
    "id": "BooleanMetric_MyType",
    "name": "BooleanMetric",
    "srcType": "MyType",
    "path": "somePath",
    "tsDecl": {
      "data": "timedIntervalValueField",
      "treatment": "LATEST",
      "start": "start",
      "end": "exists(end)? end : start + period(1, interval())",
      "value" : "1",
      "transform": "fillMissing(this, 0)"
    }
}

Then the metric behaves as desired - it shows up as 0 before start, then 1 forever afterwards. This seems to me like it should only be 1 for a single interval, based on how the metric is defined but it’s actually 1 forever after that.

The way this type is being used, there is an actual reason why we would want end to be null for an instance; in this scenario we want the metric to behave exactly as it is with the second metric I have defined above, but this feels like this is a bug in the expression engine that happens to benefit us moreso than the expected behavior for this.

So, 2 questions:

  1. Is this really the expected behavior for a metric defined as it is in the second code snippet?
  2. If not, is there a way to set up a TsDecl metric such that it does have this desired behavior?
0 Likes

#6

you are correct, this sounds like a bug. Since the end is specified, then it should make sure the point is valid only for that start/end combination. IF it is giving value 1 till the end of time that sounds like a bug to me and should be reported & fixed. I remember fixing an issue around this in some version of the server, so let’s try to validate this on a later version before filing a new ticket.

In order to achieve the value 1 till end of time, we can use something like:

      "end": "exists(end)? end : dateTime('2099-01-01')",

The engine underneath is smart enough to restrict the value till the end of the query interval and not evaluate until 2099.

1 Like

#7

Thank you! This is on 7.8.8.70 so I’ll see if I can get a repro on 7.9. If so I’ll go ahead and create a ticket

0 Likes