@formant/formant-cli 0.4.2 → 0.4.4

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 CHANGED
@@ -33,7 +33,9 @@ This CLI provides programmatic access to all Formant capabilities:
33
33
  - List, create, rename, and delete robots/sensors
34
34
  - Add tags for organization (environment, location, customer)
35
35
  - View real-time device status and configuration
36
- - List available telemetry streams
36
+ - List available telemetry streams with per-stream data presence (datapoint counts, last seen, freshness)
37
+ - Data-based last seen timestamps and datapoint counts on device listings
38
+ - Filter to devices that have ingested data (`--with-data`)
37
39
 
38
40
  ### Telemetry Queries
39
41
  - Query historical sensor data (battery, temperature, position, custom metrics)
@@ -171,8 +173,8 @@ The CLI will automatically load credentials from your `.env` file.
171
173
  # View your organization
172
174
  fcli org get
173
175
 
174
- # List all devices
175
- fcli device list --dev
176
+ # List devices with data
177
+ fcli device list --with-data --dev
176
178
 
177
179
  # Get device details
178
180
  fcli device get <device-id> --dev
@@ -214,15 +216,20 @@ Create, list, and manage robots/sensors in your fleet.
214
216
 
215
217
  ```bash
216
218
  # Listing and filtering
217
- fcli device list # List all devices
218
- fcli device list --online # Only online devices
219
+ fcli device list # Online devices (default)
220
+ fcli device list --include-offline # Include offline devices
221
+ fcli device list --with-data # Only devices with ingested data
222
+ fcli device list --with-data --days 90 # Widen the search window (default: 30d)
219
223
  fcli device list --tag location=warehouse # Filter by tag
220
224
 
221
225
  # Device details
222
226
  fcli device get <device-id> # Get full device details
223
227
  fcli device config <device-id> # Get device configuration
224
- fcli device streams <device-id> # List available data streams
225
- fcli device last-seen <device-id> # Get last activity timestamp
228
+
229
+ # Stream discovery with data presence
230
+ fcli device streams <device-id> # List streams with datapoint counts,
231
+ # last seen (ISO), and freshness
232
+ fcli device streams <device-id> --days 30 # Adjust presence lookback (default: 7d)
226
233
 
227
234
  # Device management
228
235
  fcli device create --name "robot-001" # Create a new device
@@ -258,6 +265,18 @@ Retrieve historical telemetry and sensor data.
258
265
  fcli query --device <device-id> --stream battery_level \
259
266
  --start 2026-01-01 --end 2026-01-02
260
267
 
268
+ # Multiple streams in one query
269
+ fcli query --device <device-id> --stream heat.current --stream power.available \
270
+ --start 2026-02-01 --end 2026-02-20
271
+
272
+ # Multiple devices in one query
273
+ fcli query --device <id1> --device <id2> --stream battery_level \
274
+ --start 2026-02-01 --end 2026-02-20
275
+
276
+ # Aggregated data (downsample to hourly)
277
+ fcli query --device <device-id> --stream temperature \
278
+ --start 2026-01-01 --end 2026-02-01 --aggregate hour
279
+
261
280
  # Latest values
262
281
  fcli query latest-values --device <device-id> --stream battery_level
263
282
 
@@ -454,14 +473,50 @@ These flags work with any command:
454
473
  Human-readable tables optimized for terminal viewing:
455
474
 
456
475
  ```bash
457
- $ fcli device list --dev
476
+ $ fcli device list --with-data --dev
477
+
478
+ Devices — with data (dev):
479
+
480
+ NAME ID ONLINE TYPE LAST SEEN (30D) DATAPOINTS (30D)
481
+ ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
482
+ carter.1 a8840212-a0a4-4d0b-8a47-098563894748 false default 2026-02-19T19:05:37.536Z 720156
483
+ DJI Matrice 4E 10f78fd5-c00d-42d9-94c4-b310646f59be false default 2026-02-18T01:17:41.167Z 917051
484
+ ```
485
+
486
+ ```bash
487
+ $ fcli device streams <device-id> --dev
488
+
489
+ Device Streams (dev):
490
+
491
+ Device: Walt (020e59a1-...)
492
+ Configured: 10 | Discovered from data: 34
493
+ Presence (last 7d): 0 active, 32 recent, 0 stale, 0 dormant, 12 no data
494
+
495
+ NAME TYPE SOURCE DATAPOINTS LAST SEEN FRESHNESS
496
+ spot.robot_state.battery numeric data 20195 2026-02-19T23:37:01.281Z recent
497
+ spot.localization text data 16962 2026-02-19T23:37:01.271Z recent
498
+ spot.hand.image custom config — — —
499
+ ```
500
+
501
+ ```bash
502
+ $ fcli query --device <device-id> --stream heat.current --stream power.available \
503
+ --start 2026-02-01 --end 2026-02-20 --dev
504
+
505
+ Telemetry Data (dev environment):
506
+
507
+ Stream: heat.current (numeric) Device: 01397354-d17a-4b53-ac27-61753de7918c
508
+ Points: 1
458
509
 
