Skip to content

Commit

Permalink
adds new endpoing for fetching multiple asset metrics by label and as…
Browse files Browse the repository at this point in the history
…set id
  • Loading branch information
ilyarrgh committed Feb 2, 2021
1 parent dc5bd5c commit 51b1bcd
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ esm/*
lib/*

.wercker
.idea
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## [v4.1.0](http://github.com/ndustrialio/contxt-sdk-js/tree/v4.1.0) (2021-02-02)

**Changed**

- Adds `AssetMetrics#getValuesByMetricIdsAssetIds` to fetch multiple asset metrics for multiple asset ids within a specified date range.

## [v4.0.0](http://github.com/ndustrialio/contxt-sdk-js/tree/v4.0.0) (2021-01-22)

**Changed**
Expand Down
37 changes: 37 additions & 0 deletions docs/AssetMetrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Module that provides access to, and the manipulation of, information about diffe
* [.deleteValue(assetMetricValueId)](#AssetMetrics+deleteValue) ⇒ <code>Promise</code>
* [.getValuesByAssetId(assetId, [assetMetricValuesFilters])](#AssetMetrics+getValuesByAssetId) ⇒ <code>Promise</code>
* [.getValuesByMetricId(assetId, assetMetricId, [assetMetricValuesFilters])](#AssetMetrics+getValuesByMetricId) ⇒ <code>Promise</code>
* [.getValuesByMetricIdsAssetIds([assetMetricFilters])](#AssetMetrics+getValuesByMetricIdsAssetIds) ⇒ <code>Promise</code>
* [.updateValue(assetMetricValueId, update)](#AssetMetrics+updateValue) ⇒ <code>Promise</code>

<a name="new_AssetMetrics_new"></a>
Expand Down Expand Up @@ -341,6 +342,42 @@ contxtSdk.assets.metrics
})
.catch((err) => console.log(err));
```
<a name="AssetMetrics+getValuesByMetricIdsAssetIds"></a>

### contxtSdk.assets.metrics.getValuesByMetricIdsAssetIds([assetMetricFilters]) ⇒ <code>Promise</code>
Gets asset metric values for a particular asset and metric

API Endpoint: '/assets/metrics/values'
Method: GET

**Kind**: instance method of [<code>AssetMetrics</code>](#AssetMetrics)
**Fulfill**: [<code>AssetMetricValuesByAssetIdMetricId</code>](./Typedefs.md#AssetMetricValuesByAssetIdMetricId)
**Rejects**: <code>Error</code>

| Param | Type | Description |
| --- | --- | --- |
| [assetMetricFilters] | <code>Object</code> | Specific information that is used to filter the list of asset metric values |
| assetMetricFilters.assetIds | <code>Array.&lt;String&gt;</code> | an array of asset ids to request the metrics for |
| assetMetricFilters.labels | <code>Array.&lt;String&gt;</code> | an array of metric labels to request the metrics for |
| [assetMetricFilters.effectiveEndDate] | <code>String</code> | Effective end date (ISO 8601 Extended formatted) of the asset metric values |
| [assetMetricFilters.effectiveStartDate] | <code>String</code> | Effective start date (ISO 8601 Extended formatted) of the asset metric values |

**Example**
```js
contxtSdk.assets.metrics
.getValuesByMetricIdsAssetIds(
{
effectiveStartDate: '2018-07-11T19:14:49.715Z',
effectiveEndDate: '2018-07-11T19:14:49.715Z',
assetIds: ['2140cc2e-6d13-42ee-9941-487fe98f8e2d', '5540cc2e-6d13-42ee-9941-487fe98f8efc'],
labels: ['facility_kwh', 'facility_cuft'],
}
)
.then((assetMetricValuesByAssetIdMetricId) => {
console.log(assetMetricValuesByAssetIdMetricId);
})
.catch((err) => console.log(err));
```
<a name="AssetMetrics+updateValue"></a>

### contxtSdk.assets.metrics.updateValue(assetMetricValueId, update) ⇒ <code>Promise</code>
Expand Down
6 changes: 6 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,16 @@ environments. Documentation for browser environments is found under
<dd></dd>
<dt><a href="./Typedefs.md#AssetMetricValue">AssetMetricValue</a> : <code>Object</code></dt>
<dd></dd>
<dt><a href="./Typedefs.md#AssetMetricValueCompact">AssetMetricValueCompact</a> : <code>Object</code></dt>
<dd></dd>
<dt><a href="./Typedefs.md#AssetMetricValuesByAssetIdMetricId">AssetMetricValuesByAssetIdMetricId</a> : <code>Object.&lt;Asset.id, AssetMetricsKeyedByMetricId&gt;</code></dt>
<dd></dd>
<dt><a href="./Typedefs.md#AssetMetricValuesFromServer">AssetMetricValuesFromServer</a> : <code>Object</code></dt>
<dd></dd>
<dt><a href="./Typedefs.md#AssetMetricsFromServer">AssetMetricsFromServer</a> : <code>Object</code></dt>
<dd></dd>
<dt><a href="./Typedefs.md#AssetMetricsKeyedByMetricId">AssetMetricsKeyedByMetricId</a> : <code>Object.&lt;AssetMetric.id, Array.&lt;AssetMetricValueCompact&gt;&gt;</code></dt>
<dd></dd>
<dt><a href="./Typedefs.md#AssetType">AssetType</a> : <code>Object</code></dt>
<dd></dd>
<dt><a href="./Typedefs.md#AssetTypesFromServer">AssetTypesFromServer</a> : <code>Object</code></dt>
Expand Down
21 changes: 21 additions & 0 deletions docs/Typedefs.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,23 @@
| value | <code>string</code> | |
| isEstimated | <code>boolean</code> | Whether the value is an estimation or a true reading |

<a name="AssetMetricValueCompact"></a>

## AssetMetricValueCompact : <code>Object</code>
**Kind**: global typedef
**Properties**

| Name | Type | Description |
| --- | --- | --- |
| id | <code>string</code> | the UUID corresponding to the asset metric value id |
| value | <code>string</code> | |
| effectiveEndDate | <code>string</code> | ISO 8601 Extended Format date/time string |
| effectiveStartDate | <code>string</code> | ISO 8601 Extended Format date/time string |

<a name="AssetMetricValuesByAssetIdMetricId"></a>

## AssetMetricValuesByAssetIdMetricId : <code>Object.&lt;Asset.id, AssetMetricsKeyedByMetricId&gt;</code>
**Kind**: global typedef
<a name="AssetMetricValuesFromServer"></a>

## AssetMetricValuesFromServer : <code>Object</code>
Expand All @@ -141,6 +158,10 @@
| _metadata.totalRecords | <code>number</code> | Total number of asset types found |
| records | [<code>Array.&lt;AssetMetric&gt;</code>](#AssetMetric) | |

<a name="AssetMetricsKeyedByMetricId"></a>

## AssetMetricsKeyedByMetricId : <code>Object.&lt;AssetMetric.id, Array.&lt;AssetMetricValueCompact&gt;&gt;</code>
**Kind**: global typedef
<a name="AssetType"></a>

## AssetType : <code>Object</code>
Expand Down
69 changes: 69 additions & 0 deletions src/assets/assetMetrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ import { formatPaginatedDataFromServer } from '../utils/pagination';
* @property {AssetMetricValue[]} records
*/

