kuzzle-device-manager 2.0.0-rc21 → 2.0.0-rc22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/lib/DeviceManagerPlugin.js +7 -7
  2. package/lib/controllers/AssetController.d.ts +13 -6
  3. package/lib/controllers/AssetController.js +22 -12
  4. package/lib/controllers/{DecodersController.d.ts → DecoderController.d.ts} +1 -1
  5. package/lib/controllers/{DecodersController.js → DecoderController.js} +4 -4
  6. package/lib/controllers/DeviceController.d.ts +5 -3
  7. package/lib/controllers/DeviceController.js +21 -9
  8. package/lib/controllers/RelationalController.d.ts +7 -0
  9. package/lib/controllers/RelationalController.js +9 -0
  10. package/lib/controllers/index.d.ts +1 -1
  11. package/lib/controllers/index.js +1 -1
  12. package/lib/core-classes/AssetCategoryService.d.ts +7 -1
  13. package/lib/core-classes/AssetCategoryService.js +12 -0
  14. package/lib/core-classes/AssetService.d.ts +1 -1
  15. package/lib/core-classes/AssetService.js +3 -3
  16. package/lib/core-classes/Decoder.d.ts +23 -15
  17. package/lib/core-classes/Decoder.js +21 -16
  18. package/lib/core-classes/DeviceService.d.ts +0 -2
  19. package/lib/core-classes/DeviceService.js +8 -15
  20. package/lib/core-classes/MeasureService.d.ts +6 -5
  21. package/lib/core-classes/MeasureService.js +30 -19
  22. package/lib/core-classes/PayloadService.d.ts +7 -3
  23. package/lib/core-classes/PayloadService.js +15 -8
  24. package/lib/core-classes/registers/DecodersRegister.d.ts +7 -1
  25. package/lib/core-classes/registers/DecodersRegister.js +22 -4
  26. package/lib/measures/BatteryMeasure.d.ts +3 -5
  27. package/lib/measures/HumidityMeasure.d.ts +3 -5
  28. package/lib/measures/MovementMeasure.d.ts +3 -5
  29. package/lib/measures/PositionMeasure.d.ts +7 -9
  30. package/lib/measures/TemperatureMeasure.d.ts +4 -6
  31. package/lib/models/BaseAsset.js +4 -1
  32. package/lib/models/Device.d.ts +2 -0
  33. package/lib/models/Device.js +7 -0
  34. package/lib/types/DecodedPayload.d.ts +43 -30
  35. package/lib/types/DecodedPayload.js +70 -1
  36. package/lib/types/DecoderContent.d.ts +1 -1
  37. package/lib/types/index.d.ts +2 -0
  38. package/lib/types/index.js +2 -0
  39. package/lib/types/measures/MeasureContent.d.ts +9 -12
  40. package/lib/types/measures/MeasureContent.js +0 -9
  41. package/lib/types/measures/MeasureDefinition.d.ts +1 -1
  42. package/package.json +2 -2
@@ -8,7 +8,6 @@ const kuzzle_1 = require("kuzzle");
8
8
  const lodash_1 = __importDefault(require("lodash"));
9
9
  const InternalCollection_1 = require("../InternalCollection");
10
10
  const models_1 = require("../models");
