@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.
- package/README.md +209 -2
- package/dist/cjs/generated/types.d.ts +59 -2
- package/dist/cjs/generated/types.js +13 -1
- package/dist/cjs/schema_data.d.ts +262 -0
- package/dist/cjs/schema_data.js +313 -1
- package/dist/cjs/schemas/command.schema.json +62 -0
- package/dist/cjs/schemas/command_response.schema.json +53 -0
- package/dist/cjs/schemas/envelope.schema.json +24 -1
- package/dist/cjs/schemas/gateway_metrics.schema.json +11 -1
- package/dist/cjs/schemas/mqtt_v1_bundle.json +2 -0
- package/dist/cjs/schemas/sensor_data.schema.json +15 -1
- package/dist/cjs/schemas/validation_rules.md +15 -0
- package/dist/cjs/validators.d.ts +2 -0
- package/dist/cjs/validators.js +12 -0
- package/dist/esm/generated/types.js +11 -1
- package/dist/esm/schema_data.js +312 -0
- package/dist/esm/schemas/command.schema.json +62 -0
- package/dist/esm/schemas/command_response.schema.json +53 -0
- package/dist/esm/schemas/envelope.schema.json +24 -1
- package/dist/esm/schemas/gateway_metrics.schema.json +11 -1
- package/dist/esm/schemas/mqtt_v1_bundle.json +2 -0
- package/dist/esm/schemas/sensor_data.schema.json +15 -1
- package/dist/esm/schemas/validation_rules.md +15 -0
- package/dist/esm/validators.js +13 -1
- package/package.json +1 -1
- package/schemas/command.schema.json +62 -0
- package/schemas/command_response.schema.json +53 -0
- package/schemas/envelope.schema.json +24 -1
- package/schemas/gateway_metrics.schema.json +11 -1
- package/schemas/mqtt_v1_bundle.json +2 -0
- package/schemas/sensor_data.schema.json +15 -1
- 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-
|
|
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-
|
|
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";
|