Skip to content

Commit

Permalink
Merge pull request #222 from kuzzleio/2-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrien Maret committed Sep 19, 2022
2 parents 625e2ee + 9839f10 commit 91a1005
Show file tree
Hide file tree
Showing 40 changed files with 1,366 additions and 653 deletions.
8 changes: 4 additions & 4 deletions doc/1/controllers/decoder/list-decoders/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@ List available registered decoders.
### HTTP

```http
URL: http://localhost:7512/_/device-manager/decoders/_list
URL: http://localhost:7512/_/device-manager/decoder/_list
Method: GET
```

### Other protocols

```js
{
"controller": "device-manager/decoders",
"controller": "device-manager/decoder",
"action": "list",
}
```

### Kourou

```bash
kourou device-manager/decoders:list
kourou device-manager/decoder:list
```
---

Expand All @@ -41,7 +41,7 @@ kourou device-manager/decoders:list
```js
{
"action": "list",
"controller": "device-manager/decoders",
"controller": "device-manager/decoder",
"error": null,
"node": "knode-nine-hydra-22631",
"requestId": "d888a8e1-2f80-4849-99d0-86ea70fe91e4",
Expand Down
14 changes: 12 additions & 2 deletions features/AssetCategory.feature
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Feature: AssetCategory
| status | 400 |


Scenario: Create an asset with AssetCategory and present mandatory metadata
Scenario: Create an asset with AssetCategory and present mandatory metadata, then verify content given by get and search method
When I successfully execute the action "device-manager/asset":"create" with args:
| engineId | "engine-ayse" |
| body.type | "truck" |
Expand All @@ -197,6 +197,16 @@ Feature: AssetCategory
| reference | "asset_02" |
| category.name | "bigTruck" |
| metadata.surname | "test" |
Then I refresh the collection "engine-ayse":"assets"
When I successfully execute the action "device-manager/asset":"search" with args:
| engineId | "engine-ayse" |
| body.query.match.reference | "asset_02" |
Then I should receive a result matching:
| hits[0]._source.type | "truck" |
| hits[0]._source.model | "M" |
| hits[0]._source.reference | "asset_02" |
| hits[0]._source.category.name | "bigTruck" |
| hits[0]._source.metadata.surname | "test" |

Scenario: Create an assetCategory, a mandatory metadata, link them statically and create an asset with
When I successfully execute the action "device-manager/assetCategory":"create" with args:
Expand Down Expand Up @@ -470,4 +480,4 @@ Feature: AssetCategory
| body.category | "genericTrailerTruck" |
| body.metadata.trailer | {'color' : 'red', 'size' : 'giant', 'maxLoad' : 60} |
Then I should receive an error matching:
| id | "device-manager.asset_controller.enum_metadata" |
| id | "device-manager.asset_controller.enum_metadata" |
7 changes: 0 additions & 7 deletions features/Decoders.feature
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
Feature: Device Manager Decoders

Scenario: List all registered decoders
When When I successfully execute the action "device-manager/decoders":"list"
Then I should receive a result matching:
| decoders[0] | {"deviceModel":"DummyTemp","decoderMeasures":{"theBatteryLevel":"battery"}} |
| decoders[1] | {"deviceModel":"DummyMultiTemp","decoderMeasures":{"innerTemp":"temperature","outerTemp":"temperature","lvlBattery":"battery"}} |
| decoders[2] | {"deviceModel":"DummyTempPosition","decoderMeasures":{"theTemperature":"temperature","theBattery":"battery","thePosition":"position"}} |

Scenario: Creates default roles, profiles and users
Then I am able to get a role with id "payload-gateway.dummy-temp"
Then I am able to get a role with id "payload-gateway.dummy-temp-position"
Expand Down
15 changes: 14 additions & 1 deletion features/DeviceController/LinkAsset.feature
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Feature: LinkAsset
| deviceLinks[0].measureNamesLinks[2].assetMeasureName | "lvlBattery" |
| deviceLinks[0].measureNamesLinks[2].deviceMeasureName | "lvlBattery" |

Scenario: Link device to an asset with measureNamesLinks
Scenario: Link device to an asset with partial measureNamesLinks and receive a payload
When I successfully execute the action "device-manager/device":"linkAsset" with args:
| _id | "DummyMultiTemp-attached_ayse_unlinked_1" |
| assetId | "container-FRIDGE-unlinked_1" |
Expand All @@ -50,6 +50,19 @@ Feature: LinkAsset
| deviceLinks[0].deviceId | "DummyMultiTemp-attached_ayse_unlinked_1" |
| deviceLinks[0].measureNamesLinks[0].assetMeasureName | "coreInnerTemp" |
| deviceLinks[0].measureNamesLinks[0].deviceMeasureName | "innerTemp" |
When I successfully receive a "dummy-multi-temp" payload with:
| payloads[0].deviceEUI | "attached_ayse_unlinked_1" |
| payloads[0].registerInner | 1 |
| payloads[0].registerOuter | 2 |
| payloads[0].lvlBattery | 1 |
And I refresh the collection "engine-ayse":"assets"
Then The document "engine-ayse":"assets":"container-FRIDGE-unlinked_1" content match:
| measures[0].type | "temperature" |
| measures[0].values.temperature | 1 |
| measures[0].deviceMeasureName | "innerTemp" |
| measures[0].assetMeasureName | "coreInnerTemp" |
| measures[0].origin.assetId | "container-FRIDGE-unlinked_1" |
| measures[0].origin.id | "DummyMultiTemp-attached_ayse_unlinked_1" |

Scenario: Link device to an asset and enriching the asset with before event
When I successfully execute the action "device-manager/device":"linkAsset" with args:
Expand Down
22 changes: 10 additions & 12 deletions features/DeviceController/Misc.feature
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,15 @@ Feature: Device Controller actions
Then I should receive a result matching:
| total | 1 |

Scenario: Get measure without deviceMeasureName
Scenario: Throw an error when decoding unknown measure name
Given I successfully execute the action "device-manager/device":"create" with args:
| engineId | "device-manager" |
| body.model | "DummyTemp" |
| body.reference | "test" |
When I successfully receive a "dummy-temp" payload with:
| deviceEUI | "test" |
| register55 | 100 |
| batteryLevel | 1 |
| engineId | "device-manager" |
| body.model | "DummyTemp" |
| body.reference | "test" |
When I receive a "dummy-temp" payload with:
| deviceEUI | "test" |
| register55 | 100 |
| unknownMeasure | 100 |
| batteryLevel | 1 |
Then The document "device-manager":"devices":"DummyTemp-test" content match:
| measures[0].type | "temperature" |
| measures[0].deviceMeasureName | "temperature" |
| measures[1].type | "battery" |
| measures[1].deviceMeasureName | "theBatteryLevel" |
| measures | [] |
11 changes: 11 additions & 0 deletions features/PayloadController.feature
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,14 @@ Feature: Payloads Controller
| measures[0].origin.id | "DummyMultiTemp-enrich_me_master+container-FRIDGE-unlinked_1" |
| measures[1].origin.id | "DummyMultiTemp-enrich_me_master+container-FRIDGE-unlinked_1" |

Scenario: Decode Device metadata from payload
When I successfully receive a "dummy-temp" payload with:
| deviceEUI | "12345" |
| register55 | 23.3 |
| lvlBattery | 0.8 |
| metadata.color | "RED" |
And I refresh the collection "device-manager":"devices"
Then The document "device-manager":"devices":"DummyTemp-12345" content match:
| reference | "12345" |
| model | "DummyTemp" |
| metadata.color | "RED" |
15 changes: 12 additions & 3 deletions features/fixtures/application/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,27 @@ import {
DummyMultiTempDecoder,
DummyTempDecoder,
DummyTempPositionDecoder,
DummyAccelerometer3dDecoder,
} from './decoders';
import { registerTestPipes } from './testPipes'
import { TreeNodeController } from '../../fakeclasses/TreeNodeController';
import { InvertTreeNodeController } from '../../fakeclasses/InvertTreeNodeController';
import { acceleration3dMeasure } from './measures/Acceleration3dMeasure';

const app = new Backend('kuzzle');

const deviceManager = new DeviceManagerPlugin();

deviceManager.decoders.register(new DummyTempDecoder(deviceManager.measures));
deviceManager.decoders.register(new DummyMultiTempDecoder(deviceManager.measures));
deviceManager.decoders.register(new DummyTempPositionDecoder(deviceManager.measures));
deviceManager.measures.register('acceleration3d', acceleration3dMeasure);

deviceManager.decoders.register(new DummyTempDecoder());
deviceManager.devices.registerMetadata({
color: { type: 'keyword' }
});

deviceManager.decoders.register(new DummyMultiTempDecoder());
deviceManager.decoders.register(new DummyTempPositionDecoder());
deviceManager.decoders.register(new DummyAccelerometer3dDecoder());

deviceManager.devices.registerMetadata({
group: {
Expand Down
42 changes: 42 additions & 0 deletions features/fixtures/application/decoders/DummyAccelerometer3d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { JSONObject } from 'kuzzle';

import {
DecodedPayload, Decoder
} from '../../../../index';
import { Acceleration3dMeasurement } from '../measures/Acceleration3dMeasure';

export class DummyAccelerometer3dDecoder extends Decoder {
public measures = [
{ name: 'acceleration3d', type: 'acceleration3d' },
] as const;

constructor () {
super();

this.payloadsMappings = {
deviceEUI: { type: 'keyword' }
};
}

async validate (payload: JSONObject) {
return payload.x && payload.y && payload.z && payload.id;
}

async decode (payload: JSONObject): Promise<DecodedPayload<Decoder>> {
const decodedPayload = new DecodedPayload<DummyAccelerometer3dDecoder>(this);

const measurement: Acceleration3dMeasurement = {
measuredAt: Date.now(),
type: 'acceleration3d',
values: {
x: payload.x,
y: payload.y,
z: payload.z,
}
}

decodedPayload.addMeasurement(payload.id, 'acceleration3d', measurement);

return decodedPayload;
}
}
59 changes: 29 additions & 30 deletions features/fixtures/application/decoders/DummyMultiTempDecoder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JSONObject, KuzzleRequest, PreconditionError } from 'kuzzle';
import { JSONObject, PreconditionError } from 'kuzzle';

import {
Decoder,
Expand All @@ -9,20 +9,21 @@ import {
} from '../../../../index';

export class DummyMultiTempDecoder extends Decoder {
constructor (measuresRegister: MeasuresRegister) {
super('DummyMultiTemp', {
innerTemp: 'temperature',
outerTemp: 'temperature',
lvlBattery: 'battery',
},
measuresRegister);
public measures = [
{ name: 'innerTemp', type: 'temperature' },
{ name: 'outerTemp', type: 'temperature' },
{ name: 'lvlBattery', type: 'battery' },
] as const;

constructor () {
super();

this.payloadsMappings = {
deviceEUI: { type: 'keyword' }
};
}

async validate (payload: JSONObject, request: KuzzleRequest) {
async validate (payload: JSONObject) {
if (payload.payloads.find(devicePayload => ! devicePayload.deviceEUI)) {
throw new PreconditionError('Invalid payload: missing "deviceEUI" in some devicePayload');
}
Expand All @@ -34,47 +35,45 @@ export class DummyMultiTempDecoder extends Decoder {
return true;
}

async decode (payload: JSONObject, request: KuzzleRequest): Promise<DecodedPayload> {
const decodedPayload: DecodedPayload = {};
async decode (payload: JSONObject): Promise<DecodedPayload<Decoder>> {
const decodedPayload = new DecodedPayload<DummyMultiTempDecoder>(this);

for (const devicePayload of payload.payloads) {
const deviceMeasurements = [];

if (devicePayload.registerInner) {
deviceMeasurements.push({
deviceMeasureName: 'innerTemp',
const innerTemp: TemperatureMeasurement = {
measuredAt: devicePayload.measuredAtRegisterInner ?? Date.now(),
type: 'temperature',
values: {
temperature: devicePayload.registerInner,
},
});
}

decodedPayload.addMeasurement(devicePayload.deviceEUI, 'innerTemp', innerTemp);
}

if (devicePayload.registerOuter) {
deviceMeasurements.push(
{
deviceMeasureName: 'outerTemp',
measuredAt: devicePayload.measuredAtRegisterOuter ?? Date.now(),
type: 'temperature',
values: {
temperature: devicePayload.registerOuter,
},
});
const outerTemp: TemperatureMeasurement = {
measuredAt: devicePayload.measuredAtRegisterOuter ?? Date.now(),
type: 'temperature',
values: {
temperature: devicePayload.registerOuter,
},
};

decodedPayload.addMeasurement(devicePayload.deviceEUI, 'outerTemp', outerTemp);
}

if (devicePayload.lvlBattery) {
deviceMeasurements.push({
deviceMeasureName: 'lvlBattery',
const battery: BatteryMeasurement = {
measuredAt: devicePayload.measuredAtLvlBattery ?? Date.now(),
type: 'battery',
values: {
battery: devicePayload.lvlBattery * 100,
},
});
}
}

decodedPayload[devicePayload.deviceEUI] = deviceMeasurements;
decodedPayload.addMeasurement(devicePayload.deviceEUI, 'lvlBattery', battery);
}
}

return decodedPayload;
Expand Down
Loading

0 comments on commit 91a1005

Please sign in to comment.