11
- const types_1 = require("../types");
12
11
  class MeasureService {
13
12
  constructor(plugin, batchController, assetService, measuresRegister) {
14
13
  this.config = plugin.config;
@@ -33,14 +32,11 @@ class MeasureService {
33
32
  * @param deviceModel Model of the device
34
33
  * @param decodedPayloads `decodedPayload`
35
34
  * @param payloadUuids Payload Uuids that generated the measurements
36
- * @param {object} options
37
- * @param options.provisionDevice If true and a `decodedPayload`
38
- * reference a nonexisting device, create this device
35
+ * @param options.provisionDevice If true and a `decodedPayload` reference a nonexisting device, create this device
39
36
  * @param options.refresh Wait for ES indexation
40
37
  */
41
- async processDecodedPayload(deviceModel, decodedPayloads, payloadUuids, options) {
42
- const references = Object.keys(decodedPayloads);
43
- const devices = await this.getDevices(deviceModel, references, options);
38
+ async processDecodedPayload(deviceModel, decodedPayload, payloadUuids, options) {
39
+ const devices = await this.getDevices(deviceModel, decodedPayload.references, options);
44
40
  for (const device of devices) {
45
41
  let asset = null;
46
42
  if (device._source.assetId) {
@@ -52,7 +48,13 @@ class MeasureService {
52
48
  this.app.log.error(`[${device._source.engineId}] Cannot find asset "${device._source.assetId}" linked to device "${device._id}".`);
53
49
  }
54
50
  }
55
- const measures = this.buildMeasures(device, asset, decodedPayloads[device._source.reference], payloadUuids);
51
+ const measurements = decodedPayload.getMeasurements(device._source.reference);
52
+ if (!measurements) {
53
+ this.app.log.warn(`Cannot find measurements for device "${device._source.reference}"`);
54
+ continue;
55
+ }
56
+ const measures = this.buildMeasures(device, asset, measurements, payloadUuids);
57
+ device.updateMetadata(decodedPayload.getMetadata(device._source.reference));
56
58
  /**
57
59
  * Event before starting to process new measures.
58
60
  *
@@ -63,14 +65,14 @@ class MeasureService {
63
65
  await this.app.trigger(`engine:${device._source.engineId}:device-manager:measures:process:before`, { asset, device, measures });
64
66
  }
65
67
  device.updateMeasures(updatedMeasures);
66
- await this.sdk.document.update(this.config.adminIndex, InternalCollection_1.InternalCollection.DEVICES, device._id, { measures: device._source.measures });
68
+ await this.sdk.document.update(this.config.adminIndex, InternalCollection_1.InternalCollection.DEVICES, device._id, device._source);
67
69
  if (device._source.engineId) {
68
- await this.sdk.document.update(device._source.engineId, InternalCollection_1.InternalCollection.DEVICES, device._id, { measures: device._source.measures });
70
+ await this.sdk.document.update(device._source.engineId, InternalCollection_1.InternalCollection.DEVICES, device._id, device._source);
69
71
  // @todo replace by batch.mCreate when available
70
72
  await this.sdk.document.mCreate(device._source.engineId, InternalCollection_1.InternalCollection.MEASURES, updatedMeasures.map(measure => ({ body: measure })), { strict: true });
71
73
  if (asset) {
72
74
  asset.updateMeasures(updatedMeasures);
73
- await this.sdk.document.update(device._source.engineId, InternalCollection_1.InternalCollection.ASSETS, asset._id, { measures: asset._source.measures });
75
+ await this.sdk.document.update(device._source.engineId, InternalCollection_1.InternalCollection.ASSETS, asset._id, asset._source);
74
76
  }
75
77
  }
76
78
  /**
@@ -94,17 +96,19 @@ class MeasureService {
94
96
  continue;
95
97
  }
96
98
  const deviceMeasureName = measurement.deviceMeasureName || measurement.type;
97
- const assetMeasureName = asset === null ? undefined : this.findAssetMeasureName(device, asset, deviceMeasureName);
99
+ const assetMeasureName = asset === null
100
+ ? undefined
101
+ : this.findAssetMeasureName(device, asset, deviceMeasureName);
98
102
  const measureContent = {
99
103
  assetMeasureName,
100
104
  deviceMeasureName,
101
105
  measuredAt: measurement.measuredAt,
102
106
  origin: {
103
- assetId: asset ? asset._id : undefined,
107
+ assetId: asset?._id,
104
108
  deviceModel: device._source.model,
105
109
  id: device._id,
106
110
  payloadUuids,
107
- type: types_1.OriginType.DEVICE,
111
+ type: 'device',
108
112
  },
109
113
  type: measurement.type,
110
114
  unit: this.measuresRegister.get(measurement.type).unit,
@@ -114,8 +118,11 @@ class MeasureService {
114
118
  }
115
119
  return measures;
116
120
  }
121
+ /**
122
+ * Get devices or create missing ones (when auto-provisionning is enabled)
123
+ */
117
124
  async getDevices(deviceModel, references, { refresh }) {
118
- let devices = [];
125
+ const devices = [];
119
126
  // @todo replace with batch.mGet when available
120
127
  const { successes, errors } = await this.sdk.document.mGet(this.config.adminIndex, InternalCollection_1.InternalCollection.DEVICES, references.map(reference => models_1.Device.id(deviceModel, reference)));
121
128
  for (const { _source, _id } of successes) {
@@ -172,7 +179,7 @@ class MeasureService {
172
179
  async registerByAsset(engineId, assetId, jsonMeasurements, kuid, { refresh, strict } = {}) {
173
180
  const invalidMeasurements = [];
174
181
  const validMeasures = [];
175
- const asset = await this.assetService.getAsset(engineId, assetId);
182
+ const asset = await this.assetService.get(engineId, assetId);
176
183
  if (!asset) {
177
184
  throw new kuzzle_1.NotFoundError(`Asset ${assetId} does not exist`);
178
185
  }
@@ -184,11 +191,11 @@ class MeasureService {
184
191
  validMeasures.push({
185
192
  assetMeasureName,
186
193
  deviceMeasureName: null,
187
- measuredAt: measurement.measuredAt ? measurement.measuredAt : Date.now(),
194
+ measuredAt: measurement.measuredAt || Date.now(),
188
195
  origin: {
189
196
  assetId,
190
197
  id: kuid,
191
- type: types_1.OriginType.USER,
198
+ type: 'user',
192
199
  },
193
200
  type: measurement.type,
194
201
  unit: this.measuresRegister.get(measurement.type).unit,
@@ -235,8 +242,12 @@ class MeasureService {
235
242
  }
236
243
  findAssetMeasureName(device, asset, deviceMeasureName) {
237
244
  const deviceLink = asset._source.deviceLinks.find(link => link.deviceId === device._id);
245
+ // TOSEE Convert to assert ?
246
+ if (!deviceLink) {
247
+ throw new kuzzle_1.PluginImplementationError(`The device "${device._id}" is not linked to the asset "${asset._id}"`);
248
+ }
238
249
  const measureLink = deviceLink.measureNamesLinks.find(nameLink => nameLink.deviceMeasureName === deviceMeasureName);
239
- return measureLink.assetMeasureName;
250
+ return measureLink ? measureLink.assetMeasureName : undefined;
240
251
  }
241
252
  }
242
253
  exports.MeasureService = MeasureService;
@@ -2,16 +2,14 @@ import { BatchController, KuzzleRequest } from 'kuzzle';
2
2
  import { DeviceManagerPlugin } from '../DeviceManagerPlugin';
3
3
  import { Decoder } from './Decoder';
4
4
  import { MeasureService } from './MeasureService';
5
- import { MeasuresRegister } from './registers/MeasuresRegister';
6
5
  export declare class PayloadService {
7
6
  private config;
8
7
  private context;
9
8
  private batch;
10
- private measuresRegister;
11
9
  private measureService;
12
10
  private get sdk();
13
11
  private get app();
14
- constructor(plugin: DeviceManagerPlugin, batchController: BatchController, measuresRegister: MeasuresRegister, measureService: MeasureService);
12
+ constructor(plugin: DeviceManagerPlugin, batchController: BatchController, measureService: MeasureService);
15
13
  /**
16
14
  * Process a payload by validating and decode it with the `decoder` associated
17
15
  * with the device model. It :
@@ -23,4 +21,10 @@ export declare class PayloadService {
23
21
  }): Promise<void | {
24
22
  valid: boolean;
25
23
  }>;
24
+ /**
25
+ * Method used to save the payload and catch + log the error if any.
26
+ *
27
+ * This method never returns a rejected promise.
28
+ */
29
+ private savePayload;
26
30
  }
@@ -3,11 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PayloadService = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  class PayloadService {
6
- constructor(plugin, batchController, measuresRegister, measureService) {
6
+ constructor(plugin, batchController, measureService) {
7
7
  this.config = plugin.config;
8
8
  this.context = plugin.context;
9
9
  this.measureService = measureService;
10
- this.measuresRegister = measuresRegister;
11
10
  this.batch = batchController;
12
11
  }
13
12
  get sdk() {
@@ -37,16 +36,24 @@ class PayloadService {
37
36
  throw error;
38
37
  }
39
38
  finally {
40
- await this.batch.create(this.config.adminIndex, 'payloads', {
41
- deviceModel: decoder.deviceModel,
42
- payload,
43
- uuid,
44
- valid,
45
- }, uuid);
39
+ await this.savePayload(decoder.deviceModel, uuid, valid, payload);
46
40
  }
47
41
  const decodedPayload = await decoder.decode(payload, request);
48
42
  return this.measureService.processDecodedPayload(decoder.deviceModel, decodedPayload, [uuid], { refresh });
49
43
  }
44
+ /**
45
+ * Method used to save the payload and catch + log the error if any.
46
+ *
47
+ * This method never returns a rejected promise.
48
+ */
49
+ async savePayload(deviceModel, uuid, valid, payload) {
50
+ try {
51
+ await this.batch.create(this.config.adminIndex, 'payloads', { deviceModel, payload, uuid, valid }, uuid);
52
+ }
53
+ catch (error) {
54
+ this.app.log.error(`Cannot save the payload from "${deviceModel}": ${error}`);
55
+ }
56
+ }
50
57
  }
51
58
  exports.PayloadService = PayloadService;
52
59
  //# sourceMappingURL=PayloadService.js.map
@@ -1,14 +1,20 @@
1
1
  import { ControllerDefinition, PluginContext } from 'kuzzle';
2
+ import { MeasuresRegister } from './MeasuresRegister';
2
3
  import { DecoderContent } from '../../types';
3
4
  import { Decoder } from '../Decoder';
4
5
  import { PayloadService } from '../PayloadService';
5
6
  export declare class DecodersRegister {
7
+ private measuresRegister;
6
8
  private context;
9
+ /**
10
+ * Map<deviceModel, Decoder>
11
+ */
7
12
  private _decoders;
8
13
  private get sdk();
9
- getByDeviceModel(deviceModel: string): Decoder;
10
14
  get decoders(): Decoder[];
15
+ constructor(measuresRegister: MeasuresRegister);
11
16
  init(context: PluginContext): void;
17
+ get(deviceModel: string): Decoder;
12
18
  list(): DecoderContent[];
13
19
  /**
14
20
  * Registers a new decoder for a device model.
@@ -3,21 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DecodersRegister = void 0;
4
4
  const kuzzle_1 = require("kuzzle");
5
5
  class DecodersRegister {
6
- constructor() {
6
+ constructor(measuresRegister) {
7
+ /**
8
+ * Map<deviceModel, Decoder>
9
+ */
7
10
  this._decoders = new Map();
11
+ this.measuresRegister = measuresRegister;
8
12
  }
9
13
  get sdk() {
10
14
  return this.context.accessors.sdk;
11
15
  }
12
- getByDeviceModel(deviceModel) {
13
- return this._decoders.get(deviceModel);
14
- }
15
16
  get decoders() {
16
17
  return Array.from(this._decoders.values());
17
18
  }
18
19
  init(context) {
19
20
  this.context = context;
20
21
  }
22
+ get(deviceModel) {
23
+ if (!this._decoders.has(deviceModel)) {
24
+ throw new kuzzle_1.BadRequestError(`Cannot find decoder for "${deviceModel}"`);
25
+ }
26
+ return this._decoders.get(deviceModel);
27
+ }
21
28
  list() {
22
29
  const decoders = this.decoders.map(decoder => decoder.serialize());
23
30
  return decoders;
@@ -35,7 +42,18 @@ class DecodersRegister {
35
42
  * @returns Corresponding API action requestPayload
36
43
  */
37
44
  register(decoder) {
45
+ if (!decoder.deviceModel) {
46
+ decoder.deviceModel = decoder.constructor.name.replace('Decoder', '');
47
+ }
38
48
  decoder.action = decoder.action || kuzzle_1.Inflector.kebabCase(decoder.deviceModel);
49
+ if (decoder.measures.length === 0) {
50
+ throw new kuzzle_1.PluginImplementationError(`Decoder "${decoder.deviceModel}" did not declare any measures in the "decoder.measures" property.`);
51
+ }
52
+ for (const measureDeclaration of decoder.measures) {
53
+ if (!this.measuresRegister.has(measureDeclaration.type)) {
54
+ throw new kuzzle_1.PluginImplementationError(`Decoder "${decoder.deviceModel}" cannot register unknown measure type "${measureDeclaration.type}"`);
55
+ }
56
+ }
39
57
  if (this._decoders.has(decoder.deviceModel)) {
40
58
  throw new kuzzle_1.PluginImplementationError(`Decoder for device model "${decoder.deviceModel}" already registered`);
41
59
  }
@@ -1,7 +1,5 @@
1
1
  import { Measurement, MeasureDefinition } from '../types';
2
- export interface BatteryMeasurement extends Measurement {
3
- values: {
4
- battery: number;
5
- };
6
- }
2
+ export declare type BatteryMeasurement = Measurement<{
3
+ battery: number;
4
+ }>;
7
5
  export declare const batteryMeasure: MeasureDefinition;
@@ -1,7 +1,5 @@
1
1
  import { Measurement, MeasureDefinition } from '../types';
2
- export interface HumidityMeasurement extends Measurement {
3
- values: {
4
- humidity: number;
5
- };
6
- }
2
+ export declare type HumidityMeasurement = Measurement<{
3
+ humidity: number;
4
+ }>;
7
5
  export declare const humidityMeasure: MeasureDefinition;
@@ -1,7 +1,5 @@
1
1
  import { Measurement, MeasureDefinition } from '../types';
2
- export interface MovementMeasurement extends Measurement {
3
- values: {
4
- movement: boolean;
5
- };
6
- }
2
+ export declare type MovementMeasurement = Measurement<{
3
+ movement: boolean;
4
+ }>;
7
5
  export declare const movementMeasure: MeasureDefinition;
@@ -1,12 +1,10 @@
1
1
  import { Measurement, MeasureDefinition } from '../types';
2
- export interface PositionMeasurement extends Measurement {
3
- values: {
4
- position: {
5
- lat: number;
6
- lon: number;
7
- };
8
- altitude?: number;
9
- accuracy?: number;
2
+ export declare type PositionMeasurement = Measurement<{
3
+ position: {
4
+ lat: number;
5
+ lon: number;
10
6
  };
11
- }
7
+ altitude?: number;
8
+ accuracy?: number;
9
+ }>;
12
10
  export declare const positionMeasure: MeasureDefinition;
@@ -1,7 +1,5 @@
1
- import { Measurement, MeasureDefinition } from '../types';
2
- export interface TemperatureMeasurement extends Measurement {
3
- values: {
4
- temperature: number;
5
- };
6
- }
1
+ import { MeasureDefinition, Measurement } from '../types';
2
+ export declare type TemperatureMeasurement = Measurement<{
3
+ temperature: number;
4
+ }>;
7
5
  export declare const temperatureMeasure: MeasureDefinition;
@@ -8,6 +8,9 @@ class BaseAsset {
8
8
  if (!Array.isArray(this._source.measures)) {
9
9
  this._source.measures = [];
10
10
  }
11
+ if (!Array.isArray(this._source.deviceLinks)) {
12
+ this._source.deviceLinks = [];
13
+ }
11
14
  }
12
15
  static id(type, model, reference) {
13
16
  return `${type}-${model}-${reference}`;
@@ -18,7 +21,7 @@ class BaseAsset {
18
21
  unlinkDevice(device) {
19
22
  // TOSEE : Iterate over all or assert there is
20
23
  // only one link and remove first match?
21
- const linkToKeep = this._source.deviceLinks.filter((deviceLink) => deviceLink.deviceId !== device._id);
24
+ const linkToKeep = this._source.deviceLinks.filter(link => link.deviceId !== device._id);
22
25
  this._source.deviceLinks = linkToKeep;
23
26
  }
24
27
  /**
@@ -1,3 +1,4 @@
1
+ import { JSONObject } from 'kuzzle-sdk';
1
2
  import { LinkRequest } from '../types/Request';
2
3
  import { DeviceContent, MeasureContent } from '../types';
3
4
  export declare class Device {
@@ -17,4 +18,5 @@ export declare class Device {
17
18
  * Only keep the latest measures
18
19
  */
19
20
  updateMeasures(newMeasures: MeasureContent[]): void;
21
+ updateMetadata(metadata: JSONObject): void;
20
22
  }
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.Device = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
4
8
  class Device {
5
9
  constructor(content, _id) {
6
10
  this._id = _id || Device.id(content.model, content.reference);
@@ -43,6 +47,9 @@ class Device {
43
47
  }
44
48
  }
45
49
  }
50
+ updateMetadata(metadata) {
51
+ this._source.metadata = lodash_1.default.merge(this._source.metadata, metadata);
52
+ }
46
53
  }
47
54
  exports.Device = Device;
48
55
  //# sourceMappingURL=Device.js.map
@@ -1,33 +1,46 @@
1
+ import { JSONObject } from 'kuzzle';
2
+ import { Decoder } from '../core-classes/Decoder';
1
3
  import { Measurement } from './measures/MeasureContent';
2
4
  /**
3
- * Record containing decoded measurements for each device.
4
- *
5
- * Record<deviceReference, Measurement[]>
6
- *
7
- * @example
8
- * const decodedPayload: DecodedPayload = {
9
- * 'BZH42AZF': [
10
- * {
11
- * deviceMeasureName: 'battery',
12
- * measuredAt: 1655379939496,
13
- * type: 'battery',
14
- * values: { battery: 32 },
15
- * },
16
- * ],
17
- * 'IS7L8HK': [
18
- * {
19
- * deviceMeasureName: 'internal_temperature',
20
- * measuredAt: 1655379939496,
21
- * type: 'temperature',
22
- * values: { temperature: -3 },
23
- * },
24
- * {
25
- * deviceMeasureName: 'external_temperature',
26
- * measuredAt: 1655379939496,
27
- * type: 'temperature',
28
- * values: { temperature: 39 },
29
- * },
30
- * ],
31
- * };
5
+ * Class containing the decoded measures.
32
6
  */
33
- export declare type DecodedPayload = Record<string, Measurement[]>;
7
+ export declare class DecodedPayload<TDecoder extends Decoder = Decoder> {
8
+ decoder: TDecoder;
9
+ /**
10
+ * Measurements per device.
11
+ *
12
+ * Record<deviceReference, Measurement[]>
13
+ */
14
+ private measurementsByDevice;
15
+ /**
16
+ * Metadata per device.
17
+ */
18
+ private metadataByDevice;
19
+ constructor(decoder: TDecoder);
20
+ get references(): string[];
21
+ /**
22
+ * Add a new measure into the decoded payload
23
+ *
24
+ * @param deviceReference Device reference
25
+ * @param measureName Name of the decoded measure
26
+ * @param measurement Measurement object
27
+ */
28
+ addMeasurement<TMeasurement extends Measurement = Measurement>(deviceReference: string, measureName: TDecoder['measures'][number]['name'], measurement: TMeasurement): void;
29
+ /**
30
+ * Add metadata values for a Device.
31
+ *
32
+ * Metadata should have been declared on the plugin to be used.
33
+ *
34
+ * @param deviceReference Device reference
35
+ * @param metadata Object containing metadata values
36
+ */
37
+ addMetadata(deviceReference: string, metadata: JSONObject): void;
38
+ /**
39
+ * Gets the measurements decoded for a device
40
+ */
41
+ getMeasurements(deviceReference: string): Measurement[];
42
+ /**
43
+ * Get the metadata for a device
44
+ */
45
+ getMetadata(deviceReference: string): JSONObject;
46
+ }
@@ -1,4 +1,73 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- // @todo we should have an intermediary object
3
+ exports.DecodedPayload = void 0;
4
+ const kuzzle_1 = require("kuzzle");
5
+ /**
6
+ * Class containing the decoded measures.
7
+ */
8
+ class DecodedPayload {
9
+ constructor(decoder) {
10
+ /**
11
+ * Measurements per device.
12
+ *
13
+ * Record<deviceReference, Measurement[]>
14
+ */
15
+ this.measurementsByDevice = {};
16
+ /**
17
+ * Metadata per device.
18
+ */
19
+ this.metadataByDevice = {};
20
+ this.decoder = decoder;
21
+ }
22
+ get references() {
23
+ return Object.keys(this.measurementsByDevice);
24
+ }
25
+ /**
26
+ * Add a new measure into the decoded payload
27
+ *
28
+ * @param deviceReference Device reference
29
+ * @param measureName Name of the decoded measure
30
+ * @param measurement Measurement object
31
+ */
32
+ addMeasurement(deviceReference, measureName, measurement) {
33
+ if (!this.decoder.measureNames.includes(measureName)) {
34
+ throw new kuzzle_1.PluginImplementationError(`Decoder "${this.decoder.deviceModel}" has no measure named "${measureName}"`);
35
+ }
36
+ if (!this.measurementsByDevice[deviceReference]) {
37
+ this.measurementsByDevice[deviceReference] = [];
38
+ }
39
+ measurement.deviceMeasureName = measureName;
40
+ this.measurementsByDevice[deviceReference].push(measurement);
41
+ }
42
+ /**
43
+ * Add metadata values for a Device.
44
+ *
45
+ * Metadata should have been declared on the plugin to be used.
46
+ *
47
+ * @param deviceReference Device reference
48
+ * @param metadata Object containing metadata values
49
+ */
50
+ addMetadata(deviceReference, metadata) {
51
+ if (!this.metadataByDevice[deviceReference]) {
52
+ this.metadataByDevice[deviceReference] = {};
53
+ }
54
+ this.metadataByDevice[deviceReference] = {
55
+ ...this.metadataByDevice[deviceReference],
56
+ ...metadata,
57
+ };
58
+ }
59
+ /**
60
+ * Gets the measurements decoded for a device
61
+ */
62
+ getMeasurements(deviceReference) {
63
+ return this.measurementsByDevice[deviceReference];
64
+ }
65
+ /**
66
+ * Get the metadata for a device
67
+ */
68
+ getMetadata(deviceReference) {
69
+ return this.metadataByDevice[deviceReference];
70
+ }
71
+ }
72
+ exports.DecodedPayload = DecodedPayload;
4
73
  //# sourceMappingURL=DecodedPayload.js.map
@@ -1,5 +1,5 @@
1
1
  import { DecoderMeasures } from '../core-classes/Decoder';
2
2
  export interface DecoderContent {
3
3
  deviceModel: string;
4
- decoderMeasures: DecoderMeasures;
4
+ measures: DecoderMeasures;
5
5
  }
@@ -5,3 +5,5 @@ export * from './measures/MeasureDefinition';
5
5
  export * from './DecoderContent';
6
6
  export * from './DecodedPayload';
7
7
  export * from './DeviceManagerConfiguration';
8
+ export * from './MetadataContent';
9
+ export * from './AssetCategoryContent';
@@ -21,4 +21,6 @@ __exportStar(require("./measures/MeasureDefinition"), exports);
21
21
  __exportStar(require("./DecoderContent"), exports);
22
22
  __exportStar(require("./DecodedPayload"), exports);
23
23
  __exportStar(require("./DeviceManagerConfiguration"), exports);
24
+ __exportStar(require("./MetadataContent"), exports);
25
+ __exportStar(require("./AssetCategoryContent"), exports);
24
26
  //# sourceMappingURL=index.js.map
@@ -5,8 +5,10 @@ import { MeasureUnit } from './MeasureDefinition';
5
5
  *
6
6
  * This interface should be extended and the `values` property specialized
7
7
  * to declare new measurement type.
8
+ *
9
+ * @todo cannot use type when iterating on measure of the pipe event
8
10
  */
9
- export interface Measurement {
11
+ export interface Measurement<TMeasurementValues extends JSONObject = JSONObject> {
10
12
  /**
11
13
  * Type of the measure. (e.g. "temperature")
12
14
  * The type name is also the name of the sub-property to look at
@@ -18,7 +20,7 @@ export interface Measurement {
18
20
  *
19
21
  * This should be specialized by child interfaces.
20
22
  */
21
- values: JSONObject;
23
+ values: TMeasurementValues;
22
24
  /**
23
25
  * Micro Timestamp of the measurement time.
24
26
  */
@@ -27,19 +29,21 @@ export interface Measurement {
27
29
  * Name given by the decoder to the measure.
28
30
  *
29
31
  * By default, it's the type of the measure
32
+ * @todo device.name
30
33
  */
31
34
  deviceMeasureName?: string;
32
35
  }
33
- export interface AssetMeasurement extends Measurement {
36
+ export interface AssetMeasurement<TMeasurementValues extends JSONObject = JSONObject> extends Measurement<TMeasurementValues> {
34
37
  /**
35
38
  * Name given by the `deviceLink` of the linked asset.
39
+ * @todo asset.name
36
40
  */
37
41
  assetMeasureName: string;
38
42
  }
39
43
  /**
40
44
  * Represent the full content of a measure document.
41
45
  */
42
- export interface MeasureContent extends KDocumentContent, AssetMeasurement {
46
+ export interface MeasureContent<TMeasurementValues extends JSONObject = JSONObject> extends KDocumentContent, AssetMeasurement<TMeasurementValues> {
43
47
  /**
44
48
  * Measurement self-description.
45
49
  */
@@ -51,7 +55,7 @@ export interface MeasureContent extends KDocumentContent, AssetMeasurement {
51
55
  /**
52
56
  * From what the measure has been pushed.
53
57
  */
54
- type: OriginType;
58
+ type: 'user' | 'device';
55
59
  /**
56
60
  * Payload uuid that was used to create this measure.
57
61
  */
@@ -72,10 +76,3 @@ export interface MeasureContent extends KDocumentContent, AssetMeasurement {
72
76
  assetId?: string;
73
77
  };
74
78
  }
75
- /**
76
- * From where the measure has been pushed
77
- */
78
- export declare enum OriginType {
79
- USER = "user",
80
- DEVICE = "device"
81
- }
@@ -1,12 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OriginType = void 0;
4
- /**
5
- * From where the measure has been pushed
6
- */
7
- var OriginType;
8
- (function (OriginType) {
9
- OriginType["USER"] = "user";
10
- OriginType["DEVICE"] = "device";
11
- })(OriginType = exports.OriginType || (exports.OriginType = {}));
12
3
  //# sourceMappingURL=MeasureContent.js.map
@@ -20,7 +20,7 @@ export interface MeasureUnit {
20
20
  *
21
21
  * @example
22
22
  * {
23
- * measurementMappings: { temperature: { type: 'float' } },
23
+ * valuesMappings: { temperature: { type: 'float' } },
24
24
  * unit: {
25
25
  * name: 'Degree',
26
26
  * sign: '°',