kuzzle-device-manager 2.0.0-rc1 → 2.0.0-rc3

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.
@@ -5,6 +5,9 @@ export declare class AssetController extends CRUDController {
5
5
  private assetService;
6
6
  private get sdk();
7
7
  constructor(plugin: Plugin, assetService: AssetService);
8
+ measures(request: KuzzleRequest): Promise<{
9
+ measures: import("kuzzle").KDocument<import("../types").MeasureContent>[];
10
+ }>;
8
11
  update(request: KuzzleRequest): Promise<import("kuzzle").KDocument<{
9
12
  [x: string]: any;
10
13
  }>>;
@@ -6,11 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.AssetController = void 0;
7
7
  const csvtojson_1 = __importDefault(require("csvtojson"));
8
8
  const kuzzle_plugin_commons_1 = require("kuzzle-plugin-commons");
9
+ const kuzzle_1 = require("kuzzle");
9
10
  const BaseAsset_1 = require("../models/BaseAsset");
10
11
  class AssetController extends kuzzle_plugin_commons_1.CRUDController {
11
12
  constructor(plugin, assetService) {
12
13
  super(plugin, 'assets');
13
14
  this.assetService = assetService;
15
+ /* eslint-disable sort-keys */
14
16
  this.definition = {
15
17
  actions: {
16
18
  create: {
@@ -35,13 +37,30 @@ class AssetController extends kuzzle_plugin_commons_1.CRUDController {
35
37
  update: {
36
38
  handler: this.update.bind(this),
37
39
  http: [{ path: 'device-manager/:index/assets/:_id', verb: 'put' }],
40
+ },
41
+ measures: {
42
+ handler: this.measures.bind(this),
43
+ http: [{ path: 'device-manager/:index/assets/:_id/measures', verb: 'get' }],
38
44
  }
39
45
  },
40
46
  };
47
+ /* eslint-enable sort-keys */
41
48
  }
42
49
  get sdk() {
43
50
  return this.context.accessors.sdk;
44
51
  }
52
+ async measures(request) {
53
+ const id = request.getId();
54
+ const engineId = request.getString('engineId');
55
+ const size = request.input.args.size;
56
+ const startAt = request.input.args.startAt;
57
+ const endAt = request.input.args.endAt;
58
+ if (size && startAt || size && endAt) {
59
+ throw new kuzzle_1.BadRequestError('You cannot specify both a "size" and a "startAt" or "endAt"');
60
+ }
61
+ const measures = await this.assetService.measureHistory(engineId, id, { endAt, size, startAt });
62
+ return { measures };
63
+ }
45
64
  async update(request) {
46
65
  const id = request.getId();
47
66
  const engineId = request.getString('engineId');
@@ -1,9 +1,24 @@
1
- import { Plugin, JSONObject } from 'kuzzle';
1
+ import { Plugin, JSONObject, KDocument } from 'kuzzle';
2
+ import { MeasureContent } from '../types';
2
3
  export declare class AssetService {
3
4
  private config;
4
5
  private context;
5
6
  private get sdk();
6
7
  constructor(plugin: Plugin);
8
+ /**
9
+ * Returns measures history for an asset
10
+ *
11
+ * @param engineId Engine ID
12
+ * @param assetId Asset ID
13
+ * @param options.size Number of measures to return
14
+ * @param options.startAt Returns measures starting from this date (ISO8601)
15
+ * @param options.endAt Returns measures until this date (ISO8601)
16
+ */
17
+ measureHistory(engineId: string, assetId: string, { size, startAt, endAt }: {
18
+ size?: number;
19
+ startAt?: string;
20
+ endAt?: string;
21
+ }): Promise<KDocument<MeasureContent>[]>;
7
22
  importAssets(index: string, assets: JSONObject, { strict, options }: {
8
23
  strict?: boolean;
9
24
  options?: JSONObject;
@@ -11,4 +26,6 @@ export declare class AssetService {
11
26
  errors: any[];
12
27
  successes: any[];
13
28
  }>;
29
+ private getAsset;
30
+ private iso8601;
14
31
  }
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.AssetService = void 0;
7
7
  const lodash_1 = __importDefault(require("lodash"));
8
+ const kuzzle_1 = require("kuzzle");
8
9
  const writeMany_1 = require("../utils/writeMany");
9
10
  const BaseAsset_1 = require("../models/BaseAsset");
10
11
  class AssetService {
@@ -15,6 +16,35 @@ class AssetService {
15
16
  get sdk() {
16
17
  return this.context.accessors.sdk;
17
18
  }
19
+ /**
20
+ * Returns measures history for an asset
21
+ *
22
+ * @param engineId Engine ID
23
+ * @param assetId Asset ID
24
+ * @param options.size Number of measures to return
25
+ * @param options.startAt Returns measures starting from this date (ISO8601)
26
+ * @param options.endAt Returns measures until this date (ISO8601)
27
+ */
28
+ async measureHistory(engineId, assetId, { size = 25, startAt, endAt }) {
29
+ await this.getAsset(engineId, assetId);
30
+ const query = {
31
+ range: {
32
+ measuredAt: {
33
+ gte: 0,
34
+ lte: Number.MAX_SAFE_INTEGER,
35
+ }
36
+ }
37
+ };
38
+ if (startAt) {
39
+ query.range.measuredAt.gte = this.iso8601(startAt, 'startAt').getTime();
40
+ }
41
+ if (endAt) {
42
+ query.range.measuredAt.lte = this.iso8601(startAt, 'endAt').getTime();
43
+ }
44
+ const sort = { 'measuredAt': 'desc' };
45
+ const measures = await this.sdk.document.search(engineId, 'measures', { query, sort }, { size: size || 25 });
46
+ return measures.hits;
47
+ }
18
48
  async importAssets(index, assets, { strict, options }) {
19
49
  const results = {
20
50
  errors: [],
@@ -36,6 +66,17 @@ class AssetService {
36
66
  });
37
67
  return results;
38
68
  }
69
+ getAsset(engineId, assetId) {
70
+ return this.sdk.document.get(engineId, 'assets', assetId);
71
+ }
72
+ // @todo remove when we have the date extractor in the core
73
+ iso8601(value, name) {
74
+ const parsed = new Date(value);
75
+ if (isNaN(parsed)) {
76
+ throw new kuzzle_1.BadRequestError(`"${name}" is not a valid ISO8601 date`);
77
+ }
78
+ return parsed;
79
+ }
39
80
  }
40
81
  exports.AssetService = AssetService;
41
82
  //# sourceMappingURL=AssetService.js.map
@@ -45,6 +45,9 @@ export declare abstract class Decoder {
45
45
  /**
46
46
  * @param deviceModel Device model for this decoder
47
47
  * @param deviceMeasures Devices measure types for this decoder
48
+ *
49
+ * @example
50
+ * super('AbeewayGPS', ['position']);
48
51
  */
49
52
  constructor(deviceModel: string, deviceMeasures: string[]);
50
53
  /**
@@ -65,7 +68,6 @@ export declare abstract class Decoder {
65
68
  * Decode the payload:
66
69
  * - set "reference"
67
70
  * - fetch measures
68
- * - fetch qos
69
71
  *
70
72
  * @param payload Raw payload received in the API action body
71
73
  * @param request Original request
@@ -16,6 +16,9 @@ class Decoder {
16
16
  /**
17
17
  * @param deviceModel Device model for this decoder
18
18
  * @param deviceMeasures Devices measure types for this decoder
19
+ *
20
+ * @example
21
+ * super('AbeewayGPS', ['position']);
19
22
  */
20
23
  constructor(deviceModel, deviceMeasures) {
21
24
  /**
@@ -53,10 +53,10 @@ class PayloadService {
53
53
  newMeasures.push({
54
54
  measuredAt: measure.measuredAt,
55
55
  origin: {
56
+ assetId: null,
56
57
  id: deviceId,
57
58
  model: decoder.deviceModel,
58
59
  payloadUuids: [uuid],
59
- reference: decodedPayload.reference,
60
60
  type: 'device',
61
61
  },
62
62
  type,
@@ -67,6 +67,11 @@ class PayloadService {
67
67
  try {
68
68
  const deviceDoc = await this.batch.get(this.config.adminIndex, 'devices', deviceId);
69
69
  const device = new models_1.Device(deviceDoc._source);
70
+ if (device._source.assetId) {
71
+ for (const measure of newMeasures) {
72
+ measure.origin.assetId = device._source.assetId;
73
+ }
74
+ }
70
75
  return await this.update(device, newMeasures, { refresh });
71
76
  }
72
77
  catch (error) {
@@ -12,6 +12,7 @@ export declare const measuresMappings: {
12
12
  type: string;
13
13
  };
14
14
  origin: {
15
+ type: string;
15
16
  properties: {
16
17
  id: {
17
18
  type: string;
@@ -22,10 +23,10 @@ export declare const measuresMappings: {
22
23
  payloadUuids: {
23
24
  type: string;
24
25
  };
25
- reference: {
26
+ type: {
26
27
  type: string;
27
28
  };
28
- type: {
29
+ assetId: {
29
30
  type: string;
30
31
  };
31
32
  };
@@ -42,17 +43,8 @@ export declare const measuresMappings: {
42
43
  * Measure self-description
43
44
  */
44
45
  unit: {
45
- properties: {
46
- name: {
47
- type: string;
48
- };
49
- sign: {
50
- type: string;
51
- };
52
- type: {
53
- type: string;
54
- };
55
- };
46
+ dynamic: string;
47
+ properties: {};
56
48
  };
57
49
  values: {
58
50
  properties: {};
@@ -1,16 +1,18 @@
1
1
  "use strict";
2
+ /* eslint-disable sort-keys */
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.measuresMappings = void 0;
4
5
  exports.measuresMappings = {
5
6
  dynamic: 'strict',
6
7
  properties: {
7
- measuredAt: { type: 'float' },
8
+ measuredAt: { type: 'double' },
8
9
  /**
9
10
  * A device may have different measures for the same type (e.g. measure temperature 2 times)
10
11
  * Should be set when you link the device to the asset
11
12
  */
12
13
  name: { type: 'keyword' },
13
14
  origin: {
15
+ type: 'nested',
14
16
  properties: {
15
17
  // ID of the device (document _id)
16
18
  id: { type: 'keyword' },
@@ -18,10 +20,10 @@ exports.measuresMappings = {
18
20
  model: { type: 'keyword' },
19
21
  // Array of payload uuids that were used to create this measure.
20
22
  payloadUuids: { type: 'keyword' },
21
- // Reference of the data source (e.g. a device manufacturer ID)
22
- reference: { type: 'keyword' },
23
23
  // E.g. "device"
24
24
  type: { type: 'keyword' },
25
+ // Asset linked to the device when the measure was made
26
+ assetId: { type: 'keyword' },
25
27
  }
26
28
  },
27
29
  /**
@@ -34,15 +36,13 @@ exports.measuresMappings = {
34
36
  * Measure self-description
35
37
  */
36
38
  unit: {
37
- properties: {
38
- name: { type: 'keyword' },
39
- sign: { type: 'keyword' },
40
- type: { type: 'keyword' },
41
- }
39
+ dynamic: 'false',
40
+ properties: {}
42
41
  },
43
42
  values: {
44
43
  properties: {},
45
- }
44
+ },
46
45
  }
47
46
  };
47
+ /* eslint-enable sort-keys */
48
48
  //# sourceMappingURL=measuresMappings.js.map
@@ -1,7 +1,7 @@
1
1
  import { Measurement, MeasureDefinition } from '../types';
2
- export interface MovementMeasure extends Measurement {
2
+ export interface MovementMeasurement extends Measurement {
3
3
  values: {
4
- movement: number;
4
+ movement: boolean;
5
5
  };
6
6
  }
7
7
  export declare const movementMeasure: MeasureDefinition;
@@ -1,4 +1,33 @@
1
1
  import { Measurement } from './measures/Measurement';
2
+ /**
3
+ * Result of the `Decoder.decode` method.
4
+ *
5
+ * Contains the decoded measures.
6
+ *
7
+ * @example
8
+ *
9
+ * const decodedPayload: DecodedPayload = {
10
+ * reference: 'BZH42AZF',
11
+ * measures: {
12
+ * temperature: {
13
+ * measuredAt: Date.now(),
14
+ * values: {
15
+ * temperature: 23.8,
16
+ * }
17
+ * },
18
+ * position: {
19
+ * measuredAt: Date.now(),
20
+ * values: {
21
+ * position: {
22
+ * lat: 21.297,
23
+ * lon: 4.8421,
24
+ * },
25
+ * accuracy: 100,
26
+ * }
27
+ * },
28
+ * },
29
+ * };
30
+ */
2
31
  export interface DecodedPayload {
3
32
  /**
4
33
  * Device unique reference
@@ -44,13 +44,13 @@ export interface MeasureContent extends KDocumentContent {
44
44
  * E.g. "AbeewayTemp"
45
45
  */
46
46
  model: string;
47
- /**
48
- * Reference of the data source (e.g. a device manufacturer ID)
49
- */
50
- reference: string;
51
47
  /**
52
48
  * Array of payload uuids that were used to create this measure.
53
49
  */
54
50
  payloadUuids: string[];
51
+ /**
52
+ * Asset ID linked to the device when the measure was made
53
+ */
54
+ assetId?: string;
55
55
  };
56
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kuzzle-device-manager",
3
- "version": "2.0.0-rc1",
3
+ "version": "2.0.0-rc3",
4
4
  "description": "Manage your IoT devices and assets. Choose a provisioning strategy, receive and decode payload, handle your IoT business logic.",
5
5
  "author": "The Kuzzle Team (support@kuzzle.io)",
6
6
  "repository": {