Stored calc field with timedValueHistoryField annotation

#1

I have an application in which the Facility type has two TimedValueHistory fields which indicate whether they should be excluded from EUI calculations, and another TImedValueHistory field for floor area. The goal is to have a TimedValueHistory field on Organization to track cumulative floor area over time as buildings have their excluded flags changed to false.

Two questions on this:

  1. Is it possible to have a stored calc field on the Organization type such that it’s also the field with a @db(timedValueHistoryField='grossFloorAreaHistory') annotation?
  2. Is there a reason why a stored calc field with type GrossFloorArea wouldn’t work but the same stored calc of type ExactDimension works as expected?

I tried the following:

type GrossFloorArea mixes TimedValue, ExactDimension

...

remix type Organization {
  @db(timedValueHistoryField='grossFloorAreaHistory')
  grossFloorArea: GrossFloorArea stored calc 'sum(denormChildren.to.facilities.(excludedField1.value != true && excludedField2.value != true).grossFloorArea)'

  @db(order='descending(toUTC(timestamp))')
  grossFloorAreaHistory: [OrganizationGrossFloorAreaHistory](parent)
}

but nothing got populated in the grossFloorArea field. When I set it up as:

remix type Organization {
  grossFloorArea: ExactDimension stored calc 'sum(denormChildren.to.facilities.(excludedField1.value != true && excludedField2.value != true).grossFloorArea)'
}

I got a result for grossFloorArea but I wasn’t able to find a way to track changes in this value over time now that it’s just stored in an ExactDimension. I think the issue is that I’m trying to assign an ExactDimension value to the GrossFloorArea type, because if I remove the annotation and just have it set up as:

remix type Organization {
  grossFloorArea: GrossFloorArea stored calc 'sum(denormChildren.to.facilities.(excludedField1.value != true && excludedField2.value != true).grossFloorArea)'
}

I get no results

0 Likes

#2

This should be written as a metric.

{
  sourceType: Organization,
  metricName: 'GrossFloorArea',
  path: denormChildren.to
  expression: "sum(sum(facilities.(excludedField1.value != true && excludedField2.value != true).grossFloorAreaHistory.value))
}
1 Like

#3

My understanding of that metric would be that it takes the current value of whether a building is excluded for the entire timeseries. I need to be able to calculate the history of aggregated floor area for an Organization

0 Likes

#4

I edited my expression. If the expression traverses a “timed value” then you’ll get a historical timeseries.

If your ‘excluded’ value is a timed value and your ‘gross floor area’ is a timed value then this should work.

0 Likes

#5

That doesn’t seem to work properly. It works when evaluating on the Facility type but not at the org level:

Data model

type FacilityExcluded mixes TimedValue, Boolean

entity type FacilityExcludedHistory mixes TimedValueHistory<Facility>, Boolean schema name 'EXCL_HIST' 

type GrossFloorArea mixes TimedValue, Double

entity type GrossFloorAreaHistory mixes TimedValueHistory<Facility>, Double schema name 'FL_AREA_HIST'

remix type Facility {

  self: [Facility] (id,id)

  @db(timedValueHistoryField='excludedFieldHistory')
  excludedField: FacilityExcluded

  @db(order='descending(toUTC(timestamp))')
  excludedFieldHistory: [FacilityExcludedHistory](parent)

  @db(timedValueHistoryField='grossFloorAreaHistory')
  grossFloorArea: GrossFloorArea

  @db(order='descending(toUTC(timestamp))')
  grossFloorAreaHistory: [GrossFloorAreaHistory](parent)
}

Setup data

var filename = 'test';

var context = TestApi.createContext(filename);
var organization = TestApi.createEntity(context, 'Organization');
var department = TestApi.createEntity(context, 'Department', {
  party: organization
});
var facility = TestApi.createEntity(context, 'Facility');
var assetOwner = TestApi.createEntity(context, 'AssetOwner', {
  assetOwned: facility,
  partyRole: department
});
var floorArea = TestApi.createEntity(context, 'GrossFloorAreaHistory', {
  parent: facility,
  value: 100
});

var excludedObjs = TestApi.createBatchEntity(context, 'FacilityExcludedHistory', [
  {
    parent: facility,
    value: false,
    timestamp: DateTime.nowWithoutZone().toDateMidnight().plusDays(-10)
  },
  {
    parent: facility,
    value: true,
    timestamp: DateTime.nowWithoutZone().toDateMidnight().plusDays(-1)
  }
]);

metrics

c3Visualize(Facility.evalMetricsWithMetadata({
  ids: [facility.id],
  expressions: ['GrossFloorArea'],
  start: DateTime.nowWithoutZone().toDateMidnight().plusDays(-5),
  end: DateTime.nowWithoutZone().toDateMidnight().plusDays(1),
  interval: 'DAY'
}, [
    SimpleMetric.make({
      "id": "GrossFloorArea_Facility",
      "name": "GrossFloorArea",
      "srcType": "Facility",
      "path": "self.(excludedField != true).grossFloorAreaHistory",
      "expression": "value"
    })
  ]))

c3Visualize(Organization.evalMetricsWithMetadata({
  ids: [organization.id],
  expressions: ['GFloorArea', 'GFloorArea2', 'RawGFloorArea'],
  start: DateTime.nowWithoutZone().toDateMidnight().plusDays(-5),
  end: DateTime.nowWithoutZone().toDateMidnight().plusDays(1),
  interval: 'HOUR'
}, [
    SimpleMetric.make({
      "id": "RawGFloorArea_Organization",
      "name": "RawGFloorArea",
      "srcType": "Organization",
      "path": "denormChildren.to.facilities.grossFloorAreaHistory",
      "expression": "value"
    }),
    SimpleMetric.make({
      "id": "GFloorArea_Organization",
      "name": "GFloorArea",
      "srcType": "Organization",
      "path": "denormChildren.to.facilities.(excludedField != true).self",
      "expression": "grossFloorAreaHistory"
    }),
    SimpleMetric.make({
      "id": "GFloorArea2_Organization",
      "name": "GFloorArea2",
      "srcType": "Organization",
      "path": "denormChildren.to.facilities.(excludedField != true).grossFloorAreaHistory",
      "expression": "value"
    }),
    SimpleMetric.make({
      "id": "GFloorArea3_Organization",
      "name": "GFloorArea3",
      "srcType": "Organization",
      "path": "denormChildren.to",
      "expression": "facilities.(excludedField != true).grossFloorAreaHistory.value"
    })
  ]))

results

Facility result:

Org result:

0 Likes