@alteriom/mqtt-schema 0.4.0 → 0.6.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 (32) hide show
  1. package/README.md +209 -2
  2. package/dist/cjs/generated/types.d.ts +59 -2
  3. package/dist/cjs/generated/types.js +13 -1
  4. package/dist/cjs/schema_data.d.ts +262 -0
  5. package/dist/cjs/schema_data.js +313 -1
  6. package/dist/cjs/schemas/command.schema.json +62 -0
  7. package/dist/cjs/schemas/command_response.schema.json +53 -0
  8. package/dist/cjs/schemas/envelope.schema.json +24 -1
  9. package/dist/cjs/schemas/gateway_metrics.schema.json +11 -1
  10. package/dist/cjs/schemas/mqtt_v1_bundle.json +2 -0
  11. package/dist/cjs/schemas/sensor_data.schema.json +15 -1
  12. package/dist/cjs/schemas/validation_rules.md +15 -0
  13. package/dist/cjs/validators.d.ts +2 -0
  14. package/dist/cjs/validators.js +12 -0
  15. package/dist/esm/generated/types.js +11 -1
  16. package/dist/esm/schema_data.js +312 -0
  17. package/dist/esm/schemas/command.schema.json +62 -0
  18. package/dist/esm/schemas/command_response.schema.json +53 -0
  19. package/dist/esm/schemas/envelope.schema.json +24 -1
  20. package/dist/esm/schemas/gateway_metrics.schema.json +11 -1
  21. package/dist/esm/schemas/mqtt_v1_bundle.json +2 -0
  22. package/dist/esm/schemas/sensor_data.schema.json +15 -1
  23. package/dist/esm/schemas/validation_rules.md +15 -0
  24. package/dist/esm/validators.js +13 -1
  25. package/package.json +1 -1
  26. package/schemas/command.schema.json +62 -0
  27. package/schemas/command_response.schema.json +53 -0
  28. package/schemas/envelope.schema.json +24 -1
  29. package/schemas/gateway_metrics.schema.json +11 -1
  30. package/schemas/mqtt_v1_bundle.json +2 -0
  31. package/schemas/sensor_data.schema.json +15 -1
  32. package/schemas/validation_rules.md +15 -0
package/README.md CHANGED
@@ -33,6 +33,9 @@ Firmware emits structured MQTT payloads that must remain tightly aligned with we
33
33
  - Helpful error paths (JSON Pointer style)
34
34
  - Lightweight (Ajv peer dependency, schemas embedded)
35
35
  - Ships original schema JSON files (optional consumption)
36
+ - **NEW in v0.6.0**: Enhanced location/geolocation support for asset tracking
37
+ - **NEW in v0.6.0**: Extended sensor metadata (accuracy, calibration, operational range)
38
+ - **NEW in v0.6.0**: Comprehensive gateway health metrics (storage, network, errors)
36
39
 
37
40
  ## Installation
38
41
 
@@ -89,6 +92,206 @@ Access raw schema JSON (if you need to introspect or power form generation):
89
92
  import envelopeSchema from '@alteriom/mqtt-schema/schemas/envelope.schema.json';