/**
* @typedef {Object} AssetMetricValueCompact
* @property {string} id the UUID corresponding to the asset metric value id
* @property {string} value
* @property {string} effectiveEndDate ISO 8601 Extended Format date/time string
* @property {string} effectiveStartDate ISO 8601 Extended Format date/time string
*/

/**
* @typedef {Object.<AssetMetric.id, AssetMetricValueCompact[]>} AssetMetricsKeyedByMetricId
*/

/**
* @typedef {Object.<Asset.id, AssetMetricsKeyedByMetricId>} AssetMetricValuesByAssetIdMetricId
*/

/**
* Module that provides access to, and the manipulation of, information about different asset metrics
*
Expand Down Expand Up @@ -572,6 +588,59 @@ class AssetMetrics {
);
}

/**
* Gets asset metric values for a particular asset and metric
*
* API Endpoint: '/assets/metrics/values'
* Method: GET
*
* @param {Object} [assetMetricFilters] Specific information that is
* used to filter the list of asset metric values
* @param {String[]} assetMetricFilters.assetIds an array of asset ids
* to request the metrics for
* @param {String[]} assetMetricFilters.labels an array of metric labels
* to request the metrics for
* @param {String} [assetMetricFilters.effectiveEndDate] Effective end
* date (ISO 8601 Extended formatted) of the asset metric values
* @param {String} [assetMetricFilters.effectiveStartDate] Effective
* start date (ISO 8601 Extended formatted) of the asset metric values
* @returns {Promise}
* @fulfill {AssetMetricValuesByAssetIdMetricId}
* @rejects {Error}
*
* @example
* contxtSdk.assets.metrics
* .getValuesByMetricIdsAssetIds(
* {
* effectiveStartDate: '2018-07-11T19:14:49.715Z',
* effectiveEndDate: '2018-07-11T19:14:49.715Z',
* assetIds: ['2140cc2e-6d13-42ee-9941-487fe98f8e2d', '5540cc2e-6d13-42ee-9941-487fe98f8efc'],
* labels: ['facility_kwh', 'facility_cuft'],
* }
* )
* .then((assetMetricValuesByAssetIdMetricId) => {
* console.log(assetMetricValuesByAssetIdMetricId);
* })
* .catch((err) => console.log(err));
*/
getValuesByMetricIdsAssetIds(assetMetricFilters) {
const requiredFields = ['assetIds', 'labels'];

for (let i = 0; i < requiredFields.length; i++) {
const field = requiredFields[i];

if (!assetMetricFilters[field]) {
return Promise.reject(
new Error(`The ${field} param is required to fetch data.`)
);
}
}

return this._request.get(`${this._baseUrl}/assets/metrics/values`, {
params: toSnakeCase(assetMetricFilters)
});
}

