@hello.nrfcloud.com/proto-map 4.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 (169) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +122 -0
  3. package/dist/generator/addDocBlock.js +5 -0
  4. package/dist/generator/generateLwM2MDefinitions.js +82 -0
  5. package/dist/generator/generateLwM2MDefinitions.spec.js +91 -0
  6. package/dist/generator/generateLwm2mTimestampResources.js +69 -0
  7. package/dist/generator/generateModels.js +142 -0
  8. package/dist/generator/generateType.js +90 -0
  9. package/dist/generator/generateValidator.js +132 -0
  10. package/dist/generator/generateValidators.js +63 -0
  11. package/dist/generator/isDir.js +163 -0
  12. package/dist/generator/isDir.spec.js +212 -0
  13. package/dist/generator/lwm2m.js +106 -0
  14. package/dist/generator/models.js +306 -0
  15. package/dist/generator/printNode.js +8 -0
  16. package/dist/generator/tokenizeName.js +5 -0
  17. package/dist/generator/tokenizeName.spec.js +98 -0
  18. package/dist/generator/types.js +140 -0
  19. package/dist/lwm2m/LWM2MObjectDefinition.js +88 -0
  20. package/dist/lwm2m/LWM2MObjectInfo.js +9 -0
  21. package/dist/lwm2m/LwM2MObject.d.js +1 -0
  22. package/dist/lwm2m/LwM2MObjectID.js +57 -0
  23. package/dist/lwm2m/ParsedLwM2MObjectDefinition.js +1 -0
  24. package/dist/lwm2m/check-lwm2m-rules.js +480 -0
  25. package/dist/lwm2m/definitions.js +596 -0
  26. package/dist/lwm2m/fromXML2JSON.js +194 -0
  27. package/dist/lwm2m/instanceTs.js +9 -0
  28. package/dist/lwm2m/instanceTs.spec.js +16 -0
  29. package/dist/lwm2m/isRegisteredLwM2MObject.js +3 -0
  30. package/dist/lwm2m/isRegisteredLwM2MObject.spec.js +45 -0
  31. package/dist/lwm2m/object/14201.d.js +5 -0
  32. package/dist/lwm2m/object/14202.d.js +5 -0
  33. package/dist/lwm2m/object/14203.d.js +5 -0
  34. package/dist/lwm2m/object/14204.d.js +5 -0
  35. package/dist/lwm2m/object/14205.d.js +5 -0
  36. package/dist/lwm2m/object/14210.d.js +5 -0
  37. package/dist/lwm2m/object/14220.d.js +5 -0
  38. package/dist/lwm2m/object/14230.d.js +5 -0
  39. package/dist/lwm2m/object/validate14201.js +18 -0
  40. package/dist/lwm2m/object/validate14202.js +17 -0
  41. package/dist/lwm2m/object/validate14203.js +19 -0
  42. package/dist/lwm2m/object/validate14204.js +17 -0
  43. package/dist/lwm2m/object/validate14205.js +15 -0
  44. package/dist/lwm2m/object/validate14210.js +13 -0
  45. package/dist/lwm2m/object/validate14220.js +12 -0
  46. package/dist/lwm2m/object/validate14230.js +13 -0
  47. package/dist/lwm2m/objects.js +8 -0
  48. package/dist/lwm2m/parseRangeEnumeration.js +20 -0
  49. package/dist/lwm2m/parseRangeEnumeration.spec.js +27 -0
  50. package/dist/lwm2m/resourceType.js +12 -0
  51. package/dist/lwm2m/timestampResources.js +12 -0
  52. package/dist/lwm2m/unwrapNestedArray.js +114 -0
  53. package/dist/lwm2m/unwrapNestedArray.spec.js +374 -0
  54. package/dist/lwm2m/validate.js +14 -0
  55. package/dist/lwm2m/validation.js +146 -0
  56. package/dist/lwm2m/validators.js +20 -0
  57. package/dist/markdown/getCodeBlock.js +74 -0
  58. package/dist/markdown/getFrontMatter.js +15 -0
  59. package/dist/markdown/parseREADME.js +19 -0
  60. package/dist/models/asset_tracker_v2+AWS/examples/examples.spec.js +489 -0
  61. package/dist/models/check-model-rules.js +137 -0
  62. package/dist/models/models.js +137 -0
  63. package/dist/models/types.js +13 -0
  64. package/dist/senml/SenMLSchema.js +79 -0
  65. package/dist/senml/SenMLSchema.spec.js +23 -0
  66. package/dist/senml/hasValue.js +8 -0
  67. package/dist/senml/hasValue.spec.js +103 -0
  68. package/dist/senml/lwm2mToSenML.js +137 -0
  69. package/dist/senml/lwm2mToSenML.spec.js +104 -0
  70. package/dist/senml/parseResourceId.js +58 -0
  71. package/dist/senml/parseResourceId.spec.js +13 -0
  72. package/dist/senml/senMLtoLwM2M.js +126 -0
  73. package/dist/senml/senMLtoLwM2M.spec.js +226 -0
  74. package/dist/senml/validateSenML.js +6 -0
  75. package/dist/senml/validateSenML.spec.js +31 -0
  76. package/export.js +13 -0
  77. package/index.d.ts +14 -0
  78. package/lwm2m/14201.xml +94 -0
  79. package/lwm2m/14202.xml +84 -0
  80. package/lwm2m/14203.xml +104 -0
  81. package/lwm2m/14204.xml +84 -0
  82. package/lwm2m/14205.xml +64 -0
  83. package/lwm2m/14210.xml +44 -0
  84. package/lwm2m/14220.xml +34 -0
  85. package/lwm2m/14230.xml +44 -0
  86. package/lwm2m/LWM2M-v1_1.xsd +168 -0
  87. package/lwm2m/LWM2MObjectDefinition.ts +84 -0
  88. package/lwm2m/LWM2MObjectInfo.ts +42 -0
  89. package/lwm2m/LwM2MObject.d.ts +19 -0
  90. package/lwm2m/LwM2MObjectID.ts +73 -0
  91. package/lwm2m/ParsedLwM2MObjectDefinition.ts +28 -0
  92. package/lwm2m/check-lwm2m-rules.ts +160 -0
  93. package/lwm2m/definitions.ts +278 -0
  94. package/lwm2m/format.sh +3 -0
  95. package/lwm2m/fromXML2JSON.ts +44 -0
  96. package/lwm2m/instanceTs.spec.ts +19 -0
  97. package/lwm2m/instanceTs.ts +10 -0
  98. package/lwm2m/isRegisteredLwM2MObject.spec.ts +48 -0
  99. package/lwm2m/isRegisteredLwM2MObject.ts +4 -0
  100. package/lwm2m/object/14201.d.ts +73 -0
  101. package/lwm2m/object/14202.d.ts +59 -0
  102. package/lwm2m/object/14203.d.ts +67 -0
  103. package/lwm2m/object/14204.d.ts +55 -0
  104. package/lwm2m/object/14205.d.ts +43 -0
  105. package/lwm2m/object/14210.d.ts +31 -0
  106. package/lwm2m/object/14220.d.ts +25 -0
  107. package/lwm2m/object/14230.d.ts +31 -0
  108. package/lwm2m/object/validate14201.ts +10 -0
  109. package/lwm2m/object/validate14202.ts +10 -0
  110. package/lwm2m/object/validate14203.ts +10 -0
  111. package/lwm2m/object/validate14204.ts +10 -0
  112. package/lwm2m/object/validate14205.ts +10 -0
  113. package/lwm2m/object/validate14210.ts +10 -0
  114. package/lwm2m/object/validate14220.ts +10 -0
  115. package/lwm2m/object/validate14230.ts +10 -0
  116. package/lwm2m/objects.ts +16 -0
  117. package/lwm2m/parseRangeEnumeration.spec.ts +34 -0
  118. package/lwm2m/parseRangeEnumeration.ts +29 -0
  119. package/lwm2m/resourceType.ts +11 -0
  120. package/lwm2m/timestampResources.ts +4 -0
  121. package/lwm2m/unwrapNestedArray.spec.ts +241 -0
  122. package/lwm2m/unwrapNestedArray.ts +27 -0
  123. package/lwm2m/validate.ts +30 -0
  124. package/lwm2m/validation.ts +120 -0
  125. package/lwm2m/validators.ts +21 -0
  126. package/models/PCA20035+solar/README.md +10 -0
  127. package/models/PCA20035+solar/transforms/airQuality.md +48 -0
  128. package/models/PCA20035+solar/transforms/battery.md +46 -0
  129. package/models/PCA20035+solar/transforms/button.md +45 -0
  130. package/models/PCA20035+solar/transforms/deviceInfo.md +72 -0
  131. package/models/PCA20035+solar/transforms/gain.md +45 -0
  132. package/models/PCA20035+solar/transforms/geolocationFromGroundfix.md +67 -0
  133. package/models/PCA20035+solar/transforms/geolocationFromMessage.md +80 -0
  134. package/models/PCA20035+solar/transforms/humidity.md +43 -0
  135. package/models/PCA20035+solar/transforms/networkInfo.md +84 -0
  136. package/models/PCA20035+solar/transforms/pressure.md +43 -0
  137. package/models/PCA20035+solar/transforms/temperature.md +43 -0
  138. package/models/README.md +10 -0
  139. package/models/asset_tracker_v2+AWS/README.md +6 -0
  140. package/models/asset_tracker_v2+AWS/examples/examples.spec.ts +229 -0
  141. package/models/asset_tracker_v2+AWS/examples/shadow/example-1.json +24 -0
  142. package/models/asset_tracker_v2+AWS/examples/shadow/example-2.json +30 -0
  143. package/models/asset_tracker_v2+AWS/examples/shadow/example-3.json +37 -0
  144. package/models/asset_tracker_v2+AWS/examples/shadow/example-4.json +48 -0
  145. package/models/asset_tracker_v2+AWS/examples/shadow/example-5.json +43 -0
  146. package/models/asset_tracker_v2+AWS/transforms/GNSS.md +66 -0
  147. package/models/asset_tracker_v2+AWS/transforms/battery-voltage.md +50 -0
  148. package/models/asset_tracker_v2+AWS/transforms/device-info.md +61 -0
  149. package/models/asset_tracker_v2+AWS/transforms/env.md +69 -0
  150. package/models/asset_tracker_v2+AWS/transforms/fuel-gauge.md +62 -0
  151. package/models/asset_tracker_v2+AWS/transforms/roam.md +100 -0
  152. package/models/asset_tracker_v2+AWS/transforms/solar.md +58 -0
  153. package/models/check-model-rules.ts +125 -0
  154. package/models/kartverket-vasstandsdata/README.md +13 -0
  155. package/models/models.ts +36 -0
  156. package/models/types.ts +17 -0
  157. package/package.json +111 -0
  158. package/senml/SenMLSchema.spec.ts +21 -0
  159. package/senml/SenMLSchema.ts +74 -0
  160. package/senml/hasValue.spec.ts +19 -0
  161. package/senml/hasValue.ts +12 -0
  162. package/senml/lwm2mToSenML.spec.ts +74 -0
  163. package/senml/lwm2mToSenML.ts +62 -0
  164. package/senml/parseResourceId.spec.ts +13 -0
  165. package/senml/parseResourceId.ts +23 -0
  166. package/senml/senMLtoLwM2M.spec.ts +181 -0
  167. package/senml/senMLtoLwM2M.ts +121 -0
  168. package/senml/validateSenML.spec.ts +16 -0
  169. package/senml/validateSenML.ts +8 -0
