@microtronics/studio-cli 0.51.0 → 0.53.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "title": "Dynamic DDE Schema",
4
- "description": "Describe your data structure",
4
+ "description": "Describe your data structure for Microtronics IoT devices",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "properties": {
@@ -9,14 +9,18 @@
9
9
  "type": "string",
10
10
  "default": "1.0.0",
11
11
  "readOnly": true,
12
- "description": "Version of the dde schema"
12
+ "description": "Version of the DDE schema. Do not modify this value.",
13
+ "markdownDescription": "Version of the DDE schema.\n\n⚠️ **Do not modify this value.**"
13
14
  },
14
15
  "cloudProject": {
15
- "type": "boolean"
16
+ "type": "boolean",
17
+ "description": "Indicates whether this is a cloud project.",
18
+ "markdownDescription": "Indicates whether this is a cloud project.\n\nWhen set to `false`, certain containers and top-level custom containers are restricted."
16
19
  },
17
20
  "constants": {
18
21
  "type": "object",
19
- "description": "Here you can declare your constants that can be used across the yaml."
22
+ "description": "Declare constants that can be used across the YAML file.",
23
+ "markdownDescription": "Declare constants that can be referenced and used across the YAML file."
20
24
  },
21
25
  "state": {
22
26
  "$ref": "#/$defs/stateContainer"
@@ -29,20 +33,54 @@
29
33
  },