459
- Devices (dev):
510
+ TIME VALUE
511
+ ──────────────────────────────────────────────────────────────────────────────
512
+ 2026-02-18T21:15:38.491Z 47
460
513
 
461
- NAME ID STATUS TAGS
462
- ────────────────────────────────────────────────────────────────────────
463
- robot-001 a1b2c3d4-... online env=prod, location=warehouse
464
- robot-002 e5f6g7h8-... offline env=dev
514
+ Stream: power.available (numeric) Device: 01397354-d17a-4b53-ac27-61753de7918c
515
+ Points: 1
516
+
517
+ TIME VALUE
518
+ ──────────────────────────────────────────────────────────────────────────────
519
+ 2026-02-18T21:15:38.520Z 72
465
520
  ```
466
521
 
467
522
  ### JSON
@@ -469,17 +524,15 @@ robot-002 e5f6g7h8-... offline env=dev
469
524
  Machine-readable JSON for scripting and automation:
470
525
 
471
526
  ```bash
472
- $ fcli device list --dev --json
527
+ $ fcli device list --with-data --dev --json
473
528
  {
474
529
  "items": [
475
530
  {
476
- "id": "a1b2c3d4-...",
477
- "name": "robot-001",
478
- "online": true,
479
- "tags": {
480
- "env": "prod",
481
- "location": "warehouse"
482
- }
531
+ "id": "a8840212-...",
532
+ "name": "carter.1",
533
+ "online": false,
534
+ "last_seen": "2026-02-19T19:05:37.536Z",
535
+ "datapoints": 720156
483
536
  }
484
537
  ]
485
538
  }
@@ -496,17 +549,20 @@ fcli device list --json | jq '.items[] | select(.online==true) | .name'
496
549
  ### Monitor fleet health
497
550
 
498
551
  ```bash
552
+ # Find devices that have data
553
+ fcli device list --with-data
554
+
555
+ # Find devices with data, wider search window
556
+ fcli device list --with-data --days 90
557
+
499
558
  # Check which devices are offline
500
- fcli device list --json | jq '.items[] | select(.online==false) | .name'
559
+ fcli device list --include-offline --json | jq '.items[] | select(.online==false) | .name'
501
560
 
502
561
  # View recent critical events across the fleet
503
562
  fcli event list --severity critical --limit 50
504
563
 
505
- # Check battery levels
506
- for device in $(fcli device list --json | jq -r '.items[].id'); do
507
- echo "Device: $device"
508
- fcli query latest-values --device $device --stream battery_level
509
- done
564
+ # Discover what streams a device has and their data freshness
565
+ fcli device streams <device-id>
510
566
  ```
511
567
 
512
568
  ### Delegate a task to an AI persona
@@ -534,8 +590,8 @@ fcli investigation trigger <investigation-id> --input "Device stopped responding
534
590
  # 3. Check investigation runs
535
591
  fcli investigation runs <investigation-id>
536
592
 
537
- # 4. Query relevant telemetry
538
- fcli query --device <device-id> --stream temperature \
593
+ # 4. Query relevant telemetry (multiple streams and/or devices at once)
594
+ fcli query --device <device-id> --stream temperature --stream battery_level \
539
595
  --start 2026-02-17T10:00:00Z --end 2026-02-17T12:00:00Z
