icom-wlan-node 0.6.1 → 0.6.2
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 +32 -0
- package/dist/rig/IcomCivSpec.d.ts +83 -0
- package/dist/rig/IcomCivSpec.js +83 -0
- package/dist/rig/IcomControl.d.ts +147 -1
- package/dist/rig/IcomControl.js +661 -0
- package/dist/rig/IcomProfiles.d.ts +17 -2
- package/dist/rig/IcomProfiles.js +220 -0
- package/dist/rig/IcomRigCommands.d.ts +20 -0
- package/dist/rig/IcomRigCommands.js +60 -0
- package/dist/types.d.ts +9 -0
- package/package.json +1 -1
package/dist/rig/IcomControl.js
CHANGED
|
@@ -70,6 +70,78 @@ function modeNameToCode(mode) {
|
|
|
70
70
|
case 'scroll-fixed': return 3;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
+
const FUNCTION_SPECS = {
|
|
74
|
+
NB: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_NB },
|
|
75
|
+
NR: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_NR },
|
|
76
|
+
COMP: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_COMP },
|
|
77
|
+
VOX: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_VOX },
|
|
78
|
+
TONE: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_TONE },
|
|
79
|
+
TSQL: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_TSQL },
|
|
80
|
+
SBKIN: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_BKIN },
|
|
81
|
+
FBKIN: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_BKIN },
|
|
82
|
+
MON: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_MON },
|
|
83
|
+
ANF: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_ANF },
|
|
84
|
+
MN: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_MN },
|
|
85
|
+
LOCK: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_DIAL_LK },
|
|
86
|
+
RIT: { command: IcomCivSpec_1.CIV.C_CTL_RIT, subcmd: IcomCivSpec_1.CIV.S_RIT },
|
|
87
|
+
XIT: { command: IcomCivSpec_1.CIV.C_CTL_RIT, subcmd: IcomCivSpec_1.CIV.S_XIT },
|
|
88
|
+
TUNER: { command: IcomCivSpec_1.CIV.C_CTL_PTT, subcmd: IcomCivSpec_1.CIV.S_ANT_TUN },
|
|
89
|
+
APF: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_APF },
|
|
90
|
+
AFC: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_AFC },
|
|
91
|
+
VSC: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_VSC },
|
|
92
|
+
DUAL_WATCH: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_MEM_DUALMODE },
|
|
93
|
+
SATMODE: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_MEM_SATMODE },
|
|
94
|
+
SCOPE: { command: IcomCivSpec_1.CIV.C_CTL_SCP, subcmd: IcomCivSpec_1.CIV.S_SCP_STS },
|
|
95
|
+
SPECTRUM: { command: IcomCivSpec_1.CIV.C_CTL_SCP, subcmd: IcomCivSpec_1.CIV.S_SCP_DOP },
|
|
96
|
+
SPECTRUM_HOLD: { command: IcomCivSpec_1.CIV.C_CTL_SCP, subcmd: IcomCivSpec_1.CIV.S_SCP_HLD, payloadPrefix: [0], readPrefix: [0] },
|
|
97
|
+
OVF_STATUS: { command: IcomCivSpec_1.CIV.C_RD_SQSM, subcmd: IcomCivSpec_1.CIV.S_OVF },
|
|
98
|
+
DIGI_SEL: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_DIGISEL },
|
|
99
|
+
IPP: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_IPP },
|
|
100
|
+
TX_INHIBIT: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_TX_INHIBIT },
|
|
101
|
+
DPP: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_DPP },
|
|
102
|
+
};
|
|
103
|
+
function keySpeedWpmToRaw(wpm) {
|
|
104
|
+
const target = Math.max(6, Math.min(48, Math.round(wpm)));
|
|
105
|
+
return CW_LOOKUP.find(([, speed]) => speed === target)?.[0] ?? CW_LOOKUP[0][0];
|
|
106
|
+
}
|
|
107
|
+
function keySpeedRawToWpm(raw) {
|
|
108
|
+
return CW_LOOKUP.find(([rigValue]) => rigValue >= raw)?.[1] ?? 48;
|
|
109
|
+
}
|
|
110
|
+
const LEVEL_SPECS = {
|
|
111
|
+
AF: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_AF, dataBytes: 2, dataType: 'level' },
|
|
112
|
+
RF: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_RF, dataBytes: 2, dataType: 'level' },
|
|
113
|
+
SQL: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_SQL, dataBytes: 2, dataType: 'level' },
|
|
114
|
+
IF: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_IF, dataBytes: 2, dataType: 'level' },
|
|
115
|
+
APF: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_APF, dataBytes: 2, dataType: 'level' },
|
|
116
|
+
NR: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_NR, dataBytes: 2, dataType: 'level' },
|
|
117
|
+
NB: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_NB, dataBytes: 2, dataType: 'level' },
|
|
118
|
+
PBT_IN: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_PBTIN, dataBytes: 2, dataType: 'level' },
|
|
119
|
+
PBT_OUT: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_PBTOUT, dataBytes: 2, dataType: 'level' },
|
|
120
|
+
CWPITCH: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_CWPITCH, dataBytes: 2, dataType: 'int', publicToRaw: (hz) => Math.round((Math.max(300, Math.min(900, hz)) - 300) * 255 / 600), rawToPublic: (raw) => Math.round(300 + raw * 600 / 255) },
|
|
121
|
+
RFPOWER: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_RFPOWER, dataBytes: 2, dataType: 'level' },
|
|
122
|
+
MICGAIN: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_MICGAIN, dataBytes: 2, dataType: 'level' },
|
|
123
|
+
KEYSPD: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_KEYSPD, dataBytes: 2, dataType: 'int', publicToRaw: keySpeedWpmToRaw, rawToPublic: keySpeedRawToWpm },
|
|
124
|
+
NOTCHF_RAW: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_NOTCHF, dataBytes: 2, dataType: 'level' },
|
|
125
|
+
COMP: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_COMP, dataBytes: 2, dataType: 'level' },
|
|
126
|
+
BKINDL: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_BKINDL, dataBytes: 2, dataType: 'level' },
|
|
127
|
+
BALANCE: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_BALANCE, dataBytes: 2, dataType: 'level' },
|
|
128
|
+
VOXGAIN: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_VOXGAIN, dataBytes: 2, dataType: 'level' },
|
|
129
|
+
ANTIVOX: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_ANTIVOX, dataBytes: 2, dataType: 'level' },
|
|
130
|
+
MONITOR_GAIN: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_MON, dataBytes: 2, dataType: 'level' },
|
|
131
|
+
DRIVE_GAIN: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_DRIVE, dataBytes: 2, dataType: 'level' },
|
|
132
|
+
DIGI_SEL_LEVEL: { command: IcomCivSpec_1.CIV.C_CTL_LVL, subcmd: IcomCivSpec_1.CIV.S_LVL_DIGI, dataBytes: 2, dataType: 'level' },
|
|
133
|
+
AGC: { command: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd: IcomCivSpec_1.CIV.S_FUNC_AGC, dataBytes: 1, dataType: 'int' },
|
|
134
|
+
AGC_TIME: { command: IcomCivSpec_1.CIV.C_CTL_MEM, subcmd: 0x04, dataBytes: 1, dataType: 'int' },
|
|
135
|
+
};
|
|
136
|
+
const CW_LOOKUP = [
|
|
137
|
+
[0, 6], [7, 7], [12, 8], [19, 9], [25, 10], [31, 11], [37, 12], [43, 13],
|
|
138
|
+
[49, 14], [55, 15], [61, 16], [67, 17], [73, 18], [79, 19], [84, 20],
|
|
139
|
+
[91, 21], [97, 22], [103, 23], [108, 24], [114, 25], [121, 26], [128, 27],
|
|
140
|
+
[134, 28], [140, 29], [144, 30], [151, 31], [156, 32], [164, 33],
|
|
141
|
+
[169, 34], [175, 35], [182, 36], [188, 37], [192, 38], [199, 39],
|
|
142
|
+
[203, 40], [211, 41], [215, 42], [224, 43], [229, 44], [234, 45],
|
|
143
|
+
[239, 46], [244, 47], [250, 48],
|
|
144
|
+
];
|
|
73
145
|
class IcomControl {
|
|
74
146
|
constructor(options) {
|
|
75
147
|
this.ev = new events_1.EventEmitter();
|
|
@@ -1393,6 +1465,595 @@ class IcomControl {
|
|
|
1393
1465
|
amps: (0, IcomProfiles_1.interpolateCalibration)(raw, this.activeProfile.calibrations.current)
|
|
1394
1466
|
};
|
|
1395
1467
|
}
|
|
1468
|
+
async getFunction(name, options) {
|
|
1469
|
+
if (!this.activeProfile.functions.includes(name))
|
|
1470
|
+
return null;
|
|
1471
|
+
const ext = this.activeProfile.extParamSpecs[name];
|
|
1472
|
+
if (ext) {
|
|
1473
|
+
const value = await this.readExtParamValue(ext, `func-ext:${name}`, options);
|
|
1474
|
+
return value === null ? null : value !== 0;
|
|
1475
|
+
}
|
|
1476
|
+
const spec = FUNCTION_SPECS[name];
|
|
1477
|
+
if (!spec)
|
|
1478
|
+
return null;
|
|
1479
|
+
const raw = await this.readFunctionRaw(name, spec, options);
|
|
1480
|
+
if (raw === null)
|
|
1481
|
+
return null;
|
|
1482
|
+
if (name === 'SBKIN')
|
|
1483
|
+
return raw === 1;
|
|
1484
|
+
if (name === 'FBKIN')
|
|
1485
|
+
return raw === 2;
|
|
1486
|
+
return raw !== 0;
|
|
1487
|
+
}
|
|
1488
|
+
setFunction(name, enabled) {
|
|
1489
|
+
if (!this.activeProfile.functions.includes(name)) {
|
|
1490
|
+
throw this.unsupported(name, 'setFunction', 'Function is not enabled for active profile');
|
|
1491
|
+
}
|
|
1492
|
+
const ext = this.activeProfile.extParamSpecs[name];
|
|
1493
|
+
if (ext) {
|
|
1494
|
+
this.writeExtParamValue(ext, enabled ? 1 : 0);
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
const spec = FUNCTION_SPECS[name];
|
|
1498
|
+
if (!spec || name === 'OVF_STATUS') {
|
|
1499
|
+
throw this.unsupported(name, 'setFunction', 'Function is read-only or has no CI-V writer');
|
|
1500
|
+
}
|
|
1501
|
+
let value = enabled ? 1 : 0;
|
|
1502
|
+
if (name === 'SBKIN')
|
|
1503
|
+
value = enabled ? 1 : 0;
|
|
1504
|
+
if (name === 'FBKIN')
|
|
1505
|
+
value = enabled ? 2 : 0;
|
|
1506
|
+
this.writeFunctionRaw(spec, value);
|
|
1507
|
+
}
|
|
1508
|
+
async getLevel(name, options) {
|
|
1509
|
+
if (!this.activeProfile.levels.includes(name))
|
|
1510
|
+
return null;
|
|
1511
|
+
const ext = this.activeProfile.extParamSpecs[name];
|
|
1512
|
+
if (ext) {
|
|
1513
|
+
return this.readExtParamValue(ext, `level-ext:${name}`, options);
|
|
1514
|
+
}
|
|
1515
|
+
const spec = LEVEL_SPECS[name];
|
|
1516
|
+
if (!spec)
|
|
1517
|
+
return null;
|
|
1518
|
+
const raw = await this.readLevelRaw(name, spec, options);
|
|
1519
|
+
if (raw === null)
|
|
1520
|
+
return null;
|
|
1521
|
+
return spec.rawToPublic ? spec.rawToPublic(raw) : spec.dataType === 'level' ? raw / 255 : raw;
|
|
1522
|
+
}
|
|
1523
|
+
setLevel(name, value) {
|
|
1524
|
+
if (!this.activeProfile.levels.includes(name)) {
|
|
1525
|
+
throw this.unsupported(name, 'setLevel', 'Level is not enabled for active profile');
|
|
1526
|
+
}
|
|
1527
|
+
const ext = this.activeProfile.extParamSpecs[name];
|
|
1528
|
+
if (ext) {
|
|
1529
|
+
this.writeExtParamValue(ext, value);
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
const spec = LEVEL_SPECS[name];
|
|
1533
|
+
if (!spec) {
|
|
1534
|
+
throw this.unsupported(name, 'setLevel', 'No level command mapping');
|
|
1535
|
+
}
|
|
1536
|
+
const raw = spec.publicToRaw
|
|
1537
|
+
? spec.publicToRaw(value)
|
|
1538
|
+
: spec.dataType === 'level'
|
|
1539
|
+
? Math.round(Math.max(0, Math.min(1, value)) * 255)
|
|
1540
|
+
: Math.round(value);
|
|
1541
|
+
this.writeLevelRaw(spec, raw);
|
|
1542
|
+
}
|
|
1543
|
+
async getParameter(name, options) {
|
|
1544
|
+
if (!this.activeProfile.parameters.includes(name))
|
|
1545
|
+
return null;
|
|
1546
|
+
const ext = this.activeProfile.extParamSpecs[name];
|
|
1547
|
+
if (!ext)
|
|
1548
|
+
return null;
|
|
1549
|
+
const value = await this.readExtParamValue(ext, `parm:${name}`, options);
|
|
1550
|
+
if (value === null)
|
|
1551
|
+
return null;
|
|
1552
|
+
return ext.dataType === 'bool' ? value !== 0 : value;
|
|
1553
|
+
}
|
|
1554
|
+
setParameter(name, value) {
|
|
1555
|
+
if (!this.activeProfile.parameters.includes(name)) {
|
|
1556
|
+
throw this.unsupported(name, 'setParameter', 'Parameter is not enabled for active profile');
|
|
1557
|
+
}
|
|
1558
|
+
const ext = this.activeProfile.extParamSpecs[name];
|
|
1559
|
+
if (!ext) {
|
|
1560
|
+
throw this.unsupported(name, 'setParameter', 'No parameter command mapping');
|
|
1561
|
+
}
|
|
1562
|
+
this.writeExtParamValue(ext, typeof value === 'boolean' ? (value ? 1 : 0) : value);
|
|
1563
|
+
}
|
|
1564
|
+
async getNoiseBlankerEnabled(options) { return this.getFunction('NB', options); }
|
|
1565
|
+
setNoiseBlankerEnabled(enabled) { this.setFunction('NB', enabled); }
|
|
1566
|
+
async getNoiseReductionEnabled(options) { return this.getFunction('NR', options); }
|
|
1567
|
+
setNoiseReductionEnabled(enabled) { this.setFunction('NR', enabled); }
|
|
1568
|
+
async getCompressorEnabled(options) { return this.getFunction('COMP', options); }
|
|
1569
|
+
setCompressorEnabled(enabled) { this.setFunction('COMP', enabled); }
|
|
1570
|
+
async getVoxEnabled(options) { return this.getFunction('VOX', options); }
|
|
1571
|
+
setVoxEnabled(enabled) { this.setFunction('VOX', enabled); }
|
|
1572
|
+
async getMonitorEnabled(options) { return this.getFunction('MON', options); }
|
|
1573
|
+
setMonitorEnabled(enabled) { this.setFunction('MON', enabled); }
|
|
1574
|
+
async getAutoNotchEnabled(options) { return this.getFunction('ANF', options); }
|
|
1575
|
+
setAutoNotchEnabled(enabled) { this.setFunction('ANF', enabled); }
|
|
1576
|
+
async getManualNotchEnabled(options) { return this.getFunction('MN', options); }
|
|
1577
|
+
setManualNotchEnabled(enabled) { this.setFunction('MN', enabled); }
|
|
1578
|
+
async getDialLockEnabled(options) { return this.getFunction('LOCK', options); }
|
|
1579
|
+
setDialLockEnabled(enabled) { this.setFunction('LOCK', enabled); }
|
|
1580
|
+
async getBreakInMode(options) {
|
|
1581
|
+
const spec = FUNCTION_SPECS.SBKIN;
|
|
1582
|
+
if (!spec || !this.activeProfile.functions.includes('SBKIN'))
|
|
1583
|
+
return null;
|
|
1584
|
+
const raw = await this.readFunctionRaw('SBKIN', spec, options);
|
|
1585
|
+
if (raw === null)
|
|
1586
|
+
return null;
|
|
1587
|
+
return raw === 1 ? 'semi' : raw === 2 ? 'full' : 'off';
|
|
1588
|
+
}
|
|
1589
|
+
setBreakInMode(mode) {
|
|
1590
|
+
const spec = FUNCTION_SPECS.SBKIN;
|
|
1591
|
+
if (!spec || !this.activeProfile.functions.includes('SBKIN')) {
|
|
1592
|
+
throw this.unsupported('SBKIN', 'setBreakInMode', 'Break-in function is not enabled for active profile');
|
|
1593
|
+
}
|
|
1594
|
+
this.writeFunctionRaw(spec, mode === 'semi' ? 1 : mode === 'full' ? 2 : 0);
|
|
1595
|
+
}
|
|
1596
|
+
async getRFGain(options) { return this.getLevel('RF', options); }
|
|
1597
|
+
setRFGain(value) { this.setLevel('RF', value); }
|
|
1598
|
+
async getIFShift(options) { return this.getLevel('IF', options); }
|
|
1599
|
+
setIFShift(value) { this.setLevel('IF', value); }
|
|
1600
|
+
async getPbtIn(options) { return this.getLevel('PBT_IN', options); }
|
|
1601
|
+
setPbtIn(value) { this.setLevel('PBT_IN', value); }
|
|
1602
|
+
async getPbtOut(options) { return this.getLevel('PBT_OUT', options); }
|
|
1603
|
+
setPbtOut(value) { this.setLevel('PBT_OUT', value); }
|
|
1604
|
+
async getCwPitch(options) { return this.getLevel('CWPITCH', options); }
|
|
1605
|
+
setCwPitch(hz) { this.setLevel('CWPITCH', hz); }
|
|
1606
|
+
async getKeySpeed(options) { return this.getLevel('KEYSPD', options); }
|
|
1607
|
+
setKeySpeed(wpm) { this.setLevel('KEYSPD', wpm); }
|
|
1608
|
+
async getNotchRaw(options) { return this.getLevel('NOTCHF_RAW', options); }
|
|
1609
|
+
setNotchRaw(value) { this.setLevel('NOTCHF_RAW', value); }
|
|
1610
|
+
async getCompressionLevel(options) { return this.getLevel('COMP', options); }
|
|
1611
|
+
setCompressionLevel(value) { this.setLevel('COMP', value); }
|
|
1612
|
+
async getMonitorGain(options) { return this.getLevel('MONITOR_GAIN', options); }
|
|
1613
|
+
setMonitorGain(value) { this.setLevel('MONITOR_GAIN', value); }
|
|
1614
|
+
async getVoxGain(options) { return this.getLevel('VOXGAIN', options); }
|
|
1615
|
+
setVoxGain(value) { this.setLevel('VOXGAIN', value); }
|
|
1616
|
+
async getAntiVox(options) { return this.getLevel('ANTIVOX', options); }
|
|
1617
|
+
setAntiVox(value) { this.setLevel('ANTIVOX', value); }
|
|
1618
|
+
async getRitOffset(options) { return this.readRitOffset(options); }
|
|
1619
|
+
setRitOffset(offsetHz) { this.writeRitOffset(offsetHz); }
|
|
1620
|
+
async getXitOffset(options) { return this.readRitOffset(options); }
|
|
1621
|
+
setXitOffset(offsetHz) { this.writeRitOffset(offsetHz); }
|
|
1622
|
+
async getRitEnabled(options) { return this.getFunction('RIT', options); }
|
|
1623
|
+
setRitEnabled(enabled) { this.setFunction('RIT', enabled); }
|
|
1624
|
+
async getXitEnabled(options) { return this.getFunction('XIT', options); }
|
|
1625
|
+
setXitEnabled(enabled) { this.setFunction('XIT', enabled); }
|
|
1626
|
+
async getVfo(options) {
|
|
1627
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1628
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1629
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1630
|
+
const req = IcomRigCommands_1.IcomRigCommands.readCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_SET_VFO, IcomCivSpec_1.CIV.S_BAND_SEL);
|
|
1631
|
+
const resp = await this.waitForCivFrame('vfo:0x07:0xd2', (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_SET_VFO, [IcomCivSpec_1.CIV.S_BAND_SEL], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1632
|
+
if (!resp || resp.length < 8)
|
|
1633
|
+
return null;
|
|
1634
|
+
return resp[6] === 0 ? 'MAIN' : 'SUB';
|
|
1635
|
+
}
|
|
1636
|
+
setVfo(vfo) {
|
|
1637
|
+
const subcmd = this.vfoToSubcmd(vfo);
|
|
1638
|
+
if (subcmd === null) {
|
|
1639
|
+
throw this.unsupported(vfo, 'setVfo', 'VFO cannot be directly selected');
|
|
1640
|
+
}
|
|
1641
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1642
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1643
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_SET_VFO, subcmd));
|
|
1644
|
+
}
|
|
1645
|
+
vfoOperation(op) {
|
|
1646
|
+
if (!this.activeProfile.vfoOps.includes(op)) {
|
|
1647
|
+
throw this.unsupported(op, 'vfoOperation', 'VFO operation is not enabled for active profile');
|
|
1648
|
+
}
|
|
1649
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1650
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1651
|
+
switch (op) {
|
|
1652
|
+
case 'copy':
|
|
1653
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_SET_VFO, IcomCivSpec_1.CIV.S_BTOA));
|
|
1654
|
+
return;
|
|
1655
|
+
case 'exchange':
|
|
1656
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_SET_VFO, IcomCivSpec_1.CIV.S_XCHNG));
|
|
1657
|
+
return;
|
|
1658
|
+
case 'from-vfo':
|
|
1659
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_WR_MEM, undefined));
|
|
1660
|
+
return;
|
|
1661
|
+
case 'to-vfo':
|
|
1662
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_MEM2VFO, undefined));
|
|
1663
|
+
return;
|
|
1664
|
+
case 'memory-clear':
|
|
1665
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_CLR_MEM, undefined));
|
|
1666
|
+
return;
|
|
1667
|
+
case 'tune':
|
|
1668
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.startManualTune(ctrAddr, rigAddr));
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
async getSplitEnabled(options) {
|
|
1673
|
+
const raw = await this.readSplitRaw(options);
|
|
1674
|
+
if (raw === null)
|
|
1675
|
+
return null;
|
|
1676
|
+
return raw === IcomCivSpec_1.CIV.S_SPLT_ON;
|
|
1677
|
+
}
|
|
1678
|
+
setSplitEnabled(enabled) {
|
|
1679
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1680
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1681
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.setSplit(ctrAddr, rigAddr, enabled));
|
|
1682
|
+
}
|
|
1683
|
+
async getSplitFrequency(options) {
|
|
1684
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1685
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1686
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1687
|
+
const req = IcomRigCommands_1.IcomRigCommands.readSelectedFrequency(ctrAddr, rigAddr, 1);
|
|
1688
|
+
const resp = await this.waitForCivFrame('freq:0x25:1', (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_SEND_SEL_FREQ, [0x01], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1689
|
+
return resp ? IcomControl.parseFrequencyReply(resp, 1) : null;
|
|
1690
|
+
}
|
|
1691
|
+
setSplitFrequency(hz) {
|
|
1692
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1693
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1694
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.setSelectedFrequency(ctrAddr, rigAddr, hz, this.activeProfile.frequencyBcdBytes(hz), 1));
|
|
1695
|
+
}
|
|
1696
|
+
async getSplitMode(options) {
|
|
1697
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1698
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1699
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1700
|
+
const req = IcomRigCommands_1.IcomRigCommands.readSelectedMode(ctrAddr, rigAddr, 1);
|
|
1701
|
+
const resp = await this.waitForCivFrame('mode:0x26:1', (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_SEND_SEL_MODE, [0x01], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1702
|
+
if (!resp || resp.length < 10)
|
|
1703
|
+
return null;
|
|
1704
|
+
const { getModeString, getFilterString } = await Promise.resolve().then(() => __importStar(require('./IcomConstants')));
|
|
1705
|
+
const mode = resp[6];
|
|
1706
|
+
const dataMode = resp[7] !== 0x00;
|
|
1707
|
+
const filter = resp[8];
|
|
1708
|
+
return { mode, filter, dataMode, modeName: getModeString(mode), filterName: getFilterString(filter) };
|
|
1709
|
+
}
|
|
1710
|
+
setSplitMode(mode, options) {
|
|
1711
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1712
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1713
|
+
const modeCode = typeof mode === 'string' ? (0, IcomConstants_1.getModeCode)(mode) : mode;
|
|
1714
|
+
const filter = options?.filter ?? this.lastFilter ?? this.activeProfile.defaultFilter;
|
|
1715
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.setSelectedMode(ctrAddr, rigAddr, modeCode, !!options?.dataMode, filter, 1));
|
|
1716
|
+
}
|
|
1717
|
+
async getTuningStep(options) {
|
|
1718
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1719
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1720
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1721
|
+
const req = IcomRigCommands_1.IcomRigCommands.readTuningStep(ctrAddr, rigAddr);
|
|
1722
|
+
const resp = await this.waitForCivFrame('ts:0x10', (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_SET_TS, [], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1723
|
+
if (!resp || resp.length < 7)
|
|
1724
|
+
return null;
|
|
1725
|
+
return this.activeProfile.tuningSteps.find((step) => step.code === resp[5])?.hz ?? null;
|
|
1726
|
+
}
|
|
1727
|
+
setTuningStep(hz) {
|
|
1728
|
+
const matched = this.activeProfile.tuningSteps.find((step) => step.hz === hz);
|
|
1729
|
+
if (!matched) {
|
|
1730
|
+
throw this.unsupported(String(hz), 'setTuningStep', 'Tuning step is not enabled for active profile');
|
|
1731
|
+
}
|
|
1732
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1733
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1734
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.setTuningStep(ctrAddr, rigAddr, matched.code));
|
|
1735
|
+
}
|
|
1736
|
+
async getRepeaterShift(options) {
|
|
1737
|
+
const raw = await this.readSplitRaw(options);
|
|
1738
|
+
if (raw === null)
|
|
1739
|
+
return null;
|
|
1740
|
+
if (raw === IcomCivSpec_1.CIV.S_DUP_M)
|
|
1741
|
+
return 'minus';
|
|
1742
|
+
if (raw === IcomCivSpec_1.CIV.S_DUP_P)
|
|
1743
|
+
return 'plus';
|
|
1744
|
+
return 'none';
|
|
1745
|
+
}
|
|
1746
|
+
setRepeaterShift(shift) {
|
|
1747
|
+
if (!this.activeProfile.repeater) {
|
|
1748
|
+
throw this.unsupported(shift, 'setRepeaterShift', 'Repeater controls are not enabled for active profile');
|
|
1749
|
+
}
|
|
1750
|
+
const code = shift === 'minus' ? IcomCivSpec_1.CIV.S_DUP_M : shift === 'plus' ? IcomCivSpec_1.CIV.S_DUP_P : IcomCivSpec_1.CIV.S_DUP_OFF;
|
|
1751
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1752
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1753
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.setRepeaterShift(ctrAddr, rigAddr, code));
|
|
1754
|
+
}
|
|
1755
|
+
async getRepeaterOffset(options) {
|
|
1756
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1757
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1758
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1759
|
+
const req = IcomRigCommands_1.IcomRigCommands.readCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_RD_OFFS);
|
|
1760
|
+
const resp = await this.waitForCivFrame('rptr:offset', (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_RD_OFFS, [], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1761
|
+
if (!resp || resp.length < 9)
|
|
1762
|
+
return null;
|
|
1763
|
+
return (0, IcomCivFrame_1.decodeFrequencyBcdLE)(resp.subarray(5, 8)) * 100;
|
|
1764
|
+
}
|
|
1765
|
+
setRepeaterOffset(offsetHz) {
|
|
1766
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1767
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1768
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_SET_OFFS, undefined, (0, IcomCivFrame_1.encodeFrequencyBcdLE)(Math.round(offsetHz / 100), 3)));
|
|
1769
|
+
}
|
|
1770
|
+
async getToneFrequency(options) { return this.readTone(IcomCivSpec_1.CIV.S_TONE_RPTR, options); }
|
|
1771
|
+
setToneFrequency(hz) { this.writeTone(IcomCivSpec_1.CIV.S_TONE_RPTR, hz); }
|
|
1772
|
+
async getToneSquelchFrequency(options) { return this.readTone(IcomCivSpec_1.CIV.S_TONE_SQL, options); }
|
|
1773
|
+
setToneSquelchFrequency(hz) { this.writeTone(IcomCivSpec_1.CIV.S_TONE_SQL, hz); }
|
|
1774
|
+
async getBeepEnabled(options) { return this.getParameter('BEEP', options); }
|
|
1775
|
+
setBeepEnabled(enabled) { this.setParameter('BEEP', enabled); }
|
|
1776
|
+
async getBacklight(options) { return this.getParameter('BACKLIGHT', options); }
|
|
1777
|
+
setBacklight(value) { this.setParameter('BACKLIGHT', value); }
|
|
1778
|
+
async getScreenSaver(options) { return this.getParameter('SCREENSAVER', options); }
|
|
1779
|
+
setScreenSaver(value) { this.setParameter('SCREENSAVER', value); }
|
|
1780
|
+
async getKeyerType(options) { return this.getParameter('KEYERTYPE', options); }
|
|
1781
|
+
setKeyerType(value) { this.setParameter('KEYERTYPE', value); }
|
|
1782
|
+
async getAudioIfMode(options) {
|
|
1783
|
+
for (const source of ['wlan', 'lan', 'acc']) {
|
|
1784
|
+
const parm = this.audioIfSourceToParameter(source);
|
|
1785
|
+
if (parm && this.activeProfile.parameters.includes(parm)) {
|
|
1786
|
+
const enabled = await this.getParameter(parm, options);
|
|
1787
|
+
if (enabled === true)
|
|
1788
|
+
return source;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
return this.activeProfile.audioIfSources.includes('default') ? 'default' : null;
|
|
1792
|
+
}
|
|
1793
|
+
setAudioIfMode(source) {
|
|
1794
|
+
if (!this.activeProfile.audioIfSources.includes(source)) {
|
|
1795
|
+
throw this.unsupported(source, 'setAudioIfMode', 'Audio IF source is not enabled for active profile');
|
|
1796
|
+
}
|
|
1797
|
+
for (const candidate of ['wlan', 'lan', 'acc']) {
|
|
1798
|
+
const parm = this.audioIfSourceToParameter(candidate);
|
|
1799
|
+
if (parm && this.activeProfile.parameters.includes(parm)) {
|
|
1800
|
+
this.setParameter(parm, source === candidate);
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
if (this.activeProfile.parameters.includes('AFIF')) {
|
|
1804
|
+
this.setParameter('AFIF', source !== 'default');
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
async getSpectrumDataOutput(options) {
|
|
1808
|
+
return this.getScopeBoolean(IcomCivSpec_1.CIV.S_SCP_DOP, [], 'spectrum:data-output', options);
|
|
1809
|
+
}
|
|
1810
|
+
setSpectrumDataOutput(enabled) { this.writeScopeSimple(IcomCivSpec_1.CIV.S_SCP_DOP, [enabled ? 1 : 0]); }
|
|
1811
|
+
async getSpectrumHold(options) {
|
|
1812
|
+
const receiver = options?.receiver ?? 0;
|
|
1813
|
+
return this.getScopeBoolean(IcomCivSpec_1.CIV.S_SCP_HLD, [receiver], `spectrum:hold:${receiver}`, options);
|
|
1814
|
+
}
|
|
1815
|
+
setSpectrumHold(enabled, options) {
|
|
1816
|
+
const receiver = options?.receiver ?? 0;
|
|
1817
|
+
this.writeScopeSimple(IcomCivSpec_1.CIV.S_SCP_HLD, [receiver, enabled ? 1 : 0]);
|
|
1818
|
+
}
|
|
1819
|
+
async getSpectrumSpeed(options) {
|
|
1820
|
+
const receiver = options?.receiver ?? 0;
|
|
1821
|
+
const raw = await this.getScopeByte(IcomCivSpec_1.CIV.S_SCP_SWP, [receiver], `spectrum:speed:${receiver}`, options);
|
|
1822
|
+
if (raw === null)
|
|
1823
|
+
return null;
|
|
1824
|
+
return raw === 0 ? 'fast' : raw === 1 ? 'mid' : 'slow';
|
|
1825
|
+
}
|
|
1826
|
+
setSpectrumSpeed(speed, options) {
|
|
1827
|
+
const receiver = options?.receiver ?? 0;
|
|
1828
|
+
const raw = speed === 'fast' ? 0 : speed === 'mid' ? 1 : 2;
|
|
1829
|
+
this.writeScopeSimple(IcomCivSpec_1.CIV.S_SCP_SWP, [receiver, raw]);
|
|
1830
|
+
}
|
|
1831
|
+
async getSpectrumRef(options) {
|
|
1832
|
+
const receiver = options?.receiver ?? 0;
|
|
1833
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1834
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1835
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1836
|
+
const req = IcomRigCommands_1.IcomRigCommands.readCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_CTL_SCP, IcomCivSpec_1.CIV.S_SCP_REF, [receiver]);
|
|
1837
|
+
const resp = await this.waitForCivFrame(`spectrum:ref:${receiver}`, (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_CTL_SCP, [IcomCivSpec_1.CIV.S_SCP_REF, receiver], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1838
|
+
if (!resp || resp.length < 10)
|
|
1839
|
+
return null;
|
|
1840
|
+
const value = (0, IcomCivFrame_1.decodeBcdBE)(resp.subarray(7, 9)) / 100;
|
|
1841
|
+
return resp[9] ? -value : value;
|
|
1842
|
+
}
|
|
1843
|
+
setSpectrumRef(db, options) {
|
|
1844
|
+
const receiver = options?.receiver ?? 0;
|
|
1845
|
+
const rounded = Math.round(db * 2) / 2;
|
|
1846
|
+
this.writeScopeSimple(IcomCivSpec_1.CIV.S_SCP_REF, [receiver, ...(0, IcomCivFrame_1.encodeBcdBE)(Math.abs(Math.round(rounded * 100)), 2), rounded < 0 ? 1 : 0]);
|
|
1847
|
+
}
|
|
1848
|
+
async getSpectrumAverage(options) { return this.getLevel('SPECTRUM_AVG', options); }
|
|
1849
|
+
setSpectrumAverage(value) { this.setLevel('SPECTRUM_AVG', value); }
|
|
1850
|
+
async getSpectrumVbw(options) {
|
|
1851
|
+
const receiver = options?.receiver ?? 0;
|
|
1852
|
+
return this.getScopeByte(IcomCivSpec_1.CIV.S_SCP_VBW, [receiver], `spectrum:vbw:${receiver}`, options);
|
|
1853
|
+
}
|
|
1854
|
+
setSpectrumVbw(value, options) {
|
|
1855
|
+
const receiver = options?.receiver ?? 0;
|
|
1856
|
+
this.writeScopeSimple(IcomCivSpec_1.CIV.S_SCP_VBW, [receiver, Math.max(0, Math.min(1, Math.trunc(value)))]);
|
|
1857
|
+
}
|
|
1858
|
+
async getSpectrumRbw(options) {
|
|
1859
|
+
const receiver = options?.receiver ?? 0;
|
|
1860
|
+
return this.getScopeByte(IcomCivSpec_1.CIV.S_SCP_RBW, [receiver], `spectrum:rbw:${receiver}`, options);
|
|
1861
|
+
}
|
|
1862
|
+
setSpectrumRbw(value, options) {
|
|
1863
|
+
const receiver = options?.receiver ?? 0;
|
|
1864
|
+
this.writeScopeSimple(IcomCivSpec_1.CIV.S_SCP_RBW, [receiver, Math.max(0, Math.min(2, Math.trunc(value)))]);
|
|
1865
|
+
}
|
|
1866
|
+
async getSpectrumDuringTx(options) {
|
|
1867
|
+
return this.getScopeBoolean(IcomCivSpec_1.CIV.S_SCP_STX, [], 'spectrum:during-tx', options);
|
|
1868
|
+
}
|
|
1869
|
+
setSpectrumDuringTx(enabled) { this.writeScopeSimple(IcomCivSpec_1.CIV.S_SCP_STX, [enabled ? 1 : 0]); }
|
|
1870
|
+
async getSpectrumCenterType(options) {
|
|
1871
|
+
const raw = await this.getScopeByte(IcomCivSpec_1.CIV.S_SCP_CFQ, [], 'spectrum:center-type', options);
|
|
1872
|
+
if (raw === null)
|
|
1873
|
+
return null;
|
|
1874
|
+
return raw === 1 ? 'carrier-point-center' : raw === 2 ? 'carrier-point-center-abs' : 'filter-center';
|
|
1875
|
+
}
|
|
1876
|
+
setSpectrumCenterType(type) {
|
|
1877
|
+
const raw = type === 'carrier-point-center' ? 1 : type === 'carrier-point-center-abs' ? 2 : 0;
|
|
1878
|
+
this.writeScopeSimple(IcomCivSpec_1.CIV.S_SCP_CFQ, [raw]);
|
|
1879
|
+
}
|
|
1880
|
+
unsupported(commandName, api, reason) {
|
|
1881
|
+
return new errors_1.UnsupportedCommandError({
|
|
1882
|
+
modelId: this.getProfileModelId(),
|
|
1883
|
+
commandName: api,
|
|
1884
|
+
civCommand: commandName,
|
|
1885
|
+
reason,
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
async readFunctionRaw(name, spec, options) {
|
|
1889
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1890
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1891
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1892
|
+
const prefix = spec.readPrefix ?? [];
|
|
1893
|
+
const req = IcomRigCommands_1.IcomRigCommands.readCommand(ctrAddr, rigAddr, spec.command, spec.subcmd, prefix);
|
|
1894
|
+
const tail = [spec.subcmd, ...prefix];
|
|
1895
|
+
const resp = await this.waitForCivFrame(`func:0x${spec.command.toString(16)}:0x${spec.subcmd.toString(16)}:${prefix.join('.')}:${name}`, (frame) => IcomControl.matchCommandFrame(frame, spec.command, tail, ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1896
|
+
if (!resp)
|
|
1897
|
+
return null;
|
|
1898
|
+
const index = 5 + tail.length;
|
|
1899
|
+
return index < resp.length - 1 ? resp[index] : null;
|
|
1900
|
+
}
|
|
1901
|
+
writeFunctionRaw(spec, value) {
|
|
1902
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1903
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1904
|
+
const payload = [...(spec.payloadPrefix ?? []), value & 0xff];
|
|
1905
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, spec.command, spec.subcmd, payload));
|
|
1906
|
+
}
|
|
1907
|
+
async readLevelRaw(name, spec, options) {
|
|
1908
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1909
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1910
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1911
|
+
const req = IcomRigCommands_1.IcomRigCommands.readCommand(ctrAddr, rigAddr, spec.command, spec.subcmd);
|
|
1912
|
+
const resp = await this.waitForCivFrame(`level:0x${spec.command.toString(16)}:0x${spec.subcmd.toString(16)}:${name}`, (frame) => IcomControl.matchCommandFrame(frame, spec.command, [spec.subcmd], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1913
|
+
if (!resp)
|
|
1914
|
+
return null;
|
|
1915
|
+
const data = resp.subarray(6, resp.length - 1);
|
|
1916
|
+
if (data.length < spec.dataBytes)
|
|
1917
|
+
return null;
|
|
1918
|
+
return (0, IcomCivFrame_1.decodeBcdBE)(data.subarray(0, spec.dataBytes));
|
|
1919
|
+
}
|
|
1920
|
+
writeLevelRaw(spec, raw) {
|
|
1921
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1922
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1923
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, spec.command, spec.subcmd, IcomControl.encodeDataValue(raw, spec.dataType, spec.dataBytes)));
|
|
1924
|
+
}
|
|
1925
|
+
async readExtParamValue(ext, keyPrefix, options) {
|
|
1926
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1927
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1928
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1929
|
+
const req = IcomRigCommands_1.IcomRigCommands.readExtParam(ctrAddr, rigAddr, ext.command, ext.subcmd, ext.subext);
|
|
1930
|
+
const tail = [ext.subcmd, ...ext.subext];
|
|
1931
|
+
const resp = await this.waitForCivFrame(`${keyPrefix}:0x${ext.command.toString(16)}:0x${ext.subcmd.toString(16)}:${ext.subext.join('.')}`, (frame) => IcomControl.matchCommandFrame(frame, ext.command, tail, ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1932
|
+
if (!resp)
|
|
1933
|
+
return null;
|
|
1934
|
+
const start = 5 + tail.length;
|
|
1935
|
+
return IcomControl.decodeDataValue(resp.subarray(start, resp.length - 1), ext.dataType, ext.dataBytes);
|
|
1936
|
+
}
|
|
1937
|
+
writeExtParamValue(ext, value) {
|
|
1938
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1939
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1940
|
+
const raw = ext.dataType === 'level' ? Math.round(Math.max(0, Math.min(1, value)) * 255) : Math.round(value);
|
|
1941
|
+
const payload = IcomControl.encodeDataValue(raw, ext.dataType, ext.dataBytes);
|
|
1942
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeExtParam(ctrAddr, rigAddr, ext.command, ext.subcmd, ext.subext, payload));
|
|
1943
|
+
}
|
|
1944
|
+
static encodeDataValue(value, dataType, bytes) {
|
|
1945
|
+
if (dataType === 'time') {
|
|
1946
|
+
const seconds = Math.max(0, Math.round(value));
|
|
1947
|
+
const hhmm = Math.floor(seconds / 3600) * 100 + Math.floor(seconds / 60) % 60;
|
|
1948
|
+
return (0, IcomCivFrame_1.encodeBcdBE)(hhmm, bytes);
|
|
1949
|
+
}
|
|
1950
|
+
return (0, IcomCivFrame_1.encodeBcdBE)(value, bytes);
|
|
1951
|
+
}
|
|
1952
|
+
static decodeDataValue(data, dataType, bytes) {
|
|
1953
|
+
if (data.length < bytes)
|
|
1954
|
+
return null;
|
|
1955
|
+
const value = (0, IcomCivFrame_1.decodeBcdBE)(data.subarray(0, bytes));
|
|
1956
|
+
if (dataType === 'level')
|
|
1957
|
+
return value / 255;
|
|
1958
|
+
if (dataType === 'bool')
|
|
1959
|
+
return value === 0 ? 0 : 1;
|
|
1960
|
+
if (dataType === 'time') {
|
|
1961
|
+
const hours = Math.floor(value / 100);
|
|
1962
|
+
const minutes = value % 100;
|
|
1963
|
+
return hours * 3600 + minutes * 60;
|
|
1964
|
+
}
|
|
1965
|
+
return value;
|
|
1966
|
+
}
|
|
1967
|
+
async readRitOffset(options) {
|
|
1968
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
1969
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1970
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1971
|
+
const req = IcomRigCommands_1.IcomRigCommands.readRitOffset(ctrAddr, rigAddr);
|
|
1972
|
+
const resp = await this.waitForCivFrame('rit:offset', (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_CTL_RIT, [IcomCivSpec_1.CIV.S_RIT_FREQ], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
1973
|
+
if (!resp || resp.length < 9)
|
|
1974
|
+
return null;
|
|
1975
|
+
const value = (0, IcomCivFrame_1.decodeFrequencyBcdLE)(resp.subarray(6, 8));
|
|
1976
|
+
return resp[8] === 0 ? value : -value;
|
|
1977
|
+
}
|
|
1978
|
+
writeRitOffset(offsetHz) {
|
|
1979
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1980
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1981
|
+
const payload = [...(0, IcomCivFrame_1.encodeFrequencyBcdLE)(Math.abs(Math.round(offsetHz)), 2), offsetHz < 0 ? 1 : 0];
|
|
1982
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.setRitOffset(ctrAddr, rigAddr, payload));
|
|
1983
|
+
}
|
|
1984
|
+
vfoToSubcmd(vfo) {
|
|
1985
|
+
switch (vfo) {
|
|
1986
|
+
case 'A': return IcomCivSpec_1.CIV.S_VFOA;
|
|
1987
|
+
case 'B': return IcomCivSpec_1.CIV.S_VFOB;
|
|
1988
|
+
case 'MAIN':
|
|
1989
|
+
case 'MAIN_A':
|
|
1990
|
+
case 'MAIN_B': return IcomCivSpec_1.CIV.S_MAIN;
|
|
1991
|
+
case 'SUB':
|
|
1992
|
+
case 'SUB_A':
|
|
1993
|
+
case 'SUB_B': return IcomCivSpec_1.CIV.S_SUB;
|
|
1994
|
+
case 'CURR':
|
|
1995
|
+
case 'TX': return null;
|
|
1996
|
+
case 'MEM': return null;
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
async readSplitRaw(options) {
|
|
2000
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
2001
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
2002
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
2003
|
+
const req = IcomRigCommands_1.IcomRigCommands.readSplit(ctrAddr, rigAddr);
|
|
2004
|
+
const resp = await this.waitForCivFrame('split:0x0f', (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_CTL_SPLT, [], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
2005
|
+
if (!resp || resp.length < 7)
|
|
2006
|
+
return null;
|
|
2007
|
+
return resp[5];
|
|
2008
|
+
}
|
|
2009
|
+
async readTone(subcmd, options) {
|
|
2010
|
+
if (!this.activeProfile.tone)
|
|
2011
|
+
return null;
|
|
2012
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
2013
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
2014
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
2015
|
+
const req = IcomRigCommands_1.IcomRigCommands.readTone(ctrAddr, rigAddr, subcmd);
|
|
2016
|
+
const resp = await this.waitForCivFrame(`tone:0x${subcmd.toString(16)}`, (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_SET_TONE, [subcmd], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
2017
|
+
if (!resp || resp.length < 10)
|
|
2018
|
+
return null;
|
|
2019
|
+
return (0, IcomCivFrame_1.decodeBcdBE)(resp.subarray(6, 9)) / 10;
|
|
2020
|
+
}
|
|
2021
|
+
writeTone(subcmd, hz) {
|
|
2022
|
+
if (!this.activeProfile.tone) {
|
|
2023
|
+
throw this.unsupported(String(subcmd), 'setToneFrequency', 'Tone controls are not enabled for active profile');
|
|
2024
|
+
}
|
|
2025
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
2026
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
2027
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.setTone(ctrAddr, rigAddr, subcmd, Math.round(hz * 10)));
|
|
2028
|
+
}
|
|
2029
|
+
audioIfSourceToParameter(source) {
|
|
2030
|
+
switch (source) {
|
|
2031
|
+
case 'wlan': return 'AFIF_WLAN';
|
|
2032
|
+
case 'lan': return 'AFIF_LAN';
|
|
2033
|
+
case 'acc': return 'AFIF_ACC';
|
|
2034
|
+
case 'default': return 'AFIF';
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
async getScopeBoolean(subcmd, payload, key, options) {
|
|
2038
|
+
const raw = await this.getScopeByte(subcmd, payload, key, options);
|
|
2039
|
+
return raw === null ? null : raw !== 0;
|
|
2040
|
+
}
|
|
2041
|
+
async getScopeByte(subcmd, payload, key, options) {
|
|
2042
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
2043
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
2044
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
2045
|
+
const req = IcomRigCommands_1.IcomRigCommands.readCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_CTL_SCP, subcmd, payload);
|
|
2046
|
+
const resp = await this.waitForCivFrame(key, (frame) => IcomControl.matchCommandFrame(frame, IcomCivSpec_1.CIV.C_CTL_SCP, [subcmd, ...payload], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
2047
|
+
if (!resp)
|
|
2048
|
+
return null;
|
|
2049
|
+
const index = 5 + 1 + payload.length;
|
|
2050
|
+
return index < resp.length - 1 ? resp[index] : null;
|
|
2051
|
+
}
|
|
2052
|
+
writeScopeSimple(subcmd, payload) {
|
|
2053
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
2054
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
2055
|
+
this.sendCiv(IcomRigCommands_1.IcomRigCommands.writeCommand(ctrAddr, rigAddr, IcomCivSpec_1.CIV.C_CTL_SCP, subcmd, payload));
|
|
2056
|
+
}
|
|
1396
2057
|
static isReplyOf(frame, cmd, ctrAddr, rigAddr) {
|
|
1397
2058
|
// typical reply FE FE [ctr] [rig] cmd ... FD
|
|
1398
2059
|
return frame.length >= 7 && frame[0] === 0xfe && frame[1] === 0xfe && frame[4] === (cmd & 0xff);
|