90
93
  ```
91
94
 
95
+ ## Command & Control (v0.5.0+)
96
+
97
+ Send commands to devices and receive responses with correlation tracking:
98
+
99
+ ```ts
100
+ import { validators, isCommandMessage, isCommandResponseMessage } from '@alteriom/mqtt-schema';
101
+
102
+ // Create a command message
103
+ const command = {
104
+ schema_version: 1,
105
+ device_id: 'ALT-441D64F804A0',
106
+ device_type: 'sensor',
107
+ timestamp: new Date().toISOString(),
108
+ firmware_version: 'WEB 1.0.0',
109
+ event: 'command',
110
+ command: 'read_sensors',
111
+ correlation_id: `cmd-${Date.now()}-001`,
112
+ parameters: {
113
+ immediate: true,
114
+ sensors: ['temperature', 'humidity']
115
+ },
116
+ priority: 'high'
117
+ };
118
+
119
+ // Validate before sending
120
+ const cmdResult = validators.command(command);
121
+ if (cmdResult.valid) {
122
+ // Publish to MQTT topic: alteriom/nodes/{device_id}/commands
123
+ mqttClient.publish(`alteriom/nodes/${command.device_id}/commands`, JSON.stringify(command));
124
+ }
125
+
126
+ // Handle response from device
127
+ mqttClient.subscribe(`alteriom/nodes/${command.device_id}/responses`, (message) => {
128
+ const response = JSON.parse(message);
129
+ const respResult = validators.commandResponse(response);
130
+
131
+ if (respResult.valid && isCommandResponseMessage(response)) {
132
+ if (response.correlation_id === command.correlation_id) {
133
+ if (response.success) {
134
+ console.log('Command succeeded:', response.result);
135
+ console.log(`Latency: ${response.latency_ms}ms`);
136
+ } else {
137
+ console.error(`Command failed: ${response.error_code} - ${response.message}`);
138
+ }
139
+ }
140
+ }
141
+ });
142
+ ```
143
+
144
+ **Command Pattern Features:**
145
+ - Event-based discrimination (`event: "command"` and `event: "command_response"`)
146
+ - Correlation IDs for request/response tracking
147
+ - Command name validation (lowercase snake_case)
148
+ - Flexible parameters object for command-specific data
149
+ - Priority field for queue management
150
+ - Success boolean and error codes in responses
151
+ - Latency tracking for performance monitoring
152
+
153
+ ## Enhanced Location & Environment Tracking (v0.6.0+)
154
+
155
+ Track device location and deployment context for asset management and map-based visualization:
156
+
157
+ ```ts
158
+ import { validators, isSensorDataMessage } from '@alteriom/mqtt-schema';
159
+
160
+ const sensorData = {
161
+ schema_version: 1,
162
+ device_id: 'SN456',
163
+ device_type: 'sensor',
164
+ timestamp: new Date().toISOString(),
165
+ firmware_version: 'SN 2.1.0',
166
+ // Standardized location for map visualization
167
+ location: {
168
+ latitude: 43.6532,
169
+ longitude: -79.3832,
170
+ altitude: 76.5,
171
+ accuracy_m: 10.0,
172
+ zone: 'warehouse_A',
173
+ description: 'Shelf 3, Row B'
174
+ },
175
+ // Deployment context
176
+ environment: {
177
+ deployment_type: 'indoor',
178
+ power_source: 'battery',
179
+ expected_battery_life_days: 365
180
+ },
181
+ sensors: {
182
+ temperature: {
183
+ value: 22.3,
184
+ unit: 'C',
185
+ // Enhanced sensor metadata
186
+ timestamp: '2025-10-19T20:59:58.000Z',
187
+ accuracy: 0.5,
188
+ last_calibration: '2025-01-15',
189
+ error_margin_pct: 2.0,
190
+ operational_range: { min: -40, max: 85 },
191
+ quality_score: 0.95
192
+ }
193
+ },
194
+ battery_level: 78,
195
+ signal_strength: -65
196
+ };
197
+
198
+ const result = validators.sensorData(sensorData);
199
+ if (result.valid && isSensorDataMessage(sensorData)) {
200
+ // Display on map using location data
201
+ displayOnMap(sensorData.location.latitude, sensorData.location.longitude);
202
+
203
+ // Show sensor health based on metadata
204
+ if (sensorData.sensors.temperature.accuracy) {
205
+ console.log(`Temperature accuracy: ±${sensorData.sensors.temperature.accuracy}${sensorData.sensors.temperature.unit}`);
206
+ }
207
+
208
+ // Check calibration status
209
+ const lastCal = new Date(sensorData.sensors.temperature.last_calibration);
210
+ const daysSinceCalibration = (Date.now() - lastCal.getTime()) / (1000 * 60 * 60 * 24);
211
+ if (daysSinceCalibration > 365) {
212
+ console.warn('Sensor calibration overdue');
213
+ }
214
+ }
215
+ ```
216
+
217
+ **Location & Environment Features:**
218
+ - GPS coordinates (latitude, longitude, altitude) with accuracy tracking
219
+ - Zone-based organization (warehouses, floors, rooms)
220
+ - Human-readable location descriptions
221
+ - Deployment type tracking (indoor/outdoor/mobile)
222
+ - Power source information for battery management
223
+ - Per-sensor timestamps for async polling scenarios
224
+ - Sensor accuracy and calibration tracking
225
+ - Operational range validation support
226
+
227
+ ## Enhanced Gateway Metrics (v0.6.0+)
228
+
229
+ Comprehensive system health monitoring for gateways:
230
+
231
+ ```ts
232
+ import { validators, isGatewayMetricsMessage } from '@alteriom/mqtt-schema';
233
+
234
+ const metrics = {
235
+ schema_version: 1,
236
+ device_id: 'GW002',
237
+ device_type: 'gateway',
238
+ timestamp: new Date().toISOString(),
239
+ firmware_version: 'GW 1.4.0',
240
+ metrics: {
241
+ uptime_s: 86400,
242
+ cpu_usage_pct: 15.3,
243
+ memory_usage_pct: 42.7,
244
+ temperature_c: 45.2,
245
+ // Enhanced storage metrics
246
+ storage_usage_pct: 45.2,
247
+ storage_total_mb: 512,
248
+ storage_free_mb: 280.5,
249
+ // Network bandwidth tracking
250
+ network_rx_kbps: 125.4,
251
+ network_tx_kbps: 89.3,
252
+ active_connections: 5,
253
+ // System health indicators
254
+ error_count_24h: 3,
255
+ warning_count_24h: 12,
256
+ restart_count: 2,
257
+ last_restart_reason: 'firmware_update',
258
+ // Mesh network metrics
259
+ connected_devices: 12,
260
+ mesh_nodes: 8,
261
+ packet_loss_pct: 0.5
262
+ }
263
+ };
264
+
265
+ const result = validators.gatewayMetrics(metrics);
266
+ if (result.valid && isGatewayMetricsMessage(metrics)) {
267
+ // Storage monitoring
268
+ if (metrics.metrics.storage_usage_pct > 80) {
269
+ console.warn('Storage usage critical:', metrics.metrics.storage_usage_pct);
270
+ }
271
+
272
+ // Network health
273
+ const totalBandwidth = metrics.metrics.network_rx_kbps + metrics.metrics.network_tx_kbps;
274
+ console.log(`Total bandwidth: ${totalBandwidth.toFixed(1)} kbps`);
275
+
276
+ // Error trend analysis
277
+ if (metrics.metrics.error_count_24h > 10) {
278
+ console.error('High error rate detected:', metrics.metrics.error_count_24h);
279
+ }
280
+
281
+ // Restart tracking
282
+ console.log(`Last restart: ${metrics.metrics.last_restart_reason}`);
283
+ console.log(`Total restarts: ${metrics.metrics.restart_count}`);
284
+ }
285
+ ```
286
+
287
+ **Enhanced Gateway Metrics Features:**
288
+ - Storage usage tracking (percentage, total, free space)
289
+ - Network bandwidth monitoring (RX/TX rates)
290
+ - Active connection counting
291
+ - Error and warning counters (24-hour rolling window)
292
+ - Restart tracking with reason codes
293
+ - All metrics are optional for gradual firmware adoption
294
+
92
295
  ## OTA Firmware Manifest Schema (v0.3.1+)
93
296
 
94
297
  The package includes OTA firmware manifest schema with both rich and minimal formats.
@@ -172,7 +375,9 @@ All Ajv validator functions are compiled once at module load. For typical web us
172
375
  | gateway_info.schema.json | Gateway identity & capabilities |
173
376
  | gateway_metrics.schema.json | Gateway performance metrics |
174
377
  | firmware_status.schema.json | Firmware update lifecycle events |
175
- | control_response.schema.json | Command/control response messages |
378
+ | control_response.schema.json | Command/control response messages (deprecated, use command_response) |
379
+ | **command.schema.json** | **Device control commands (v0.5.0+)** |
380
+ | **command_response.schema.json** | **Command execution responses with correlation (v0.5.0+)** |
176
381
  | mesh_node_list.schema.json | Mesh network node list with status |
177
382
  | mesh_topology.schema.json | Mesh network topology and connections |
178
383
  | mesh_alert.schema.json | Mesh network alerts and warnings |
@@ -190,10 +395,12 @@ All Ajv validator functions are compiled once at module load. For typical web us
190
395
 
191
396
  ### Validator Keys
192
397
 
193
- `sensorData`, `sensorHeartbeat`, `sensorStatus`, `gatewayInfo`, `gatewayMetrics`, `firmwareStatus`, `controlResponse`, `meshNodeList`, `meshTopology`, `meshAlert`
398
+ `sensorData`, `sensorHeartbeat`, `sensorStatus`, `gatewayInfo`, `gatewayMetrics`, `firmwareStatus`, `controlResponse`, `command`, `commandResponse`, `meshNodeList`, `meshTopology`, `meshAlert`
194
399
 
195
400
  ### Classification Heuristics (Simplified)
196
401
 
402
+ - `event: "command"` → `command` (v0.5.0+)
403
+ - `event: "command_response"` → `commandResponse` (v0.5.0+)
197
404
  - `metrics` → `gatewayMetrics`
198
405
  - `sensors` → `sensorData`
199
406
  - `nodes` array → `meshNodeList`
@@ -1,9 +1,24 @@
1
1
  /**
2
2
  * Auto-generated TypeScript types for Alteriom MQTT Schema v1
3
3
  * Source: docs/mqtt_schema/*.schema.json
4
- * Generation Date: 2025-09-20
4
+ * Generation Date: 2025-10-19
5
5
  * NOTE: This file is maintained in firmware repo for UI alignment. Changes require coordinated review.
6
6
  */
7
+ export interface LocationInfo {
8
+ latitude?: number;
9
+ longitude?: number;
10
+ altitude?: number;
11
+ accuracy_m?: number;
12
+ zone?: string;
13
+ description?: string;
14
+ [k: string]: unknown;
15
+ }
16
+ export interface EnvironmentInfo {
17
+ deployment_type?: 'indoor' | 'outdoor' | 'mobile' | 'mixed';
18
+ power_source?: 'battery' | 'mains' | 'solar' | 'mixed' | 'other';
19
+ expected_battery_life_days?: number;
20
+ [k: string]: unknown;
21
+ }
7
22
  export interface BaseEnvelope {
8
23
  schema_version: 1;
9
24
  device_id: string;
@@ -11,6 +26,8 @@ export interface BaseEnvelope {
11
26
  timestamp: string;
12
27
  firmware_version?: string;
13
28
  hardware_version?: string;
29
+ location?: LocationInfo;
30
+ environment?: EnvironmentInfo;
14
31
  [k: string]: unknown;
15
32
  }
16
33
  export interface SensorEntry {
@@ -22,6 +39,14 @@ export interface SensorEntry {
22
39
  name?: string;
23
40
  location?: string;
24
41
  additional_data?: Record<string, unknown>;
42
+ timestamp?: string;
43
+ accuracy?: number;
44
+ last_calibration?: string;
45
+ error_margin_pct?: number;
46
+ operational_range?: {
47
+ min: number;
48
+ max: number;
49
+ };
25
50
  [k: string]: unknown;
26
51
  }
27
52
  export interface SensorDataMessage extends BaseEnvelope {
@@ -67,6 +92,16 @@ export interface GatewayMetricsMessage extends BaseEnvelope {
67
92
  mesh_nodes?: number;
68
93
  packet_loss_pct?: number;
69
94
  data_throughput_kbps?: number;
95
+ storage_usage_pct?: number;
96
+ storage_total_mb?: number;
97
+ storage_free_mb?: number;
98
+ network_rx_kbps?: number;
99
+ network_tx_kbps?: number;
100
+ active_connections?: number;
101
+ error_count_24h?: number;
102
+ warning_count_24h?: number;
103
+ restart_count?: number;
104
+ last_restart_reason?: string;
70
105
  [k: string]: unknown;
71
106
  };
72
107
  }
@@ -84,6 +119,26 @@ export interface ControlResponseMessage extends BaseEnvelope {
84
119
  message?: string;
85
120
  result?: unknown;
86
121
  }
122
+ export interface CommandMessage extends BaseEnvelope {
123
+ firmware_version: string;
124
+ event: 'command';
125
+ command: string;
126
+ correlation_id?: string;
127
+ parameters?: Record<string, unknown>;
128
+ timeout_ms?: number;
129
+ priority?: 'low' | 'normal' | 'high' | 'urgent';
130
+ }
131
+ export interface CommandResponseMessage extends BaseEnvelope {
132
+ firmware_version: string;
133
+ event: 'command_response';
134
+ command?: string;
135
+ correlation_id?: string;
136
+ success: boolean;
137
+ result?: unknown;
138
+ message?: string;
139
+ error_code?: string;
140
+ latency_ms?: number;
141
+ }
87
142
  export interface MeshNodeListMessage extends BaseEnvelope {
88
143
  device_type: 'gateway';
89
144
  firmware_version: string;
@@ -126,7 +181,7 @@ export interface MeshAlertMessage extends BaseEnvelope {
126
181
  }>;
127
182
  alert_count?: number;
128
183
  }
129
- export type AnyMqttV1Message = SensorDataMessage | SensorHeartbeatMessage | SensorStatusMessage | GatewayInfoMessage | GatewayMetricsMessage | FirmwareStatusMessage | ControlResponseMessage | MeshNodeListMessage | MeshTopologyMessage | MeshAlertMessage;
184
+ export type AnyMqttV1Message = SensorDataMessage | SensorHeartbeatMessage | SensorStatusMessage | GatewayInfoMessage | GatewayMetricsMessage | FirmwareStatusMessage | ControlResponseMessage | CommandMessage | CommandResponseMessage | MeshNodeListMessage | MeshTopologyMessage | MeshAlertMessage;
130
185
  export declare function isSensorDataMessage(msg: any): msg is SensorDataMessage;
131
186
  export declare function isSensorHeartbeatMessage(msg: any): msg is SensorHeartbeatMessage;
132
187
  export declare function isSensorStatusMessage(msg: any): msg is SensorStatusMessage;
@@ -137,6 +192,8 @@ export declare function isControlResponseMessage(msg: any): msg is ControlRespon
137
192
  export declare function isMeshNodeListMessage(msg: any): msg is MeshNodeListMessage;
138
193
  export declare function isMeshTopologyMessage(msg: any): msg is MeshTopologyMessage;
139
194
  export declare function isMeshAlertMessage(msg: any): msg is MeshAlertMessage;
195
+ export declare function isCommandMessage(msg: any): msg is CommandMessage;
196
+ export declare function isCommandResponseMessage(msg: any): msg is CommandResponseMessage;
140
197
  export declare function classifyMessage(msg: any): AnyMqttV1Message | null;
141
198
  export interface BasicValidationIssue {
142
199
  field?: string;
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Auto-generated TypeScript types for Alteriom MQTT Schema v1
4
4
  * Source: docs/mqtt_schema/*.schema.json
5
- * Generation Date: 2025-09-20
5
+ * Generation Date: 2025-10-19
6
6
  * NOTE: This file is maintained in firmware repo for UI alignment. Changes require coordinated review.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -16,6 +16,8 @@ exports.isControlResponseMessage = isControlResponseMessage;
16
16
  exports.isMeshNodeListMessage = isMeshNodeListMessage;
17
17
  exports.isMeshTopologyMessage = isMeshTopologyMessage;
18
18
  exports.isMeshAlertMessage = isMeshAlertMessage;
19
+ exports.isCommandMessage = isCommandMessage;
20
+ exports.isCommandResponseMessage = isCommandResponseMessage;
19
21
  exports.classifyMessage = classifyMessage;
20
22
  exports.basicValidate = basicValidate;
21
23
  exports.parseMessage = parseMessage;
@@ -50,6 +52,12 @@ function isMeshTopologyMessage(msg) {
50
52
  function isMeshAlertMessage(msg) {
51
53
  return msg && msg.schema_version === 1 && msg.device_type === 'gateway' && Array.isArray(msg.alerts);
52
54
  }
55
+ function isCommandMessage(msg) {
56
+ return msg && msg.schema_version === 1 && msg.event === 'command' && typeof msg.command === 'string';
57
+ }
58
+ function isCommandResponseMessage(msg) {
59
+ return msg && msg.schema_version === 1 && msg.event === 'command_response' && typeof msg.success === 'boolean';
60
+ }
53
61
  function classifyMessage(msg) {
54
62
  if (isSensorDataMessage(msg))
55
63
  return msg;
@@ -61,6 +69,10 @@ function classifyMessage(msg) {
61
69
  return msg;
62
70
  if (isMeshAlertMessage(msg))
63
71
  return msg;
72
+ if (isCommandMessage(msg))
73
+ return msg;
74
+ if (isCommandResponseMessage(msg))
75
+ return msg;
64
76
  if (isSensorStatusMessage(msg))
65
77
  return msg;
66
78
  if (isGatewayInfoMessage(msg))
@@ -32,6 +32,64 @@ export declare const envelope_schema: {
32
32
  readonly type: "string";
33
33
  readonly maxLength: 80;
34
34
  };
35
+ readonly location: {
36
+ readonly type: "object";
37
+ readonly description: "Standardized location information for geospatial tracking";
38
+ readonly properties: {
39
+ readonly latitude: {
40
+ readonly type: "number";
41
+ readonly minimum: -90;
42
+ readonly maximum: 90;
43
+ };
44
+ readonly longitude: {
45
+ readonly type: "number";
46
+ readonly minimum: -180;
47
+ readonly maximum: 180;
48
+ };
49
+ readonly altitude: {
50
+ readonly type: "number";
51
+ readonly description: "Altitude in meters";
52
+ };
53
+ readonly accuracy_m: {
54
+ readonly type: "number";
55
+ readonly minimum: 0;
56
+ readonly description: "Position accuracy in meters";
57
+ };
58
+ readonly zone: {
59
+ readonly type: "string";
60
+ readonly maxLength: 64;
61
+ readonly description: "Logical zone identifier (e.g., warehouse_A, floor_2)";
62
+ };
63
+ readonly description: {
64
+ readonly type: "string";
65
+ readonly maxLength: 256;
66
+ readonly description: "Human-readable location description";
67
+ };
68
+ };
69
+ readonly additionalProperties: true;
70
+ };
71
+ readonly environment: {
72
+ readonly type: "object";
73
+ readonly description: "Environmental and deployment context metadata";
74
+ readonly properties: {
75
+ readonly deployment_type: {
76
+ readonly type: "string";
77
+ readonly enum: readonly ["indoor", "outdoor", "mobile", "mixed"];
78
+ readonly description: "Type of deployment environment";
79
+ };
80
+ readonly power_source: {
81
+ readonly type: "string";
82
+ readonly enum: readonly ["battery", "mains", "solar", "mixed", "other"];
83
+ readonly description: "Primary power source";
84
+ };
85
+ readonly expected_battery_life_days: {
86
+ readonly type: "integer";
87
+ readonly minimum: 0;
88
+ readonly description: "Expected battery life in days (if battery-powered)";
89
+ };
90
+ };
91
+ readonly additionalProperties: true;
92
+ };
35
93
  };
36
94
  readonly additionalProperties: true;
37
95
  };
@@ -78,6 +136,41 @@ export declare const sensor_data_schema: {
78
136
  readonly additional_data: {
79
137
  readonly type: "object";
80
138
  };
139
+ readonly timestamp: {
140
+ readonly type: "string";
141
+ readonly format: "date-time";
142
+ readonly description: "Per-sensor reading timestamp (useful for async multi-sensor polling)";
143
+ };
144
+ readonly accuracy: {
145
+ readonly type: "number";
146
+ readonly minimum: 0;
147
+ readonly description: "Sensor accuracy (±value in sensor units)";
148
+ };
149
+ readonly last_calibration: {
150
+ readonly type: "string";
151
+ readonly format: "date";
152
+ readonly description: "Last calibration date (ISO 8601 date)";
153
+ };
154
+ readonly error_margin_pct: {
155
+ readonly type: "number";
156
+ readonly minimum: 0;
157
+ readonly maximum: 100;
158
+ readonly description: "Error margin as percentage";
159
+ };
160
+ readonly operational_range: {
161
+ readonly type: "object";
162
+ readonly description: "Valid operational range for this sensor";
163
+ readonly required: readonly ["min", "max"];
164
+ readonly properties: {
165
+ readonly min: {
166
+ readonly type: "number";
167
+ };
168
+ readonly max: {
169
+ readonly type: "number";
170
+ };
171
+ };
172
+ readonly additionalProperties: false;
173
+ };
81
174
  };
82
175
  readonly additionalProperties: false;
83
176
  };
@@ -237,6 +330,57 @@ export declare const gateway_metrics_schema: {
237
330
  readonly type: "number";
238
331
  readonly minimum: 0;
239
332
  };
333
+ readonly storage_usage_pct: {
334
+ readonly type: "number";
335
+ readonly minimum: 0;
336
+ readonly maximum: 100;
337
+ readonly description: "Disk/flash storage usage percentage";
338
+ };
339
+ readonly storage_total_mb: {
340
+ readonly type: "number";
341
+ readonly minimum: 0;
342
+ readonly description: "Total storage capacity in megabytes";
343
+ };
344
+ readonly storage_free_mb: {
345
+ readonly type: "number";
346
+ readonly minimum: 0;
347
+ readonly description: "Free storage space in megabytes";
348
+ };
349
+ readonly network_rx_kbps: {
350
+ readonly type: "number";
351
+ readonly minimum: 0;
352
+ readonly description: "Network receive bandwidth in kilobits per second";
353
+ };
354
+ readonly network_tx_kbps: {
355
+ readonly type: "number";
356
+ readonly minimum: 0;
357
+ readonly description: "Network transmit bandwidth in kilobits per second";
358
+ };
359
+ readonly active_connections: {
360
+ readonly type: "integer";
361
+ readonly minimum: 0;
362
+ readonly description: "Number of active network connections";
363
+ };
364
+ readonly error_count_24h: {
365
+ readonly type: "integer";
366
+ readonly minimum: 0;
367
+ readonly description: "Error count in last 24 hours";
368
+ };
369
+ readonly warning_count_24h: {
370
+ readonly type: "integer";
371
+ readonly minimum: 0;
372
+ readonly description: "Warning count in last 24 hours";
373
+ };
374
+ readonly restart_count: {
375
+ readonly type: "integer";
376
+ readonly minimum: 0;
377
+ readonly description: "Total restart counter since deployment";
378
+ };
379
+ readonly last_restart_reason: {
380
+ readonly type: "string";
381
+ readonly maxLength: 128;
382
+ readonly description: "Reason for last restart (e.g., watchdog, power_loss, update, manual)";
383
+ };
240
384
  };
241
385
  readonly additionalProperties: true;
242
386
  };
@@ -303,6 +447,122 @@ export declare const control_response_schema: {
303
447
  };
304
448
  readonly additionalProperties: true;
305
449
  };
450
+ export declare const command_schema: {
451
+ readonly $schema: "https://json-schema.org/draft/2020-12/schema";
452
+ readonly $id: "https://schemas.alteriom.io/mqtt/v1/command.schema.json";
453
+ readonly title: "Device Command v1";
454
+ readonly description: "Command message sent from MQTT client to IoT device for control operations";
455
+ readonly allOf: readonly [{
456
+ readonly $ref: "envelope.schema.json";
457
+ }];
458
+ readonly type: "object";
459
+ readonly required: readonly ["event", "command"];
460
+ readonly properties: {
461
+ readonly event: {
462
+ readonly type: "string";
463
+ readonly const: "command";
464
+ readonly description: "Event type discriminator";
465
+ };
466
+ readonly command: {
467
+ readonly type: "string";
468
+ readonly minLength: 1;
469
+ readonly maxLength: 64;
470
+ readonly pattern: "^[a-z][a-z0-9_]*$";
471
+ readonly description: "Command name in snake_case (e.g., read_sensors, set_interval, restart)";
472
+ readonly examples: readonly ["read_sensors", "set_interval", "enable_sensor", "update_config", "restart", "get_status"];
473
+ };
474
+ readonly correlation_id: {
475
+ readonly type: "string";
476
+ readonly minLength: 1;
477
+ readonly maxLength: 128;
478
+ readonly pattern: "^[A-Za-z0-9_-]+$";
479
+ readonly description: "Unique identifier for tracking command → response lifecycle";
480
+ };
481
+ readonly parameters: {
482
+ readonly type: "object";
483
+ readonly description: "Command-specific parameters (validated by device)";
484
+ readonly additionalProperties: true;
485
+ readonly examples: readonly [{
486
+ readonly interval: 30000;
487
+ }, {
488
+ readonly sensor: "temperature";
489
+ readonly enabled: true;
490
+ }, {
491
+ readonly immediate: true;
492
+ readonly sensors: readonly ["temperature", "humidity"];
493
+ }];
494
+ };
495
+ readonly timeout_ms: {
496
+ readonly type: "integer";
497
+ readonly minimum: 1000;
498
+ readonly maximum: 300000;
499
+ readonly default: 5000;
500
+ readonly description: "Command execution timeout in milliseconds";
501
+ };
502
+ readonly priority: {
503
+ readonly type: "string";
504
+ readonly enum: readonly ["low", "normal", "high", "urgent"];
505
+ readonly default: "normal";
506
+ readonly description: "Command priority for queue management";
507
+ };
508
+ };
509
+ readonly additionalProperties: true;
510
+ };
511
+ export declare const command_response_schema: {
512
+ readonly $schema: "https://json-schema.org/draft/2020-12/schema";
513
+ readonly $id: "https://schemas.alteriom.io/mqtt/v1/command_response.schema.json";
514
+ readonly title: "Command Response v1";
515
+ readonly description: "Response message from IoT device after executing a command";
516
+ readonly allOf: readonly [{
517
+ readonly $ref: "envelope.schema.json";
518
+ }];
519
+ readonly type: "object";
520
+ readonly required: readonly ["event", "success"];
521
+ readonly properties: {
522
+ readonly event: {
523
+ readonly type: "string";
524
+ readonly const: "command_response";
525
+ readonly description: "Event type discriminator";
526
+ };
527
+ readonly command: {
528
+ readonly type: "string";
529
+ readonly minLength: 1;
530
+ readonly maxLength: 64;
531
+ readonly description: "Original command name that was executed";
532
+ };
533
+ readonly correlation_id: {
534
+ readonly type: "string";
535
+ readonly minLength: 1;
536
+ readonly maxLength: 128;
537
+ readonly pattern: "^[A-Za-z0-9_-]+$";
538
+ readonly description: "Matches correlation_id from original command";
539
+ };
540
+ readonly success: {
541
+ readonly type: "boolean";
542
+ readonly description: "Whether command execution succeeded";
543
+ };
544
+ readonly result: {
545
+ readonly type: readonly ["object", "array", "string", "number", "boolean", "null"];
546
+ readonly description: "Command execution result data";
547
+ };
548
+ readonly message: {
549
+ readonly type: "string";
550
+ readonly maxLength: 256;
551
+ readonly description: "Human-readable status message";
552
+ };
553
+ readonly error_code: {
554
+ readonly type: "string";
555
+ readonly maxLength: 64;
556
+ readonly description: "Machine-readable error code (e.g., TIMEOUT, INVALID_PARAMS)";
557
+ };
558
+ readonly latency_ms: {
559
+ readonly type: "integer";
560
+ readonly minimum: 0;
561
+ readonly description: "Time taken to execute command in milliseconds";
562
+ };
563
+ };
564
+ readonly additionalProperties: true;
565
+ };
306
566
  export declare const mesh_node_list_schema: {
307
567
  readonly $schema: "https://json-schema.org/draft/2020-12/schema";
308
568
  readonly $id: "https://schemas.alteriom.io/mqtt/v1/mesh_node_list.schema.json";
@@ -481,6 +741,8 @@ export declare const mqtt_v1_bundle_json: {
481
741
  readonly gateway_metrics: "gateway_metrics.schema.json";
482
742
  readonly firmware_status: "firmware_status.schema.json";
483
743
  readonly control_response: "control_response.schema.json";
744
+ readonly command: "command.schema.json";
745
+ readonly command_response: "command_response.schema.json";
484
746
  readonly mesh_node_list: "mesh_node_list.schema.json";
485
747
  readonly mesh_topology: "mesh_topology.schema.json";
486
748
  readonly mesh_alert: "mesh_alert.schema.json";