30
34
  "timeseries": {
31
35
  "type": "object",
32
- "description": "",
36
+ "description": "Define time-series data channels for recording measurements.",
37
+ "markdownDescription": "Define time-series data channels for recording measurements.\n\n**Limits:** Maximum 9 fields.\n\n**Naming rules:**\n- Must start with a letter or `_`\n- May contain letters, digits, and `_`\n- Names like `field0`, `ch0`, etc. are **not allowed**\n- Reserved names (`_id`, `id`, `_stamp`, `stamp`, `tag`, `_uid`, `customer_id`, `site_id`, `_rec_flags__`, `applog`) are **not allowed**",
33
38
  "additionalProperties": false,
34
39
  "maxProperties": 9,
40
+ "errorMessage": {
41
+ "maxProperties": "The timeseries container supports a maximum of 9 fields."
42
+ },
35
43
  "properties": {
36
- "_id": false,
37
- "id": false,
38
- "_stamp": false,
39
- "stamp": false,
40
- "tag": false,
41
- "_uid": false,
42
- "customer_id": false,
43
- "site_id": false,
44
- "_rec_flags__": false,
45
- "applog": false
44
+ "_id": {
45
+ "not": {},
46
+ "errorMessage": "'_id' is a reserved name and cannot be used as a timeseries field."
47
+ },
48
+ "id": {
49
+ "not": {},
50
+ "errorMessage": "'id' is a reserved name and cannot be used as a timeseries field."
51
+ },
52
+ "_stamp": {
53
+ "not": {},
54
+ "errorMessage": "'_stamp' is a reserved name and cannot be used as a timeseries field."
55
+ },
56
+ "stamp": {
57
+ "not": {},
58
+ "errorMessage": "'stamp' is a reserved name and cannot be used as a timeseries field."
59
+ },
60
+ "tag": {
61
+ "not": {},
62
+ "errorMessage": "'tag' is a reserved name and cannot be used as a timeseries field."
63
+ },
64
+ "_uid": {
65
+ "not": {},
66
+ "errorMessage": "'_uid' is a reserved name and cannot be used as a timeseries field."
67
+ },
68
+ "customer_id": {
69
+ "not": {},
70
+ "errorMessage": "'customer_id' is a reserved name and cannot be used as a timeseries field."
71
+ },
72
+ "site_id": {
73
+ "not": {},
74
+ "errorMessage": "'site_id' is a reserved name and cannot be used as a timeseries field."
75
+ },
76
+ "_rec_flags__": {
77
+ "not": {},
78
+ "errorMessage": "'_rec_flags__' is a reserved name and cannot be used as a timeseries field."
79
+ },
80
+ "applog": {
81
+ "not": {},
82
+ "errorMessage": "'applog' is a reserved name and cannot be used as a timeseries field."
83
+ }
46
84
  },
47
85
  "patternProperties": {
48
86
  "^(?!.*^field\\d+$)(?!.*^ch\\d+$)[a-zA-Z_][0-9a-zA-Z_]*$": {
@@ -53,6 +91,7 @@
53
91
  "aloha": {
54
92
  "type": "object",
55
93
  "description": "Special container to transport live data during put-into-operation procedures.",
94
+ "markdownDescription": "Special container to transport **live data** during put-into-operation procedures.\n\nUsed for real-time data exchange between device and server during commissioning.",
56
95
  "$ref": "#/$defs/alohaContainer"
57
96
  },
58
97
  "setting": {
@@ -71,6 +110,7 @@
71
110
  "patternProperties": {
72
111
  "^(?!.*^field\\d+$)(?!.*^ch\\d+$)(?!(dde|cloudProject|constants|state|result|volatile|timeseries|aloha|setting|command|storage|relations))[a-zA-Z_][0-9a-zA-Z_]*$": {
73
112
  "type": "object",
113
+ "description": "Custom configuration container. Field names must start with a letter or underscore and may contain letters, digits, and underscores.",
74
114
  "$ref": "#/$defs/configurationFields"
75
115
  }
76
116
  },
@@ -86,19 +126,22 @@
86
126
  "then": {
87
127
  "type": "object",
88
128
  "additionalProperties": false,
129
+ "errorMessage": {
130
+ "additionalProperties": "Non-cloud projects only allow standard containers (state, result, volatile, timeseries, aloha, setting, command, storage, relations). Set 'cloudProject' to true to use custom top-level containers."
131
+ },
89
132
  "properties": {
90
133
  "dde": {
91
134
  "type": "string",
92
135
  "default": "1.0.0",
93
136
  "readOnly": true,
94
- "description": "Version of the dde schema"
137
+ "description": "Version of the DDE schema. Do not modify this value."
95
138
  },
96
139
  "cloudProject": {
97
140
  "type": "boolean"
98
141
  },
99
142
  "constants": {
100
143
  "type": "object",
101
- "description": "Here you can declare your constants that can be used across the yaml."
144
+ "description": "Declare constants that can be used across the YAML file."
102
145
  },
103
146
  "state": {
104
147
  "$ref": "#/$defs/stateContainer"
@@ -111,20 +154,53 @@
111
154
  },
112
155
  "timeseries": {
113
156
  "type": "object",
114
- "description": "",
157
+ "description": "Define time-series data channels for recording measurements.",
115
158
  "additionalProperties": false,
116
159
  "maxProperties": 9,
160
+ "errorMessage": {
161
+ "maxProperties": "The timeseries container supports a maximum of 9 fields."
162
+ },
117
163
  "properties": {
118
- "_id": false,
119
- "id": false,
120
- "_stamp": false,
121
- "stamp": false,
122
- "tag": false,
123
- "_uid": false,
124
- "customer_id": false,
125
- "site_id": false,
126
- "_rec_flags__": false,
127
- "applog": false
164
+ "_id": {
165
+ "not": {},
166
+ "errorMessage": "'_id' is a reserved name and cannot be used as a timeseries field."
167
+ },
168
+ "id": {
169
+ "not": {},
170
+ "errorMessage": "'id' is a reserved name and cannot be used as a timeseries field."
171
+ },
172
+ "_stamp": {
173
+ "not": {},
174
+ "errorMessage": "'_stamp' is a reserved name and cannot be used as a timeseries field."
175
+ },
176
+ "stamp": {
177
+ "not": {},
178
+ "errorMessage": "'stamp' is a reserved name and cannot be used as a timeseries field."
179
+ },
180
+ "tag": {
181
+ "not": {},
182
+ "errorMessage": "'tag' is a reserved name and cannot be used as a timeseries field."
183
+ },
184
+ "_uid": {
185
+ "not": {},
186
+ "errorMessage": "'_uid' is a reserved name and cannot be used as a timeseries field."
187
+ },
188
+ "customer_id": {
189
+ "not": {},
190
+ "errorMessage": "'customer_id' is a reserved name and cannot be used as a timeseries field."
191
+ },
192
+ "site_id": {
193
+ "not": {},
194
+ "errorMessage": "'site_id' is a reserved name and cannot be used as a timeseries field."
195
+ },
196
+ "_rec_flags__": {
197
+ "not": {},
198
+ "errorMessage": "'_rec_flags__' is a reserved name and cannot be used as a timeseries field."
199
+ },
200
+ "applog": {
201
+ "not": {},
202
+ "errorMessage": "'applog' is a reserved name and cannot be used as a timeseries field."
203
+ }
128
204
  },
129
205
  "patternProperties": {
130
206
  "^(?!.*^field\\d+$)(?!.*^ch\\d+$)[a-zA-Z_][0-9a-zA-Z_]*$": {
@@ -157,55 +233,67 @@
157
233
  "stateContainer": {
158
234
  "type": "object",
159
235
  "title": "state - Transferred from the device",
160
- "description": "Use this container for low frequent state changes.",
236
+ "description": "Use this container for low-frequency state changes. Data is transferred from the device to the server.",
237
+ "markdownDescription": "**state** – Transferred from the device\n\nUse this container for **low-frequency state changes**.\n\nData is transferred from the device to the server.",
161
238
  "$ref": "#/$defs/configurationFields"
162
239
  },
163
240
  "resultContainer": {
164
241
  "type": "object",
165
242
  "title": "result - Transferred from the device",
166
- "description": "Use this container for higher frequent changes.\ne.g. responses to an executed command.",
243
+ "description": "Use this container for higher-frequency changes, e.g. responses to an executed command. Data is transferred from the device to the server.",
244
+ "markdownDescription": "**result** – Transferred from the device\n\nUse this container for **higher-frequency changes**, e.g. responses to an executed command.\n\nData is transferred from the device to the server.",
167
245
  "$ref": "#/$defs/configurationFields"
168
246
  },
169
247
  "volatileContainer": {
170
248
  "type": "object",
171
249
  "title": "volatile - Transferred from the device",
172
- "description": "Container is not persisted on the device.\nCommon use case would be a transaction response.\nIf you want to persist this data, use 'DDE_volatile_persist()'",
250
+ "description": "Container is not persisted on the device. Common use case: transaction responses. Use 'DDE_volatile_persist()' to persist this data.",
251
+ "markdownDescription": "**volatile** – Transferred from the device\n\nContainer is **not persisted** on the device.\n\nCommon use case: transaction responses.\n\nIf you want to persist this data, use `DDE_volatile_persist()`.",
173
252
  "$ref": "#/$defs/configurationFields"
174
253
  },
175
254
  "alohaContainer": {
176
255
  "type": "object",
177
256
  "title": "aloha - Transferred from the device",
178
- "description": "A special container to transport live data during put-into-operation procedures",
257
+ "description": "A special container to transport live data during put-into-operation procedures.",
258
+ "markdownDescription": "**aloha** – Transferred from the device\n\nA special container to transport **live data** during put-into-operation procedures.",
179
259
  "$ref": "#/$defs/configurationFields"
180
260
  },
181
261
  "settingContainer": {
182
262
  "type": "object",
183
263
  "title": "setting - Transferred to the device",
184
- "description": "Use this container for low frequent changes.\ne.g. application settings like a transfer interval",
264
+ "description": "Use this container for low-frequency changes, e.g. application settings like a transfer interval. Data is transferred from the server to the device.",
265
+ "markdownDescription": "**setting** – Transferred to the device\n\nUse this container for **low-frequency changes**, e.g. application settings like a transfer interval.\n\nData is transferred from the server to the device.",
185
266
  "$ref": "#/$defs/configurationFields"
186
267
  },
187
268
  "commandContainer": {
188
269
  "type": "object",
189
270
  "title": "command - Transferred to the device",
190
- "description": "Use this container for high frequent changes.\ne.g. changing the state of an physical output",
271
+ "description": "Use this container for high-frequency changes, e.g. changing the state of a physical output. Data is transferred from the server to the device.",
272
+ "markdownDescription": "**command** – Transferred to the device\n\nUse this container for **high-frequency changes**, e.g. changing the state of a physical output.\n\nData is transferred from the server to the device.",
191
273
  "$ref": "#/$defs/configurationFields"
192
274
  },
193
275
  "serverStorageContainer": {
194
276
  "type": "object",
195
277
  "title": "storage - Server only",
196
- "description": "Use this container to store any POV or BLO related settings.",
278
+ "description": "Use this container to store any POV or BLO related settings. This data is only stored on the server and not transferred to the device.",
279
+ "markdownDescription": "**storage** – Server only\n\nUse this container to store any **POV** or **BLO** related settings.\n\nThis data is only stored on the server and **not transferred** to the device.",
197
280
  "$ref": "#/$defs/configurationFields"
198
281
  },
199
282
  "serverRelationsContainer": {
200
283
  "type": "object",
201
284
  "title": "relations - Server only",
202
- "description": "Use this container to store any field related configuration.",
285
+ "description": "Use this container to store field-related configuration. This data is only stored on the server.",
286
+ "markdownDescription": "**relations** – Server only\n\nUse this container to store **field-related configuration**.\n\nThis data is only stored on the server.",
203
287
  "$ref": "#/$defs/configurationFields"
204
288
  },
205
289
  "configurationFields": {
206
290
  "type": "object",
207
- "description": "Fields of the container.",
291
+ "description": "Fields of the container. Field names must start with a letter or underscore, and may contain letters, digits, and underscores. Names like 'field0', 'ch0', etc. are not allowed.",
292
+ "markdownDescription": "Fields of the container.\n\n**Naming rules:**\n- Must start with a letter or `_`\n- May contain letters, digits, and `_`\n- Names like `field0`, `ch0`, etc. are **not allowed**\n- Reserved names (`_id`, `id`, `_stamp`, `stamp`, `tag`, `_uid`, `customer_id`, `site_id`, `_rec_flags__`, `applog`) are **not allowed**",
208
293
  "additionalProperties": false,
294
+ "errorMessage": {
295
+ "additionalProperties": "Invalid field name. Field names must start with a letter or underscore, may contain letters, digits, and underscores. Names matching 'fieldN' or 'chN' patterns and reserved names (_id, id, _stamp, stamp, tag, _uid, customer_id, site_id, _rec_flags__, applog) are not allowed."
296
+ },
209
297
  "$ref": "#/$defs/reservedNamesFieldNames",
210
298
  "properties": {},
211
299
  "patternProperties": {
@@ -223,8 +311,12 @@
223
311
  },
224
312
  "timeseriesFields": {
225
313
  "type": "object",
226
- "description": "Fields of the container.",
314
+ "description": "Timeseries fields of the container. Supports additional chart and channel properties compared to configuration fields.",
315
+ "markdownDescription": "Timeseries fields of the container.\n\nSupports additional **chart** and **channel** properties compared to configuration fields.",
227
316
  "additionalProperties": false,
317
+ "errorMessage": {
318
+ "additionalProperties": "Invalid field name. Field names must start with a letter or underscore, may contain letters, digits, and underscores. Names matching 'fieldN' or 'chN' patterns and reserved names are not allowed."
319
+ },
228
320
  "$ref": "#/$defs/reservedNamesFieldNames",
229
321
  "patternProperties": {
230
322
  "^(?!.*^field\\d+$)(?!.*^ch\\d+$)[a-zA-Z_][0-9a-zA-Z_]*$": {
@@ -237,7 +329,8 @@
237
329
  "properties": {
238
330
  "channelMode": {
239
331
  "type": ["string", "number"],
240
- "description": "Defines how values are treated up on aggregation.\nApplies to numeric fields only",
332
+ "description": "Defines how values are treated upon aggregation. Applies to numeric fields only.",
333
+ "markdownDescription": "Defines how values are treated upon aggregation.\n\n**Applies to numeric fields only.**\n\nOptions:\n- `digital` – Treatment as digital value (0 or 1)\n- `day-counter` – Counter reset once per day\n- `interval-counter` – Counter reset on each recording\n- `analog` – (default) Normal measurement value\n- `infinite-counter` – Counter that is never reset\n- Relation link (`@container.field`)",
241
334
  "anyOf": [
242
335
  {
243
336
  "const": "digital",
@@ -249,7 +342,7 @@
249
342
  },
250
343
  {
251
344
  "const": "interval-counter",
252
- "description": "A Counter which is reset on each recording"
345
+ "description": "A counter which is reset on each recording"
253
346
  },
254
347
  {
255
348
  "const": "analog",
@@ -283,19 +376,22 @@
283
376
  "chartHysteresis": {
284
377
  "title": "Chart Hysteresis",
285
378
  "type": ["number", "string"],
286
- "description": "The server uses this property to show a hysteresis in charts.\nThe value is in %.\n'chartWarningX' and/or 'chartAlarmX' needed.",
379
+ "description": "The server uses this property to show a hysteresis in charts. The value is in %. Requires 'chartWarningX' and/or 'chartAlarmX'.",
380
+ "markdownDescription": "The server uses this property to show a **hysteresis** in charts.\n\nThe value is in **%**.\n\n⚠️ Requires `chartWarningX` and/or `chartAlarmX` to be set.",
287
381
  "$ref": "#/$defs/relationLinkPattern"
288
382
  },
289
383
  "chartTriggerThreshold": {
290
384
  "title": "Chart Trigger Threshold",
291
385
  "type": ["number", "string"],
292
386
  "description": "The server uses this property to show a trigger threshold in charts.",
387
+ "markdownDescription": "The server uses this property to show a **trigger threshold** in charts.",
293
388
  "$ref": "#/$defs/relationLinkPattern"
294
389
  },
295
390
  "chartTriggerRelation": {
296
391
  "title": "Chart Trigger Relation",
297
392
  "type": ["string"],
298
- "description": "Defines if the 'chartTriggerThreshold' displays as overshoot or undershoot",
393
+ "description": "Defines if the 'chartTriggerThreshold' displays as overshoot or undershoot. Requires 'chartTriggerThreshold' to be set.",
394
+ "markdownDescription": "Defines if the `chartTriggerThreshold` displays as **overshoot** or **undershoot**.\n\n⚠️ Requires `chartTriggerThreshold` to be set.",
299
395
  "anyOf": [
300
396
  {
301
397
  "title": "Greater or equal",
@@ -315,12 +411,16 @@
315
411
  "chartSetPoint": {
316
412
  "title": "Chart Set Point",
317
413
  "type": ["string"],
318
- "description": "Used to report the actual state of the referenced value.\nThe server will display a pending information if the value is not transmitted yet.",
414
+ "description": "Used to report the actual state of the referenced value. The server will display a pending information if the value is not transmitted yet.",
415
+ "markdownDescription": "Used to report the actual state of the referenced value.\n\nThe server will display a **pending** indicator if the value has not been transmitted yet.",
319
416
  "$ref": "#/$defs/setPointRelationPattern"
320
417
  }
321
418
  },
322
419
  "dependencies": {
323
- "chartTriggerRelation": ["chartTriggerThreshold"]
420
+ "chartTriggerRelation": {
421
+ "required": ["chartTriggerThreshold"],
422
+ "errorMessage": "'chartTriggerRelation' requires 'chartTriggerThreshold' to also be defined."
423
+ }
324
424
  }
325
425
  },
326
426
  {
@@ -333,16 +433,46 @@
333
433
  "reservedNamesFieldNames": {
334
434
  "type": "object",
335
435
  "properties": {
336
- "_id": false,
337
- "id": false,
338
- "_stamp": false,
339
- "stamp": false,
340
- "tag": false,
341
- "_uid": false,
342
- "customer_id": false,
343
- "site_id": false,
344
- "_rec_flags__": false,
345
- "applog": false
436
+ "_id": {
437
+ "not": {},
438
+ "errorMessage": "'_id' is a reserved name and cannot be used as a field name."
439
+ },
440
+ "id": {
441
+ "not": {},
442
+ "errorMessage": "'id' is a reserved name and cannot be used as a field name."
443
+ },
444
+ "_stamp": {
445
+ "not": {},
446
+ "errorMessage": "'_stamp' is a reserved name and cannot be used as a field name."
447
+ },
448
+ "stamp": {
449
+ "not": {},
450
+ "errorMessage": "'stamp' is a reserved name and cannot be used as a field name."
451
+ },
452
+ "tag": {
453
+ "not": {},
454
+ "errorMessage": "'tag' is a reserved name and cannot be used as a field name."
455
+ },
456
+ "_uid": {
457
+ "not": {},
458
+ "errorMessage": "'_uid' is a reserved name and cannot be used as a field name."
459
+ },
460
+ "customer_id": {
461
+ "not": {},
462
+ "errorMessage": "'customer_id' is a reserved name and cannot be used as a field name."
463
+ },
464
+ "site_id": {
465
+ "not": {},
466
+ "errorMessage": "'site_id' is a reserved name and cannot be used as a field name."
467
+ },
468
+ "_rec_flags__": {
469
+ "not": {},
470
+ "errorMessage": "'_rec_flags__' is a reserved name and cannot be used as a field name."
471
+ },
472
+ "applog": {
473
+ "not": {},
474
+ "errorMessage": "'applog' is a reserved name and cannot be used as a field name."
475
+ }
346
476
  }
347
477
  },
348
478
  "defaultFieldProperties": {
@@ -354,7 +484,8 @@
354
484
  },
355
485
  "title": {
356
486
  "type": "string",
357
- "description": "Title to describe the fields content within the portal"
487
+ "description": "Title to describe the field's content within the portal.",
488
+ "markdownDescription": "Title to describe the field's content within the portal.\n\nCan also reference a relation using `@container.field` syntax."
358
489
  },
359
490
  "description": {
360
491
  "type": "string",
@@ -362,23 +493,27 @@
362
493
  },
363
494
  "array": {
364
495
  "type": "number",
365
- "description": "Length of the array",
496
+ "description": "Length of the array. Must be between 1 and 1024.",
497
+ "markdownDescription": "Length of the array.\n\n**Range:** 1–1024",
366
498
  "minimum": 1,
367
499
  "inclusiveMaximum": 1024
368
500
  },
369
501
  "unit": {
370
502
  "type": "string",
371
- "description": "Unit information to be shown in the default POV.\nE.g. kg"
503
+ "description": "Unit information to be shown in the default POV (e.g. 'kg', '°C', 'V').",
504
+ "markdownDescription": "Unit information to be shown in the default POV.\n\n**Examples:** `kg`, `°C`, `V`, `%`\n\nCan also reference a relation using `@container.field` syntax."
372
505
  },
373
506
  "hex": {
374
507
  "type": "boolean",
375
- "description": "Server side progressing. Declares if this field should be displayed as HEX string.\nThe API will als process the field as HEX."
508
+ "description": "Server-side processing. Declares if this field should be displayed as HEX string. The API will also process the field as HEX.",
509
+ "markdownDescription": "Server-side processing. Declares if this field should be displayed as **HEX** string.\n\nThe API will also process the field as HEX."
376
510
  },
377
511
  "decimalPlaces": {
378
512
  "$ref": "#/$defs/decimalPlaces"
379
513
  },
380
514
  "writePermission": {
381
- "description": "User level required for editing.\nApplies for down containers only.",
515
+ "description": "User level required for editing. Applies for down containers only (setting, command).",
516
+ "markdownDescription": "User level required for editing.\n\n**Applies for down containers only** (`setting`, `command`).\n\nSet to `read-only` to prevent editing.",
382
517
  "anyOf": [
383
518
  {
384
519
  "$ref": "#/$defs/userLevel"
@@ -392,6 +527,7 @@
392
527
  },
393
528
  "readPermission": {
394
529
  "description": "User level required for viewing.",
530
+ "markdownDescription": "User level required for viewing this field.",
395
531
  "$ref": "#/$defs/userLevel"
396
532
  },
397
533
  "bytes": true,
@@ -416,32 +552,41 @@
416
552
  "type": "object",
417
553
  "deprecated": true,
418
554
  "title": "DEPRECATED",
419
- "description": "Allows defining multiple fields within the same memory space",
555
+ "description": "Allows defining multiple fields within the same memory space. This property is deprecated and should not be used in new projects.",
556
+ "markdownDescription": "⚠️ **DEPRECATED**\n\nAllows defining multiple fields within the same memory space.\n\nThis property is deprecated and should not be used in new projects.",
420
557
  "$ref": "#/$defs/configurationFields"
421
558
  },
422
559
  "bitmask": {
423
560
  "type": "string",
424
561
  "title": "Bitmask",
425
- "description": "Defines what bits of the according data type are used for storage.",
562
+ "description": "Defines what bits of the according data type are used for storage. Must be a hex (0x...) or binary (0b...) string.",
563
+ "markdownDescription": "Defines what bits of the according data type are used for storage.\n\n**Formats:**\n- Hexadecimal: `0xAB CD` (prefix `0x`, hex digits and spaces)\n- Binary: `0b1010 0101` (prefix `0b`, binary digits and spaces)",
426
564
  "anyOf": [
427
565
  {
428
566
  "default": "\"0x\"",
429
567
  "pattern": "^0x[0-9A-F ]+$",
430
- "description": "Bitmask defined as hexadecimal.\nDefines what bits of the according data type are used for storage."
568
+ "patternErrorMessage": "Hexadecimal bitmask must start with '0x' followed by uppercase hex digits (0-9, A-F) and optional spaces (e.g. '0xFF' or '0xFF 00').",
569
+ "description": "Bitmask defined as hexadecimal. Defines what bits of the according data type are used for storage."
431
570
  },
432
571
  {
433
572
  "default": "\"0b\"",
434
573
  "pattern": "^0b[0-1 ]+$",
435
- "description": "Bitmask defined as binary\nDefines what bits of the according data type are used for storage."
574
+ "patternErrorMessage": "Binary bitmask must start with '0b' followed by binary digits (0, 1) and optional spaces (e.g. '0b11110000' or '0b1111 0000').",
575
+ "description": "Bitmask defined as binary. Defines what bits of the according data type are used for storage."
436
576
  }
437
577
  ]
438
578
  }
439
579
  },
440
580
  "required": ["type"],
581
+ "errorMessage": {
582
+ "required": {
583
+ "type": "Every field must have a 'type' property specifying its data type."
584
+ }
585
+ },
441
586
  "allOf": [
442
587
  {
443
588
  "if": {
444
- "description": "Force the byte amount if datatype is bytes",
589
+ "description": "Force the byte amount if datatype is binary",
445
590
  "properties": {
446
591
  "type": {
447
592
  "enum": ["binary"]
@@ -452,19 +597,30 @@
452
597
  "properties": {
453
598
  "bytes": {
454
599
  "type": "number",
455
- "description": "Number of bytes"
600
+ "description": "Number of bytes for binary data. Required when type is 'binary'.",
601
+ "markdownDescription": "Number of bytes for binary data.\n\n**Required** when type is `binary`."
456
602
  },
457
603
  "defaultValue": {
458
604
  "type": "string",
459
- "description": "default value as hex",
460
- "pattern": "^0x[0-9A-F ]+$"
605
+ "description": "Default value as hex (e.g. '0xFF 00'). Must start with '0x'.",
606
+ "markdownDescription": "Default value as hex.\n\n**Format:** `0x` followed by uppercase hex digits and optional spaces.\n\n**Example:** `0xFF 00`",
607
+ "pattern": "^0x[0-9A-F ]+$",
608
+ "patternErrorMessage": "Default value for binary type must be a hex string starting with '0x' followed by uppercase hex digits (0-9, A-F) and optional spaces."
461
609
  }
462
610
  },
463
- "required": ["bytes"]
611
+ "required": ["bytes"],
612
+ "errorMessage": {
613
+ "required": {
614
+ "bytes": "The 'bytes' property is required when type is 'binary'. Specify the number of bytes."
615
+ }
616
+ }
464
617
  },
465
618
  "else": {
466
619
  "properties": {
467
- "bytes": false
620
+ "bytes": {
621
+ "not": {},
622
+ "errorMessage": "The 'bytes' property is only allowed when type is 'binary'."
623
+ }
468
624
  }
469
625
  }
470
626
  },
@@ -481,14 +637,21 @@
481
637
  "properties": {
482
638
  "length": {
483
639
  "type": "number",
484
- "description": "Length of the string",
640
+ "description": "Length of the string. Required for string types. Must be at least 1.",
641
+ "markdownDescription": "Length of the string.\n\n**Required** for string types (`astring`, `nstring`, `cstring`, `wstring`, `ustring`).\n\n**Minimum:** 1",
485
642
  "minimum": 1
486
643
  },
487
644
  "defaultValue": {
488
- "type": "string"
645
+ "type": "string",
646
+ "description": "Default string value for this field."
489
647
  }
490
648
  },
491
- "required": ["length"]
649
+ "required": ["length"],
650
+ "errorMessage": {
651
+ "required": {
652
+ "length": "The 'length' property is required for string types (astring, nstring, cstring, wstring, ustring). Specify the string length."
653
+ }
654
+ }
492
655
  }
493
656
  },
494
657
  {
@@ -517,45 +680,67 @@
517
680
  },
518
681
  "defaultValue": {
519
682
  "type": ["number", "string"],
520
- "description": "Default value for this field.",
521
- "pattern": "^NaN$"
683
+ "description": "Default value for this field. Use a number or 'NaN'.",
684
+ "markdownDescription": "Default value for this field.\n\nAccepts a **number** or the string `NaN`.",
685
+ "pattern": "^NaN$",
686
+ "patternErrorMessage": "String default values for numeric types must be 'NaN'. Use a number for other default values."
522
687
  },
523
688
  "chartMinimum": {
524
689
  "type": ["number", "string"],
525
690
  "description": "Disables auto scaling of lower range in POV charts.",
691
+ "markdownDescription": "Disables **auto scaling** of the lower range in POV charts.\n\nAccepts a number or a relation link (`@container.field`).",
526
692
  "$ref": "#/$defs/relationLinkPattern"
527
693
  },
528
694
  "chartMaximum": {
529
695
  "type": ["number", "string"],
530
696
  "description": "Disables auto scaling of higher range in POV charts.",
697
+ "markdownDescription": "Disables **auto scaling** of the higher range in POV charts.\n\nAccepts a number or a relation link (`@container.field`).",
531
698
  "$ref": "#/$defs/relationLinkPattern"
532
699
  },
533
700
  "scale": {
534
701
  "type": ["number", "string"],
535
702
  "title": "Scale the raw value",
536
- "description": "Server side progressing. Applies to POV and API.\nscaled = raw x scale + offset",
703
+ "description": "Server-side processing. Applies to POV and API. Formula: scaled = raw × scale + offset",
704
+ "markdownDescription": "Server-side processing. Applies to POV and API.\n\n**Formula:** `scaled = raw × scale + offset`\n\nAccepts a number or a relation link (`@container.field`).",
537
705
  "$ref": "#/$defs/relationLinkPattern"
538
706
  },
539
707
  "offset": {
540
708
  "type": ["number", "string"],
541
709
  "title": "Add an offset to the raw value",
542
- "description": "Server side progressing. Applies to POV and API.\nscaled = raw x scale + offset",
710
+ "description": "Server-side processing. Applies to POV and API. Formula: scaled = raw × scale + offset",
711
+ "markdownDescription": "Server-side processing. Applies to POV and API.\n\n**Formula:** `scaled = raw × scale + offset`\n\nAccepts a number or a relation link (`@container.field`).",
543
712
  "$ref": "#/$defs/relationLinkPattern"
544
713
  },
545
714
  "utilsTransferInterval": {
546
715
  "title": "Transfer Interval",
547
716
  "type": ["boolean"],
548
- "description": "Indicates the server that this field should be used for the remaining time until next connections.\nField value has to be in seconds."
717
+ "description": "Indicates the server that this field should be used for the remaining time until next connection. Field value has to be in seconds.",
718
+ "markdownDescription": "Indicates the server that this field should be used for the **remaining time until next connection**.\n\nField value has to be in **seconds**."
549
719
  }
550
720
  }
551
721
  },
552
722
  "else": {
553
723
  "properties": {
554
- "decimalPlaces": false,
555
- "chartMinimum": false,
556
- "chartMaximum": false,
557
- "scale": false,
558
- "offset": false
724
+ "decimalPlaces": {
725
+ "not": {},
726
+ "errorMessage": "'decimalPlaces' is only allowed for numeric types (int8, int16, int32, int64, uint8, uint16, uint32, float16, float32, float64)."
727
+ },
728
+ "chartMinimum": {
729
+ "not": {},
730
+ "errorMessage": "'chartMinimum' is only allowed for numeric types (int8, int16, int32, int64, uint8, uint16, uint32, float16, float32, float64)."
731
+ },
732
+ "chartMaximum": {
733
+ "not": {},
734
+ "errorMessage": "'chartMaximum' is only allowed for numeric types (int8, int16, int32, int64, uint8, uint16, uint32, float16, float32, float64)."
735
+ },
736
+ "scale": {
737
+ "not": {},
738
+ "errorMessage": "'scale' is only allowed for numeric types (int8, int16, int32, int64, uint8, uint16, uint32, float16, float32, float64)."
739
+ },
740
+ "offset": {
741
+ "not": {},
742
+ "errorMessage": "'offset' is only allowed for numeric types (int8, int16, int32, int64, uint8, uint16, uint32, float16, float32, float64)."
743
+ }
559
744
  }
560
745
  }
561
746
  },
@@ -597,7 +782,8 @@
597
782
  },
598
783
  "dataTypes": {
599
784
  "type": "string",
600
- "description": "Datatype of the field",
785
+ "description": "Data type of the field. Integer types: int8, int16, int32, int64, uint8, uint16, uint32. Float types: float16, float32, float64. Binary: binary. Timestamps: stamp32, stamp40. Strings: astring, nstring, cstring, wstring, ustring. Composite: array.",
786
+ "markdownDescription": "Data type of the field.\n\n**Integer types:** `int8`, `int16`, `int32`, `int64`, `uint8`, `uint16`, `uint32`\n\n**Float types:** `float16`, `float32`, `float64`\n\n**Binary:** `binary`\n\n**Timestamps:** `stamp32`, `stamp40`\n\n**Strings:** `astring`, `nstring`, `cstring`, `wstring`, `ustring`\n\n**Composite:** `array`",
601
787
  "anyOf": [
602
788
  {
603
789
  "const": "int8",
@@ -667,37 +853,39 @@
667
853
  {
668
854
  "const": "array",
669
855
  "title": "Array",
670
- "description": "Array of parameters."
856
+ "description": "Array of parameters. Requires 'length' and 'fields' properties."
671
857
  },
672
858
  {
673
859
  "const": "astring",
674
860
  "title": "astring",
675
- "description": "ANSI CP-1252 stored as 8bit ANSI.\nCharacter codes 0x01 … 0xFF are by default assigned to CP-1252 (0x00 is reserved for terminating zero).\n"
861
+ "description": "ANSI CP-1252 stored as 8bit ANSI.\nCharacter codes 0x01 … 0xFF are by default assigned to CP-1252 (0x00 is reserved for terminating zero).\nRequires the 'length' property."
676
862
  },
677
863
  {
678
864
  "const": "nstring",
679
- "title": "nstring"
865
+ "title": "nstring",
866
+ "description": "Named string type.\nRequires the 'length' property."
680
867
  },
681
868
  {
682
869
  "const": "cstring",
683
870
  "title": "cstring",
684
- "description": "ANSI with custom codepage stored as binary."
871
+ "description": "ANSI with custom codepage stored as binary.\nRequires the 'length' property."
685
872
  },
686
873
  {
687
874
  "const": "wstring",
688
875
  "title": "wstring",
689
- "description": "Unicode utf-32 stored as utf-8.\nUse this type only if Unicode is required and your DLO routines insist on utf-32 encoded strings.\n"
876
+ "description": "Unicode utf-32 stored as utf-8.\nUse this type only if Unicode is required and your DLO routines insist on utf-32 encoded strings.\nRequires the 'length' property."
690
877
  },
691
878
  {
692
879
  "const": "ustring",
693
880
  "title": "ustring",
694
- "description": "Unicode utf-8 stored as utf-8.\nUse this type only if Unicode is required and your DLO routines (such as display drivers) are able to deal with utf-8 encoded strings.\n"
881
+ "description": "Unicode utf-8 stored as utf-8.\nUse this type only if Unicode is required and your DLO routines (such as display drivers) are able to deal with utf-8 encoded strings.\nRequires the 'length' property."
695
882
  }
696
883
  ]
697
884
  },
698
885
  "userLevel": {
699
886
  "type": "string",
700
- "description": "Datatype of the field",
887
+ "description": "User permission level. Ranges from UL1 (Customer operator) to UL7 (Administrator).",
888
+ "markdownDescription": "User permission level.\n\n| Level | Role |\n|-------|------|\n| `UL1` | Customer operator |\n| `UL2` | Customer administrator |\n| `UL3` | Provider operator |\n| `UL4` | Provider administrator |\n| `UL6` | Rights administrator |\n| `UL7` | Administrator |\n| `UL8+` | Custom levels |",
701
889
  "anyOf": [
702
890
  {
703
891
  "const": "UL1",
@@ -730,7 +918,9 @@
730
918
  "description": "Administrator"
731
919
  },
732
920
  {
733
- "pattern": "UL([7-9]|[1-9][0-9])"
921
+ "pattern": "UL([7-9]|[1-9][0-9])",
922
+ "patternErrorMessage": "Custom user level must match the pattern 'ULN' where N is 7 or higher (e.g. 'UL8', 'UL10').",
923
+ "description": "Custom user level (UL7 or higher)"
734
924
  }
735
925
  ]
736
926
  },
@@ -750,18 +940,34 @@
750
940
  },
751
941
  "length": {
752
942
  "type": "number",
753
- "description": "Size of the array",
943
+ "description": "Size of the array. Must be between 1 and 1024.",
944
+ "markdownDescription": "Size of the array.\n\n**Range:** 1–1024",
754
945
  "minimum": 1,
755
946
  "inclusiveMaximum": 1024
756
947
  },
757
- "array": false,
758
- "title": false
948
+ "array": {
949
+ "not": {},
950
+ "errorMessage": "The 'array' property is not allowed when type is 'array'. Use 'length' to define the array size."
951
+ },
952
+ "title": {
953
+ "not": {},
954
+ "errorMessage": "The 'title' property is not allowed when type is 'array'."
955
+ }
759
956
  },
760
- "required": ["length", "fields"]
957
+ "required": ["length", "fields"],
958
+ "errorMessage": {
959
+ "required": {
960
+ "length": "The 'length' property is required when type is 'array'. Specify the array size.",
961
+ "fields": "The 'fields' property is required when type is 'array'. Define the array's sub-fields."
962
+ }
963
+ }
761
964
  },
762
965
  "else": {
763
966
  "properties": {
764
- "fields": false
967
+ "fields": {
968
+ "not": {},
969
+ "errorMessage": "The 'fields' property is only allowed when type is 'array'."
970
+ }
765
971
  }
766
972
  }
767
973
  },
@@ -781,38 +987,57 @@
781
987
  },
782
988
  "length": {
783
989
  "type": "number",
784
- "description": "Size of the array",
990
+ "description": "Size of the array. Must be between 1 and 1024.",
991
+ "markdownDescription": "Size of the array.\n\n**Range:** 1–1024",
785
992
  "minimum": 1,
786
993
  "inclusiveMaximum": 1024
787
994
  },
788
- "array": false,
789
- "title": false
995
+ "array": {
996
+ "not": {},
997
+ "errorMessage": "The 'array' property is not allowed when type is 'array'. Use 'length' to define the array size."
998
+ },
999
+ "title": {
1000
+ "not": {},
1001
+ "errorMessage": "The 'title' property is not allowed when type is 'array'."
1002
+ }
790
1003
  },
791
- "required": ["length", "fields"]
1004
+ "required": ["length", "fields"],
1005
+ "errorMessage": {
1006
+ "required": {
1007
+ "length": "The 'length' property is required when type is 'array'. Specify the array size.",
1008
+ "fields": "The 'fields' property is required when type is 'array'. Define the array's sub-fields."
1009
+ }
1010
+ }
792
1011
  },
793
1012
  "else": {
794
1013
  "properties": {
795
- "fields": false
1014
+ "fields": {
1015
+ "not": {},
1016
+ "errorMessage": "The 'fields' property is only allowed when type is 'array'."
1017
+ }
796
1018
  }
797
1019
  }
798
1020
  },
799
1021
  "decimalPlaces": {
800
1022
  "type": ["number", "string"],
801
- "description": "Number of decimal places to show.\nApplies to POV and API",
1023
+ "description": "Number of decimal places to show. Applies to POV and API. Only valid for numeric types.",
1024
+ "markdownDescription": "Number of decimal places to show.\n\nApplies to POV and API. Only valid for numeric types.\n\nAccepts a number (≥ 0) or a relation link (`@container.field`).",
802
1025
  "minimum": 0,
803
1026
  "$ref": "#/$defs/relationLinkPattern"
804
1027
  },
805
1028
  "relationLinkPattern": {
806
1029
  "anyOf": [
807
1030
  {
808
- "pattern": "^(@[a-zA-Z_][a-zA-Z0-9_]*\\.[a-zA-Z_][a-zA-Z0-9_]*(\\[[^\\]]+\\])?(\\.[a-zA-Z_][a-zA-Z0-9_]*)*|lib:[a-zA-Z0-9_-]+@[a-zA-Z_][a-zA-Z0-9_]*\\.[a-zA-Z_][a-zA-Z0-9_]*(\\[[^\\]]+\\])?(\\.[a-zA-Z_][a-zA-Z0-9_]*)*)$"
1031
+ "pattern": "^(@[a-zA-Z_][a-zA-Z0-9_]*\\.[a-zA-Z_][a-zA-Z0-9_]*(\\[[^\\]]+\\])?(\\.[a-zA-Z_][a-zA-Z0-9_]*)*|lib:[a-zA-Z0-9_-]+@[a-zA-Z_][a-zA-Z0-9_]*\\.[a-zA-Z_][a-zA-Z0-9_]*(\\[[^\\]]+\\])?(\\.[a-zA-Z_][a-zA-Z0-9_]*)*)$",
1032
+ "patternErrorMessage": "Relation link must match the format '@container.field' or 'lib:library-name@container.field'. Optional array index '[index]' and nested paths are supported (e.g. '@setting.myField', '@state.data[0].value', 'lib:my-lib@setting.param')."
809
1033
  }
810
1034
  ]
811
1035
  },
812
1036
  "setPointRelationPattern": {
813
1037
  "anyOf": [
814
1038
  {
815
- "pattern": "^(@[a-zA-Z_][a-zA-Z0-9_]*\\.[a-zA-Z_][a-zA-Z0-9_]*(\\[[^\\]]+\\])?(\\.[a-zA-Z_][a-zA-Z0-9_]*)*|lib:[a-zA-Z0-9_-]+@[a-zA-Z_][a-zA-Z0-9_]*\\.[a-zA-Z_][a-zA-Z0-9_]*(\\[[^\\]]+\\])?(\\.[a-zA-Z_][a-zA-Z0-9_]*)*)$"
1039
+ "pattern": "^(@[a-zA-Z_][a-zA-Z0-9_]*\\.[a-zA-Z_][a-zA-Z0-9_]*(\\[[^\\]]+\\])?(\\.[a-zA-Z_][a-zA-Z0-9_]*)*|lib:[a-zA-Z0-9_-]+@[a-zA-Z_][a-zA-Z0-9_]*\\.[a-zA-Z_][a-zA-Z0-9_]*(\\[[^\\]]+\\])?(\\.[a-zA-Z_][a-zA-Z0-9_]*)*)$",
1040
+ "patternErrorMessage": "Set point relation must match the format '@container.field' or 'lib:library-name@container.field' (e.g. '@setting.targetTemperature')."
816
1041
  },
817
1042
  {
818
1043
  "const": "\"@setting.\"",
@@ -828,7 +1053,8 @@
828
1053
  },
829
1054
  "chartAlarmWarn": {
830
1055
  "type": ["number", "string"],
831
- "description": "The server uses this property to show the threshold in charts and gauges.\nImportant: This does not activate any alarming. This must be done in the DLO.",
1056
+ "description": "The server uses this property to show the threshold in charts and gauges. Important: This does not activate any alarming. This must be done in the DLO.",
1057
+ "markdownDescription": "The server uses this property to show the **threshold** in charts and gauges.\n\n⚠️ **Important:** This does not activate any alarming. Alarming must be implemented in the DLO.\n\nAccepts a number or a relation link (`@container.field`).",
832
1058
  "$ref": "#/$defs/relationLinkPattern"
833
1059
  }
834
1060
  }