kuzzle-device-manager 2.0.0-rc8 → 2.0.0-rc9
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/DeviceManagerPlugin.js +1 -1
- package/lib/core-classes/Decoder.d.ts +4 -2
- package/lib/core-classes/MeasureService.d.ts +7 -14
- package/lib/core-classes/MeasureService.js +90 -171
- package/lib/core-classes/PayloadService.d.ts +3 -1
- package/lib/core-classes/PayloadService.js +1 -3
- package/lib/models/BaseAsset.d.ts +6 -1
- package/lib/models/BaseAsset.js +13 -10
- package/lib/models/Device.d.ts +6 -1
- package/lib/models/Device.js +13 -10
- package/lib/types/DecodedPayload.d.ts +4 -24
- package/lib/types/DecodedPayload.js +1 -0
- package/lib/types/measures/MeasureContent.d.ts +2 -0
- package/package.json +1 -1
|
@@ -158,7 +158,7 @@ class DeviceManagerPlugin extends kuzzle_1.Plugin {
|
|
|
158
158
|
});
|
|
159
159
|
this.assetService = new core_classes_1.AssetService(this, this.batchController);
|
|
160
160
|
this.deviceService = new core_classes_1.DeviceService(this, this.batchController, this.assetService, this.decodersRegister);
|
|
161
|
-
this.measuresService = new MeasureService_1.MeasureService(this, this.batchController, this.
|
|
161
|
+
this.measuresService = new MeasureService_1.MeasureService(this, this.batchController, this.assetService, this.measuresRegister);
|
|
162
162
|
this.payloadService = new core_classes_1.PayloadService(this, this.batchController, this.measuresRegister, this.measuresService);
|
|
163
163
|
this.deviceManagerEngine = new core_classes_1.DeviceManagerEngine(this, this.assetsRegister, this.devicesRegister, this.measuresRegister, this.adminConfigManager, this.engineConfigManager);
|
|
164
164
|
this.decodersRegister.init(this.context);
|
|
@@ -2,8 +2,10 @@ import { HttpRoute, JSONObject, KuzzleRequest } from 'kuzzle';
|
|
|
2
2
|
import { DecodedPayload } from '../types/DecodedPayload';
|
|
3
3
|
import { DecoderContent } from '../types';
|
|
4
4
|
import { MeasuresRegister } from './registers/MeasuresRegister';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Record<deviceMeasureName, type>
|
|
7
|
+
*/
|
|
8
|
+
export declare type DecoderMeasures = Record<string, string>;
|
|
7
9
|
/**
|
|
8
10
|
* Base class to implement a decoder for a device model.
|
|
9
11
|
* The device model must be passed to the parent constructor.
|
|
@@ -2,19 +2,16 @@ import { BatchController, JSONObject } from 'kuzzle';
|
|
|
2
2
|
import { DeviceManagerPlugin } from '../DeviceManagerPlugin';
|
|
3
3
|
import { DecodedPayload, MeasureContent } from '../types';
|
|
4
4
|
import { AssetService } from './AssetService';
|
|
5
|
-
import { DeviceService } from './DeviceService';
|
|
6
5
|
import { MeasuresRegister } from './registers/MeasuresRegister';
|
|
7
6
|
export declare class MeasureService {
|
|
8
7
|
private config;
|
|
9
8
|
private context;
|
|
10
9
|
private batch;
|
|
11
|
-
private deviceService;
|
|
12
10
|
private assetService;
|
|
13
11
|
private measuresRegister;
|
|
14
|
-
private static eventId;
|
|
15
12
|
private get sdk();
|
|
16
13
|
private get app();
|
|
17
|
-
constructor(plugin: DeviceManagerPlugin, batchController: BatchController,
|
|
14
|
+
constructor(plugin: DeviceManagerPlugin, batchController: BatchController, assetService: AssetService, measuresRegister: MeasuresRegister);
|
|
18
15
|
/**
|
|
19
16
|
* Register new measures from a device, updates :
|
|
20
17
|
* - admin device
|
|
@@ -30,15 +27,12 @@ export declare class MeasureService {
|
|
|
30
27
|
* reference a nonexisting device, create this device
|
|
31
28
|
* @param options.refresh Wait for ES indexation
|
|
32
29
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* caching structures
|
|
40
|
-
*/
|
|
41
|
-
private insertIntoSortingRecords;
|
|
30
|
+
processDecodedPayload(deviceModel: string, decodedPayloads: DecodedPayload, payloadUuids: string[], options: {
|
|
31
|
+
refresh?: string;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
private buildMeasures;
|
|
34
|
+
private getDevices;
|
|
35
|
+
private provisionDevices;
|
|
42
36
|
/**
|
|
43
37
|
* Register new measures from a device, updates :
|
|
44
38
|
* - linked asset
|
|
@@ -50,7 +44,6 @@ export declare class MeasureService {
|
|
|
50
44
|
* @param assetId Asset id
|
|
51
45
|
* @param jsonMeasurements `AssetMeasurement` array from a request
|
|
52
46
|
* @param kuid Kuid of the user pushing the measurements
|
|
53
|
-
* @param {object} options
|
|
54
47
|
* @param options.refresh Wait for ES indexation
|
|
55
48
|
* @param options.strict If true, throw if an operation isn't possible
|
|
56
49
|
*/
|
|
@@ -10,10 +10,9 @@ const InternalCollection_1 = require("../InternalCollection");
|
|
|
10
10
|
const models_1 = require("../models");
|
|
11
11
|
const types_1 = require("../types");
|
|
12
12
|
class MeasureService {
|
|
13
|
-
constructor(plugin, batchController,
|
|
13
|
+
constructor(plugin, batchController, assetService, measuresRegister) {
|
|
14
14
|
this.config = plugin.config;
|
|
15
15
|
this.context = plugin.context;
|
|
16
|
-
this.deviceService = deviceService;
|
|
17
16
|
this.assetService = assetService;
|
|
18
17
|
this.measuresRegister = measuresRegister;
|
|
19
18
|
this.batch = batchController;
|
|
@@ -39,158 +38,100 @@ class MeasureService {
|
|
|
39
38
|
* reference a nonexisting device, create this device
|
|
40
39
|
* @param options.refresh Wait for ES indexation
|
|
41
40
|
*/
|
|
42
|
-
async
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const response = await this.app.trigger(`${eventId}:before`, {
|
|
56
|
-
assetMeasuresInEngineCache: assetMeasuresInEngine,
|
|
57
|
-
deviceMeasuresInEngineCache: deviceMeasuresInEngine,
|
|
58
|
-
engineMeasuresCache: engineMeasures,
|
|
59
|
-
unknownTypeMeasurements,
|
|
60
|
-
});
|
|
61
|
-
// Push measures in db
|
|
62
|
-
// In Engine measures
|
|
63
|
-
await Promise.all(Object.entries(response.engineMeasuresCache).map(([engineId, measures]) => {
|
|
64
|
-
const measureArray = measures;
|
|
65
|
-
return this.historizeEngineMeasures(engineId, measureArray, { refresh });
|
|
66
|
-
}));
|
|
67
|
-
// Update measures of assets and update documents
|
|
68
|
-
await Promise.all(Object.entries(response.assetMeasuresInEngineCache).map(async ([engineId, assetMeasuresRecord]) => {
|
|
69
|
-
for (const { asset, measures } of Object.values(assetMeasuresRecord)) {
|
|
70
|
-
asset.updateMeasures(measures);
|
|
71
|
-
}
|
|
72
|
-
await this.sdk.document.mUpdate(engineId, InternalCollection_1.InternalCollection.ASSETS, Object.values(assetMeasuresRecord).map(({ asset }) => ({ _id: asset._id, body: asset._source })), { refresh });
|
|
73
|
-
}));
|
|
74
|
-
// Update measures of devices and update documents
|
|
75
|
-
const devices = [];
|
|
76
|
-
await Promise.all(Object.entries(response.deviceMeasuresInEngineCache).map(async ([engineId, deviceMeasuresRecord]) => {
|
|
77
|
-
await Promise.all(Object.values(deviceMeasuresRecord).map(({ device, measures }) => {
|
|
78
|
-
device.updateMeasures(measures);
|
|
79
|
-
devices.push(device);
|
|
80
|
-
}));
|
|
81
|
-
if (engineId !== this.config.adminIndex) {
|
|
82
|
-
await this.sdk.document.mUpdate(engineId, InternalCollection_1.InternalCollection.DEVICES, Object.values(deviceMeasuresRecord).map(({ device }) => ({ _id: device._id, body: device._source })), { refresh });
|
|
83
|
-
}
|
|
84
|
-
}));
|
|
85
|
-
await this.sdk.document.mUpdate(this.config.adminIndex, InternalCollection_1.InternalCollection.DEVICES, devices.map(device => ({ _id: device._id, body: device._source })), { refresh });
|
|
86
|
-
await this.app.trigger(`${eventId}:after`, {
|
|
87
|
-
assetMeasuresInEngineCache: assetMeasuresInEngine,
|
|
88
|
-
deviceMeasuresInEngineCache: deviceMeasuresInEngine,
|
|
89
|
-
engineMeasuresCache: engineMeasures,
|
|
90
|
-
});
|
|
91
|
-
return {
|
|
92
|
-
// TOSEE : What to return, how (serialization) ?
|
|
93
|
-
// TOSEE : Stock updated assets, devices and measures for return result ?
|
|
94
|
-
// engineMeasuresCache,
|
|
95
|
-
// assetMeasuresInEngineCache,
|
|
96
|
-
// deviceMeasuresInEngineCache,
|
|
97
|
-
// unaivailableTypeMeasurements,
|
|
98
|
-
// measurementsWithoutDevice,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Takes all informations to craft a Measure and insert it in
|
|
103
|
-
* caching structures
|
|
104
|
-
*/
|
|
105
|
-
async insertIntoSortingRecords(engineMeasuresCache, assetMeasuresInEngineCache, deviceMeasuresInEngineCache, measurementsWithoutDevice, unknownTypeMeasurements, payloadUuids, deviceModel, reference, measurements, autoProvisionDevice) {
|
|
106
|
-
// Search device in cache or get in db
|
|
107
|
-
const deviceId = models_1.Device.id(deviceModel, reference);
|
|
108
|
-
let device = null;
|
|
109
|
-
try {
|
|
110
|
-
device = await this.deviceService.getDevice(this.config, deviceId);
|
|
111
|
-
}
|
|
112
|
-
catch (error) { }
|
|
113
|
-
if (!device) {
|
|
114
|
-
if (autoProvisionDevice) {
|
|
115
|
-
// TODO : Optimize, ES request to create and then update at end
|
|
116
|
-
device = await this.deviceService.create({
|
|
117
|
-
model: deviceModel,
|
|
118
|
-
reference,
|
|
119
|
-
});
|
|
41
|
+
async processDecodedPayload(deviceModel, decodedPayloads, payloadUuids, options) {
|
|
42
|
+
const references = Object.keys(decodedPayloads);
|
|
43
|
+
const devices = await this.getDevices(deviceModel, references, options);
|
|
44
|
+
for (const device of devices) {
|
|
45
|
+
let asset = null;
|
|
46
|
+
if (device._source.assetId) {
|
|
47
|
+
try {
|
|
48
|
+
const { _source, _id } = await this.batch.get(device._source.engineId, InternalCollection_1.InternalCollection.ASSETS, device._source.assetId);
|
|
49
|
+
asset = new models_1.BaseAsset(_source, _id);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
this.app.log.error(`[${device._source.engineId}] Cannot find asset "${device._source.assetId}" linked to device "${device._id}".`);
|
|
53
|
+
}
|
|
120
54
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
55
|
+
const measures = this.buildMeasures(device, asset, decodedPayloads[device._source.reference], payloadUuids);
|
|
56
|
+
const updatedMeasures = await this.app.trigger('device-manager:measures:receive', measures, { asset, device });
|
|
57
|
+
device.updateMeasures(updatedMeasures);
|
|
58
|
+
await this.sdk.document.update(this.config.adminIndex, InternalCollection_1.InternalCollection.DEVICES, device._id, { measures: device._source.measures });
|
|
59
|
+
if (device._source.engineId) {
|
|
60
|
+
await this.sdk.document.update(device._source.engineId, InternalCollection_1.InternalCollection.DEVICES, device._id, { measures: device._source.measures });
|
|
61
|
+
// @todo replace by batch.mCreate when available
|
|
62
|
+
await this.sdk.document.mCreate(device._source.engineId, InternalCollection_1.InternalCollection.MEASURES, updatedMeasures.map(measure => ({ body: measure })), { strict: true });
|
|
63
|
+
if (asset) {
|
|
64
|
+
asset.updateMeasures(updatedMeasures);
|
|
65
|
+
await this.sdk.document.update(device._source.engineId, InternalCollection_1.InternalCollection.ASSETS, asset._id, { measures: asset._source.measures });
|
|
66
|
+
}
|
|
124
67
|
}
|
|
125
68
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
// Search asset in cache or get in db
|
|
135
|
-
let assetCacheEntity = null;
|
|
136
|
-
if (assetId) {
|
|
137
|
-
let assetMeasuresInEngine = assetMeasuresInEngineCache[engineId];
|
|
138
|
-
if (!assetMeasuresInEngine) {
|
|
139
|
-
assetMeasuresInEngine = {};
|
|
140
|
-
assetMeasuresInEngineCache[engineId] = assetMeasuresInEngine;
|
|
141
|
-
}
|
|
142
|
-
assetCacheEntity = assetMeasuresInEngine[assetId];
|
|
143
|
-
if (!assetCacheEntity) {
|
|
144
|
-
assetCacheEntity = {
|
|
145
|
-
asset: await this.assetService.getAsset(engineId, assetId),
|
|
146
|
-
measures: [],
|
|
147
|
-
};
|
|
148
|
-
assetMeasuresInEngine[assetId] = assetCacheEntity;
|
|
69
|
+
}
|
|
70
|
+
buildMeasures(device, asset, measurements, payloadUuids) {
|
|
71
|
+
const measures = [];
|
|
72
|
+
for (const measurement of measurements) {
|
|
73
|
+
if (!this.measuresRegister.has(measurement.type)) {
|
|
74
|
+
this.app.log.warn(`Unknown measurement "${measurement.type}" from Decoder "${device._source.model}"`);
|
|
75
|
+
continue;
|
|
149
76
|
}
|
|
77
|
+
const deviceMeasureName = measurement.deviceMeasureName || measurement.type;
|
|
78
|
+
const assetMeasureName = asset === null ? undefined : this.findAssetMeasureName(device, asset, deviceMeasureName);
|
|
79
|
+
const measureContent = {
|
|
80
|
+
assetMeasureName,
|
|
81
|
+
deviceMeasureName,
|
|
82
|
+
measuredAt: measurement.measuredAt,
|
|
83
|
+
origin: {
|
|
84
|
+
assetId: asset ? asset._id : undefined,
|
|
85
|
+
deviceModel: device._source.model,
|
|
86
|
+
id: device._id,
|
|
87
|
+
payloadUuids,
|
|
88
|
+
type: types_1.OriginType.DEVICE,
|
|
89
|
+
},
|
|
90
|
+
type: measurement.type,
|
|
91
|
+
unit: this.measuresRegister.get(measurement.type).unit,
|
|
92
|
+
values: measurement.values,
|
|
93
|
+
};
|
|
94
|
+
measures.push(measureContent);
|
|
150
95
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
96
|
+
return measures;
|
|
97
|
+
}
|
|
98
|
+
async getDevices(deviceModel, references, { refresh }) {
|
|
99
|
+
let devices = [];
|
|
100
|
+
// @todo replace with batch.mGet when available
|
|
101
|
+
const { successes, errors } = await this.sdk.document.mGet(this.config.adminIndex, InternalCollection_1.InternalCollection.DEVICES, references.map(reference => models_1.Device.id(deviceModel, reference)));
|
|
102
|
+
for (const { _source, _id } of successes) {
|
|
103
|
+
devices.push(new models_1.Device(_source, _id));
|
|
159
104
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
105
|
+
// If we have unknown devices, let's check if we should register them
|
|
106
|
+
if (errors.length > 0) {
|
|
107
|
+
const { _source } = await this.batch.get(this.config.adminIndex, this.config.adminCollections.config.name, 'plugin--device-manager');
|
|
108
|
+
if (_source['device-manager'].provisioningStrategy === 'auto') {
|
|
109
|
+
const newDevices = await this.provisionDevices(deviceModel, errors, { refresh });
|
|
110
|
+
devices.push(...newDevices);
|
|
164
111
|
}
|
|
165
112
|
else {
|
|
166
|
-
|
|
167
|
-
const deviceMeasureName = measurement.deviceMeasureName ?? measurement.type;
|
|
168
|
-
const assetMeasureName = this.findAssetMeasureName(deviceId, measurement.deviceMeasureName, assetCacheEntity);
|
|
169
|
-
const measureContent = {
|
|
170
|
-
assetMeasureName,
|
|
171
|
-
deviceMeasureName,
|
|
172
|
-
measuredAt: measurement.measuredAt,
|
|
173
|
-
origin: {
|
|
174
|
-
assetId,
|
|
175
|
-
deviceModel,
|
|
176
|
-
id: deviceId,
|
|
177
|
-
payloadUuids,
|
|
178
|
-
type: types_1.OriginType.DEVICE,
|
|
179
|
-
},
|
|
180
|
-
type: measurement.type,
|
|
181
|
-
unit: this.measuresRegister.get(measurement.type).unit,
|
|
182
|
-
values: measurement.values,
|
|
183
|
-
};
|
|
184
|
-
// Insert measures in cache structs
|
|
185
|
-
if (engineMeasures) {
|
|
186
|
-
engineMeasures.push(measureContent);
|
|
187
|
-
}
|
|
188
|
-
if (assetMeasureName) {
|
|
189
|
-
assetCacheEntity.measures.push(measureContent);
|
|
190
|
-
}
|
|
191
|
-
deviceMeasures.measures.push(measureContent);
|
|
113
|
+
this.app.log.info(`Skipping new devices "${errors.join(', ')}". Auto-provisioning is disabled.`);
|
|
192
114
|
}
|
|
193
115
|
}
|
|
116
|
+
return devices;
|
|
117
|
+
}
|
|
118
|
+
async provisionDevices(deviceModel, deviceIds, { refresh }) {
|
|
119
|
+
const newDevices = deviceIds.map(deviceId => {
|
|
120
|
+
// Reference may contains a "-"
|
|
121
|
+
const [, ...rest] = deviceId.split('-');
|
|
122
|
+
const reference = rest.join('');
|
|
123
|
+
return {
|
|
124
|
+
_id: models_1.Device.id(deviceModel, reference),
|
|
125
|
+
body: {
|
|
126
|
+
measures: [],
|
|
127
|
+
model: deviceModel,
|
|
128
|
+
reference,
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
// @todo replace with batch.mCreate when available
|
|
133
|
+
const { successes } = await this.sdk.document.mCreate(this.config.adminIndex, InternalCollection_1.InternalCollection.DEVICES, newDevices, { refresh, strict: true, });
|
|
134
|
+
return successes.map(({ _source, _id }) => new models_1.Device(_source, _id));
|
|
194
135
|
}
|
|
195
136
|
/**
|
|
196
137
|
* Register new measures from a device, updates :
|
|
@@ -203,12 +144,10 @@ class MeasureService {
|
|
|
203
144
|
* @param assetId Asset id
|
|
204
145
|
* @param jsonMeasurements `AssetMeasurement` array from a request
|
|
205
146
|
* @param kuid Kuid of the user pushing the measurements
|
|
206
|
-
* @param {object} options
|
|
207
147
|
* @param options.refresh Wait for ES indexation
|
|
208
148
|
* @param options.strict If true, throw if an operation isn't possible
|
|
209
149
|
*/
|
|
210
150
|
async registerByAsset(engineId, assetId, jsonMeasurements, kuid, { refresh, strict } = {}) {
|
|
211
|
-
const eventId = `${MeasureService.eventId}:registerByAsset`;
|
|
212
151
|
const invalidMeasurements = [];
|
|
213
152
|
const validMeasures = [];
|
|
214
153
|
const asset = await this.assetService.getAsset(engineId, assetId);
|
|
@@ -250,20 +189,8 @@ class MeasureService {
|
|
|
250
189
|
};
|
|
251
190
|
}
|
|
252
191
|
asset.updateMeasures(validMeasures);
|
|
253
|
-
|
|
254
|
-
asset,
|
|
255
|
-
engineId,
|
|
256
|
-
invalidMeasurements,
|
|
257
|
-
validMeasures,
|
|
258
|
-
});
|
|
259
|
-
await this.sdk.document.update(engineId, InternalCollection_1.InternalCollection.ASSETS, asset._id, { measures: response.asset._source.measures });
|
|
192
|
+
await this.sdk.document.update(engineId, InternalCollection_1.InternalCollection.ASSETS, asset._id, { measures: asset._source.measures });
|
|
260
193
|
await this.historizeEngineMeasures(engineId, validMeasures, { refresh });
|
|
261
|
-
await this.app.trigger(`${eventId}:after`, {
|
|
262
|
-
asset,
|
|
263
|
-
engineId,
|
|
264
|
-
invalidMeasurements,
|
|
265
|
-
validMeasures,
|
|
266
|
-
});
|
|
267
194
|
return {
|
|
268
195
|
asset: asset.serialize,
|
|
269
196
|
engineId,
|
|
@@ -284,19 +211,11 @@ class MeasureService {
|
|
|
284
211
|
&& lodash_1.default.has(toValidate, 'type')
|
|
285
212
|
&& this.measuresRegister.has(toValidate.type);
|
|
286
213
|
}
|
|
287
|
-
findAssetMeasureName(
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const measureNameLink = link.measureNamesLinks.find(nameLink => nameLink.deviceMeasureName === deviceMeasureName);
|
|
292
|
-
if (measureNameLink) {
|
|
293
|
-
return measureNameLink.assetMeasureName;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
return null;
|
|
214
|
+
findAssetMeasureName(device, asset, deviceMeasureName) {
|
|
215
|
+
const deviceLink = asset._source.deviceLinks.find(link => link.deviceId === device._id);
|
|
216
|
+
const measureLink = deviceLink.measureNamesLinks.find(nameLink => nameLink.deviceMeasureName === deviceMeasureName);
|
|
217
|
+
return measureLink.assetMeasureName;
|
|
298
218
|
}
|
|
299
219
|
}
|
|
300
220
|
exports.MeasureService = MeasureService;
|
|
301
|
-
MeasureService.eventId = 'device-manager:measure';
|
|
302
221
|
//# sourceMappingURL=MeasureService.js.map
|
|
@@ -45,9 +45,7 @@ class PayloadService {
|
|
|
45
45
|
}, uuid);
|
|
46
46
|
}
|
|
47
47
|
const decodedPayload = await decoder.decode(payload, request);
|
|
48
|
-
|
|
49
|
-
const autoProvisionDevice = pluginConfig._source['device-manager'].provisioningStrategy === 'auto';
|
|
50
|
-
return this.measureService.registerByDecodedPayload(decoder.deviceModel, decodedPayload, [uuid], { autoProvisionDevice, refresh });
|
|
48
|
+
return this.measureService.processDecodedPayload(decoder.deviceModel, decodedPayload, [uuid], { refresh });
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
exports.PayloadService = PayloadService;
|
|
@@ -9,7 +9,12 @@ export declare class BaseAsset {
|
|
|
9
9
|
constructor(content: BaseAssetContent, _id?: string);
|
|
10
10
|
linkToDevice(linkRequest: LinkRequest): void;
|
|
11
11
|
unlinkDevice(device: Device): void;
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Updates the asset measures.
|
|
14
|
+
*
|
|
15
|
+
* Only keep the latest measures
|
|
16
|
+
*/
|
|
17
|
+
updateMeasures(newMeasures: MeasureContent[]): void;
|
|
13
18
|
removeMeasures(assetMeasureNames: string[]): {
|
|
14
19
|
notFound: string[];
|
|
15
20
|
removed: any[];
|
package/lib/models/BaseAsset.js
CHANGED
|
@@ -21,18 +21,21 @@ class BaseAsset {
|
|
|
21
21
|
const linkToKeep = this._source.deviceLinks.filter((deviceLink) => deviceLink.deviceId !== device._id);
|
|
22
22
|
this._source.deviceLinks = linkToKeep;
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Updates the asset measures.
|
|
26
|
+
*
|
|
27
|
+
* Only keep the latest measures
|
|
28
|
+
*/
|
|
29
|
+
updateMeasures(newMeasures) {
|
|
30
|
+
for (const newMeasure of newMeasures) {
|
|
31
|
+
const idx = this._source.measures.findIndex(measure => measure.assetMeasureName === newMeasure.assetMeasureName);
|
|
32
|
+
if (idx === -1) {
|
|
33
|
+
this._source.measures.push(newMeasure);
|
|
34
|
+
}
|
|
35
|
+
else if (newMeasure.measuredAt > this._source.measures[idx].measuredAt) {
|
|
36
|
+
this._source.measures[idx] = newMeasure;
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
|
-
this._source.measures = Array.from(measuresByName.values());
|
|
36
39
|
}
|
|
37
40
|
removeMeasures(assetMeasureNames) {
|
|
38
41
|
const removed = [];
|
package/lib/models/Device.d.ts
CHANGED
|
@@ -11,5 +11,10 @@ export declare class Device {
|
|
|
11
11
|
};
|
|
12
12
|
unlinkToAsset(): void;
|
|
13
13
|
linkToAsset(linkRequest: LinkRequest): void;
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Updates the asset measures.
|
|
16
|
+
*
|
|
17
|
+
* Only keep the latest measures
|
|
18
|
+
*/
|
|
19
|
+
updateMeasures(newMeasures: MeasureContent[]): void;
|
|
15
20
|
}
|
package/lib/models/Device.js
CHANGED
|
@@ -27,18 +27,21 @@ class Device {
|
|
|
27
27
|
linkToAsset(linkRequest) {
|
|
28
28
|
this._source.assetId = linkRequest.assetId;
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Updates the asset measures.
|
|
32
|
+
*
|
|
33
|
+
* Only keep the latest measures
|
|
34
|
+
*/
|
|
35
|
+
updateMeasures(newMeasures) {
|
|
36
|
+
for (const newMeasure of newMeasures) {
|
|
37
|
+
const idx = this._source.measures.findIndex(measure => measure.deviceMeasureName === newMeasure.deviceMeasureName);
|
|
38
|
+
if (idx === -1) {
|
|
39
|
+
this._source.measures.push(newMeasure);
|
|
40
|
+
}
|
|
41
|
+
else if (newMeasure.measuredAt > this._source.measures[idx].measuredAt) {
|
|
42
|
+
this._source.measures[idx] = newMeasure;
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
|
-
this._source.measures = Array.from(measuresByName.values());
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
exports.Device = Device;
|
|
@@ -1,40 +1,21 @@
|
|
|
1
1
|
import { Measurement } from './measures/MeasureContent';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Record containing decoded measurements for each device.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Record<deviceReference, Measurement[]>
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* const decodedPayload: DecodedPayload = {
|
|
9
9
|
* 'BZH42AZF': [
|
|
10
10
|
* {
|
|
11
11
|
* deviceMeasureName: 'battery',
|
|
12
|
-
* measuredAt:
|
|
12
|
+
* measuredAt: 1655379939496,
|
|
13
13
|
* type: 'battery',
|
|
14
14
|
* values: { battery: 32 },
|
|
15
15
|
* },
|
|
16
|
-
* {
|
|
17
|
-
* deviceMeasureName: 'internal_temperature',
|
|
18
|
-
* measuredAt: Date.now(),
|
|
19
|
-
* type: 'temperature',
|
|
20
|
-
* values: { temperature: -3 },
|
|
21
|
-
* },
|
|
22
|
-
* {
|
|
23
|
-
* deviceMeasureName: 'external_temperature',
|
|
24
|
-
* measuredAt: Date.now(),
|
|
25
|
-
* type: 'temperature',
|
|
26
|
-
* values: { temperature: 39 },
|
|
27
|
-
* },
|
|
28
16
|
* ],
|
|
29
|
-
*
|
|
30
17
|
* 'IS7L8HK': [
|
|
31
18
|
* {
|
|
32
|
-
* deviceMeasureName: 'battery',
|
|
33
|
-
* measuredAt: 1655379939496,
|
|
34
|
-
* type: 'battery',
|
|
35
|
-
* values: { battery: 92 },
|
|
36
|
-
* },
|
|
37
|
-
* {
|
|
38
19
|
* deviceMeasureName: 'internal_temperature',
|
|
39
20
|
* measuredAt: 1655379939496,
|
|
40
21
|
* type: 'temperature',
|
|
@@ -49,5 +30,4 @@ import { Measurement } from './measures/MeasureContent';
|
|
|
49
30
|
* ],
|
|
50
31
|
* };
|
|
51
32
|
*/
|
|
52
|
-
export declare type DecodedPayload = Record<string,
|
|
53
|
-
Measurement[]>;
|
|
33
|
+
export declare type DecodedPayload = Record<string, Measurement[]>;
|
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-rc9",
|
|
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": {
|