tciv-client 0.0.4 → 0.0.5

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
@@ -29,6 +29,7 @@ This library is intended for **system integrators and IT administrators** managi
29
29
  - [Provisioning](#full-device-provisioning)
30
30
  - [Video](#video)
31
31
  - [Factory Reset](#factory-reset)
32
+ - [Mode (SIP/Edge)](#mode-sipedge)
32
33
  - [Reboot](#device-reboot)
33
34
  - [API](#api)
34
35
  - [Connectivity](#connectivity)
@@ -240,6 +241,27 @@ tciv factory-reset -h 192.168.1.143 --keep-ip
240
241
  tciv factory-reset -h 192.168.1.143 --dhcp
241
242
  ```
242
243
 
244
+ ### Mode (SIP/Edge)
245
+
246
+ ```bash
247
+ # Read current mode
248
+ tciv mode -h 192.168.1.143
249
+ # 📡 Current mode: SIP (sip)
250
+
251
+ # Switch to SIP mode (reboots device, waits ~40s)
252
+ tciv mode set sip -h 192.168.1.143
253
+
254
+ # Switch to Edge mode
255
+ tciv mode set exc -h 192.168.1.143
256
+ ```
257
+
258
+ | Mode value | Description |
259
+ |------------|-------------|
260
+ | `sip` | SIP mode (required for Portia) |
261
+ | `dip` | ICX-AlphaCom |
262
+ | `exc` | Edge |
263
+ | `srv` | Edge Controller |
264
+
243
265
  ### CLI Options
244
266
 
245
267
  | Flag | Short | Description | Default |
@@ -434,6 +456,27 @@ await z.factoryReset('dhcp');
434
456
  | `dhcp` | All defaults, DHCP enabled |
435
457
  | `keep-ip` | All defaults, current IP preserved |
436
458
 
459
+ #### Mode
460
+
461
+ ```typescript
462
+ // Read current mode
463
+ const mode = await z.getMode();
464
+ // 'sip' | 'dip' | 'pulse' (Edge) | 'srv'
465
+
466
+ // Switch to SIP mode
467
+ await z.setMode('sip');
468
+ await z.applyChanges(); // triggers reboot
469
+ await z.waitForReboot(); // polls until online (~40s)
470
+ ```
471
+
472
+ #### Wait for Reboot
473
+
474
+ ```typescript
475
+ // Poll until device comes back online (default 60s timeout)
476
+ const online = await z.waitForReboot(60000, 3000);
477
+ // true = device is back, false = timeout
478
+ ```
479
+
437
480
  ---
438
481
 
439
482
  ### `scanNetwork()`
package/dist/cli.js CHANGED
@@ -229,6 +229,41 @@ async function main() {
229
229
  console.log(`⚠️ Factory reset (${labels[mode]}) — all settings will be lost!`);
230
230
  await client.factoryReset(mode);
231
231
  console.log('✅ Factory reset sent. Device will reboot with default settings.');
232
+ if (!hasFlag('no-wait')) {
233
+ console.log('⏳ Waiting for device to come back online...');
234
+ const ok = await client.waitForReboot(90000);
235
+ console.log(ok ? '✅ Device is back online!' : '⚠️ Timeout — device may still be rebooting.');
236
+ }
237
+ break;
238
+ }
239
+ case 'mode': {
240
+ const client = getClient();
241
+ const subCmd = args[1]; // get | set
242
+ if (subCmd === 'set') {
243
+ const target = args[2];
244
+ if (!target || !['sip', 'dip', 'exc', 'srv'].includes(target)) {
245
+ console.error('Usage: tciv mode set <sip|dip|exc|srv>');
246
+ console.log(' sip = SIP mode');
247
+ console.log(' dip = ICX-AlphaCom');
248
+ console.log(' exc = Edge');
249
+ console.log(' srv = Edge Controller');
250
+ process.exit(1);
251
+ }
252
+ console.log(`🔄 Setting mode to ${target}...`);
253
+ await client.setMode(target);
254
+ console.log('📤 Applying changes (device will reboot)...');
255
+ await client.applyChanges();
256
+ if (!hasFlag('no-wait')) {
257
+ console.log('⏳ Waiting for device to come back online...');
258
+ const ok = await client.waitForReboot(90000);
259
+ console.log(ok ? '✅ Device is back online!' : '⚠️ Timeout — device may still be rebooting.');
260
+ }
261
+ }
262
+ else {
263
+ const mode = await client.getMode();
264
+ const labels = { sip: 'SIP', dip: 'ICX-AlphaCom', exc: 'Edge', srv: 'Edge Controller', pulse: 'Edge' };
265
+ console.log(`📡 Current mode: ${labels[mode] || mode} (${mode})`);
266
+ }
232
267
  break;
233
268
  }
234
269
  case 'video': {
package/dist/client.d.ts CHANGED
@@ -137,6 +137,28 @@ export declare class TcivClient {
137
137
  * - 'keep-ip' → Factory defaults but keep current IP settings
138
138
  */
139
139
  factoryReset(mode?: 'full' | 'dhcp' | 'keep-ip'): Promise<void>;
140
+ /**
141
+ * Get the current device mode.
142
+ * Returns 'sip', 'dip' (ICX-AlphaCom), 'exc' (Edge), or 'srv' (Edge Controller).
143
+ */
144
+ getMode(): Promise<string>;
145
+ /**
146
+ * Set device mode. Requires applyChanges() + reboot afterwards.
147
+ * @param mode - 'sip' | 'dip' (ICX-AlphaCom) | 'exc' (Edge) | 'srv' (Edge Controller)
148
+ */
149
+ setMode(mode: 'sip' | 'dip' | 'exc' | 'srv'): Promise<void>;
150
+ /**
151
+ * Send APPLY command to trigger reboot after config changes.
152
+ * The device responds with "System is rebooting..." and goes offline.
153
+ */
154
+ applyChanges(): Promise<void>;
155
+ /**
156
+ * Poll the device until it comes back online after a reboot.
157
+ * @param timeoutMs - Max wait time (default 60s)
158
+ * @param intervalMs - Poll interval (default 3s)
159
+ * @returns true if device came back, false if timeout
160
+ */
161
+ waitForReboot(timeoutMs?: number, intervalMs?: number): Promise<boolean>;
140
162
  private _fetch;
141
163
  private _html;
142
164
  private _post;
package/dist/client.js CHANGED
@@ -673,6 +673,55 @@ export class TcivClient {
673
673
  // Device disconnects during reset — expected
674
674
  }
675
675
  }
676
+ // ── Mode (SIP / Edge / ICX-AlphaCom) ───────────────────────────────────
677
+ /**
678
+ * Get the current device mode.
679
+ * Returns 'sip', 'dip' (ICX-AlphaCom), 'exc' (Edge), or 'srv' (Edge Controller).
680
+ */
681
+ async getMode() {
682
+ const info = await this.getDeviceInfo();
683
+ return info.mode || 'sip';
684
+ }
685
+ /**
686
+ * Set device mode. Requires applyChanges() + reboot afterwards.
687
+ * @param mode - 'sip' | 'dip' (ICX-AlphaCom) | 'exc' (Edge) | 'srv' (Edge Controller)
688
+ */
689
+ async setMode(mode) {
690
+ await this._post('/goform/zForm_save_changes', {
691
+ sigmode: mode,
692
+ signallingMode: 'SAVE',
693
+ });
694
+ }
695
+ /**
696
+ * Send APPLY command to trigger reboot after config changes.
697
+ * The device responds with "System is rebooting..." and goes offline.
698
+ */
699
+ async applyChanges() {
700
+ try {
701
+ await this._fetch('/goform/zForm_send_cmd?message=APPLY', 'GET', 5000);
702
+ }
703
+ catch {
704
+ // Device disconnects during reboot — expected
705
+ }
706
+ }
707
+ // ── Wait for reboot ────────────────────────────────────────────────────
708
+ /**
709
+ * Poll the device until it comes back online after a reboot.
710
+ * @param timeoutMs - Max wait time (default 60s)
711
+ * @param intervalMs - Poll interval (default 3s)
712
+ * @returns true if device came back, false if timeout
713
+ */
714
+ async waitForReboot(timeoutMs = 60000, intervalMs = 3000) {
715
+ const start = Date.now();
716
+ // Wait a bit for device to actually go offline first
717
+ await new Promise(r => setTimeout(r, 5000));
718
+ while (Date.now() - start < timeoutMs) {
719
+ if (await this.isReachable())
720
+ return true;
721
+ await new Promise(r => setTimeout(r, intervalMs));
722
+ }
723
+ return false;
724
+ }
676
725
  // ── Internal helpers ────────────────────────────────────────────────────
677
726
  async _fetch(path, method = 'GET', timeout, body, contentType) {
678
727
  const controller = new AbortController();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tciv-client",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "HTTP client for TCIV-series intercom systems (TCIV-2+, TCIV-3). Control relays, SIP configuration, DAK provisioning, webcall, audio settings, and camera feeds.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",