@@ -0,0 +1,181 @@
1
+ import assert from 'node:assert/strict'
2
+ import { describe, it } from 'node:test'
3
+ import { senMLtoLwM2M, type LwM2MObjectInstance } from './senMLtoLwM2M.js'
4
+ import type { SenMLType } from './SenMLSchema.js'
5
+
6
+ void describe('senMLtoLwM2M()', () => {
7
+ void it('should resolve a senML message into objects', () => {
8
+ const input: SenMLType = [
9
+ {
10
+ bn: '/14201/1/',
11
+ blv: '1.1',
12
+ bt: 1698155694999,
13
+ n: '0',
14
+ v: 33.98755678796222,
15
+ },
16
+ {
17
+ n: '1',
18
+ v: -84.506132079174634,
19
+ },
20
+ {
21
+ n: '2',
22
+ v: 295.468994140625,
23
+ },
24
+ {
25
+ n: '3',
26
+ v: 17.74077033996582,
27
+ },
28
+ {
29
+ n: '4',
30
+ v: 26.376304626464844,
31
+ },
32
+ {
33
+ n: '5',
34
+ v: 359.1545715332,
35
+ },
36
+ ]
37
+ const expected: LwM2MObjectInstance[] = [
38
+ {
39
+ ObjectID: 14201,
40
+ ObjectInstanceID: 1,
41
+ ObjectVersion: '1.1',
42
+ Resources: {
43
+ 0: 33.98755678796222,
44
+ 1: -84.506132079174634,
45
+ 2: 295.468994140625,
46
+ 3: 17.74077033996582,
47
+ 4: 26.376304626464844,
48
+ 5: 359.1545715332,
49
+ 99: new Date(1698155694999),
50
+ },
51
+ },
52
+ ]
53
+ assert.deepEqual(senMLtoLwM2M(input), expected)
54
+ })
55
+
56
+ void it('should drop empty resources', () => {
57
+ const input: SenMLType = [
58
+ {
59
+ bn: '/14203/0/',
60
+ n: '0',
61
+ vs: 'LTE-M',
62
+ bt: 1676369307222,
63
+ },
64
+ {
65
+ n: '1',
66
+ v: 20,
67
+ },
68
+ {
69
+ n: '2',
70
+ v: -79,
71
+ },
72
+ {
73
+ n: '3',
74
+ v: 6,
75
+ },
76
+ {
77
+ n: '4',
78
+ v: 56879116,
79
+ },
80
+ {
81
+ n: '5',
82
+ v: 24001,
83
+ },
84
+ {
85
+ n: '6',
86
+ vs: '10.160.243.113',
87
+ },
88
+ {
89
+ n: '11',
90
+ },
91
+ ]
92
+ const expected: LwM2MObjectInstance[] = [
93
+ {
94
+ ObjectID: 14203,
95
+ Resources: {
96
+ 0: 'LTE-M',
97
+ 1: 20,
98
+ 2: -79,
99
+ 3: 6,
100
+ 4: 56879116,
101
+ 5: 24001,
102
+ 6: '10.160.243.113',
103
+ 99: new Date(1676369307222),
104
+ },
105
+ },
106
+ ]
107
+ assert.deepEqual(senMLtoLwM2M(input), expected)
108
+ })
109
+
110
+ void it('should ignore repeated base properties', () => {
111
+ const input: SenMLType = [
112
+ { bn: '/14203/0/', n: '0', vs: 'LTE-M', bt: 1699049665511 },
113
+ { n: '1', v: 20 },
114
+ { bn: '/14203/0/', n: '2', v: -89, bt: 1699049665511 },
115
+ { n: '3', v: 2305 },
116
+ { n: '4', v: 34784790 },
117
+ { n: '5', v: 24202 },
118
+ { n: '6', vs: '100.81.95.75' },
119
+ { bn: '/14203/0/', n: '11', v: 7, bt: 1699049665511 },
120
+ ]
121
+ const expected: LwM2MObjectInstance[] = [
122
+ {
123
+ ObjectID: 14203,
124
+ Resources: {
125
+ 0: 'LTE-M',
126
+ 1: 20,
127
+ 2: -89,
128
+ 3: 2305,
129
+ 4: 34784790,
130
+ 5: 24202,
131
+ 6: '100.81.95.75',
132
+ 11: 7,
133
+ 99: new Date(1699049665511),
134
+ },
135
+ },
136
+ ]
137
+ assert.deepEqual(senMLtoLwM2M(input), expected)
138
+ })
139
+
140
+ void it('should handle multiple measurements for the same resource', () => {
141
+ const input: SenMLType = [
142
+ { bn: '/14205/0/', n: '0', v: 21, bt: 1699049600000 },
143
+ { bn: '/14205/1/', n: '0', v: 31, bt: 1699049600000 },
144
+ { bn: '/14205/0/', n: '0', v: 22, bt: 1699049700000 },
145
+ { bn: '/14205/1/', n: '0', v: 32, bt: 1699049700000 },
146
+ ]
147
+ const expected: LwM2MObjectInstance[] = [
148
+ {
149
+ ObjectID: 14205,
150
+ Resources: {
151
+ 0: 21,
152
+ 99: new Date(1699049600000),
153
+ },
154
+ },
155
+ {
156
+ ObjectID: 14205,
157
+ ObjectInstanceID: 1,
158
+ Resources: {
159
+ 0: 31,
160
+ 99: new Date(1699049600000),
161
+ },
162
+ },
163
+ {
164
+ ObjectID: 14205,
165
+ Resources: {
166
+ 0: 22,
167
+ 99: new Date(1699049700000),
168
+ },
169
+ },
170
+ {
171
+ ObjectID: 14205,
172
+ ObjectInstanceID: 1,
173
+ Resources: {
174
+ 0: 32,
175
+ 99: new Date(1699049700000),
176
+ },
177
+ },
178
+ ]
179
+ assert.deepEqual(senMLtoLwM2M(input), expected)
180
+ })
181
+ })
@@ -0,0 +1,121 @@
1
+ import type { MeasurementType, SenMLType } from './SenMLSchema'
2
+ import { timestampResources } from '../lwm2m/timestampResources.js'
3
+ import { parseResourceId, type ResourceID } from './parseResourceId.js'
4
+ import { hasValue } from './hasValue.js'
5
+ import type { LwM2MObjectID } from '../lwm2m/LwM2MObjectID.js'
6
+
7
+ export type LwM2MResourceValue = string | number | boolean | Date
8
+ type GenericLwM2MObjectInstance = {
9
+ ObjectID: LwM2MObjectID
10
+ /**
11
+ * @default 0
12
+ */
13
+ ObjectInstanceID?: number
14
+ /**
15
+ * @default '1.0'
16
+ */
17
+ ObjectVersion?: string
18
+ /**
19
+ * Key range: 0..65534
20
+ */
21
+ Resources: Partial<Record<number, LwM2MResourceValue>>
22
+ }
23
+ export type LwM2MObjectInstance<
24
+ Instance extends GenericLwM2MObjectInstance = GenericLwM2MObjectInstance,
25
+ > = {
26
+ ObjectID: LwM2MObjectID
27
+ /**
28
+ * @default 0
29
+ */
30
+ ObjectInstanceID?: number
31
+ /**
32
+ * @default '1.0'
33
+ */
34
+ ObjectVersion?: Instance['ObjectVersion']
35
+ /**
36
+ * Key range: 0..65534
37
+ */
38
+ Resources: Instance['Resources']
39
+ }
40
+
41
+ const isInfoForDifferentInstance = (
42
+ currentObject: LwM2MObjectInstance,
43
+ resourceID: ResourceID,
44
+ currentBaseTime: number,
45
+ ): boolean => {
46
+ if (currentObject === undefined) return true
47
+ if (currentObject.ObjectID !== resourceID.ObjectID) return true
48
+ if ((currentObject.ObjectInstanceID ?? 0) !== resourceID.ObjectInstanceID)
49
+ return true
50
+ const tsRes = timestampResources[resourceID.ObjectID]
51
+ if (tsRes === undefined)
52
+ throw new Error(`Unknown LwM2M Object ID: ${resourceID.ObjectID}!`)
53
+ if (
54
+ currentBaseTime !==
55
+ (currentObject.Resources?.[tsRes] as Date | undefined)?.getTime()
56
+ )
57
+ return true
58
+ return false
59
+ }
60
+
61
+ const getValue = (
62
+ measurement: MeasurementType,
63
+ ): string | number | boolean | undefined => {
64
+ if ('bv' in measurement && !('v' in measurement)) return measurement.bv
65
+ if ('bv' in measurement && 'v' in measurement)
66
+ return measurement.bv + measurement.v
67
+ if ('v' in measurement) return measurement.v
68
+ if ('vs' in measurement) return measurement.vs
69
+ if ('vb' in measurement) return measurement.vb
70
+ if ('vd' in measurement) return measurement.vd
71
+ return undefined
72
+ }
73
+ export const senMLtoLwM2M = (senML: SenMLType): Array<LwM2MObjectInstance> => {
74
+ let currentBaseName: string = ''
75
+ let currentBaseTime: number | undefined = undefined
76
+ let currentObject: LwM2MObjectInstance | undefined = undefined
77
+ const items: LwM2MObjectInstance[] = []
78
+
79
+ for (const item of senML) {
80
+ if ('bn' in item && item.bn !== undefined) currentBaseName = item.bn
81
+ if ('bt' in item && item.bt !== undefined) currentBaseTime = item.bt
82
+ if (!hasValue(item)) continue
83
+ const itemResourceId = `${currentBaseName}${item.n ?? ''}/0`
84
+ const resourceId = parseResourceId(itemResourceId)
85
+ if (resourceId === null)
86
+ throw new Error(`Invalid resource ID: ${itemResourceId}`)
87
+
88
+ if (
89
+ currentObject === undefined ||
90
+ (currentBaseTime !== undefined &&
91
+ isInfoForDifferentInstance(currentObject, resourceId, currentBaseTime))
92
+ ) {
93
+ if (currentObject !== undefined) items.push(currentObject)
94
+ const tsRes = timestampResources[resourceId.ObjectID]
95
+ if (tsRes === undefined)
96
+ throw new Error(`Unknown LwM2M Object ID: ${resourceId.ObjectID}!`)
97
+ if (currentBaseTime === undefined)
98
+ throw new Error(`No base time defined for object!`)
99
+ currentObject = {
100
+ ObjectID: resourceId.ObjectID,
101
+ Resources: {
102
+ [tsRes]: new Date(currentBaseTime),
103
+ },
104
+ }
105
+ if (resourceId.ObjectInstanceID !== 0)
106
+ currentObject.ObjectInstanceID = resourceId.ObjectInstanceID
107
+ if ('blv' in item) currentObject.ObjectVersion = item.blv
108
+ }
109
+ if (currentObject?.Resources === undefined) continue
110
+ const value = getValue(item)
111
+ if (value !== undefined) {
112
+ currentObject.Resources = {
113
+ ...currentObject.Resources,
114
+ [item.n]: value,
115
+ }
116
+ }
117
+ }
118
+ if (currentObject !== undefined) items.push(currentObject)
119
+
120
+ return items
121
+ }
@@ -0,0 +1,16 @@
1
+ import { describe, it } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { validateSenML } from './validateSenML.js'
4
+ import type { SenMLType } from './SenMLSchema.js'
5
+
6
+ void describe('validateSenML()', () => {
7
+ void it('should validate', () => {
8
+ const senMl: SenMLType = [
9
+ { bn: '/14202/1/', blv: '1.1', n: '0', v: 99, bt: 1699049685992 },
10
+ { n: '1', v: 4.179 },
11
+ { n: '2', v: 0 },
12
+ { n: '3', v: 25.7 },
13
+ ]
14
+ assert.deepEqual(validateSenML(senMl), { value: senMl })
15
+ })
16
+ })
@@ -0,0 +1,8 @@
1
+ import { SenML } from '../senml/SenMLSchema.js'
2
+ import { validate } from '../validate.js'
3
+
4
+ const validator = validate(SenML)
5
+
6
+ export const validateSenML = (
7
+ maybeSenML: unknown,
8
+ ): ReturnType<typeof validator> => validator(maybeSenML)