hamlib 0.3.3 → 0.4.1
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 +29 -24
- package/index.d.ts +84 -137
- package/lib/index.js +101 -407
- package/lib/spectrum.d.ts +63 -0
- package/lib/spectrum.js +364 -0
- package/lib/spectrum.mjs +7 -0
- package/package.json +17 -1
- package/prebuilds/darwin-arm64/libhamlib.4.dylib +0 -0
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/darwin-x64/libhamlib.4.dylib +0 -0
- package/prebuilds/darwin-x64/node.napi.node +0 -0
- package/prebuilds/linux-arm64/libhamlib.so +0 -0
- package/prebuilds/linux-arm64/libhamlib.so.4 +0 -0
- package/prebuilds/linux-arm64/libhamlib.so.4.0.7 +0 -0
- package/prebuilds/linux-arm64/node.napi.node +0 -0
- package/prebuilds/linux-x64/libhamlib.so +0 -0
- package/prebuilds/linux-x64/libhamlib.so.4 +0 -0
- package/prebuilds/linux-x64/libhamlib.so.4.0.7 +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
- package/prebuilds/win32-x64/hamlib_shim.dll +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/spectrum.d.ts +2 -0
- package/spectrum.js +1 -0
- package/spectrum.mjs +2 -0
- package/src/hamlib.cpp +173 -133
- package/src/shim/hamlib_shim.c +8 -0
- package/src/shim/hamlib_shim.h +3 -1
package/lib/index.js
CHANGED
|
@@ -4,17 +4,6 @@ const nodeGypBuild = require('node-gyp-build');
|
|
|
4
4
|
// Ensure loader resolves from package root (contains prebuilds/ and build/)
|
|
5
5
|
const nativeModule = nodeGypBuild(path.join(__dirname, '..'));
|
|
6
6
|
|
|
7
|
-
const DEFAULT_SPECTRUM_EDGE_SLOTS = [1, 2, 3, 4];
|
|
8
|
-
|
|
9
|
-
function normalizeSpectrumModeName(name) {
|
|
10
|
-
const normalized = String(name || '').trim().toLowerCase();
|
|
11
|
-
if (normalized === 'center') return 'center';
|
|
12
|
-
if (normalized === 'fixed') return 'fixed';
|
|
13
|
-
if (normalized === 'center scroll' || normalized === 'center-scroll' || normalized === 'scroll-center') return 'scroll-center';
|
|
14
|
-
if (normalized === 'fixed scroll' || normalized === 'fixed-scroll' || normalized === 'scroll-fixed') return 'scroll-fixed';
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
7
|
/**
|
|
19
8
|
* HamLib class for controlling amateur radio devices
|
|
20
9
|
*
|
|
@@ -32,30 +21,6 @@ class HamLib extends EventEmitter {
|
|
|
32
21
|
constructor(model, port) {
|
|
33
22
|
super();
|
|
34
23
|
this._nativeInstance = new nativeModule.HamLib(model, port);
|
|
35
|
-
this._managedSpectrumRunning = false;
|
|
36
|
-
this._lastSpectrumLine = null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
_recordSpectrumLine(line) {
|
|
40
|
-
if (!line || typeof line !== 'object') {
|
|
41
|
-
return line;
|
|
42
|
-
}
|
|
43
|
-
this._lastSpectrumLine = line;
|
|
44
|
-
return line;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
_getLastSpectrumDisplayStateFromLine() {
|
|
48
|
-
const line = this._lastSpectrumLine;
|
|
49
|
-
if (!line || typeof line !== 'object') {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
modeId: Number.isFinite(line.mode) ? line.mode : null,
|
|
55
|
-
spanHz: Number.isFinite(line.spanHz) ? line.spanHz : null,
|
|
56
|
-
edgeLowHz: Number.isFinite(line.lowEdgeFreq) ? line.lowEdgeFreq : null,
|
|
57
|
-
edgeHighHz: Number.isFinite(line.highEdgeFreq) ? line.highEdgeFreq : null,
|
|
58
|
-
};
|
|
59
24
|
}
|
|
60
25
|
|
|
61
26
|
/**
|
|
@@ -87,7 +52,7 @@ class HamLib extends EventEmitter {
|
|
|
87
52
|
* - 5 = TRACE (trace messages - very detailed)
|
|
88
53
|
* @static
|
|
89
54
|
* @example
|
|
90
|
-
* // Disable all debug output
|
|
55
|
+
* // Disable all debug output
|
|
91
56
|
* HamLib.setDebugLevel(0);
|
|
92
57
|
*
|
|
93
58
|
* // Enable verbose debugging
|
|
@@ -122,7 +87,7 @@ class HamLib extends EventEmitter {
|
|
|
122
87
|
|
|
123
88
|
/**
|
|
124
89
|
* Set VFO (Variable Frequency Oscillator)
|
|
125
|
-
* @param {string} vfo - VFO identifier ('
|
|
90
|
+
* @param {string} vfo - VFO identifier ('VFOA' or 'VFOB')
|
|
126
91
|
* @throws {Error} Throws error when device doesn't support or operation fails
|
|
127
92
|
*/
|
|
128
93
|
async setVfo(vfo) {
|
|
@@ -132,10 +97,10 @@ class HamLib extends EventEmitter {
|
|
|
132
97
|
/**
|
|
133
98
|
* Set frequency
|
|
134
99
|
* @param {number} frequency - Frequency in hertz
|
|
135
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
100
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
136
101
|
*/
|
|
137
102
|
async setFrequency(frequency, vfo) {
|
|
138
|
-
if (vfo) {
|
|
103
|
+
if (vfo !== undefined) {
|
|
139
104
|
return this._nativeInstance.setFrequency(frequency, vfo);
|
|
140
105
|
} else {
|
|
141
106
|
return this._nativeInstance.setFrequency(frequency);
|
|
@@ -146,16 +111,16 @@ class HamLib extends EventEmitter {
|
|
|
146
111
|
* Set radio mode
|
|
147
112
|
* @param {string} mode - Radio mode ('USB', 'LSB', 'FM', 'PKTFM', etc.)
|
|
148
113
|
* @param {string} [bandwidth] - Optional bandwidth ('narrow', 'wide')
|
|
149
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
114
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
150
115
|
*/
|
|
151
116
|
async setMode(mode, bandwidth, vfo) {
|
|
152
117
|
if (vfo !== undefined) {
|
|
153
|
-
if (bandwidth) {
|
|
118
|
+
if (bandwidth !== undefined) {
|
|
154
119
|
return this._nativeInstance.setMode(mode, bandwidth, vfo);
|
|
155
120
|
} else {
|
|
156
121
|
return this._nativeInstance.setMode(mode, vfo);
|
|
157
122
|
}
|
|
158
|
-
} else if (bandwidth) {
|
|
123
|
+
} else if (bandwidth !== undefined) {
|
|
159
124
|
return this._nativeInstance.setMode(mode, bandwidth);
|
|
160
125
|
} else {
|
|
161
126
|
return this._nativeInstance.setMode(mode);
|
|
@@ -172,26 +137,19 @@ class HamLib extends EventEmitter {
|
|
|
172
137
|
|
|
173
138
|
/**
|
|
174
139
|
* Get current VFO
|
|
175
|
-
* @
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
async getVfo(options = {}) {
|
|
180
|
-
try {
|
|
181
|
-
return await this._nativeInstance.getVfo();
|
|
182
|
-
} catch (error) {
|
|
183
|
-
// 如果无线电不支持VFO查询,且用户要求回退到默认值
|
|
184
|
-
return 'VFO-CURR'; // 返回合理的默认值
|
|
185
|
-
}
|
|
140
|
+
* @returns {string} Current Hamlib VFO token
|
|
141
|
+
*/
|
|
142
|
+
async getVfo() {
|
|
143
|
+
return this._nativeInstance.getVfo();
|
|
186
144
|
}
|
|
187
145
|
|
|
188
146
|
/**
|
|
189
147
|
* Get current frequency
|
|
190
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
148
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
191
149
|
* @returns {number} Current frequency in hertz
|
|
192
150
|
*/
|
|
193
151
|
async getFrequency(vfo) {
|
|
194
|
-
if (vfo) {
|
|
152
|
+
if (vfo !== undefined) {
|
|
195
153
|
return this._nativeInstance.getFrequency(vfo);
|
|
196
154
|
} else {
|
|
197
155
|
return this._nativeInstance.getFrequency();
|
|
@@ -208,11 +166,11 @@ class HamLib extends EventEmitter {
|
|
|
208
166
|
|
|
209
167
|
/**
|
|
210
168
|
* Get current signal strength
|
|
211
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
169
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
212
170
|
* @returns {number} Signal strength value
|
|
213
171
|
*/
|
|
214
172
|
async getStrength(vfo) {
|
|
215
|
-
if (vfo) {
|
|
173
|
+
if (vfo !== undefined) {
|
|
216
174
|
return this._nativeInstance.getStrength(vfo);
|
|
217
175
|
} else {
|
|
218
176
|
return this._nativeInstance.getStrength();
|
|
@@ -224,9 +182,6 @@ class HamLib extends EventEmitter {
|
|
|
224
182
|
* Connection can be re-established by calling open()
|
|
225
183
|
*/
|
|
226
184
|
async close() {
|
|
227
|
-
if (this._managedSpectrumRunning) {
|
|
228
|
-
await this.stopManagedSpectrum();
|
|
229
|
-
}
|
|
230
185
|
return this._nativeInstance.close();
|
|
231
186
|
}
|
|
232
187
|
|
|
@@ -235,9 +190,6 @@ class HamLib extends EventEmitter {
|
|
|
235
190
|
* Object reference should be deleted after calling this
|
|
236
191
|
*/
|
|
237
192
|
async destroy() {
|
|
238
|
-
if (this._managedSpectrumRunning) {
|
|
239
|
-
await this.stopManagedSpectrum();
|
|
240
|
-
}
|
|
241
193
|
return this._nativeInstance.destroy();
|
|
242
194
|
}
|
|
243
195
|
|
|
@@ -263,10 +215,10 @@ class HamLib extends EventEmitter {
|
|
|
263
215
|
/**
|
|
264
216
|
* Get memory channel data
|
|
265
217
|
* @param {number} channelNumber - Memory channel number
|
|
266
|
-
* @param {boolean}
|
|
218
|
+
* @param {boolean} readOnly - Whether to read in read-only mode
|
|
267
219
|
* @returns {Object} Channel data
|
|
268
220
|
*/
|
|
269
|
-
async getMemoryChannel(channelNumber, readOnly
|
|
221
|
+
async getMemoryChannel(channelNumber, readOnly) {
|
|
270
222
|
return this._nativeInstance.getMemoryChannel(channelNumber, readOnly);
|
|
271
223
|
}
|
|
272
224
|
|
|
@@ -327,7 +279,7 @@ class HamLib extends EventEmitter {
|
|
|
327
279
|
* @param {string} scanType - Scan type ('VFO', 'MEM', 'PROG', 'DELTA', 'PRIO')
|
|
328
280
|
* @param {number} [channel=0] - Optional channel number for some scan types
|
|
329
281
|
*/
|
|
330
|
-
async startScan(scanType, channel
|
|
282
|
+
async startScan(scanType, channel) {
|
|
331
283
|
return this._nativeInstance.startScan(scanType, channel);
|
|
332
284
|
}
|
|
333
285
|
|
|
@@ -346,7 +298,7 @@ class HamLib extends EventEmitter {
|
|
|
346
298
|
* @param {number} value - Level value (0.0-1.0 typically)
|
|
347
299
|
*/
|
|
348
300
|
async setLevel(levelType, value, vfo) {
|
|
349
|
-
if (vfo) {
|
|
301
|
+
if (vfo !== undefined) {
|
|
350
302
|
return this._nativeInstance.setLevel(levelType, value, vfo);
|
|
351
303
|
}
|
|
352
304
|
return this._nativeInstance.setLevel(levelType, value);
|
|
@@ -357,7 +309,10 @@ class HamLib extends EventEmitter {
|
|
|
357
309
|
* @param {string} levelType - Level type ('AF', 'RF', 'SQL', 'STRENGTH', etc.)
|
|
358
310
|
* @returns {number} Level value
|
|
359
311
|
*/
|
|
360
|
-
async getLevel(levelType) {
|
|
312
|
+
async getLevel(levelType, vfo) {
|
|
313
|
+
if (vfo !== undefined) {
|
|
314
|
+
return this._nativeInstance.getLevel(levelType, vfo);
|
|
315
|
+
}
|
|
361
316
|
return this._nativeInstance.getLevel(levelType);
|
|
362
317
|
}
|
|
363
318
|
|
|
@@ -413,10 +368,10 @@ class HamLib extends EventEmitter {
|
|
|
413
368
|
/**
|
|
414
369
|
* Set split mode TX frequency
|
|
415
370
|
* @param {number} txFrequency - TX frequency in Hz
|
|
416
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
371
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
417
372
|
*/
|
|
418
373
|
async setSplitFreq(txFrequency, vfo) {
|
|
419
|
-
if (vfo) {
|
|
374
|
+
if (vfo !== undefined) {
|
|
420
375
|
return this._nativeInstance.setSplitFreq(txFrequency, vfo);
|
|
421
376
|
} else {
|
|
422
377
|
return this._nativeInstance.setSplitFreq(txFrequency);
|
|
@@ -425,11 +380,11 @@ class HamLib extends EventEmitter {
|
|
|
425
380
|
|
|
426
381
|
/**
|
|
427
382
|
* Get split mode TX frequency
|
|
428
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
383
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
429
384
|
* @returns {number} TX frequency in Hz
|
|
430
385
|
*/
|
|
431
386
|
async getSplitFreq(vfo) {
|
|
432
|
-
if (vfo) {
|
|
387
|
+
if (vfo !== undefined) {
|
|
433
388
|
return this._nativeInstance.getSplitFreq(vfo);
|
|
434
389
|
} else {
|
|
435
390
|
return this._nativeInstance.getSplitFreq();
|
|
@@ -440,7 +395,7 @@ class HamLib extends EventEmitter {
|
|
|
440
395
|
* Set split mode TX mode
|
|
441
396
|
* @param {string} txMode - TX mode ('USB', 'LSB', 'FM', etc.)
|
|
442
397
|
* @param {number} [txWidth] - Optional TX bandwidth
|
|
443
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
398
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
444
399
|
*/
|
|
445
400
|
async setSplitMode(txMode, txWidth, vfo) {
|
|
446
401
|
if (vfo !== undefined) {
|
|
@@ -458,11 +413,11 @@ class HamLib extends EventEmitter {
|
|
|
458
413
|
|
|
459
414
|
/**
|
|
460
415
|
* Get split mode TX mode
|
|
461
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
416
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
462
417
|
* @returns {Object} TX mode and width
|
|
463
418
|
*/
|
|
464
419
|
async getSplitMode(vfo) {
|
|
465
|
-
if (vfo) {
|
|
420
|
+
if (vfo !== undefined) {
|
|
466
421
|
return this._nativeInstance.getSplitMode(vfo);
|
|
467
422
|
} else {
|
|
468
423
|
return this._nativeInstance.getSplitMode();
|
|
@@ -472,8 +427,8 @@ class HamLib extends EventEmitter {
|
|
|
472
427
|
/**
|
|
473
428
|
* Enable/disable split operation
|
|
474
429
|
* @param {boolean} enable - true to enable split, false to disable
|
|
475
|
-
* @param {string} [rxVfo] - RX VFO ('
|
|
476
|
-
* @param {string} [txVfo] - TX VFO ('
|
|
430
|
+
* @param {string} [rxVfo] - RX VFO ('VFOA' or 'VFOB'). Default: current VFO
|
|
431
|
+
* @param {string} [txVfo] - TX VFO ('VFOA' or 'VFOB'). Default: current VFO
|
|
477
432
|
*/
|
|
478
433
|
async setSplit(enable, rxVfo, txVfo) {
|
|
479
434
|
if (txVfo !== undefined) {
|
|
@@ -490,11 +445,11 @@ class HamLib extends EventEmitter {
|
|
|
490
445
|
|
|
491
446
|
/**
|
|
492
447
|
* Get split operation status
|
|
493
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
448
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
494
449
|
* @returns {Object} Split status and TX VFO
|
|
495
450
|
*/
|
|
496
451
|
async getSplit(vfo) {
|
|
497
|
-
if (vfo) {
|
|
452
|
+
if (vfo !== undefined) {
|
|
498
453
|
return this._nativeInstance.getSplit(vfo);
|
|
499
454
|
} else {
|
|
500
455
|
return this._nativeInstance.getSplit();
|
|
@@ -666,7 +621,7 @@ class HamLib extends EventEmitter {
|
|
|
666
621
|
|
|
667
622
|
/**
|
|
668
623
|
* Get current PTT status
|
|
669
|
-
* @param {string} [vfo] - Optional VFO to get PTT status from ('
|
|
624
|
+
* @param {string} [vfo] - Optional VFO to get PTT status from ('VFOA' or 'VFOB'). If not specified, uses current VFO
|
|
670
625
|
* @returns {Promise<boolean>} PTT status (true if transmitting, false if receiving)
|
|
671
626
|
* @example
|
|
672
627
|
* const isTransmitting = await rig.getPtt();
|
|
@@ -675,7 +630,7 @@ class HamLib extends EventEmitter {
|
|
|
675
630
|
* }
|
|
676
631
|
*/
|
|
677
632
|
async getPtt(vfo) {
|
|
678
|
-
if (vfo) {
|
|
633
|
+
if (vfo !== undefined) {
|
|
679
634
|
return this._nativeInstance.getPtt(vfo);
|
|
680
635
|
} else {
|
|
681
636
|
return this._nativeInstance.getPtt();
|
|
@@ -686,7 +641,7 @@ class HamLib extends EventEmitter {
|
|
|
686
641
|
|
|
687
642
|
/**
|
|
688
643
|
* Get current DCD (Data Carrier Detect) status
|
|
689
|
-
* @param {string} [vfo] - Optional VFO to get DCD status from ('
|
|
644
|
+
* @param {string} [vfo] - Optional VFO to get DCD status from ('VFOA' or 'VFOB'). If not specified, uses current VFO
|
|
690
645
|
* @returns {Promise<boolean>} DCD status (true if carrier detected, false if no carrier)
|
|
691
646
|
* @example
|
|
692
647
|
* const carrierDetected = await rig.getDcd();
|
|
@@ -695,7 +650,7 @@ class HamLib extends EventEmitter {
|
|
|
695
650
|
* }
|
|
696
651
|
*/
|
|
697
652
|
async getDcd(vfo) {
|
|
698
|
-
if (vfo) {
|
|
653
|
+
if (vfo !== undefined) {
|
|
699
654
|
return this._nativeInstance.getDcd(vfo);
|
|
700
655
|
} else {
|
|
701
656
|
return this._nativeInstance.getDcd();
|
|
@@ -707,7 +662,7 @@ class HamLib extends EventEmitter {
|
|
|
707
662
|
/**
|
|
708
663
|
* Set tuning step
|
|
709
664
|
* @param {number} step - Tuning step in Hz
|
|
710
|
-
* @param {string} [vfo] - Optional VFO to set tuning step on ('
|
|
665
|
+
* @param {string} [vfo] - Optional VFO to set tuning step on ('VFOA' or 'VFOB'). If not specified, uses current VFO
|
|
711
666
|
* @returns {Promise<number>} Success status
|
|
712
667
|
* @example
|
|
713
668
|
* await rig.setTuningStep(25000); // 25 kHz steps
|
|
@@ -715,7 +670,7 @@ class HamLib extends EventEmitter {
|
|
|
715
670
|
* await rig.setTuningStep(100); // 100 Hz steps for HF
|
|
716
671
|
*/
|
|
717
672
|
async setTuningStep(step, vfo) {
|
|
718
|
-
if (vfo) {
|
|
673
|
+
if (vfo !== undefined) {
|
|
719
674
|
return this._nativeInstance.setTuningStep(step, vfo);
|
|
720
675
|
} else {
|
|
721
676
|
return this._nativeInstance.setTuningStep(step);
|
|
@@ -724,14 +679,14 @@ class HamLib extends EventEmitter {
|
|
|
724
679
|
|
|
725
680
|
/**
|
|
726
681
|
* Get current tuning step
|
|
727
|
-
* @param {string} [vfo] - Optional VFO to get tuning step from ('
|
|
682
|
+
* @param {string} [vfo] - Optional VFO to get tuning step from ('VFOA' or 'VFOB'). If not specified, uses current VFO
|
|
728
683
|
* @returns {Promise<number>} Current tuning step in Hz
|
|
729
684
|
* @example
|
|
730
685
|
* const step = await rig.getTuningStep();
|
|
731
686
|
* console.log(`Current tuning step: ${step} Hz`);
|
|
732
687
|
*/
|
|
733
688
|
async getTuningStep(vfo) {
|
|
734
|
-
if (vfo) {
|
|
689
|
+
if (vfo !== undefined) {
|
|
735
690
|
return this._nativeInstance.getTuningStep(vfo);
|
|
736
691
|
} else {
|
|
737
692
|
return this._nativeInstance.getTuningStep();
|
|
@@ -743,7 +698,7 @@ class HamLib extends EventEmitter {
|
|
|
743
698
|
/**
|
|
744
699
|
* Set repeater shift direction
|
|
745
700
|
* @param {string} shift - Repeater shift direction ('NONE', 'MINUS', 'PLUS', '-', '+')
|
|
746
|
-
* @param {string} [vfo] - Optional VFO to set repeater shift on ('
|
|
701
|
+
* @param {string} [vfo] - Optional VFO to set repeater shift on ('VFOA' or 'VFOB'). If not specified, uses current VFO
|
|
747
702
|
* @returns {Promise<number>} Success status
|
|
748
703
|
* @example
|
|
749
704
|
* await rig.setRepeaterShift('PLUS'); // Positive shift (+)
|
|
@@ -751,7 +706,7 @@ class HamLib extends EventEmitter {
|
|
|
751
706
|
* await rig.setRepeaterShift('NONE'); // No shift (simplex)
|
|
752
707
|
*/
|
|
753
708
|
async setRepeaterShift(shift, vfo) {
|
|
754
|
-
if (vfo) {
|
|
709
|
+
if (vfo !== undefined) {
|
|
755
710
|
return this._nativeInstance.setRepeaterShift(shift, vfo);
|
|
756
711
|
} else {
|
|
757
712
|
return this._nativeInstance.setRepeaterShift(shift);
|
|
@@ -760,14 +715,14 @@ class HamLib extends EventEmitter {
|
|
|
760
715
|
|
|
761
716
|
/**
|
|
762
717
|
* Get current repeater shift direction
|
|
763
|
-
* @param {string} [vfo] - Optional VFO to get repeater shift from ('
|
|
718
|
+
* @param {string} [vfo] - Optional VFO to get repeater shift from ('VFOA' or 'VFOB'). If not specified, uses current VFO
|
|
764
719
|
* @returns {Promise<string>} Current repeater shift direction
|
|
765
720
|
* @example
|
|
766
721
|
* const shift = await rig.getRepeaterShift();
|
|
767
722
|
* console.log(`Repeater shift: ${shift}`); // 'None', 'Minus', or 'Plus'
|
|
768
723
|
*/
|
|
769
724
|
async getRepeaterShift(vfo) {
|
|
770
|
-
if (vfo) {
|
|
725
|
+
if (vfo !== undefined) {
|
|
771
726
|
return this._nativeInstance.getRepeaterShift(vfo);
|
|
772
727
|
} else {
|
|
773
728
|
return this._nativeInstance.getRepeaterShift();
|
|
@@ -777,14 +732,14 @@ class HamLib extends EventEmitter {
|
|
|
777
732
|
/**
|
|
778
733
|
* Set repeater offset frequency
|
|
779
734
|
* @param {number} offset - Repeater offset in Hz
|
|
780
|
-
* @param {string} [vfo] - Optional VFO to set repeater offset on ('
|
|
735
|
+
* @param {string} [vfo] - Optional VFO to set repeater offset on ('VFOA' or 'VFOB'). If not specified, uses current VFO
|
|
781
736
|
* @returns {Promise<number>} Success status
|
|
782
737
|
* @example
|
|
783
738
|
* await rig.setRepeaterOffset(600000); // 600 kHz offset (2m band)
|
|
784
739
|
* await rig.setRepeaterOffset(5000000); // 5 MHz offset (70cm band)
|
|
785
740
|
*/
|
|
786
741
|
async setRepeaterOffset(offset, vfo) {
|
|
787
|
-
if (vfo) {
|
|
742
|
+
if (vfo !== undefined) {
|
|
788
743
|
return this._nativeInstance.setRepeaterOffset(offset, vfo);
|
|
789
744
|
} else {
|
|
790
745
|
return this._nativeInstance.setRepeaterOffset(offset);
|
|
@@ -793,14 +748,14 @@ class HamLib extends EventEmitter {
|
|
|
793
748
|
|
|
794
749
|
/**
|
|
795
750
|
* Get current repeater offset frequency
|
|
796
|
-
* @param {string} [vfo] - Optional VFO to get repeater offset from ('
|
|
751
|
+
* @param {string} [vfo] - Optional VFO to get repeater offset from ('VFOA' or 'VFOB'). If not specified, uses current VFO
|
|
797
752
|
* @returns {Promise<number>} Current repeater offset in Hz
|
|
798
753
|
* @example
|
|
799
754
|
* const offset = await rig.getRepeaterOffset();
|
|
800
755
|
* console.log(`Repeater offset: ${offset} Hz`);
|
|
801
756
|
*/
|
|
802
757
|
async getRepeaterOffset(vfo) {
|
|
803
|
-
if (vfo) {
|
|
758
|
+
if (vfo !== undefined) {
|
|
804
759
|
return this._nativeInstance.getRepeaterOffset(vfo);
|
|
805
760
|
} else {
|
|
806
761
|
return this._nativeInstance.getRepeaterOffset();
|
|
@@ -812,10 +767,10 @@ class HamLib extends EventEmitter {
|
|
|
812
767
|
/**
|
|
813
768
|
* Set CTCSS tone frequency
|
|
814
769
|
* @param {number} tone - CTCSS tone frequency in tenths of Hz (e.g., 1000 for 100.0 Hz)
|
|
815
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
770
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
816
771
|
*/
|
|
817
772
|
async setCtcssTone(tone, vfo) {
|
|
818
|
-
if (vfo) {
|
|
773
|
+
if (vfo !== undefined) {
|
|
819
774
|
return this._nativeInstance.setCtcssTone(tone, vfo);
|
|
820
775
|
} else {
|
|
821
776
|
return this._nativeInstance.setCtcssTone(tone);
|
|
@@ -824,11 +779,11 @@ class HamLib extends EventEmitter {
|
|
|
824
779
|
|
|
825
780
|
/**
|
|
826
781
|
* Get current CTCSS tone frequency
|
|
827
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
782
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
828
783
|
* @returns {number} Current CTCSS tone frequency in tenths of Hz
|
|
829
784
|
*/
|
|
830
785
|
async getCtcssTone(vfo) {
|
|
831
|
-
if (vfo) {
|
|
786
|
+
if (vfo !== undefined) {
|
|
832
787
|
return this._nativeInstance.getCtcssTone(vfo);
|
|
833
788
|
} else {
|
|
834
789
|
return this._nativeInstance.getCtcssTone();
|
|
@@ -838,10 +793,10 @@ class HamLib extends EventEmitter {
|
|
|
838
793
|
/**
|
|
839
794
|
* Set DCS code
|
|
840
795
|
* @param {number} code - DCS code (e.g., 23, 174, 754)
|
|
841
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
796
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
842
797
|
*/
|
|
843
798
|
async setDcsCode(code, vfo) {
|
|
844
|
-
if (vfo) {
|
|
799
|
+
if (vfo !== undefined) {
|
|
845
800
|
return this._nativeInstance.setDcsCode(code, vfo);
|
|
846
801
|
} else {
|
|
847
802
|
return this._nativeInstance.setDcsCode(code);
|
|
@@ -850,11 +805,11 @@ class HamLib extends EventEmitter {
|
|
|
850
805
|
|
|
851
806
|
/**
|
|
852
807
|
* Get current DCS code
|
|
853
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
808
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
854
809
|
* @returns {number} Current DCS code
|
|
855
810
|
*/
|
|
856
811
|
async getDcsCode(vfo) {
|
|
857
|
-
if (vfo) {
|
|
812
|
+
if (vfo !== undefined) {
|
|
858
813
|
return this._nativeInstance.getDcsCode(vfo);
|
|
859
814
|
} else {
|
|
860
815
|
return this._nativeInstance.getDcsCode();
|
|
@@ -864,10 +819,10 @@ class HamLib extends EventEmitter {
|
|
|
864
819
|
/**
|
|
865
820
|
* Set CTCSS SQL (squelch) tone frequency
|
|
866
821
|
* @param {number} tone - CTCSS SQL tone frequency in tenths of Hz (e.g., 1000 for 100.0 Hz)
|
|
867
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
822
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
868
823
|
*/
|
|
869
824
|
async setCtcssSql(tone, vfo) {
|
|
870
|
-
if (vfo) {
|
|
825
|
+
if (vfo !== undefined) {
|
|
871
826
|
return this._nativeInstance.setCtcssSql(tone, vfo);
|
|
872
827
|
} else {
|
|
873
828
|
return this._nativeInstance.setCtcssSql(tone);
|
|
@@ -876,11 +831,11 @@ class HamLib extends EventEmitter {
|
|
|
876
831
|
|
|
877
832
|
/**
|
|
878
833
|
* Get current CTCSS SQL tone frequency
|
|
879
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
834
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
880
835
|
* @returns {number} Current CTCSS SQL tone frequency in tenths of Hz
|
|
881
836
|
*/
|
|
882
837
|
async getCtcssSql(vfo) {
|
|
883
|
-
if (vfo) {
|
|
838
|
+
if (vfo !== undefined) {
|
|
884
839
|
return this._nativeInstance.getCtcssSql(vfo);
|
|
885
840
|
} else {
|
|
886
841
|
return this._nativeInstance.getCtcssSql();
|
|
@@ -890,10 +845,10 @@ class HamLib extends EventEmitter {
|
|
|
890
845
|
/**
|
|
891
846
|
* Set DCS SQL (squelch) code
|
|
892
847
|
* @param {number} code - DCS SQL code (e.g., 23, 174, 754)
|
|
893
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
848
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
894
849
|
*/
|
|
895
850
|
async setDcsSql(code, vfo) {
|
|
896
|
-
if (vfo) {
|
|
851
|
+
if (vfo !== undefined) {
|
|
897
852
|
return this._nativeInstance.setDcsSql(code, vfo);
|
|
898
853
|
} else {
|
|
899
854
|
return this._nativeInstance.setDcsSql(code);
|
|
@@ -902,11 +857,11 @@ class HamLib extends EventEmitter {
|
|
|
902
857
|
|
|
903
858
|
/**
|
|
904
859
|
* Get current DCS SQL code
|
|
905
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
860
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
906
861
|
* @returns {number} Current DCS SQL code
|
|
907
862
|
*/
|
|
908
863
|
async getDcsSql(vfo) {
|
|
909
|
-
if (vfo) {
|
|
864
|
+
if (vfo !== undefined) {
|
|
910
865
|
return this._nativeInstance.getDcsSql(vfo);
|
|
911
866
|
} else {
|
|
912
867
|
return this._nativeInstance.getDcsSql();
|
|
@@ -938,10 +893,10 @@ class HamLib extends EventEmitter {
|
|
|
938
893
|
/**
|
|
939
894
|
* Send DTMF digits
|
|
940
895
|
* @param {string} digits - DTMF digits to send (0-9, A-D, *, #)
|
|
941
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
896
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
942
897
|
*/
|
|
943
898
|
async sendDtmf(digits, vfo) {
|
|
944
|
-
if (vfo) {
|
|
899
|
+
if (vfo !== undefined) {
|
|
945
900
|
return this._nativeInstance.sendDtmf(digits, vfo);
|
|
946
901
|
} else {
|
|
947
902
|
return this._nativeInstance.sendDtmf(digits);
|
|
@@ -950,15 +905,15 @@ class HamLib extends EventEmitter {
|
|
|
950
905
|
|
|
951
906
|
/**
|
|
952
907
|
* Receive DTMF digits
|
|
953
|
-
* @param {number}
|
|
954
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
908
|
+
* @param {number} maxLength - Maximum number of digits to receive
|
|
909
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
955
910
|
* @returns {Object} Object containing digits and length
|
|
956
911
|
*/
|
|
957
912
|
async recvDtmf(maxLength, vfo) {
|
|
958
|
-
if (vfo) {
|
|
959
|
-
return this._nativeInstance.recvDtmf(maxLength
|
|
913
|
+
if (vfo !== undefined) {
|
|
914
|
+
return this._nativeInstance.recvDtmf(maxLength, vfo);
|
|
960
915
|
} else {
|
|
961
|
-
return this._nativeInstance.recvDtmf(maxLength
|
|
916
|
+
return this._nativeInstance.recvDtmf(maxLength);
|
|
962
917
|
}
|
|
963
918
|
}
|
|
964
919
|
|
|
@@ -966,11 +921,11 @@ class HamLib extends EventEmitter {
|
|
|
966
921
|
|
|
967
922
|
/**
|
|
968
923
|
* Get current memory channel number
|
|
969
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
924
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
970
925
|
* @returns {number} Current memory channel number
|
|
971
926
|
*/
|
|
972
927
|
async getMem(vfo) {
|
|
973
|
-
if (vfo) {
|
|
928
|
+
if (vfo !== undefined) {
|
|
974
929
|
return this._nativeInstance.getMem(vfo);
|
|
975
930
|
} else {
|
|
976
931
|
return this._nativeInstance.getMem();
|
|
@@ -980,10 +935,10 @@ class HamLib extends EventEmitter {
|
|
|
980
935
|
/**
|
|
981
936
|
* Set memory bank
|
|
982
937
|
* @param {number} bank - Bank number to select
|
|
983
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
938
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
984
939
|
*/
|
|
985
940
|
async setBank(bank, vfo) {
|
|
986
|
-
if (vfo) {
|
|
941
|
+
if (vfo !== undefined) {
|
|
987
942
|
return this._nativeInstance.setBank(bank, vfo);
|
|
988
943
|
} else {
|
|
989
944
|
return this._nativeInstance.setBank(bank);
|
|
@@ -1003,10 +958,10 @@ class HamLib extends EventEmitter {
|
|
|
1003
958
|
/**
|
|
1004
959
|
* Send Morse code message
|
|
1005
960
|
* @param {string} message - Morse code message to send (text will be converted to Morse)
|
|
1006
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
961
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1007
962
|
*/
|
|
1008
963
|
async sendMorse(message, vfo) {
|
|
1009
|
-
if (vfo) {
|
|
964
|
+
if (vfo !== undefined) {
|
|
1010
965
|
return this._nativeInstance.sendMorse(message, vfo);
|
|
1011
966
|
} else {
|
|
1012
967
|
return this._nativeInstance.sendMorse(message);
|
|
@@ -1015,10 +970,10 @@ class HamLib extends EventEmitter {
|
|
|
1015
970
|
|
|
1016
971
|
/**
|
|
1017
972
|
* Stop current Morse code transmission
|
|
1018
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
973
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1019
974
|
*/
|
|
1020
975
|
async stopMorse(vfo) {
|
|
1021
|
-
if (vfo) {
|
|
976
|
+
if (vfo !== undefined) {
|
|
1022
977
|
return this._nativeInstance.stopMorse(vfo);
|
|
1023
978
|
} else {
|
|
1024
979
|
return this._nativeInstance.stopMorse();
|
|
@@ -1027,10 +982,10 @@ class HamLib extends EventEmitter {
|
|
|
1027
982
|
|
|
1028
983
|
/**
|
|
1029
984
|
* Wait for Morse code transmission to complete
|
|
1030
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
985
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1031
986
|
*/
|
|
1032
987
|
async waitMorse(vfo) {
|
|
1033
|
-
if (vfo) {
|
|
988
|
+
if (vfo !== undefined) {
|
|
1034
989
|
return this._nativeInstance.waitMorse(vfo);
|
|
1035
990
|
} else {
|
|
1036
991
|
return this._nativeInstance.waitMorse();
|
|
@@ -1042,10 +997,10 @@ class HamLib extends EventEmitter {
|
|
|
1042
997
|
/**
|
|
1043
998
|
* Play voice memory channel
|
|
1044
999
|
* @param {number} channel - Voice memory channel number to play
|
|
1045
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
1000
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1046
1001
|
*/
|
|
1047
1002
|
async sendVoiceMem(channel, vfo) {
|
|
1048
|
-
if (vfo) {
|
|
1003
|
+
if (vfo !== undefined) {
|
|
1049
1004
|
return this._nativeInstance.sendVoiceMem(channel, vfo);
|
|
1050
1005
|
} else {
|
|
1051
1006
|
return this._nativeInstance.sendVoiceMem(channel);
|
|
@@ -1054,10 +1009,10 @@ class HamLib extends EventEmitter {
|
|
|
1054
1009
|
|
|
1055
1010
|
/**
|
|
1056
1011
|
* Stop voice memory playback
|
|
1057
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
1012
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1058
1013
|
*/
|
|
1059
1014
|
async stopVoiceMem(vfo) {
|
|
1060
|
-
if (vfo) {
|
|
1015
|
+
if (vfo !== undefined) {
|
|
1061
1016
|
return this._nativeInstance.stopVoiceMem(vfo);
|
|
1062
1017
|
} else {
|
|
1063
1018
|
return this._nativeInstance.stopVoiceMem();
|
|
@@ -1071,10 +1026,10 @@ class HamLib extends EventEmitter {
|
|
|
1071
1026
|
* @param {number} txFrequency - TX frequency in Hz
|
|
1072
1027
|
* @param {string} txMode - TX mode ('USB', 'LSB', 'FM', etc.)
|
|
1073
1028
|
* @param {number} txWidth - TX bandwidth in Hz
|
|
1074
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
1029
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1075
1030
|
*/
|
|
1076
1031
|
async setSplitFreqMode(txFrequency, txMode, txWidth, vfo) {
|
|
1077
|
-
if (vfo) {
|
|
1032
|
+
if (vfo !== undefined) {
|
|
1078
1033
|
return this._nativeInstance.setSplitFreqMode(txFrequency, txMode, txWidth, vfo);
|
|
1079
1034
|
} else {
|
|
1080
1035
|
return this._nativeInstance.setSplitFreqMode(txFrequency, txMode, txWidth);
|
|
@@ -1083,11 +1038,11 @@ class HamLib extends EventEmitter {
|
|
|
1083
1038
|
|
|
1084
1039
|
/**
|
|
1085
1040
|
* Get split frequency and mode information
|
|
1086
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
1041
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1087
1042
|
* @returns {Object} Object containing TX frequency, mode, and width
|
|
1088
1043
|
*/
|
|
1089
1044
|
async getSplitFreqMode(vfo) {
|
|
1090
|
-
if (vfo) {
|
|
1045
|
+
if (vfo !== undefined) {
|
|
1091
1046
|
return this._nativeInstance.getSplitFreqMode(vfo);
|
|
1092
1047
|
} else {
|
|
1093
1048
|
return this._nativeInstance.getSplitFreqMode();
|
|
@@ -1099,14 +1054,14 @@ class HamLib extends EventEmitter {
|
|
|
1099
1054
|
/**
|
|
1100
1055
|
* Set antenna selection
|
|
1101
1056
|
* @param {number} antenna - Antenna number to select (1-based)
|
|
1102
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
1057
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1103
1058
|
* @returns {Promise<number>} Success status
|
|
1104
1059
|
* @example
|
|
1105
1060
|
* await rig.setAntenna(1); // Select antenna 1
|
|
1106
1061
|
* await rig.setAntenna(2); // Select antenna 2
|
|
1107
1062
|
*/
|
|
1108
1063
|
async setAntenna(antenna, vfo) {
|
|
1109
|
-
if (vfo) {
|
|
1064
|
+
if (vfo !== undefined) {
|
|
1110
1065
|
return this._nativeInstance.setAntenna(antenna, vfo);
|
|
1111
1066
|
} else {
|
|
1112
1067
|
return this._nativeInstance.setAntenna(antenna);
|
|
@@ -1115,7 +1070,7 @@ class HamLib extends EventEmitter {
|
|
|
1115
1070
|
|
|
1116
1071
|
/**
|
|
1117
1072
|
* Get comprehensive antenna information
|
|
1118
|
-
* @param {string} [vfo] - Optional VFO ('
|
|
1073
|
+
* @param {string} [vfo] - Optional VFO ('VFOA' or 'VFOB')
|
|
1119
1074
|
* @returns {Promise<Object>} Antenna information object containing:
|
|
1120
1075
|
* - currentAntenna: Currently selected antenna
|
|
1121
1076
|
* - txAntenna: TX antenna selection
|
|
@@ -1126,7 +1081,7 @@ class HamLib extends EventEmitter {
|
|
|
1126
1081
|
* console.log(`Current: ${antennaInfo.currentAntenna}, TX: ${antennaInfo.txAntenna}, RX: ${antennaInfo.rxAntenna}`);
|
|
1127
1082
|
*/
|
|
1128
1083
|
async getAntenna(vfo) {
|
|
1129
|
-
if (vfo) {
|
|
1084
|
+
if (vfo !== undefined) {
|
|
1130
1085
|
return this._nativeInstance.getAntenna(vfo);
|
|
1131
1086
|
} else {
|
|
1132
1087
|
return this._nativeInstance.getAntenna();
|
|
@@ -1167,9 +1122,9 @@ class HamLib extends EventEmitter {
|
|
|
1167
1122
|
|
|
1168
1123
|
/**
|
|
1169
1124
|
* Reset radio to default state
|
|
1170
|
-
* @param {string}
|
|
1125
|
+
* @param {string} resetType - Reset type ('NONE', 'SOFT', 'VFO', 'MCALL', 'MASTER')
|
|
1171
1126
|
*/
|
|
1172
|
-
async reset(resetType
|
|
1127
|
+
async reset(resetType) {
|
|
1173
1128
|
return this._nativeInstance.reset(resetType);
|
|
1174
1129
|
}
|
|
1175
1130
|
|
|
@@ -1205,202 +1160,15 @@ class HamLib extends EventEmitter {
|
|
|
1205
1160
|
return this._nativeInstance.getSpectrumCapabilities();
|
|
1206
1161
|
}
|
|
1207
1162
|
|
|
1208
|
-
/**
|
|
1209
|
-
* Summarize whether official Hamlib spectrum streaming is usable for this rig.
|
|
1210
|
-
* @returns {Promise<Object>} Product-oriented support summary.
|
|
1211
|
-
*/
|
|
1212
|
-
async getSpectrumSupportSummary() {
|
|
1213
|
-
const capabilities = await this.getSpectrumCapabilities();
|
|
1214
|
-
const supportedFunctions = this.getSupportedFunctions();
|
|
1215
|
-
const supportedLevels = this.getSupportedLevels();
|
|
1216
|
-
const hasSpectrumFunction = supportedFunctions.includes('SPECTRUM');
|
|
1217
|
-
const hasSpectrumHoldFunction = supportedFunctions.includes('SPECTRUM_HOLD');
|
|
1218
|
-
const hasTransceiveFunction = supportedFunctions.includes('TRANSCEIVE');
|
|
1219
|
-
const asyncDataSupported = capabilities.asyncDataSupported ?? hasSpectrumFunction;
|
|
1220
|
-
const configurableLevels = ['SPECTRUM_MODE', 'SPECTRUM_SPAN', 'SPECTRUM_EDGE_LOW', 'SPECTRUM_EDGE_HIGH', 'SPECTRUM_SPEED', 'SPECTRUM_REF', 'SPECTRUM_AVG']
|
|
1221
|
-
.filter((name) => supportedLevels.includes(name));
|
|
1222
|
-
let supportsEdgeSlotSelection = false;
|
|
1223
|
-
|
|
1224
|
-
try {
|
|
1225
|
-
const edgeSlot = await this.getConf('SPECTRUM_EDGE');
|
|
1226
|
-
supportsEdgeSlotSelection = Number.isFinite(Number.parseInt(String(edgeSlot), 10));
|
|
1227
|
-
} catch (_) {
|
|
1228
|
-
supportsEdgeSlotSelection = false;
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
return {
|
|
1232
|
-
supported: Boolean(hasSpectrumFunction),
|
|
1233
|
-
asyncDataSupported: Boolean(asyncDataSupported),
|
|
1234
|
-
hasSpectrumFunction,
|
|
1235
|
-
hasSpectrumHoldFunction,
|
|
1236
|
-
hasTransceiveFunction,
|
|
1237
|
-
configurableLevels,
|
|
1238
|
-
supportsFixedEdges: configurableLevels.includes('SPECTRUM_EDGE_LOW') && configurableLevels.includes('SPECTRUM_EDGE_HIGH'),
|
|
1239
|
-
supportsEdgeSlotSelection,
|
|
1240
|
-
supportedEdgeSlots: supportsEdgeSlotSelection ? [...DEFAULT_SPECTRUM_EDGE_SLOTS] : [],
|
|
1241
|
-
scopes: capabilities.scopes ?? [],
|
|
1242
|
-
modes: capabilities.modes ?? [],
|
|
1243
|
-
spans: capabilities.spans ?? [],
|
|
1244
|
-
avgModes: capabilities.avgModes ?? [],
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
/**
|
|
1249
|
-
* Apply official Hamlib spectrum settings using high-level level/function APIs.
|
|
1250
|
-
* Unsupported settings are skipped silently.
|
|
1251
|
-
* @param {Object} [config]
|
|
1252
|
-
*/
|
|
1253
|
-
async configureSpectrum(config = {}) {
|
|
1254
|
-
const summary = await this.getSpectrumSupportSummary();
|
|
1255
|
-
const applyLevel = async (name, value) => {
|
|
1256
|
-
if (value === undefined || !summary.configurableLevels.includes(name)) return;
|
|
1257
|
-
await this.setLevel(name, value);
|
|
1258
|
-
};
|
|
1259
|
-
const resolveModeId = async (mode) => {
|
|
1260
|
-
if (mode === undefined || mode === null) return undefined;
|
|
1261
|
-
if (Number.isFinite(mode)) return mode;
|
|
1262
|
-
const requested = normalizeSpectrumModeName(mode);
|
|
1263
|
-
if (!requested) {
|
|
1264
|
-
throw new Error(`Unsupported spectrum mode: ${mode}`);
|
|
1265
|
-
}
|
|
1266
|
-
const matched = (summary.modes ?? []).find((entry) => normalizeSpectrumModeName(entry?.name) === requested);
|
|
1267
|
-
if (!matched) {
|
|
1268
|
-
throw new Error(`Spectrum mode not supported by this backend: ${mode}`);
|
|
1269
|
-
}
|
|
1270
|
-
return matched.id;
|
|
1271
|
-
};
|
|
1272
|
-
|
|
1273
|
-
if (summary.hasSpectrumHoldFunction && config.hold !== undefined) {
|
|
1274
|
-
await this.setFunction('SPECTRUM_HOLD', Boolean(config.hold));
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
if (config.edgeSlot !== undefined && summary.supportsEdgeSlotSelection) {
|
|
1278
|
-
await this.setSpectrumEdgeSlot(config.edgeSlot);
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
await applyLevel('SPECTRUM_MODE', await resolveModeId(config.mode));
|
|
1282
|
-
await applyLevel('SPECTRUM_SPAN', config.spanHz);
|
|
1283
|
-
if (config.edgeLowHz !== undefined || config.edgeHighHz !== undefined) {
|
|
1284
|
-
await this.setSpectrumFixedEdges({
|
|
1285
|
-
lowHz: config.edgeLowHz,
|
|
1286
|
-
highHz: config.edgeHighHz,
|
|
1287
|
-
});
|
|
1288
|
-
}
|
|
1289
|
-
await applyLevel('SPECTRUM_SPEED', config.speed);
|
|
1290
|
-
await applyLevel('SPECTRUM_REF', config.referenceLevel);
|
|
1291
|
-
await applyLevel('SPECTRUM_AVG', config.averageMode);
|
|
1292
|
-
|
|
1293
|
-
return summary;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
async getSpectrumEdgeSlot() {
|
|
1297
|
-
const raw = await this.getConf('SPECTRUM_EDGE');
|
|
1298
|
-
const parsed = Number.parseInt(String(raw), 10);
|
|
1299
|
-
if (!Number.isFinite(parsed)) {
|
|
1300
|
-
throw new Error('Spectrum edge slot is not available');
|
|
1301
|
-
}
|
|
1302
|
-
return parsed;
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
async setSpectrumEdgeSlot(slot) {
|
|
1306
|
-
const parsed = Number.parseInt(String(slot), 10);
|
|
1307
|
-
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
1308
|
-
throw new Error(`Invalid spectrum edge slot: ${slot}`);
|
|
1309
|
-
}
|
|
1310
|
-
await this.setConf('SPECTRUM_EDGE', String(parsed));
|
|
1311
|
-
return parsed;
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
|
-
async getSpectrumSupportedEdgeSlots() {
|
|
1315
|
-
const summary = await this.getSpectrumSupportSummary();
|
|
1316
|
-
return summary.supportedEdgeSlots ?? [];
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
async getSpectrumFixedEdges() {
|
|
1320
|
-
const lineState = this._getLastSpectrumDisplayStateFromLine();
|
|
1321
|
-
if (lineState?.edgeLowHz !== null && lineState?.edgeHighHz !== null) {
|
|
1322
|
-
return { lowHz: lineState.edgeLowHz, highHz: lineState.edgeHighHz };
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
const targetVfo = 'VFO-A';
|
|
1326
|
-
const [lowHz, highHz] = await Promise.all([
|
|
1327
|
-
this.getLevel('SPECTRUM_EDGE_LOW', targetVfo),
|
|
1328
|
-
this.getLevel('SPECTRUM_EDGE_HIGH', targetVfo),
|
|
1329
|
-
]);
|
|
1330
|
-
return { lowHz, highHz };
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
async setSpectrumFixedEdges({ lowHz, highHz }) {
|
|
1334
|
-
if (!Number.isFinite(lowHz) || !Number.isFinite(highHz) || lowHz >= highHz) {
|
|
1335
|
-
throw new Error('Spectrum fixed edge range must satisfy lowHz < highHz');
|
|
1336
|
-
}
|
|
1337
|
-
const targetVfo = 'VFO-A';
|
|
1338
|
-
await this.setLevel('SPECTRUM_EDGE_LOW', lowHz, targetVfo);
|
|
1339
|
-
await this.setLevel('SPECTRUM_EDGE_HIGH', highHz, targetVfo);
|
|
1340
|
-
return { lowHz, highHz };
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
async getSpectrumDisplayState() {
|
|
1344
|
-
const summary = await this.getSpectrumSupportSummary();
|
|
1345
|
-
const lineState = this._getLastSpectrumDisplayStateFromLine();
|
|
1346
|
-
const [queriedModeId, queriedSpanHz, fixedEdges, edgeSlot] = await Promise.all([
|
|
1347
|
-
summary.configurableLevels.includes('SPECTRUM_MODE') ? this.getLevel('SPECTRUM_MODE') : Promise.resolve(null),
|
|
1348
|
-
summary.configurableLevels.includes('SPECTRUM_SPAN') ? this.getLevel('SPECTRUM_SPAN') : Promise.resolve(null),
|
|
1349
|
-
summary.supportsFixedEdges ? this.getSpectrumFixedEdges().catch(() => null) : Promise.resolve(null),
|
|
1350
|
-
summary.supportsEdgeSlotSelection ? this.getSpectrumEdgeSlot().catch(() => null) : Promise.resolve(null),
|
|
1351
|
-
]);
|
|
1352
|
-
|
|
1353
|
-
const modeId = queriedModeId ?? lineState?.modeId ?? null;
|
|
1354
|
-
const spanHz = queriedSpanHz ?? lineState?.spanHz ?? null;
|
|
1355
|
-
const modeInfo = (summary.modes ?? []).find((entry) => entry.id === modeId) ?? null;
|
|
1356
|
-
const mode = normalizeSpectrumModeName(modeInfo?.name);
|
|
1357
|
-
const edgeLowHz = fixedEdges?.lowHz ?? lineState?.edgeLowHz ?? null;
|
|
1358
|
-
const edgeHighHz = fixedEdges?.highHz ?? lineState?.edgeHighHz ?? null;
|
|
1359
|
-
const derivedSpanHz = (edgeLowHz !== null && edgeHighHz !== null) ? (edgeHighHz - edgeLowHz) : null;
|
|
1360
|
-
|
|
1361
|
-
return {
|
|
1362
|
-
mode,
|
|
1363
|
-
modeId,
|
|
1364
|
-
modeName: modeInfo?.name ?? null,
|
|
1365
|
-
spanHz: spanHz ?? derivedSpanHz,
|
|
1366
|
-
edgeSlot,
|
|
1367
|
-
edgeLowHz,
|
|
1368
|
-
edgeHighHz,
|
|
1369
|
-
supportedModes: summary.modes ?? [],
|
|
1370
|
-
supportedSpans: summary.spans ?? [],
|
|
1371
|
-
supportedEdgeSlots: summary.supportedEdgeSlots ?? [],
|
|
1372
|
-
supportsFixedEdges: Boolean(summary.supportsFixedEdges),
|
|
1373
|
-
supportsEdgeSlotSelection: Boolean(summary.supportsEdgeSlotSelection),
|
|
1374
|
-
};
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
async configureSpectrumDisplay(config = {}) {
|
|
1378
|
-
const normalizedConfig = { ...config };
|
|
1379
|
-
if ((normalizedConfig.mode === 'fixed' || normalizedConfig.mode === 'scroll-fixed')
|
|
1380
|
-
&& normalizedConfig.edgeLowHz !== undefined
|
|
1381
|
-
&& normalizedConfig.edgeHighHz !== undefined
|
|
1382
|
-
&& normalizedConfig.edgeLowHz >= normalizedConfig.edgeHighHz) {
|
|
1383
|
-
throw new Error('Spectrum fixed edge range must satisfy edgeLowHz < edgeHighHz');
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
await this.configureSpectrum(normalizedConfig);
|
|
1387
|
-
return this.getSpectrumDisplayState();
|
|
1388
|
-
}
|
|
1389
|
-
|
|
1390
1163
|
/**
|
|
1391
1164
|
* Start the official Hamlib spectrum callback stream.
|
|
1392
1165
|
* @param {(line: Object) => void} [callback]
|
|
1393
1166
|
* @returns {Promise<boolean>}
|
|
1394
1167
|
*/
|
|
1395
1168
|
async startSpectrumStream(callback) {
|
|
1396
|
-
const listener =
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
callback(recorded);
|
|
1400
|
-
return;
|
|
1401
|
-
}
|
|
1402
|
-
this.emit('spectrumLine', recorded);
|
|
1403
|
-
};
|
|
1169
|
+
const listener = typeof callback === 'function'
|
|
1170
|
+
? callback
|
|
1171
|
+
: (line) => this.emit('spectrumLine', line);
|
|
1404
1172
|
return this._nativeInstance.startSpectrumStream(listener);
|
|
1405
1173
|
}
|
|
1406
1174
|
|
|
@@ -1412,76 +1180,6 @@ class HamLib extends EventEmitter {
|
|
|
1412
1180
|
return this._nativeInstance.stopSpectrumStream();
|
|
1413
1181
|
}
|
|
1414
1182
|
|
|
1415
|
-
/**
|
|
1416
|
-
* High-level managed spectrum startup for application use.
|
|
1417
|
-
* @param {Object} [config]
|
|
1418
|
-
*/
|
|
1419
|
-
async startManagedSpectrum(config = {}) {
|
|
1420
|
-
const summary = await this.getSpectrumSupportSummary();
|
|
1421
|
-
if (!summary.supported) {
|
|
1422
|
-
throw new Error('Official Hamlib spectrum streaming is not supported by this rig/backend');
|
|
1423
|
-
}
|
|
1424
|
-
|
|
1425
|
-
if (this._managedSpectrumRunning) {
|
|
1426
|
-
return true;
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
await this.startSpectrumStream((line) => this.emit('spectrumLine', line));
|
|
1430
|
-
|
|
1431
|
-
try {
|
|
1432
|
-
try {
|
|
1433
|
-
await this.setConf('async', '1');
|
|
1434
|
-
} catch (_) {
|
|
1435
|
-
try {
|
|
1436
|
-
await this.setConf('async', 'True');
|
|
1437
|
-
} catch (_) {
|
|
1438
|
-
// Not every backend accepts the config write even if async is supported.
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
|
|
1442
|
-
await this.configureSpectrum({ hold: false, ...config });
|
|
1443
|
-
await this.setFunction('SPECTRUM', true);
|
|
1444
|
-
if (summary.hasTransceiveFunction) {
|
|
1445
|
-
await this.setFunction('TRANSCEIVE', true);
|
|
1446
|
-
}
|
|
1447
|
-
} catch (error) {
|
|
1448
|
-
try {
|
|
1449
|
-
await this.stopManagedSpectrum();
|
|
1450
|
-
} catch (_) {
|
|
1451
|
-
// Ignore cleanup failures and surface the original startup error.
|
|
1452
|
-
}
|
|
1453
|
-
throw error;
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
this._managedSpectrumRunning = true;
|
|
1457
|
-
this.emit('spectrumStateChanged', { active: true });
|
|
1458
|
-
return true;
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
/**
|
|
1462
|
-
* High-level managed spectrum shutdown for application use.
|
|
1463
|
-
*/
|
|
1464
|
-
async stopManagedSpectrum() {
|
|
1465
|
-
try {
|
|
1466
|
-
const supportedFunctions = this.getSupportedFunctions();
|
|
1467
|
-
if (supportedFunctions.includes('TRANSCEIVE')) {
|
|
1468
|
-
await this.setFunction('TRANSCEIVE', false);
|
|
1469
|
-
}
|
|
1470
|
-
if (supportedFunctions.includes('SPECTRUM_HOLD')) {
|
|
1471
|
-
await this.setFunction('SPECTRUM_HOLD', false);
|
|
1472
|
-
}
|
|
1473
|
-
if (supportedFunctions.includes('SPECTRUM')) {
|
|
1474
|
-
await this.setFunction('SPECTRUM', false);
|
|
1475
|
-
}
|
|
1476
|
-
} finally {
|
|
1477
|
-
await this.stopSpectrumStream();
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
this._managedSpectrumRunning = false;
|
|
1481
|
-
this.emit('spectrumStateChanged', { active: false });
|
|
1482
|
-
return true;
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
1183
|
/**
|
|
1486
1184
|
* Set a backend configuration parameter
|
|
1487
1185
|
* @param {string} name - Configuration token name
|
|
@@ -1686,17 +1384,13 @@ class HamLib extends EventEmitter {
|
|
|
1686
1384
|
// VFO Info (Hamlib >= 4.7.0)
|
|
1687
1385
|
|
|
1688
1386
|
async getVfoInfo(vfo) {
|
|
1689
|
-
if (vfo) {
|
|
1387
|
+
if (vfo !== undefined) {
|
|
1690
1388
|
return this._nativeInstance.getVfoInfo(vfo);
|
|
1691
1389
|
}
|
|
1692
1390
|
return this._nativeInstance.getVfoInfo();
|
|
1693
1391
|
}
|
|
1694
1392
|
}
|
|
1695
1393
|
|
|
1696
|
-
// Set debug level to NONE by default to prevent unwanted output
|
|
1697
|
-
// Users can change this using HamLib.setDebugLevel() if needed
|
|
1698
|
-
HamLib.setDebugLevel(0);
|
|
1699
|
-
|
|
1700
1394
|
// Export for CommonJS
|
|
1701
1395
|
module.exports = { HamLib };
|
|
1702
1396
|
module.exports.HamLib = HamLib;
|