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.
- package/lib/controllers/AssetController.d.ts +3 -0
- package/lib/controllers/AssetController.js +19 -0
- package/lib/core-classes/AssetService.d.ts +18 -1
- package/lib/core-classes/AssetService.js +41 -0
- package/lib/core-classes/Decoder.d.ts +3 -1
- package/lib/core-classes/Decoder.js +3 -0
- package/lib/core-classes/PayloadService.js +6 -1
- package/lib/mappings/measuresMappings.d.ts +5 -13
- package/lib/mappings/measuresMappings.js +9 -9
- package/lib/measures/MovementMeasure.d.ts +2 -2
- package/lib/types/DecodedPayload.d.ts +29 -0
- package/lib/types/measures/MeasureContent.d.ts +4 -4
- package/package.json +1 -1
|
@@ -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
|
-
|
|
26
|
+
type: {
|
|
26
27
|
type: string;
|
|
27
28
|
};
|
|
28
|
-
|
|
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
|
-
|
|
46
|
-
|
|
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: '
|
|
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
|
-
|
|
38
|
-
|
|
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
|
|
2
|
+
export interface MovementMeasurement extends Measurement {
|
|
3
3
|
values: {
|
|
4
|
-
movement:
|
|
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-
|
|
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": {
|