tciv-client 0.0.3 → 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
@@ -28,6 +28,8 @@ This library is intended for **system integrators and IT administrators** managi
28
28
  - [Call Button (DAK)](#call-button-dak-configuration)
29
29
  - [Provisioning](#full-device-provisioning)
30
30
  - [Video](#video)
31
+ - [Factory Reset](#factory-reset)
32
+ - [Mode (SIP/Edge)](#mode-sipedge)
31
33
  - [Reboot](#device-reboot)
32
34
  - [API](#api)
33
35
  - [Connectivity](#connectivity)
@@ -42,6 +44,7 @@ This library is intended for **system integrators and IT administrators** managi
42
44
  - [Provisioning](#full-device-provisioning-1)
43
45
  - [Audio Settings](#audio-settings)
44
46
  - [Reboot](#reboot)
47
+ - [Factory Reset](#factory-reset-1)
45
48
  - [Device Discovery](#scannetwork)
46
49
  - [Supported Hardware](#supported-hardware)
47
50
  - [HTTP API Reference](#http-api-reference)
@@ -225,6 +228,40 @@ tciv provision -h 192.168.1.143 \
225
228
  tciv reboot -h 192.168.1.143
226
229
  ```
227
230
 
231
+ ### Factory Reset
232
+
233
+ ```bash
234
+ # Full reset (IP → 169.254.1.100)
235
+ tciv factory-reset -h 192.168.1.143
236
+
237
+ # Reset but keep current IP settings (recommended)
238
+ tciv factory-reset -h 192.168.1.143 --keep-ip
239
+
240
+ # Reset with DHCP enabled
241
+ tciv factory-reset -h 192.168.1.143 --dhcp
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
+
228
265
  ### CLI Options
229
266
 
230
267
  | Flag | Short | Description | Default |
@@ -244,6 +281,8 @@ tciv reboot -h 192.168.1.143
244
281
  | `--no-reboot` | | Skip reboot after DAK set | |
245
282
  | `--sip-user` | | SIP auth username (provision) | |
246
283
  | `--sip-pass` | | SIP auth password (provision) | |
284
+ | `--keep-ip` | | Factory reset: keep IP settings | |
285
+ | `--dhcp` | | Factory reset: enable DHCP | |
247
286
 
248
287
  ---
249
288
 
@@ -398,6 +437,46 @@ fs.writeFileSync('audio-backup.json', JSON.stringify(raw, null, 2));
398
437
  await z.reboot(); // ~30 seconds offline
399
438
  ```
400
439
 
440
+ #### Factory Reset
441
+
442
+ ```typescript
443
+ // Full reset (static IP 169.254.1.100)
444
+ await z.factoryReset('full');
445
+
446
+ // Reset but keep current IP (recommended)
447
+ await z.factoryReset('keep-ip');
448
+
449
+ // Reset with DHCP
450
+ await z.factoryReset('dhcp');
451
+ ```
452
+
453
+ | Mode | Behavior |
454
+ |------|----------|
455
+ | `full` | All defaults, IP → 169.254.1.100 |
456
+ | `dhcp` | All defaults, DHCP enabled |
457
+ | `keep-ip` | All defaults, current IP preserved |
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
+
401
480
  ---
402
481
 
403
482
  ### `scanNetwork()`
@@ -440,6 +519,7 @@ All endpoints require valid administrator credentials via HTTP Basic Auth.
440
519
  | `/goform/zForm_config_backup` | POST | Config restore (upload) |
441
520
  | `/ipst_config.tar.gz` | GET | Config backup download |
442
521
  | `/goform/zForm_system_prefs` | POST | Reboot device |
522
+ | `/goform/zForm_send_cmd` | POST | Factory reset (full/DHCP/keep-ip) |
443
523
  | `/mjpg/video.mjpg` | GET | Live MJPG stream |
444
524
 
445
525
  ## License
package/dist/cli.js CHANGED
@@ -222,6 +222,50 @@ async function main() {
222
222
  console.log('✅ Reboot command sent. Device will be offline for ~30 seconds.');
223
223
  break;
224
224
  }
225
+ case 'factory-reset': {
226
+ const client = getClient();
227
+ const mode = hasFlag('keep-ip') ? 'keep-ip' : hasFlag('dhcp') ? 'dhcp' : 'full';
228
+ const labels = { 'full': 'full (IP → 169.254.1.100)', 'dhcp': 'full + DHCP', 'keep-ip': 'keep IP settings' };
229
+ console.log(`⚠️ Factory reset (${labels[mode]}) — all settings will be lost!`);
230
+ await client.factoryReset(mode);
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
+ }
267
+ break;
268
+ }
225
269
  case 'video': {
226
270
  const client = getClient();
227
271
  console.log(`📷 Video URLs for ${flag('host', 'h')}:\n`);
package/dist/client.d.ts CHANGED
@@ -126,8 +126,39 @@ export declare class TcivClient {
126
126
  private _replaceFileInTar;
127
127
  /** Recalculate tar header checksum (sum of all header bytes with checksum field as spaces) */
128
128
  private _updateTarChecksum;
129
- /** Reboot the Zenitel (required after config changes) */
129
+ /** Reboot the device (required after config changes) */
130
130
  reboot(): Promise<void>;
131
+ /**
132
+ * Factory reset — restores all settings to defaults. Device will reboot.
133
+ *
134
+ * @param mode - Reset mode:
135
+ * - 'full' → Static IP 169.254.1.100 (default)
136
+ * - 'dhcp' → Factory defaults + DHCP enabled
137
+ * - 'keep-ip' → Factory defaults but keep current IP settings
138
+ */
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>;
131
162
  private _fetch;
132
163
  private _html;
133
164
  private _post;
package/dist/client.js CHANGED
@@ -642,7 +642,7 @@ export class TcivClient {
642
642
  Buffer.from(checksumStr).copy(header, 148);
643
643
  }
644
644
  // ── Reboot ─────────────────────────────────────────────────────────────
645
- /** Reboot the Zenitel (required after config changes) */
645
+ /** Reboot the device (required after config changes) */
646
646
  async reboot() {
647
647
  try {
648
648
  await this._post('/goform/zForm_system_prefs', { reboot: 'Reboot' });
@@ -651,6 +651,77 @@ export class TcivClient {
651
651
  // May disconnect before response — that's expected
652
652
  }
653
653
  }
654
+ /**
655
+ * Factory reset — restores all settings to defaults. Device will reboot.
656
+ *
657
+ * @param mode - Reset mode:
658
+ * - 'full' → Static IP 169.254.1.100 (default)
659
+ * - 'dhcp' → Factory defaults + DHCP enabled
660
+ * - 'keep-ip' → Factory defaults but keep current IP settings
661
+ */
662
+ async factoryReset(mode = 'full') {
663
+ const params = {
664
+ 'full': 'factory_reset',
665
+ 'dhcp': 'factory_reset_dhcp',
666
+ 'keep-ip': 'factory_reset_keep_ip_settings',
667
+ };
668
+ const name = params[mode];
669
+ try {
670
+ await this._post('/goform/zForm_send_cmd', { [name]: '1' });
671
+ }
672
+ catch {
673
+ // Device disconnects during reset — expected
674
+ }
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
+ }
654
725
  // ── Internal helpers ────────────────────────────────────────────────────
655
726
  async _fetch(path, method = 'GET', timeout, body, contentType) {
656
727
  const controller = new AbortController();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tciv-client",
3
- "version": "0.0.3",
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",