/**
* Updates an asset metric value
*
Expand Down
105 changes: 105 additions & 0 deletions src/assets/assetMetrics.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,111 @@ describe('Assets/Metrics', function() {
});
});

describe('getValuesByMetricIdsAssetIds', function() {
let numberOfAssetMetricValues;
let numberOfAssetMetrics;
let numberOfAssets;

let assetMetricValuesCompact;
let assetMetricObjects;
let assets;

let metricsFiltersAfterFormat;
let metricsFiltersBeforeFormat;
let promise;
let request;
let toSnakeCase;

let valuesFromServer;

beforeEach(function() {
numberOfAssetMetricValues = faker.random.number({ min: 1, max: 10 });
numberOfAssetMetrics = faker.random.number({ min: 1, max: 3 });
numberOfAssets = faker.random.number({ min: 1, max: 3 });

assetMetricValuesCompact = fixture.buildList(
'assetMetricValueCompact',
numberOfAssetMetricValues
);
assetMetricObjects = fixture.buildList(
'assetMetric',
numberOfAssetMetrics
);
assets = fixture.buildList('asset', numberOfAssets);

const metricObjects = assetMetricObjects.reduce((acc, metric) => {
return { ...acc, [metric.label]: assetMetricValuesCompact };
});

valuesFromServer = assets.reduce((acc, asset) => {
return { ...acc, [asset.id]: { ...metricObjects } };
}, {});

request = {
...baseRequest,
get: sinon.stub().resolves(valuesFromServer)
};

metricsFiltersBeforeFormat = {
assetIds: assets.map((asset) => asset.id),
labels: assetMetricObjects.map((assetMetric) => assetMetric.id)
};

metricsFiltersAfterFormat = {
asset_ids: metricsFiltersBeforeFormat.assetIds,
labels: metricsFiltersBeforeFormat.labels
};

toSnakeCase = sinon
.stub(objectUtils, 'toSnakeCase')
.returns(metricsFiltersAfterFormat);
});

context('when all required information is supplied', function() {
beforeEach(function() {
const assetMetrics = new AssetMetrics(baseSdk, request, expectedHost);
promise = assetMetrics.getValuesByMetricIdsAssetIds(
metricsFiltersBeforeFormat
);
});

it('called with the correctly formatted params', function() {
expect(request.get).to.be.calledWith(
`${expectedHost}/assets/metrics/values`,
{ params: metricsFiltersAfterFormat }
);
});

it('resolves with a list of the asset metrics by asset id and label from the server', function() {
return expect(promise).to.be.fulfilled.and.to.eventually.deep.equal(
valuesFromServer
);
});

it('formats the url request params into the right format', function() {
expect(toSnakeCase).to.be.deep.calledWith(metricsFiltersBeforeFormat);
});
});

context('when any parameter is missing from filters', function() {
const missingParam = faker.random.arrayElement(['assetIds', 'labels']);

beforeEach(function() {
const assetMetrics = new AssetMetrics(baseSdk, request, expectedHost);
delete metricsFiltersBeforeFormat[missingParam];
promise = assetMetrics.getValuesByMetricIdsAssetIds(
metricsFiltersBeforeFormat
);
});

it('throws an Error', function() {
return expect(promise).to.be.eventually.rejectedWith(
`The ${missingParam} param is required to fetch data.`
);
});
});
});

describe('update', function() {
context('when all required information is supplied', function() {
let assetMetricToServerAfterFormat;
Expand Down
10 changes: 10 additions & 0 deletions support/fixtures/factories/assetMetricValueCompact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const faker = require('faker');
const factory = require('rosie').Factory;

factory.define('assetMetricValueCompact').attrs({
id: faker.random.uuid(),
value: faker.random.number(),
is_estimated: false,
effective_start_date: faker.date.past().toISOString(),
effective_end_date: faker.date.recent().toISOString()
});

0 comments on commit 51b1bcd

Please sign in to comment.