@hello.nrfcloud.com/proto-map 5.6.3 → 7.0.0
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/README.md +0 -16
- package/dist/generator/generateModels.js +0 -85
- package/dist/generator/models.js +1 -83
- package/dist/markdown/getCodeBlock.js +0 -26
- package/dist/models/check-model-rules.js +1 -91
- package/dist/models/models.js +5 -114
- package/dist/models/types.js +0 -12
- package/dist/senml/lwm2mToSenML.js +52 -26
- package/dist/senml/lwm2mToSenML.spec.js +3 -1
- package/dist/senml/senMLtoLwM2M.js +24 -12
- package/dist/senml/senMLtoLwM2M.spec.js +8 -4
- package/models/README.md +0 -4
- package/models/check-model-rules.ts +1 -90
- package/models/models.ts +1 -8
- package/models/types.ts +0 -16
- package/package.json +2 -3
- package/senml/lwm2mToSenML.spec.ts +7 -1
- package/senml/lwm2mToSenML.ts +42 -22
- package/senml/senMLtoLwM2M.spec.ts +8 -4
- package/senml/senMLtoLwM2M.ts +33 -16
- package/dist/generator/isDir.js +0 -163
- package/dist/generator/isDir.spec.js +0 -212
- package/dist/markdown/getFrontMatter.js +0 -15
- package/dist/models/asset_tracker_v2+AWS/examples/examples.spec.js +0 -489
- package/models/PCA20035+solar/README.md +0 -10
- package/models/PCA20035+solar/transforms/airQuality.md +0 -48
- package/models/PCA20035+solar/transforms/battery.md +0 -46
- package/models/PCA20035+solar/transforms/button.md +0 -45
- package/models/PCA20035+solar/transforms/deviceInfo.md +0 -72
- package/models/PCA20035+solar/transforms/gain.md +0 -45
- package/models/PCA20035+solar/transforms/geolocationFromGroundfix.md +0 -67
- package/models/PCA20035+solar/transforms/geolocationFromMessage.md +0 -80
- package/models/PCA20035+solar/transforms/humidity.md +0 -43
- package/models/PCA20035+solar/transforms/networkInfo.md +0 -84
- package/models/PCA20035+solar/transforms/pressure.md +0 -43
- package/models/PCA20035+solar/transforms/temperature.md +0 -43
- package/models/asset_tracker_v2+AWS/README.md +0 -6
- package/models/asset_tracker_v2+AWS/examples/examples.spec.ts +0 -229
- package/models/asset_tracker_v2+AWS/examples/shadow/example-1.json +0 -24
- package/models/asset_tracker_v2+AWS/examples/shadow/example-2.json +0 -30
- package/models/asset_tracker_v2+AWS/examples/shadow/example-3.json +0 -37
- package/models/asset_tracker_v2+AWS/examples/shadow/example-4.json +0 -48
- package/models/asset_tracker_v2+AWS/examples/shadow/example-5.json +0 -43
- package/models/asset_tracker_v2+AWS/transforms/GNSS.md +0 -66
- package/models/asset_tracker_v2+AWS/transforms/battery-voltage.md +0 -50
- package/models/asset_tracker_v2+AWS/transforms/device-info.md +0 -61
- package/models/asset_tracker_v2+AWS/transforms/env.md +0 -69
- package/models/asset_tracker_v2+AWS/transforms/fuel-gauge.md +0 -62
- package/models/asset_tracker_v2+AWS/transforms/roam.md +0 -100
- package/models/asset_tracker_v2+AWS/transforms/solar.md +0 -58
package/README.md
CHANGED
|
@@ -65,28 +65,12 @@ The conformity to the rules is checked using the script
|
|
|
65
65
|
mapped to the LwM2M object's timestamp property and must not be send as a
|
|
66
66
|
property.
|
|
67
67
|
|
|
68
|
-
## Model transform definitions
|
|
69
|
-
|
|
70
|
-
Optionally, a set of [JSONata](https://jsonata.org/) expression can be defined
|
|
71
|
-
[per model](./models/) which allows to convert from the data format that is
|
|
72
|
-
published by the devices to the SenML data format used to describe LwM2M objects
|
|
73
|
-
([example mapping](./models/PCA20035+solar/transforms/geolocation.md).
|
|
74
|
-
|
|
75
68
|
### Model definition rules
|
|
76
69
|
|
|
77
70
|
- **device models** are identified using a model name, for example
|
|
78
71
|
`PCA20035+solar`
|
|
79
72
|
- a [`README.md`](./models/PCA20035+solar/README.md) must be provided that
|
|
80
73
|
describes the model
|
|
81
|
-
- transforms may define transforms that convert the data sent by the device
|
|
82
|
-
using JSONata for JSON payloads in one or more Markdown files
|
|
83
|
-
([Example](./models/PCA20035+solar/transforms/geolocationFromGroundfix.md)):
|
|
84
|
-
- The `Match Expression` the must evaluate to `true` for the
|
|
85
|
-
`Transform Expression` to be applied to the input message
|
|
86
|
-
- an `Input Example` and a `Result Example` must be supplied to validate the
|
|
87
|
-
expression
|
|
88
|
-
- The result of the Transform Expression must be SenML according to the rules
|
|
89
|
-
outlined below.
|
|
90
74
|
|
|
91
75
|
The conformity to the rules is checked using the script
|
|
92
76
|
[`./models/check-model-rules.ts`](./models/check-model-rules.ts).
|
|
@@ -1,59 +1,9 @@
|
|
|
1
|
-
function _array_like_to_array(arr, len) {
|
|
2
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
-
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
-
return arr2;
|
|
5
|
-
}
|
|
6
|
-
function _array_with_holes(arr) {
|
|
7
|
-
if (Array.isArray(arr)) return arr;
|
|
8
|
-
}
|
|
9
|
-
function _iterable_to_array_limit(arr, i) {
|
|
10
|
-
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
11
|
-
if (_i == null) return;
|
|
12
|
-
var _arr = [];
|
|
13
|
-
var _n = true;
|
|
14
|
-
var _d = false;
|
|
15
|
-
var _s, _e;
|
|
16
|
-
try {
|
|
17
|
-
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
18
|
-
_arr.push(_s.value);
|
|
19
|
-
if (i && _arr.length === i) break;
|
|
20
|
-
}
|
|
21
|
-
} catch (err) {
|
|
22
|
-
_d = true;
|
|
23
|
-
_e = err;
|
|
24
|
-
} finally{
|
|
25
|
-
try {
|
|
26
|
-
if (!_n && _i["return"] != null) _i["return"]();
|
|
27
|
-
} finally{
|
|
28
|
-
if (_d) throw _e;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return _arr;
|
|
32
|
-
}
|
|
33
|
-
function _non_iterable_rest() {
|
|
34
|
-
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
35
|
-
}
|
|
36
|
-
function _sliced_to_array(arr, i) {
|
|
37
|
-
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
38
|
-
}
|
|
39
|
-
function _unsupported_iterable_to_array(o, minLen) {
|
|
40
|
-
if (!o) return;
|
|
41
|
-
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
42
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
43
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
44
|
-
if (n === "Map" || n === "Set") return Array.from(n);
|
|
45
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
46
|
-
}
|
|
47
1
|
import ts from 'typescript';
|
|
48
2
|
import { addDocBlock } from './addDocBlock.js';
|
|
49
3
|
import { tokenizeName } from './tokenizeName.js';
|
|
50
4
|
import { parseREADME } from 'markdown/parseREADME.js';
|
|
51
5
|
export var generateModels = function(models) {
|
|
52
6
|
var types = [];
|
|
53
|
-
types.push(ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
|
|
54
|
-
ts.factory.createImportSpecifier(true, undefined, ts.factory.createIdentifier('Transform')),
|
|
55
|
-
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier('TransformType'))
|
|
56
|
-
])), ts.factory.createStringLiteral("./types.js")));
|
|
57
7
|
types.push(addDocBlock([
|
|
58
8
|
'The Model IDs defined in this repo.'
|
|
59
9
|
], ts.factory.createEnumDeclaration([
|
|
@@ -68,11 +18,6 @@ export var generateModels = function(models) {
|
|
|
68
18
|
addDocBlock([
|
|
69
19
|
'The Model ID'
|
|
70
20
|
], ts.factory.createPropertySignature(undefined, ts.factory.createStringLiteral('id'), undefined, ts.factory.createTypeReferenceNode('ModelID'))),
|
|
71
|
-
addDocBlock([
|
|
72
|
-
'The transforms defined for this model.'
|
|
73
|
-
], ts.factory.createPropertySignature(undefined, ts.factory.createStringLiteral('transforms'), undefined, ts.factory.createTypeReferenceNode('Array', [
|
|
74
|
-
ts.factory.createTypeReferenceNode('Transform')
|
|
75
|
-
]))),
|
|
76
21
|
addDocBlock([
|
|
77
22
|
'Description of the Model from the README.md'
|
|
78
23
|
], ts.factory.createPropertySignature(undefined, ts.factory.createStringLiteral('about'), undefined, ts.factory.createTypeLiteralNode([
|
|
@@ -100,17 +45,6 @@ export var generateModels = function(models) {
|
|
|
100
45
|
ts.factory.createObjectLiteralExpression([
|
|
101
46
|
// id
|
|
102
47
|
ts.factory.createPropertyAssignment(ts.factory.createStringLiteral('id'), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('ModelID'), ts.factory.createIdentifier(tokenizeName(model.id)))),
|
|
103
|
-
// transforms
|
|
104
|
-
ts.factory.createPropertyAssignment(ts.factory.createStringLiteral('transforms'), ts.factory.createArrayLiteralExpression(model.transforms.map(function(transform) {
|
|
105
|
-
return ts.factory.createObjectLiteralExpression([
|
|
106
|
-
// type
|
|
107
|
-
ts.factory.createPropertyAssignment(ts.factory.createStringLiteral('type'), transform.type === 'messages' ? ts.factory.createIdentifier('TransformType.Messages') : ts.factory.createIdentifier('TransformType.Shadow')),
|
|
108
|
-
// match
|
|
109
|
-
ts.factory.createPropertyAssignment(ts.factory.createStringLiteral('match'), createAssignment(transform.match)),
|
|
110
|
-
// transform
|
|
111
|
-
ts.factory.createPropertyAssignment(ts.factory.createStringLiteral('transform'), createAssignment(transform.transform))
|
|
112
|
-
]);
|
|
113
|
-
}))),
|
|
114
48
|
// About
|
|
115
49
|
ts.factory.createPropertyAssignment(ts.factory.createStringLiteral('about'), ts.factory.createObjectLiteralExpression([
|
|
116
50
|
ts.factory.createPropertyAssignment(ts.factory.createStringLiteral('title'), ts.factory.createStringLiteral(readme.heading)),
|
|
@@ -121,22 +55,3 @@ export var generateModels = function(models) {
|
|
|
121
55
|
], ts.NodeFlags.Const))));
|
|
122
56
|
return types;
|
|
123
57
|
};
|
|
124
|
-
var createAssignment = function(v) {
|
|
125
|
-
if (v === null) return ts.factory.createNull();
|
|
126
|
-
if (typeof v === 'string') {
|
|
127
|
-
return ts.factory.createStringLiteral(v);
|
|
128
|
-
}
|
|
129
|
-
if (Array.isArray(v)) {
|
|
130
|
-
return ts.factory.createArrayLiteralExpression(v.map(function(el) {
|
|
131
|
-
return createAssignment(el);
|
|
132
|
-
}));
|
|
133
|
-
}
|
|
134
|
-
if (typeof v === 'object') return ts.factory.createObjectLiteralExpression(Object.entries(v).map(function(param) {
|
|
135
|
-
var _param = _sliced_to_array(param, 2), k = _param[0], _$v = _param[1];
|
|
136
|
-
return ts.factory.createPropertyAssignment(ts.factory.createStringLiteral(k), createAssignment(_$v));
|
|
137
|
-
}));
|
|
138
|
-
return addDocBlock([
|
|
139
|
-
"Could not convert node",
|
|
140
|
-
JSON.stringify(v)
|
|
141
|
-
], ts.factory.createNull());
|
|
142
|
-
};
|
package/dist/generator/models.js
CHANGED
|
@@ -154,12 +154,8 @@ import chalk from 'chalk';
|
|
|
154
154
|
import { readFile, readdir, stat, writeFile } from 'node:fs/promises';
|
|
155
155
|
import os from 'node:os';
|
|
156
156
|
import path from 'node:path';
|
|
157
|
-
import { getCodeBlock } from '../markdown/getCodeBlock.js';
|
|
158
|
-
import { getFrontMatter } from '../markdown/getFrontMatter.js';
|
|
159
157
|
import { generateModels } from './generateModels.js';
|
|
160
158
|
import { printNode } from './printNode.js';
|
|
161
|
-
import { FrontMatter } from '../models/types.js';
|
|
162
|
-
import { isDir } from './isDir.js';
|
|
163
159
|
var baseDir = process.cwd();
|
|
164
160
|
var subDir = function() {
|
|
165
161
|
for(var _len = arguments.length, tree = new Array(_len), _key = 0; _key < _len; _key++){
|
|
@@ -170,78 +166,6 @@ var subDir = function() {
|
|
|
170
166
|
].concat(_to_consumable_array(tree)));
|
|
171
167
|
};
|
|
172
168
|
console.log(chalk.gray('Models'));
|
|
173
|
-
var loadModelTransforms = function() {
|
|
174
|
-
var _ref = _async_to_generator(function(model) {
|
|
175
|
-
var transformersDir, _;
|
|
176
|
-
return _ts_generator(this, function(_state) {
|
|
177
|
-
switch(_state.label){
|
|
178
|
-
case 0:
|
|
179
|
-
transformersDir = subDir('models', model, 'transforms');
|
|
180
|
-
return [
|
|
181
|
-
4,
|
|
182
|
-
isDir(transformersDir)
|
|
183
|
-
];
|
|
184
|
-
case 1:
|
|
185
|
-
if (!_state.sent()) return [
|
|
186
|
-
2,
|
|
187
|
-
[]
|
|
188
|
-
];
|
|
189
|
-
_ = Promise.all;
|
|
190
|
-
return [
|
|
191
|
-
4,
|
|
192
|
-
readdir(transformersDir)
|
|
193
|
-
];
|
|
194
|
-
case 2:
|
|
195
|
-
return [
|
|
196
|
-
2,
|
|
197
|
-
_.apply(Promise, [
|
|
198
|
-
_state.sent()
|
|
199
|
-
]).then(function(entries) {
|
|
200
|
-
return entries.filter(function(e) {
|
|
201
|
-
return e.endsWith('.md');
|
|
202
|
-
});
|
|
203
|
-
}).then(function() {
|
|
204
|
-
var _ref = _async_to_generator(function(expressions) {
|
|
205
|
-
return _ts_generator(this, function(_state) {
|
|
206
|
-
return [
|
|
207
|
-
2,
|
|
208
|
-
Promise.all(expressions.map(function() {
|
|
209
|
-
var _ref = _async_to_generator(function(expression) {
|
|
210
|
-
return _ts_generator(this, function(_state) {
|
|
211
|
-
return [
|
|
212
|
-
2,
|
|
213
|
-
readFile(subDir('models', model, 'transforms', expression), 'utf-8')
|
|
214
|
-
];
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
return function(expression) {
|
|
218
|
-
return _ref.apply(this, arguments);
|
|
219
|
-
};
|
|
220
|
-
}()))
|
|
221
|
-
];
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
return function(expressions) {
|
|
225
|
-
return _ref.apply(this, arguments);
|
|
226
|
-
};
|
|
227
|
-
}()).then(function(transforms) {
|
|
228
|
-
return transforms.map(function(markdown) {
|
|
229
|
-
var findBlock = getCodeBlock(markdown);
|
|
230
|
-
return {
|
|
231
|
-
type: getFrontMatter(markdown, FrontMatter).type,
|
|
232
|
-
match: findBlock('jsonata', 'Match Expression'),
|
|
233
|
-
transform: findBlock('jsonata', 'Transform Expression')
|
|
234
|
-
};
|
|
235
|
-
});
|
|
236
|
-
})
|
|
237
|
-
];
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
});
|
|
241
|
-
return function loadModelTransforms(model) {
|
|
242
|
-
return _ref.apply(this, arguments);
|
|
243
|
-
};
|
|
244
|
-
}();
|
|
245
169
|
var models = await Promise.all((await Promise.all((await readdir(subDir('models'))).map(function() {
|
|
246
170
|
var _ref = _async_to_generator(function(f) {
|
|
247
171
|
var _tmp;
|
|
@@ -279,17 +203,11 @@ var models = await Promise.all((await Promise.all((await readdir(subDir('models'
|
|
|
279
203
|
_tmp = {
|
|
280
204
|
id: model.name
|
|
281
205
|
};
|
|
282
|
-
return [
|
|
283
|
-
4,
|
|
284
|
-
loadModelTransforms(model.name)
|
|
285
|
-
];
|
|
286
|
-
case 1:
|
|
287
|
-
_tmp.transforms = _state.sent();
|
|
288
206
|
return [
|
|
289
207
|
4,
|
|
290
208
|
readFile(path.join(subDir('models'), model.name, 'README.md'), 'utf-8')
|
|
291
209
|
];
|
|
292
|
-
case
|
|
210
|
+
case 1:
|
|
293
211
|
return [
|
|
294
212
|
2,
|
|
295
213
|
(_tmp.readmeMarkdown = _state.sent(), _tmp)
|
|
@@ -1,43 +1,17 @@
|
|
|
1
1
|
import { remark } from 'remark';
|
|
2
2
|
export var parseMarkdown2 = remark();
|
|
3
|
-
var isCodeBlock = function(lang) {
|
|
4
|
-
return function(child) {
|
|
5
|
-
return child.type === 'code' && child.lang === lang;
|
|
6
|
-
};
|
|
7
|
-
};
|
|
8
|
-
var isHeadingWithTitle = function(title) {
|
|
9
|
-
return function(child) {
|
|
10
|
-
var _child_children_;
|
|
11
|
-
return child.type === 'heading' && ((_child_children_ = child.children[0]) === null || _child_children_ === void 0 ? void 0 : _child_children_.type) === 'text' && child.children[0].value === title;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
3
|
var isHeading = function(child) {
|
|
15
4
|
return child.type === 'heading';
|
|
16
5
|
};
|
|
17
6
|
var isParagraph = function(child) {
|
|
18
7
|
return child.type === 'paragraph';
|
|
19
8
|
};
|
|
20
|
-
var codeBlockWithHeading = function(children) {
|
|
21
|
-
return function(lang, title) {
|
|
22
|
-
var block = children.find(function(child, index, array) {
|
|
23
|
-
if (!isCodeBlock(lang)(child)) return false;
|
|
24
|
-
var prevChild = array[index - 1];
|
|
25
|
-
if (prevChild === undefined) return false;
|
|
26
|
-
return isHeadingWithTitle(title)(prevChild);
|
|
27
|
-
});
|
|
28
|
-
if (block === undefined) throw new Error("Could not find ".concat(lang, ' codeblock with title "').concat(title, '"!'));
|
|
29
|
-
return block.value;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
9
|
var headingWithLevel = function(children, level) {
|
|
33
10
|
return children.filter(isHeading).find(function(param) {
|
|
34
11
|
var depth = param.depth;
|
|
35
12
|
return depth === level;
|
|
36
13
|
});
|
|
37
14
|
};
|
|
38
|
-
export var getCodeBlock = function(markdown) {
|
|
39
|
-
return codeBlockWithHeading(remark().parse(markdown).children);
|
|
40
|
-
};
|
|
41
15
|
export var getHeading = function(markdown, level) {
|
|
42
16
|
return headingWithLevel(remark().parse(markdown).children, level);
|
|
43
17
|
};
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import jsonata from 'jsonata';
|
|
3
2
|
import assert from 'node:assert/strict';
|
|
4
3
|
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
5
4
|
import path from 'node:path';
|
|
6
|
-
import {
|
|
7
|
-
import { senMLtoLwM2M } from '../senml/senMLtoLwM2M.js';
|
|
8
|
-
import { getCodeBlock } from '../markdown/getCodeBlock.js';
|
|
9
|
-
import { getFrontMatter } from '../markdown/getFrontMatter.js';
|
|
10
|
-
import { validateSenML } from '../senml/validateSenML.js';
|
|
11
|
-
import { isRegisteredLwM2MObject } from '../lwm2m/isRegisteredLwM2MObject.js';
|
|
12
|
-
import { hasValue } from '../senml/hasValue.js';
|
|
5
|
+
import { ModelIDRegExp } from './types.js';
|
|
13
6
|
import { parseREADME } from 'markdown/parseREADME.js';
|
|
14
7
|
console.log(chalk.gray('Models rules check'));
|
|
15
8
|
console.log('');
|
|
@@ -37,89 +30,6 @@ try {
|
|
|
37
30
|
throw new Error("README is not valid for ".concat(model, "!"));
|
|
38
31
|
}
|
|
39
32
|
console.log(chalk.green('✔'), chalk.gray("README.md is valid"));
|
|
40
|
-
// Validate jsonata expressions
|
|
41
|
-
var hasTransforms = false;
|
|
42
|
-
var transformsFolder = path.join(modelDir, 'transforms');
|
|
43
|
-
try {
|
|
44
|
-
await stat(transformsFolder);
|
|
45
|
-
hasTransforms = true;
|
|
46
|
-
console.log(' ', chalk.gray('Transforms:'));
|
|
47
|
-
} catch (e) {
|
|
48
|
-
console.log(' ', chalk.gray('No transforms found.'));
|
|
49
|
-
}
|
|
50
|
-
if (hasTransforms) {
|
|
51
|
-
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
52
|
-
try {
|
|
53
|
-
for(var _iterator1 = (await readdir(transformsFolder)).filter(function(f) {
|
|
54
|
-
return f.endsWith('.md');
|
|
55
|
-
})[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
56
|
-
var transform = _step1.value;
|
|
57
|
-
console.log(' ', chalk.white('·'), chalk.white.bold(transform));
|
|
58
|
-
var markdown = await readFile(path.join(modelDir, 'transforms', transform), 'utf-8');
|
|
59
|
-
// Validate front-matter
|
|
60
|
-
var type = getFrontMatter(markdown, FrontMatter).type;
|
|
61
|
-
console.log(' ', chalk.green('✔'), chalk.gray("Type ".concat(type, " is valid")));
|
|
62
|
-
var findBlock = getCodeBlock(markdown);
|
|
63
|
-
var matchExpression = findBlock('jsonata', 'Match Expression');
|
|
64
|
-
var transformExpression = findBlock('jsonata', 'Transform Expression');
|
|
65
|
-
var inputExample = JSON.parse(findBlock('json', 'Input Example'));
|
|
66
|
-
var resultExample = JSON.parse(findBlock('json', 'Result Example'));
|
|
67
|
-
var selectResult = await jsonata(matchExpression).evaluate(inputExample);
|
|
68
|
-
if (selectResult !== true) {
|
|
69
|
-
throw new Error("The select expression did not evaluate to true with the given example.");
|
|
70
|
-
}
|
|
71
|
-
console.log(' ', chalk.green('✔'), chalk.gray('Select expression evaluated to true for the example input'));
|
|
72
|
-
var transformResult = await jsonata(// For testing purposes this function call result is hardcoded
|
|
73
|
-
transformExpression.replace('$millis()', '1699999999999')).evaluate(inputExample);
|
|
74
|
-
var maybeValidSenML = validateSenML(transformResult.filter(hasValue));
|
|
75
|
-
if ('errors' in maybeValidSenML) {
|
|
76
|
-
console.error(maybeValidSenML.errors);
|
|
77
|
-
throw new Error('The JSONata expression must produce valid SenML');
|
|
78
|
-
}
|
|
79
|
-
assert.deepEqual(maybeValidSenML.value, resultExample);
|
|
80
|
-
console.log(' ', chalk.green('✔'), chalk.gray('Transformation result is valid SenML'));
|
|
81
|
-
assert.deepEqual(maybeValidSenML.value, resultExample);
|
|
82
|
-
console.log(' ', chalk.green('✔'), chalk.gray('The transformation result matches the example'));
|
|
83
|
-
var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
|
|
84
|
-
try {
|
|
85
|
-
// Validate
|
|
86
|
-
for(var _iterator2 = senMLtoLwM2M(maybeValidSenML.value)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true){
|
|
87
|
-
var object = _step2.value;
|
|
88
|
-
if (!isRegisteredLwM2MObject(object, console.error)) {
|
|
89
|
-
throw new Error('The LwM2M object must follow LwM2M schema definition');
|
|
90
|
-
}
|
|
91
|
-
console.log(' ', chalk.green('✔'), chalk.gray('SenML object is valid LwM2M'));
|
|
92
|
-
}
|
|
93
|
-
} catch (err) {
|
|
94
|
-
_didIteratorError2 = true;
|
|
95
|
-
_iteratorError2 = err;
|
|
96
|
-
} finally{
|
|
97
|
-
try {
|
|
98
|
-
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
|
99
|
-
_iterator2.return();
|
|
100
|
-
}
|
|
101
|
-
} finally{
|
|
102
|
-
if (_didIteratorError2) {
|
|
103
|
-
throw _iteratorError2;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
} catch (err) {
|
|
109
|
-
_didIteratorError1 = true;
|
|
110
|
-
_iteratorError1 = err;
|
|
111
|
-
} finally{
|
|
112
|
-
try {
|
|
113
|
-
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
114
|
-
_iterator1.return();
|
|
115
|
-
}
|
|
116
|
-
} finally{
|
|
117
|
-
if (_didIteratorError1) {
|
|
118
|
-
throw _iteratorError1;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
33
|
}
|
|
124
34
|
} catch (err) {
|
|
125
35
|
_didIteratorError = true;
|
package/dist/models/models.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The Model IDs defined in this repo.
|
|
3
|
+
*/ function _define_property(obj, key, value) {
|
|
2
4
|
if (key in obj) {
|
|
3
5
|
Object.defineProperty(obj, key, {
|
|
4
6
|
value: value,
|
|
@@ -11,127 +13,16 @@ function _define_property(obj, key, value) {
|
|
|
11
13
|
}
|
|
12
14
|
return obj;
|
|
13
15
|
}
|
|
14
|
-
import { TransformType } from "./types.js";
|
|
15
16
|
export var ModelID;
|
|
16
17
|
(function(ModelID) {
|
|
17
|
-
ModelID["PCA20035_solar"] = "PCA20035+solar";
|
|
18
|
-
ModelID["Asset_tracker_v2_AWS"] = "asset_tracker_v2+AWS";
|
|
19
18
|
ModelID["Kartverket_vasstandsdata"] = "kartverket-vasstandsdata";
|
|
20
19
|
})(ModelID || (ModelID = {}));
|
|
21
|
-
var _obj;
|
|
22
20
|
/**
|
|
23
21
|
* The models defined for hello.nrfcloud.com
|
|
24
|
-
*/ export var models = (
|
|
25
|
-
"id": "PCA20035+solar",
|
|
26
|
-
"transforms": [
|
|
27
|
-
{
|
|
28
|
-
"type": TransformType.Messages,
|
|
29
|
-
"match": "appId = 'AIR_QUAL'",
|
|
30
|
-
"transform": "[\n {\"bn\": \"14205/0/\", \"n\": \"10\", \"v\": $number(data), \"bt\": ts }\n]"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"type": TransformType.Messages,
|
|
34
|
-
"match": "appId = 'BATTERY'",
|
|
35
|
-
"transform": "[\n {\"bn\": \"14202/0/\", \"n\": \"0\", \"v\": $number(data), \"bt\": ts }\n]"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"type": TransformType.Messages,
|
|
39
|
-
"match": "appId = 'BUTTON'",
|
|
40
|
-
"transform": "[\n {\"bn\": \"14220/0/\", \"n\": \"0\", \"v\": $number(data), \"bt\": ts }\n]"
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"type": TransformType.Messages,
|
|
44
|
-
"match": "appId = 'DEVICE' and $exists(data.deviceInfo)",
|
|
45
|
-
"transform": "[\n {\"bn\": \"14204/0/\", \"n\": \"0\", \"vs\": data.deviceInfo.imei, \"bt\": ts },\n {\"n\": \"1\", \"vs\": data.deviceInfo.iccid },\n {\"n\": \"2\", \"vs\": data.deviceInfo.modemFirmware },\n {\"n\": \"3\", \"vs\": data.deviceInfo.appVersion },\n {\"n\": \"4\", \"vs\": data.deviceInfo.board },\n {\"n\": \"5\", \"vs\": data.deviceInfo.bat }\n]"
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"type": TransformType.Messages,
|
|
49
|
-
"match": "appId = 'SOLAR'",
|
|
50
|
-
"transform": "[\n {\"bn\": \"14210/0/\", \"n\": \"0\", \"v\": $number(data), \"bt\": ts }\n]"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"type": TransformType.Messages,
|
|
54
|
-
"match": "appId = 'GROUND_FIX' and $exists(data.lat) and $exists(data.lon) and $exists(data.uncertainty) and $exists(data.fulfilledWith)",
|
|
55
|
-
"transform": "[\n {\"bn\": \"14201/1/\", \"n\": \"0\", \"v\": data.lat, \"bt\": $millis() },\n {\"n\": \"1\", \"v\": data.lon },\n {\"n\": \"3\", \"v\": data.uncertainty },\n {\"n\": \"6\", \"vs\": data.fulfilledWith }\n]"
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"type": TransformType.Messages,
|
|
59
|
-
"match": "appId = 'GNSS'",
|
|
60
|
-
"transform": "[\n {\"bn\": \"14201/0/\", \"n\": \"0\", \"v\": data.lat, \"bt\": ts },\n {\"n\": \"1\", \"v\": data.lng },\n {\"n\": \"2\", \"v\": data.alt },\n {\"n\": \"3\", \"v\": data.acc },\n {\"n\": \"4\", \"v\": data.spd },\n {\"n\": \"5\", \"v\": data.hdg },\n {\"n\": \"6\", \"vs\": \"GNSS\" }\n]"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"type": TransformType.Messages,
|
|
64
|
-
"match": "appId = 'HUMID'",
|
|
65
|
-
"transform": "[\n {\"bn\": \"14205/0/\", \"n\": \"1\", \"v\": $number(data), \"bt\": ts }\n]"
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"type": TransformType.Messages,
|
|
69
|
-
"match": "appId = 'DEVICE' and $exists(data.networkInfo)",
|
|
70
|
-
"transform": "[\n {\"bn\": \"14203/0/\", \"n\": \"0\", \"vs\": data.networkInfo.networkMode, \"bt\": ts },\n {\"n\": \"1\", \"v\": data.networkInfo.currentBand },\n {\"n\": \"2\", \"v\": data.networkInfo.rsrp },\n {\"n\": \"3\", \"v\": data.networkInfo.areaCode },\n {\"n\": \"4\", \"v\": data.networkInfo.cellID },\n {\"n\": \"5\", \"v\": data.networkInfo.mccmnc },\n {\"n\": \"6\", \"vs\": data.networkInfo.ipAddress },\n {\"n\": \"11\", \"v\": data.networkInfo.eest }\n]"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"type": TransformType.Messages,
|
|
74
|
-
"match": "appId = 'AIR_PRESS'",
|
|
75
|
-
"transform": "[\n {\"bn\": \"14205/0/\", \"n\": \"2\", \"v\": $number(data)*10, \"bt\": ts }\n]"
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"type": TransformType.Messages,
|
|
79
|
-
"match": "appId = 'TEMP'",
|
|
80
|
-
"transform": "[\n {\"bn\": \"14205/0/\", \"n\": \"0\", \"v\": $number(data), \"bt\": ts }\n]"
|
|
81
|
-
}
|
|
82
|
-
],
|
|
83
|
-
"about": {
|
|
84
|
-
"title": "Thingy:91 with Solar Shield",
|
|
85
|
-
"description": "The Nordic Thingy:91 Solar Shield is a plug-and-play prototyping platform. Powerfoyle solar cell is mounted onto the Thingy to quickly get started exploring the endless possibilities with solar powered IoT applications and to develop products with eternal life or even battery-free products.\u200B\nThe Thingy:91 runs the asset_tracker_v2 application and sends messages to nRF Cloud using MQTT."
|
|
86
|
-
}
|
|
87
|
-
}), _define_property(_obj, "asset_tracker_v2+AWS", {
|
|
88
|
-
"id": "asset_tracker_v2+AWS",
|
|
89
|
-
"transforms": [
|
|
90
|
-
{
|
|
91
|
-
"type": TransformType.Shadow,
|
|
92
|
-
"match": "$exists(state.reported.gnss)",
|
|
93
|
-
"transform": "[\n {\"bn\": \"14201/0/\", \"n\": \"0\", \"v\": state.reported.gnss.v.lat, \"bt\": state.reported.gnss.ts },\n {\"n\": \"1\", \"v\": state.reported.gnss.v.lng },\n {\"n\": \"2\", \"v\": state.reported.gnss.v.alt },\n {\"n\": \"3\", \"v\": state.reported.gnss.v.acc },\n {\"n\": \"4\", \"v\": state.reported.gnss.v.spd },\n {\"n\": \"5\", \"v\": state.reported.gnss.v.hdg },\n {\"n\": \"6\", \"vs\": \"GNSS\" }\n]"
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"type": TransformType.Shadow,
|
|
97
|
-
"match": "$exists(state.reported.bat)",
|
|
98
|
-
"transform": "[\n {\"bn\": \"14202/0/\", \"n\": \"1\", \"v\": state.reported.bat.v/1000, \"bt\": state.reported.bat.ts }\n]"
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
"type": TransformType.Shadow,
|
|
102
|
-
"match": "$exists(state.reported.dev)",
|
|
103
|
-
"transform": "[\n {\"bn\": \"14204/0/\", \"n\": \"0\", \"vs\": state.reported.dev.v.imei, \"bt\": state.reported.dev.ts },\n {\"n\": \"1\", \"vs\": state.reported.dev.v.iccid },\n {\"n\": \"2\", \"vs\": state.reported.dev.v.modV },\n {\"n\": \"3\", \"vs\": state.reported.dev.v.appV },\n {\"n\": \"4\", \"vs\": state.reported.dev.v.brdV }\n]"
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
"type": TransformType.Shadow,
|
|
107
|
-
"match": "$exists(state.reported.env)",
|
|
108
|
-
"transform": "[\n {\"bn\": \"14205/0/\", \"n\": \"0\", \"v\": state.reported.env.v.temp, \"bt\": state.reported.env.ts },\n {\"n\": \"1\", \"v\": state.reported.env.v.hum },\n {\"n\": \"2\", \"v\": state.reported.env.v.atmp },\n {\"n\": \"10\", \"v\": state.reported.env.v.bsec_iaq }\n]"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"type": TransformType.Shadow,
|
|
112
|
-
"match": "$exists(state.reported.fg)",
|
|
113
|
-
"transform": "[\n {\"bn\": \"14202/0/\", \"n\": \"0\", \"v\": state.reported.fg.v.SoC, \"bt\": state.reported.fg.ts },\n {\"n\": \"1\", \"v\": state.reported.fg.v.V/1000 },\n {\"n\": \"2\", \"v\": state.reported.fg.v.I },\n {\"n\": \"3\", \"v\": state.reported.fg.v.T = null ? null : state.reported.fg.v.T/10 },\n {\"n\": \"4\", \"v\": state.reported.fg.v.TTF },\n {\"n\": \"5\", \"v\": state.reported.fg.v.TTE }\n]"
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
"type": TransformType.Shadow,
|
|
117
|
-
"match": "$exists(state.reported.roam)",
|
|
118
|
-
"transform": "[\n {\"bn\": \"14203/0/\", \"n\": \"0\", \"vs\": state.reported.roam.v.nw, \"bt\": state.reported.roam.ts },\n {\"n\": \"1\", \"v\": state.reported.roam.v.band },\n {\"bn\": \"14203/0/\", \"n\": \"2\", \"v\": state.reported.roam.v.rsrp, \"bt\": state.reported.roam.ts },\n {\"n\": \"3\", \"v\": state.reported.roam.v.area },\n {\"n\": \"4\", \"v\": state.reported.roam.v.cell },\n {\"n\": \"5\", \"v\": state.reported.roam.v.mccmnc },\n {\"n\": \"6\", \"vs\": state.reported.roam.v.ip },\n {\"bn\": \"14203/0/\", \"n\": \"11\", \"v\": state.reported.roam.v.eest, \"bt\": state.reported.roam.ts }\n]"
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
"type": TransformType.Shadow,
|
|
122
|
-
"match": "$exists(state.reported.sol)",
|
|
123
|
-
"transform": "[\n {\"bn\": \"14210/0/\", \"n\": \"0\", \"v\": state.reported.sol.v.gain, \"bt\": state.reported.sol.ts },\n {\"n\": \"1\", \"v\": state.reported.sol.v.bat }\n]"
|
|
124
|
-
}
|
|
125
|
-
],
|
|
126
|
-
"about": {
|
|
127
|
-
"title": "asset_tracker_v2 on AWS",
|
|
128
|
-
"description": "This implements the conversion for the asset_tracker_v2 message protocol when connected to AWS IoT."
|
|
129
|
-
}
|
|
130
|
-
}), _define_property(_obj, "kartverket-vasstandsdata", {
|
|
22
|
+
*/ export var models = _define_property({}, "kartverket-vasstandsdata", {
|
|
131
23
|
"id": "kartverket-vasstandsdata",
|
|
132
|
-
"transforms": [],
|
|
133
24
|
"about": {
|
|
134
25
|
"title": "Kartverket Vasstandsdata",
|
|
135
26
|
"description": "A simulated device reporting the current sea level as provided by the Kartverket's (Norwegian Mapping Authority) API for vasstandsdata (API for water level data).\nReports sea water level using the Object 14230.\nThe data is licensed by the Norwegian Mapping Authority\u2019s under the Creative Commons Attribution 4.0 International (CC BY 4.0) license."
|
|
136
27
|
}
|
|
137
|
-
})
|
|
28
|
+
});
|
package/dist/models/types.js
CHANGED
|
@@ -1,13 +1 @@
|
|
|
1
|
-
import { Type } from '@sinclair/typebox';
|
|
2
1
|
export var ModelIDRegExp = /^[A-Za-z0-9+_-]+$/;
|
|
3
|
-
export var TransformType;
|
|
4
|
-
(function(TransformType) {
|
|
5
|
-
TransformType["Shadow"] = "shadow";
|
|
6
|
-
TransformType["Messages"] = "messages";
|
|
7
|
-
})(TransformType || (TransformType = {}));
|
|
8
|
-
export var FrontMatter = Type.Object({
|
|
9
|
-
type: Type.Union([
|
|
10
|
-
Type.Literal('shadow'),
|
|
11
|
-
Type.Literal('messages')
|
|
12
|
-
])
|
|
13
|
-
});
|