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 +80 -0
- package/dist/cli.js +44 -0
- package/dist/client.d.ts +32 -1
- package/dist/client.js +72 -1
- package/package.json +1 -1
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
|
|
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
|
|
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
|
+
"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",
|