@hello.nrfcloud.com/proto-map 5.6.3 → 6.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.
Files changed (42) hide show
  1. package/README.md +0 -16
  2. package/dist/generator/generateModels.js +0 -85
  3. package/dist/generator/models.js +1 -83
  4. package/dist/markdown/getCodeBlock.js +0 -26
  5. package/dist/models/check-model-rules.js +1 -91
  6. package/dist/models/models.js +5 -114
  7. package/dist/models/types.js +0 -12
  8. package/models/README.md +0 -4
  9. package/models/check-model-rules.ts +1 -90
  10. package/models/models.ts +1 -8
  11. package/models/types.ts +0 -16
  12. package/package.json +2 -3
  13. package/dist/generator/isDir.js +0 -163
  14. package/dist/generator/isDir.spec.js +0 -212
  15. package/dist/markdown/getFrontMatter.js +0 -15
  16. package/dist/models/asset_tracker_v2+AWS/examples/examples.spec.js +0 -489
  17. package/models/PCA20035+solar/README.md +0 -10
  18. package/models/PCA20035+solar/transforms/airQuality.md +0 -48
  19. package/models/PCA20035+solar/transforms/battery.md +0 -46
  20. package/models/PCA20035+solar/transforms/button.md +0 -45
  21. package/models/PCA20035+solar/transforms/deviceInfo.md +0 -72
  22. package/models/PCA20035+solar/transforms/gain.md +0 -45
  23. package/models/PCA20035+solar/transforms/geolocationFromGroundfix.md +0 -67
  24. package/models/PCA20035+solar/transforms/geolocationFromMessage.md +0 -80
  25. package/models/PCA20035+solar/transforms/humidity.md +0 -43
  26. package/models/PCA20035+solar/transforms/networkInfo.md +0 -84
  27. package/models/PCA20035+solar/transforms/pressure.md +0 -43
  28. package/models/PCA20035+solar/transforms/temperature.md +0 -43
  29. package/models/asset_tracker_v2+AWS/README.md +0 -6
  30. package/models/asset_tracker_v2+AWS/examples/examples.spec.ts +0 -229
  31. package/models/asset_tracker_v2+AWS/examples/shadow/example-1.json +0 -24
  32. package/models/asset_tracker_v2+AWS/examples/shadow/example-2.json +0 -30
  33. package/models/asset_tracker_v2+AWS/examples/shadow/example-3.json +0 -37
  34. package/models/asset_tracker_v2+AWS/examples/shadow/example-4.json +0 -48
  35. package/models/asset_tracker_v2+AWS/examples/shadow/example-5.json +0 -43
  36. package/models/asset_tracker_v2+AWS/transforms/GNSS.md +0 -66
  37. package/models/asset_tracker_v2+AWS/transforms/battery-voltage.md +0 -50
  38. package/models/asset_tracker_v2+AWS/transforms/device-info.md +0 -61
  39. package/models/asset_tracker_v2+AWS/transforms/env.md +0 -69
  40. package/models/asset_tracker_v2+AWS/transforms/fuel-gauge.md +0 -62
  41. package/models/asset_tracker_v2+AWS/transforms/roam.md +0 -100
  42. 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
- };
@@ -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 2:
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 { FrontMatter, ModelIDRegExp } from './types.js';
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;
@@ -1,4 +1,6 @@
1
- function _define_property(obj, key, value) {
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 = (_obj = {}, _define_property(_obj, "PCA20035+solar", {
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
- }), _obj);
28
+ });
@@ -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
- });
package/models/README.md CHANGED
@@ -4,7 +4,3 @@ Models are defined in the subdirectories of this folder.
4
4
 
5
5
  A model definition consists of a `README.md` that provides a human-friendly
6
6
  description of the model.
7
-
8
- Optionally, if the device does not send senML directly,
9
- [transforms can be defined](../README.md#model-transform-definitions) that
10
- convert the payload sent by the model to senML.