540
596
  ```
541
597
 
@@ -3,15 +3,21 @@ export default class DevicesList extends BaseCommand<typeof DevicesList> {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
+ 'include-offline': import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ days: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
7
8
  limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
8
9
  name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'with-data': import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
11
  tag: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
12
  };
11
13
  static summary: string;
12
14
  run(): Promise<{
13
15
  items: unknown[];
14
16
  }>;
17
+ /**
18
+ * Query analytics SQL for per-device last seen and datapoint counts.
19
+ */
20
+ private getLastSeenMap;
15
21
  /**
16
22
  * Try to get online device IDs from the presence service.
17
23
  * Returns null if the endpoint fails or is unavailable.
@@ -1,21 +1,30 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { BaseCommand } from '../../base-command.js';
3
3
  import { formatTable } from '../../lib/formatters.js';
4
+ import { buildLastSeenSQL, toIsoDateTime } from '../../lib/presence.js';
4
5
  export default class DevicesList extends BaseCommand {
5
6
  static description = `List robots and sensors in your fleet. Shows only online devices by default.
6
7
 
7
- Use --all to include offline devices.`;
8
+ Use --include-offline to include offline devices. Use --with-data to show only
9
+ devices that have ingested data. Each device is enriched with data-based last
10
+ seen timestamp and datapoint count from analytics.`;
8
11
  static examples = [
9
12
  '<%= config.bin %> device list',
10
- '<%= config.bin %> device list --all',
11
- '<%= config.bin %> device list --all --limit 100',
13
+ '<%= config.bin %> device list --include-offline',
14
+ '<%= config.bin %> device list --with-data',
15
+ '<%= config.bin %> device list --with-data --days 90',
16
+ '<%= config.bin %> device list --include-offline --limit 100',
12
17
  '<%= config.bin %> device list --tag location=warehouse',
13
18
  '<%= config.bin %> device list --name robot --dev --json',
14
19
  ];
