icom-wlan-node 0.6.2 → 0.6.3
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 +19 -0
- package/dist/rig/IcomCivSpec.d.ts +1 -0
- package/dist/rig/IcomCivSpec.js +1 -0
- package/dist/rig/IcomControl.d.ts +12 -1
- package/dist/rig/IcomControl.js +96 -0
- package/dist/rig/IcomProfiles.d.ts +4 -0
- package/dist/rig/IcomProfiles.js +8 -0
- package/dist/rig/IcomRigCommands.d.ts +2 -0
- package/dist/rig/IcomRigCommands.js +7 -0
- package/dist/types.d.ts +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,8 @@ await rig.setSplitEnabled(true);
|
|
|
132
132
|
await rig.setSplitFrequency(7074000);
|
|
133
133
|
await rig.setTuningStep(100);
|
|
134
134
|
await rig.setToneFrequency(88.5);
|
|
135
|
+
await rig.setMode('CW');
|
|
136
|
+
await rig.sendMorse('CQ CQ DE N0CALL');
|
|
135
137
|
await rig.setSpectrumSpeed('slow');
|
|
136
138
|
```
|
|
137
139
|
|
|
@@ -235,6 +237,7 @@ await rig.disableScope();
|
|
|
235
237
|
- **Antenna Tuner**: `readTunerStatus()`, `setTunerEnabled()`, `startManualTune()`
|
|
236
238
|
- **Functions**: `getFunction()`, `setFunction()`, plus wrappers for NB/NR/COMP/VOX/MON/ANF/MN/LOCK/BK-IN
|
|
237
239
|
- **Levels**: `getLevel()`, `setLevel()`, plus wrappers for RF gain, IF shift, PBT, CW pitch, key speed, monitor gain, VOX gain
|
|
240
|
+
- **CW Text**: `sendMorse()`, `sendCwText()`, `stopMorse()` — Hamlib-aligned CI-V `0x17` text handoff to the rig keyer
|
|
238
241
|
- **RIT/XIT + Split/VFO**: `getRitOffset()`, `setRitOffset()`, `getSplitEnabled()`, `setSplitFrequency()`, `getVfo()`, `setVfo()`, `vfoOperation()`
|
|
239
242
|
- **Tone/Tuning**: `getTuningStep()`, `setTuningStep()`, `getToneFrequency()`, `setToneFrequency()`, `getRepeaterShift()`, `setRepeaterOffset()`
|
|
240
243
|
- **Meters (RX)**: `readSquelchStatus()`, `readAudioSquelch()`, `readOvfStatus()`, `getLevelMeter()`
|
|
@@ -384,6 +387,8 @@ The library exposes common CI‑V operations as friendly methods. Addresses are
|
|
|
384
387
|
- `getBreakInMode() => Promise<'off'|'semi'|'full'|null>` / `setBreakInMode(mode)` — Hamlib-aligned BK-IN control using `0x16 0x47`, where raw `1` is semi and raw `2` is full.
|
|
385
388
|
- `getLevel(name: IcomLevelName, options?: QueryOptions) => Promise<number|null>` / `setLevel(name, value)` — Generic level layer for `AF`, `RF`, `SQL`, `IF`, `PBT_IN`, `PBT_OUT`, `CWPITCH`, `KEYSPD`, `NOTCHF_RAW`, `COMP`, `MONITOR_GAIN`, `VOXGAIN`, `ANTIVOX`, and profile ext levels.
|
|
386
389
|
- Common level wrappers: `getRFGain()/setRFGain()`, `getIFShift()/setIFShift()`, `getPbtIn()/setPbtIn()`, `getPbtOut()/setPbtOut()`, `getCwPitch()/setCwPitch()`, `getKeySpeed()/setKeySpeed()`, `getNotchRaw()/setNotchRaw()`, `getCompressionLevel()/setCompressionLevel()`, `getMonitorGain()/setMonitorGain()`, `getVoxGain()/setVoxGain()`, `getAntiVox()/setAntiVox()`.
|
|
390
|
+
- `sendMorse(text, options?)` / `sendCwText(text, options?)` — Send printable ASCII text through the rig's internal CW keyer using CI-V `0x17`; text is uppercased and split into 30-byte chunks by default.
|
|
391
|
+
- `stopMorse(options?)` — Stop the rig CW keyer by sending CI-V `0x17 0xff` and waiting for ACK.
|
|
387
392
|
- `getRitOffset()/setRitOffset()` and `getXitOffset()/setXitOffset()` — RIT/XIT delta register using Hamlib `0x21 0x00`; `getRitEnabled()/setRitEnabled()` and `getXitEnabled()/setXitEnabled()` use `0x21 0x01/0x02`.
|
|
388
393
|
- `getSplitEnabled()/setSplitEnabled()`, `getSplitFrequency()/setSplitFrequency()`, `getSplitMode()/setSplitMode()` — Modern profiles use targetable TX VFO `0x25/0x26` with VFO number `1`.
|
|
389
394
|
- `getVfo()/setVfo()` and `vfoOperation('copy'|'exchange'|'from-vfo'|'to-vfo'|'memory-clear'|'tune')` — Safe Hamlib VFO operation subset.
|
|
@@ -391,6 +396,20 @@ The library exposes common CI‑V operations as friendly methods. Addresses are
|
|
|
391
396
|
- `getToneFrequency()/setToneFrequency(hz)` and `getToneSquelchFrequency()/setToneSquelchFrequency(hz)` — CTCSS values use public Hz, encoded as tenth-Hz BCD BE.
|
|
392
397
|
- `getRepeaterShift()/setRepeaterShift('none'|'minus'|'plus')` and `getRepeaterOffset()/setRepeaterOffset(hz)` — Repeater offset uses public Hz, encoded as 100 Hz units.
|
|
393
398
|
|
|
399
|
+
#### CW Text Sending
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
await rig.setMode('CW');
|
|
403
|
+
rig.setBreakInMode('semi');
|
|
404
|
+
rig.setKeySpeed(20);
|
|
405
|
+
|
|
406
|
+
// Sends printable ASCII text to the radio's built-in CW keyer via CI-V 0x17.
|
|
407
|
+
await rig.sendMorse('CQ CQ DE N0CALL', { timeout: 3000 });
|
|
408
|
+
await rig.stopMorse();
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
`sendMorse()` does not synthesize local Morse audio and does not automatically change mode, PTT, power, or break-in settings. By default it first verifies that the radio reports `CW` or `CW_R`; pass `{ checkMode: false }` only when your application already controls that state. CI-V ACK/NAK replies do not include request IDs, so avoid mixing raw `sendCiv()` write commands that also expect ACKs while a CW text send is in progress.
|
|
412
|
+
|
|
394
413
|
#### Scope / Spectrum
|
|
395
414
|
|
|
396
415
|
- `scope: IcomScopeService` — Standalone scope service object that can be reused with other CI‑V transport paths in the future
|
package/dist/rig/IcomCivSpec.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IcomRigOptions, RigEventEmitter, IcomMode, ConnectorDataMode, SetModeOptions, QueryOptions, SwrReading, AlcReading, WlanLevelReading, LevelMeterReading, SquelchStatusReading, AudioSquelchReading, OvfStatusReading, PowerLevelReading, CompLevelReading, VoltageReading, CurrentReading, ConnectionState, ConnectionMonitorConfig, ConnectionPhase, ConnectionMetrics, DisconnectReason, DisconnectOptions, TunerStatusReading, LevelReading, IcomScopeSpanInfo, IcomScopeMode, IcomScopeModeInfo, IcomScopeEdgeInfo, IcomScopeFixedEdgeInfo, IcomSpectrumDisplayState, IcomSpectrumDisplayConfig, IcomFunctionName, IcomLevelName, IcomParameterName, IcomVfoName, IcomVfoOperation, IcomRepeaterShift, IcomSpectrumSpeed, IcomSpectrumCenterType, IcomAudioIfSource } from '../types';
|
|
1
|
+
import { IcomRigOptions, RigEventEmitter, IcomMode, ConnectorDataMode, SetModeOptions, SendMorseOptions, QueryOptions, SwrReading, AlcReading, WlanLevelReading, LevelMeterReading, SquelchStatusReading, AudioSquelchReading, OvfStatusReading, PowerLevelReading, CompLevelReading, VoltageReading, CurrentReading, ConnectionState, ConnectionMonitorConfig, ConnectionPhase, ConnectionMetrics, DisconnectReason, DisconnectOptions, TunerStatusReading, LevelReading, IcomScopeSpanInfo, IcomScopeMode, IcomScopeModeInfo, IcomScopeEdgeInfo, IcomScopeFixedEdgeInfo, IcomSpectrumDisplayState, IcomSpectrumDisplayConfig, IcomFunctionName, IcomLevelName, IcomParameterName, IcomVfoName, IcomVfoOperation, IcomRepeaterShift, IcomSpectrumSpeed, IcomSpectrumCenterType, IcomAudioIfSource } from '../types';
|
|
2
2
|
import { IcomCiv } from './IcomCiv';
|
|
3
3
|
import { IcomAudio } from './IcomAudio';
|
|
4
4
|
import { IcomScopeService } from '../scope/IcomScopeService';
|
|
@@ -20,6 +20,8 @@ export declare class IcomControl {
|
|
|
20
20
|
private meterTimer?;
|
|
21
21
|
private activeProfile;
|
|
22
22
|
private lastFilter;
|
|
23
|
+
private cwQueue;
|
|
24
|
+
private cwGeneration;
|
|
23
25
|
private connectionSession;
|
|
24
26
|
private nextSessionId;
|
|
25
27
|
private abortHandlers;
|
|
@@ -433,6 +435,11 @@ export declare class IcomControl {
|
|
|
433
435
|
setCwPitch(hz: number): void;
|
|
434
436
|
getKeySpeed(options?: QueryOptions): Promise<number | null>;
|
|
435
437
|
setKeySpeed(wpm: number): void;
|
|
438
|
+
sendMorse(text: string, options?: SendMorseOptions): Promise<void>;
|
|
439
|
+
sendCwText(text: string, options?: SendMorseOptions): Promise<void>;
|
|
440
|
+
stopMorse(options?: {
|
|
441
|
+
timeout?: number;
|
|
442
|
+
}): Promise<void>;
|
|
436
443
|
getNotchRaw(options?: QueryOptions): Promise<number | null>;
|
|
437
444
|
setNotchRaw(value: number): void;
|
|
438
445
|
getCompressionLevel(options?: QueryOptions): Promise<number | null>;
|
|
@@ -525,6 +532,8 @@ export declare class IcomControl {
|
|
|
525
532
|
getSpectrumCenterType(options?: QueryOptions): Promise<IcomSpectrumCenterType | null>;
|
|
526
533
|
setSpectrumCenterType(type: IcomSpectrumCenterType): void;
|
|
527
534
|
private unsupported;
|
|
535
|
+
private enqueueCw;
|
|
536
|
+
private sendCwFrameAndWaitForAck;
|
|
528
537
|
private readFunctionRaw;
|
|
529
538
|
private writeFunctionRaw;
|
|
530
539
|
private readLevelRaw;
|
|
@@ -554,6 +563,8 @@ export declare class IcomControl {
|
|
|
554
563
|
private static extractTrailingBcd;
|
|
555
564
|
private static matchCommand;
|
|
556
565
|
private static matchCommandFrame;
|
|
566
|
+
private static matchAckNakFrame;
|
|
567
|
+
private static normalizeMorseText;
|
|
557
568
|
private waitForCiv;
|
|
558
569
|
static parseFrequencyReply(frame: Buffer, payloadOffsetAfterCommand: number, byteLength?: number): number | null;
|
|
559
570
|
static parseIcomFreqFromReply(frame: Buffer): number | null;
|
package/dist/rig/IcomControl.js
CHANGED
|
@@ -150,6 +150,8 @@ class IcomControl {
|
|
|
150
150
|
this.civAssembleBuf = Buffer.alloc(0); // CIV stream reassembler
|
|
151
151
|
this.activeProfile = (0, IcomProfiles_1.getProfileByModel)('generic-modern-icom');
|
|
152
152
|
this.lastFilter = 1;
|
|
153
|
+
this.cwQueue = Promise.resolve();
|
|
154
|
+
this.cwGeneration = 0;
|
|
153
155
|
// Connection state machine (replaces old fragmented state flags)
|
|
154
156
|
this.connectionSession = {
|
|
155
157
|
phase: types_1.ConnectionPhase.IDLE,
|
|
@@ -1605,6 +1607,61 @@ class IcomControl {
|
|
|
1605
1607
|
setCwPitch(hz) { this.setLevel('CWPITCH', hz); }
|
|
1606
1608
|
async getKeySpeed(options) { return this.getLevel('KEYSPD', options); }
|
|
1607
1609
|
setKeySpeed(wpm) { this.setLevel('KEYSPD', wpm); }
|
|
1610
|
+
async sendMorse(text, options = {}) {
|
|
1611
|
+
const normalized = IcomControl.normalizeMorseText(text);
|
|
1612
|
+
if (normalized.length === 0)
|
|
1613
|
+
return;
|
|
1614
|
+
const generation = this.cwGeneration;
|
|
1615
|
+
return this.enqueueCw(async () => {
|
|
1616
|
+
if (generation !== this.cwGeneration)
|
|
1617
|
+
return;
|
|
1618
|
+
if (!this.activeProfile.cw.sendMorse) {
|
|
1619
|
+
throw this.unsupported('SEND_MORSE', 'sendMorse', 'CW text sending is not enabled for active profile');
|
|
1620
|
+
}
|
|
1621
|
+
const timeoutMs = options.timeout ?? 3000;
|
|
1622
|
+
if (options.checkMode !== false) {
|
|
1623
|
+
const mode = await this.readOperatingMode({ timeout: timeoutMs });
|
|
1624
|
+
if (!mode || (mode.mode !== IcomConstants_1.MODE_MAP.CW && mode.mode !== IcomConstants_1.MODE_MAP.CW_R)) {
|
|
1625
|
+
throw new Error(`CW 0x17 sendMorse requires CW/CW_R mode; current mode is ${mode?.modeName ?? mode?.mode ?? 'unknown'}`);
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
const profileMax = Math.max(1, Math.min(30, this.activeProfile.cw.maxChunkLength || 30));
|
|
1629
|
+
const requested = Number.isFinite(options.chunkLength) ? Math.floor(options.chunkLength) : profileMax;
|
|
1630
|
+
const chunkLength = Math.max(1, Math.min(30, profileMax, requested));
|
|
1631
|
+
const interChunkDelayMs = Number.isFinite(options.interChunkDelayMs)
|
|
1632
|
+
? Math.max(0, Math.floor(options.interChunkDelayMs))
|
|
1633
|
+
: 0;
|
|
1634
|
+
const bytes = Buffer.from(normalized, 'ascii');
|
|
1635
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1636
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1637
|
+
for (let offset = 0, chunkIndex = 1; offset < bytes.length; offset += chunkLength, chunkIndex++) {
|
|
1638
|
+
if (generation !== this.cwGeneration)
|
|
1639
|
+
return;
|
|
1640
|
+
const chunk = bytes.subarray(offset, Math.min(offset + chunkLength, bytes.length));
|
|
1641
|
+
const frame = IcomRigCommands_1.IcomRigCommands.sendMorseText(ctrAddr, rigAddr, chunk);
|
|
1642
|
+
await this.sendCwFrameAndWaitForAck(frame, timeoutMs, `chunk ${chunkIndex}`);
|
|
1643
|
+
if (generation !== this.cwGeneration)
|
|
1644
|
+
return;
|
|
1645
|
+
if (interChunkDelayMs > 0 && offset + chunkLength < bytes.length) {
|
|
1646
|
+
await new Promise((resolve) => setTimeout(resolve, interChunkDelayMs));
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
sendCwText(text, options) {
|
|
1652
|
+
return this.sendMorse(text, options);
|
|
1653
|
+
}
|
|
1654
|
+
async stopMorse(options = {}) {
|
|
1655
|
+
this.cwGeneration += 1;
|
|
1656
|
+
return this.enqueueCw(async () => {
|
|
1657
|
+
if (!this.activeProfile.cw.sendMorse) {
|
|
1658
|
+
throw this.unsupported('SEND_MORSE', 'stopMorse', 'CW text sending is not enabled for active profile');
|
|
1659
|
+
}
|
|
1660
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1661
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1662
|
+
await this.sendCwFrameAndWaitForAck(IcomRigCommands_1.IcomRigCommands.stopMorse(ctrAddr, rigAddr), options.timeout ?? 3000, 'stop');
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1608
1665
|
async getNotchRaw(options) { return this.getLevel('NOTCHF_RAW', options); }
|
|
1609
1666
|
setNotchRaw(value) { this.setLevel('NOTCHF_RAW', value); }
|
|
1610
1667
|
async getCompressionLevel(options) { return this.getLevel('COMP', options); }
|
|
@@ -1885,6 +1942,22 @@ class IcomControl {
|
|
|
1885
1942
|
reason,
|
|
1886
1943
|
});
|
|
1887
1944
|
}
|
|
1945
|
+
enqueueCw(operation) {
|
|
1946
|
+
const run = this.cwQueue.then(operation, operation);
|
|
1947
|
+
this.cwQueue = run.then(() => undefined, () => undefined);
|
|
1948
|
+
return run;
|
|
1949
|
+
}
|
|
1950
|
+
async sendCwFrameAndWaitForAck(frame, timeoutMs, label) {
|
|
1951
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
1952
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
1953
|
+
const resp = await this.waitForCivFrame('cw:ack:0x17', (candidate) => IcomControl.matchAckNakFrame(candidate, ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(frame));
|
|
1954
|
+
if (!resp) {
|
|
1955
|
+
throw new Error(`CW 0x17 ${label} ACK timeout`);
|
|
1956
|
+
}
|
|
1957
|
+
if (resp[4] === IcomCivSpec_1.CIV.NAK) {
|
|
1958
|
+
throw new Error(`CW 0x17 ${label} NAK received`);
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1888
1961
|
async readFunctionRaw(name, spec, options) {
|
|
1889
1962
|
const timeoutMs = options?.timeout ?? 3000;
|
|
1890
1963
|
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
@@ -2124,6 +2197,29 @@ class IcomControl {
|
|
|
2124
2197
|
return false;
|
|
2125
2198
|
return true;
|
|
2126
2199
|
}
|
|
2200
|
+
static matchAckNakFrame(frame, ctrAddr, rigAddr) {
|
|
2201
|
+
if (!(frame.length >= 6 && frame[0] === IcomCivSpec_1.CIV.PR && frame[1] === IcomCivSpec_1.CIV.PR))
|
|
2202
|
+
return false;
|
|
2203
|
+
const addrCtrOk = frame[2] === (ctrAddr & 0xff) || frame[2] === 0x00;
|
|
2204
|
+
if (!addrCtrOk || frame[3] !== (rigAddr & 0xff))
|
|
2205
|
+
return false;
|
|
2206
|
+
if (frame[4] !== IcomCivSpec_1.CIV.ACK && frame[4] !== IcomCivSpec_1.CIV.NAK)
|
|
2207
|
+
return false;
|
|
2208
|
+
return frame[frame.length - 1] === IcomCivSpec_1.CIV.FI;
|
|
2209
|
+
}
|
|
2210
|
+
static normalizeMorseText(text) {
|
|
2211
|
+
if (typeof text !== 'string') {
|
|
2212
|
+
throw new Error('CW 0x17 sendMorse text must be a string');
|
|
2213
|
+
}
|
|
2214
|
+
const normalized = text.toUpperCase().replace(/[\r\n\t]/g, ' ');
|
|
2215
|
+
for (let i = 0; i < normalized.length; i++) {
|
|
2216
|
+
const code = normalized.charCodeAt(i);
|
|
2217
|
+
if (code < 0x20 || code > 0x7e) {
|
|
2218
|
+
throw new Error(`CW 0x17 sendMorse text contains unsupported non-printable or non-ASCII character at index ${i}`);
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
return normalized;
|
|
2222
|
+
}
|
|
2127
2223
|
async waitForCiv(predicate, timeoutMs, onSend) {
|
|
2128
2224
|
return new Promise((resolve) => {
|
|
2129
2225
|
let done = false;
|
|
@@ -41,6 +41,10 @@ export interface IcomProfile {
|
|
|
41
41
|
vfos: IcomVfoName[];
|
|
42
42
|
repeater: boolean;
|
|
43
43
|
tone: boolean;
|
|
44
|
+
cw: {
|
|
45
|
+
sendMorse: boolean;
|
|
46
|
+
maxChunkLength: number;
|
|
47
|
+
};
|
|
44
48
|
spectrumAdvanced: Array<'dataOutput' | 'hold' | 'speed' | 'ref' | 'avg' | 'vbw' | 'rbw' | 'duringTx' | 'centerType'>;
|
|
45
49
|
audioIfSources: IcomAudioIfSource[];
|
|
46
50
|
calibrations: {
|
package/dist/rig/IcomProfiles.js
CHANGED
|
@@ -115,6 +115,7 @@ const TARGETABLE_VFOS = ['A', 'B', 'MAIN', 'SUB', 'MAIN_A', 'MAIN_B', 'SUB_A', '
|
|
|
115
115
|
const COMMON_VFO_OPS = ['copy', 'exchange', 'from-vfo', 'to-vfo', 'memory-clear', 'tune'];
|
|
116
116
|
const IC905_VFO_OPS = ['copy', 'from-vfo', 'to-vfo', 'memory-clear', 'tune'];
|
|
117
117
|
const SPECTRUM_ADVANCED = ['dataOutput', 'hold', 'speed', 'ref', 'avg', 'vbw', 'rbw', 'duringTx', 'centerType'];
|
|
118
|
+
const CW_TEXT_SUPPORTED = { sendMorse: true, maxChunkLength: 30 };
|
|
118
119
|
const TS_IC756PRO = [
|
|
119
120
|
{ hz: 10, code: 0x00 },
|
|
120
121
|
{ hz: 100, code: 0x01 },
|
|
@@ -180,6 +181,7 @@ function baseProfile(overrides) {
|
|
|
180
181
|
vfos: DEFAULT_VFOS,
|
|
181
182
|
repeater: false,
|
|
182
183
|
tone: false,
|
|
184
|
+
cw: { sendMorse: false, maxChunkLength: 30 },
|
|
183
185
|
spectrumAdvanced: ['dataOutput', 'hold', 'speed', 'ref', 'vbw', 'duringTx', 'centerType'],
|
|
184
186
|
audioIfSources: ['default'],
|
|
185
187
|
calibrations: {
|
|
@@ -289,6 +291,7 @@ exports.ICOM_PROFILES = {
|
|
|
289
291
|
vfos: DEFAULT_VFOS,
|
|
290
292
|
repeater: true,
|
|
291
293
|
tone: true,
|
|
294
|
+
cw: CW_TEXT_SUPPORTED,
|
|
292
295
|
spectrumAdvanced: ['dataOutput', 'hold', 'speed', 'ref', 'avg', 'vbw', 'duringTx', 'centerType'],
|
|
293
296
|
audioIfSources: ['default', 'wlan'],
|
|
294
297
|
calibrations: {
|
|
@@ -319,6 +322,7 @@ exports.ICOM_PROFILES = {
|
|
|
319
322
|
vfos: DEFAULT_VFOS,
|
|
320
323
|
repeater: true,
|
|
321
324
|
tone: true,
|
|
325
|
+
cw: CW_TEXT_SUPPORTED,
|
|
322
326
|
spectrumAdvanced: ['dataOutput', 'hold', 'speed', 'ref', 'avg', 'vbw', 'duringTx', 'centerType'],
|
|
323
327
|
audioIfSources: ['default', 'wlan'],
|
|
324
328
|
calibrations: {
|
|
@@ -348,6 +352,7 @@ exports.ICOM_PROFILES = {
|
|
|
348
352
|
vfos: DEFAULT_VFOS,
|
|
349
353
|
repeater: false,
|
|
350
354
|
tone: true,
|
|
355
|
+
cw: CW_TEXT_SUPPORTED,
|
|
351
356
|
spectrumAdvanced: ['dataOutput', 'hold', 'speed', 'ref', 'avg', 'vbw', 'duringTx', 'centerType'],
|
|
352
357
|
audioIfSources: ['default'],
|
|
353
358
|
extParams: {
|
|
@@ -374,6 +379,7 @@ exports.ICOM_PROFILES = {
|
|
|
374
379
|
vfos: TARGETABLE_VFOS,
|
|
375
380
|
repeater: true,
|
|
376
381
|
tone: true,
|
|
382
|
+
cw: CW_TEXT_SUPPORTED,
|
|
377
383
|
spectrumAdvanced: ['dataOutput', 'hold', 'speed', 'ref', 'avg', 'vbw', 'duringTx', 'centerType'],
|
|
378
384
|
audioIfSources: ['default', 'lan', 'acc'],
|
|
379
385
|
extParams: {
|
|
@@ -396,6 +402,7 @@ exports.ICOM_PROFILES = {
|
|
|
396
402
|
vfos: TARGETABLE_VFOS,
|
|
397
403
|
repeater: false,
|
|
398
404
|
tone: true,
|
|
405
|
+
cw: CW_TEXT_SUPPORTED,
|
|
399
406
|
spectrumAdvanced: SPECTRUM_ADVANCED,
|
|
400
407
|
audioIfSources: ['default'],
|
|
401
408
|
extParams: {
|
|
@@ -426,6 +433,7 @@ exports.ICOM_PROFILES = {
|
|
|
426
433
|
vfos: DEFAULT_VFOS,
|
|
427
434
|
repeater: false,
|
|
428
435
|
tone: true,
|
|
436
|
+
cw: CW_TEXT_SUPPORTED,
|
|
429
437
|
spectrumAdvanced: [],
|
|
430
438
|
extParamSpecs: {
|
|
431
439
|
...IC7760_EXT_SPECS,
|
|
@@ -34,6 +34,8 @@ export declare const IcomRigCommands: {
|
|
|
34
34
|
writeCommand(ctrAddr: number, rigAddr: number, cmd: number, subcmd: number | number[] | undefined, payload?: number[] | Buffer): Buffer;
|
|
35
35
|
readFunction(ctrAddr: number, rigAddr: number, subcmd: number, payload?: number[] | Buffer): Buffer;
|
|
36
36
|
setFunction(ctrAddr: number, rigAddr: number, subcmd: number, value: number, payloadPrefix?: number[]): Buffer;
|
|
37
|
+
sendMorseText(ctrAddr: number, rigAddr: number, textBytes: Buffer | number[] | string): Buffer;
|
|
38
|
+
stopMorse(ctrAddr: number, rigAddr: number): Buffer;
|
|
37
39
|
readExtParam(ctrAddr: number, rigAddr: number, command: number, subcmd: number, subext?: number[]): Buffer;
|
|
38
40
|
writeExtParam(ctrAddr: number, rigAddr: number, command: number, subcmd: number, subext?: number[], payload?: number[] | Buffer): Buffer;
|
|
39
41
|
readRitOffset(ctrAddr: number, rigAddr: number): Buffer;
|
|
@@ -116,6 +116,13 @@ exports.IcomRigCommands = {
|
|
|
116
116
|
setFunction(ctrAddr, rigAddr, subcmd, value, payloadPrefix = []) {
|
|
117
117
|
return (0, IcomCivFrame_1.buildCivFrame)({ rigAddr, ctrlAddr: ctrAddr, cmd: IcomCivSpec_1.CIV.C_CTL_FUNC, subcmd, payload: [...payloadPrefix, value & 0xff] });
|
|
118
118
|
},
|
|
119
|
+
sendMorseText(ctrAddr, rigAddr, textBytes) {
|
|
120
|
+
const payload = typeof textBytes === 'string' ? Buffer.from(textBytes, 'ascii') : textBytes;
|
|
121
|
+
return (0, IcomCivFrame_1.buildCivFrame)({ rigAddr, ctrlAddr: ctrAddr, cmd: IcomCivSpec_1.CIV.C_SND_CW, payload });
|
|
122
|
+
},
|
|
123
|
+
stopMorse(ctrAddr, rigAddr) {
|
|
124
|
+
return (0, IcomCivFrame_1.buildCivFrame)({ rigAddr, ctrlAddr: ctrAddr, cmd: IcomCivSpec_1.CIV.C_SND_CW, payload: [0xff] });
|
|
125
|
+
},
|
|
119
126
|
readExtParam(ctrAddr, rigAddr, command, subcmd, subext = []) {
|
|
120
127
|
return (0, IcomCivFrame_1.buildCivFrame)({ rigAddr, ctrlAddr: ctrAddr, cmd: command, subcmd, payload: subext });
|
|
121
128
|
},
|
package/dist/types.d.ts
CHANGED
|
@@ -91,6 +91,16 @@ export interface SetModeOptions {
|
|
|
91
91
|
/** Optional IF filter preset. Modern DSP rigs commonly support 1, 2, or 3. */
|
|
92
92
|
filter?: 1 | 2 | 3;
|
|
93
93
|
}
|
|
94
|
+
export interface SendMorseOptions {
|
|
95
|
+
/** ACK/NAK timeout per CI-V 0x17 chunk. Defaults to 3000 ms. */
|
|
96
|
+
timeout?: number;
|
|
97
|
+
/** Maximum text bytes per CI-V 0x17 chunk. Defaults to the active profile limit. */
|
|
98
|
+
chunkLength?: number;
|
|
99
|
+
/** Read and require CW/CW_R mode before sending. Defaults to true. */
|
|
100
|
+
checkMode?: boolean;
|
|
101
|
+
/** Optional delay between acknowledged chunks. Defaults to 0 ms. */
|
|
102
|
+
interChunkDelayMs?: number;
|
|
103
|
+
}
|
|
94
104
|
/**
|
|
95
105
|
* Options for query operations (frequency, meters, etc.)
|
|
96
106
|
*/
|