15
20
  static flags = {
16
- all: Flags.boolean({
21
+ 'include-offline': Flags.boolean({
17
22
  char: 'a',
18
- description: 'Show all devices (online and offline)',
23
+ description: 'Include offline devices',
24
+ }),
25
+ days: Flags.integer({
26
+ default: 30,
27
+ description: 'How many days back to search for last seen data',
19
28
  }),
20
29
  limit: Flags.integer({
21
30
  char: 'l',
@@ -26,6 +35,10 @@ Use --all to include offline devices.`;
26
35
  char: 'n',
27
36
  description: 'Filter devices by name (search)',
28
37
  }),
38
+ 'with-data': Flags.boolean({
39
+ char: 'w',
40
+ description: 'Only show devices that have data in the last --days window',
41
+ }),
29
42
  tag: Flags.string({
30
43
  char: 't',
31
44
  description: 'Filter by tag (key=value), can be specified multiple times',
@@ -55,7 +68,7 @@ Use --all to include offline devices.`;
55
68
  }
56
69
  const limit = this.flags.limit;
57
70
  let filtered;
58
- if (this.flags.all) {
71
+ if (this.flags['include-offline'] || this.flags['with-data']) {
59
72
  // --all: simple single fetch, enrich with online status
60
73
  const result = await this.api('admin', 'devices/query', { body: { ...baseBody, count: limit } });
61
74
  const onlineIds = await this.getOnlineDeviceIds();
@@ -96,14 +109,29 @@ Use --all to include offline devices.`;
96
109
  }
97
110
  }
98
111
  }
112
+ // ── Enrich with analytics-based last seen + datapoint counts ─────────────
113
+ const deviceIds = filtered.map((d) => d.id).filter(Boolean);
114
+ const lastSeenMap = await this.getLastSeenMap(deviceIds);
115
+ for (const device of filtered) {
116
+ const info = lastSeenMap.get(device.id);
117
+ device.last_seen = info ? toIsoDateTime(info.last_seen) : null;
118
+ device.datapoints = info?.total_points ?? null;
119
+ }
120
+ // ── Filter to devices with data if requested ──────────────────────────────
121
+ if (this.flags['with-data']) {
122
+ filtered = filtered.filter((d) => d.last_seen !== null);
123
+ }
99
124
  const output = { items: filtered };
100
125
  if (!this.jsonEnabled()) {
101
- const mode = this.flags.all ? 'all' : 'online';
126
+ const mode = this.flags['with-data'] ? 'with data' : this.flags['include-offline'] ? 'all' : 'online';
127
+ const days = this.flags.days;
102
128
  const columns = [
103
- { key: 'name', label: 'NAME', width: 30 },
129
+ { key: 'name', label: 'NAME', width: 24 },
104
130
  { key: 'id', label: 'ID', width: 40 },
105
- { key: 'online', label: 'ONLINE', width: 10 },
106
- { key: 'type', label: 'TYPE', width: 14 },
131
+ { key: 'online', label: 'ONLINE', width: 8 },
132
+ { key: 'type', label: 'TYPE', width: 10 },
133
+ { key: 'last_seen', label: `LAST SEEN (${days}D)`, width: 28 },
134
+ { key: 'datapoints', label: `DATAPOINTS (${days}D)`, width: 16 },
107
135
  ];
108
136
  this.log(`\nDevices — ${mode} (${this.env}):\n`);
109
137
  this.log(formatTable(filtered, columns));
@@ -111,6 +139,32 @@ Use --all to include offline devices.`;
111
139
  }
112
140
  return output;
113
141
  }
142
+ /**
143
+ * Query analytics SQL for per-device last seen and datapoint counts.
144
+ */
145
+ async getLastSeenMap(deviceIds) {
146
+ const map = new Map();
147
+ if (deviceIds.length === 0)
148
+ return map;
149
+ try {
150
+ const sql = buildLastSeenSQL({
151
+ days: this.flags.days,
152
+ deviceIds,
153
+ });
154
+ const result = await this.api('query', 'analytics/rows', {
155
+ body: { sqlQuery: sql, type: 'advanced' },
156
+ });
157
+ if (!result.error && result.rows) {
158
+ for (const row of result.rows) {
159
+ map.set(row.device_id, row);
160
+ }
161
+ }
162
+ }
163
+ catch {
164
+ // non-fatal
165
+ }
166
+ return map;
167
+ }
114
168
  /**
115
169
  * Try to get online device IDs from the presence service.
116
170
  * Returns null if the endpoint fails or is unavailable.
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/device/list.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/device/list.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ export default class DevicesStreams extends BaseCommand<typeof DevicesStreams> {
7
7
  static examples: string[];
8
8
  static flags: {
9
9
  days: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'with-data': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
11
  };
11
12
  static summary: string;
12
13
  run(): Promise<{
@@ -1,27 +1,36 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import { BaseCommand } from '../../base-command.js';
3
3
  import { formatTable } from '../../lib/formatters.js';
4
+ import { buildPresenceSQL, getFreshness, toIsoDateTime, } from '../../lib/presence.js';
4
5
  export default class DevicesStreams extends BaseCommand {
5
6
  static args = {
6
7
  id: Args.string({ description: 'Device ID (UUID)', required: true }),
7
8
  };
8
- static description = `List telemetry streams for a device.
9
+ static description = `List telemetry streams for a device with data presence.
9
10
 
10
- Shows streams parsed from the device configuration as well as any streams
11
- discovered from actual ingested data (even if not explicitly configured).
12
- Unconfigured streams are marked with a SOURCE of "data" in the output.`;
11
+ Shows streams from the device configuration and any streams discovered from
12
+ ingested data. Each stream is enriched with presence info from the analytics
13
+ backend: data point count, last seen time, and a freshness indicator
14
+ (active/recent/stale/dormant).
15
+
16
+ Unconfigured streams (discovered from data only) are marked with SOURCE "data".`;
13
17
  static examples = [
14
18
  '<%= config.bin %> device streams <device-id>',
19
+ '<%= config.bin %> device streams <device-id> --with-data',
20
+ '<%= config.bin %> device streams <device-id> --with-data --days 30',
15
21
  '<%= config.bin %> device streams <device-id> --json',
16
- '<%= config.bin %> device streams <device-id> --days 30',
17
22
  ];
18
23
  static flags = {
19
24
  days: Flags.integer({
20
- default: 14,
21
- description: 'How many days back to look for unconfigured streams in ingested data',
25
+ default: 7,
26
+ description: 'How many days back to look for stream data presence',
27
+ }),
28
+ 'with-data': Flags.boolean({
29
+ char: 'w',
30
+ description: 'Only show streams that have data in the --days window',
22
31
  }),
23
32
  };
24
- static summary = 'List device streams';
33
+ static summary = 'List device streams with data presence';
25
34
  async run() {
26
35
  const deviceId = this.args.id;
27
36
  // ── 1. Fetch config-based streams ────────────────────────────────────────
@@ -49,48 +58,94 @@ Unconfigured streams are marked with a SOURCE of "data" in the output.`;
49
58
  start: since.toISOString(),
50
59
  },
51
60
  });
52
- metadataItems = metaResult?.items ?? [];
61
+ // Deduplicate metadata by stream name (the API may return multiple
62
+ // entries for the same stream with different tags)
63
+ const seen = new Set();
64
+ for (const item of metaResult?.items ?? []) {
65
+ if (!seen.has(item.name)) {
66
+ seen.add(item.name);
67
+ metadataItems.push(item);
68
+ }
69
+ }
53
70
  }
54
71
  catch {
55
72
  // metadata endpoint failure is non-fatal; we still return config streams
56
73
  }
57
- // ── 3. Build merged stream list ───────────────────────────────────────────
58
- // Configured streams come first, annotated with source="config"
74
+ // ── 3. Fetch per-stream data presence via analytics SQL ──────────────────
75
+ let presenceMap = new Map();
76
+ try {
77
+ const sql = buildPresenceSQL({
78
+ days: this.flags.days,
79
+ deviceIds: [deviceId],
80
+ });
81
+ const presenceResult = await this.api('query', 'analytics/rows', {
82
+ body: { sqlQuery: sql, type: 'advanced' },
83
+ });
84
+ if (!presenceResult.error && presenceResult.rows) {
85
+ for (const row of presenceResult.rows) {
86
+ presenceMap.set(row.stream_name, row);
87
+ }
88
+ }
89
+ }
90
+ catch {
91
+ // presence failure is non-fatal
92
+ }
93
+ // ── 4. Build merged stream list ───────────────────────────────────────────
59
94
  const rows = configStreams.map((s) => {
60
95
  const conf = s.configuration;
96
+ const name = s.name;
97
+ const presence = presenceMap.get(name);
61
98
  return {
62
- name: s.name,
63
- quality: s.quality || '—',
99
+ datapoints: presence?.data_points ?? null,
100
+ first_seen: presence ? toIsoDateTime(presence.first_seen) : null,
101
+ freshness: presence ? getFreshness(presence.last_seen) : null,
102
+ last_seen: presence ? toIsoDateTime(presence.last_seen) : null,
103
+ name,
64
104
  source: 'config',
65
- topic: conf?.topic || '—',
66
105
  type: conf?.type || '—',
67
106
  };
68
107
  });
69
- // Append streams seen in data but absent from config
70
108
  for (const item of metadataItems) {
71
109
  if (!configuredStreamNames.has(item.name)) {
110
+ const presence = presenceMap.get(item.name);
72
111
  rows.push({
112
+ datapoints: presence?.data_points ?? null,
113
+ first_seen: presence ? toIsoDateTime(presence.first_seen) : null,
114
+ freshness: presence ? getFreshness(presence.last_seen) : null,
115
+ last_seen: presence ? toIsoDateTime(presence.last_seen) : null,
73
116
  name: item.name,
74
- quality: '—',
75
117
  source: 'data',
76
- topic: '—',
77
118
  type: item.type || '—',
78
119
  });
79
120
  }
80
121
  }
122
+ // ── 5. Filter to streams with data if requested ────────────────────────
123
+ if (this.flags['with-data']) {
124
+ rows.splice(0, rows.length, ...rows.filter((r) => r.datapoints !== null));
125
+ }
81
126
  if (!this.jsonEnabled()) {
82
127
  const columns = [
83
- { key: 'name', label: 'NAME', width: 30 },
84
- { key: 'type', label: 'TYPE', width: 20 },
85
- { key: 'topic', label: 'TOPIC', width: 36 },
86
- { key: 'quality', label: 'QUALITY', width: 10 },
128
+ { key: 'name', label: 'NAME', width: 34 },
129
+ { key: 'type', label: 'TYPE', width: 14 },
87
130
  { key: 'source', label: 'SOURCE', width: 8 },
131
+ { key: 'datapoints', label: `DATAPOINTS (${this.flags.days}D)`, width: 18 },
132
+ { key: 'last_seen', label: `LAST SEEN (${this.flags.days}D)`, width: 28 },
133
+ { key: 'freshness', label: 'FRESHNESS', width: 10 },
88
134
  ];
89
135
  const configured = rows.filter((r) => r.source === 'config').length;
90
136
  const discovered = rows.filter((r) => r.source === 'data').length;
91
- this.log(`\nDevice Streams (${this.env}):\n`);
137
+ const active = rows.filter((r) => r.freshness === 'active').length;
138
+ const recent = rows.filter((r) => r.freshness === 'recent').length;
139
+ const stale = rows.filter((r) => r.freshness === 'stale').length;
140
+ const dormant = rows.filter((r) => r.freshness === 'dormant').length;
141
+ const noData = rows.filter((r) => r.freshness === null).length;
142
+ const mode = this.flags['with-data'] ? ' — with data' : '';
143
+ this.log(`\nDevice Streams${mode} (${this.env}):\n`);
92
144
  this.log(` Device: ${device.name} (${deviceId})`);
93
- this.log(` Configured: ${configured} | Discovered from data (last ${this.flags.days}d): ${discovered}\n`);
145
+ this.log(` Configured: ${configured} | Discovered from data: ${discovered}`);
146
+ this.log(` Presence (last ${this.flags.days}d): ${active} active, ${recent} recent, ${stale} stale, ${dormant} dormant` +
147
+ (noData > 0 ? `, ${noData} no data` : ''));
148
+ this.log('');
94
149
  this.log(formatTable(rows, columns));
95
150
  this.log('');
96
151
  }
@@ -1 +1 @@
1
- {"version":3,"file":"streams.js","sourceRoot":"","sources":["../../../src/commands/device/streams.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"streams.js","sourceRoot":"","sources":["../../../src/commands/device/streams.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ export default class Query extends BaseCommand<typeof Query> {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  aggregate: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
- device: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
+ device: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
8
8
  end: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
9
  latest: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
10
  limit: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -15,6 +15,8 @@ hour, 4 hours, 12 hours, day, week, month, year.`;
15
15
  static examples = [
16
16
  '<%= config.bin %> query --device <id> --stream battery_level --start 2026-01-01 --end 2026-01-02',
17
17
  '<%= config.bin %> query --device <id> --stream speed --aggregate hour --start 2026-01-01 --end 2026-02-01',
18
+ '<%= config.bin %> query --device <id> --stream battery_level --stream temperature --start 2026-01-01 --end 2026-01-02',
19
+ '<%= config.bin %> query --device <id1> --device <id2> --stream battery_level --start 2026-01-01 --end 2026-01-02',
18
20
  '<%= config.bin %> query --device <id> --stream battery_level --latest',
19
21
  '<%= config.bin %> query --device <id> --stream temperature --type numeric --json',
20
22
  ];
@@ -25,7 +27,8 @@ hour, 4 hours, 12 hours, day, week, month, year.`;
25
27
  }),
26
28
  device: Flags.string({
27
29
  char: 'd',
28
- description: 'Device ID (UUID)',
30
+ description: 'Device ID(s), can be specified multiple times',
31
+ multiple: true,
29
32
  required: true,
30
33
  }),
31
34
  end: Flags.string({
@@ -58,7 +61,7 @@ hour, 4 hours, 12 hours, day, week, month, year.`;
58
61
  this.error('--start and --end are required (unless using --latest).');
59
62
  }
60
63
  const body = {
61
- deviceIds: [this.flags.device],
64
+ deviceIds: this.flags.device,
62
65
  names: this.flags.stream,
63
66
  };
64
67
  if (this.flags.start)
@@ -90,10 +93,21 @@ hour, 4 hours, 12 hours, day, week, month, year.`;
90
93
  { key: 'time', label: 'TIME', width: 28 },
91
94
  { key: 'value', label: 'VALUE', width: 50 },
92
95
  ];
93
- const rows = points.map((p) => ({
94
- time: p.time,
95
- value: typeof p.value === 'object' ? JSON.stringify(p.value) : p.value,
96
- }));
96
+ const rows = points.map((p) => {
97
+ // Points can be [timestamp_ms, value] tuples or {time, value} objects
98
+ if (Array.isArray(p)) {
99
+ const [ts, val] = p;
100
+ return {
101
+ time: new Date(ts).toISOString(),
102
+ value: typeof val === 'object' ? JSON.stringify(val) : val,
103
+ };
104
+ }
105
+ const obj = p;
106
+ return {
107
+ time: obj.time,
108
+ value: typeof obj.value === 'object' ? JSON.stringify(obj.value) : obj.value,
109
+ };
110
+ });
97
111
  this.log(formatTable(rows, columns));
98
112
  this.log('');
99
113
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/query/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/query/index.ts"],"names":[],"mappings":"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"}