icom-wlan-node 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -306,6 +306,8 @@ The library exposes common CI‑V operations as friendly methods. Addresses are
|
|
|
306
306
|
- `scope: IcomScopeService` — Standalone scope service object that can be reused with other CI‑V transport paths in the future
|
|
307
307
|
- `enableScope() => Promise<void>` — Send the minimal command sequence to enable basic scope output
|
|
308
308
|
- `disableScope() => Promise<void>` — Send the minimal command sequence to disable scope output
|
|
309
|
+
- `readScopeSpan(options?: QueryOptions & { receiver?: 0 | 1 }) => Promise<{ receiver: 0 | 1; spanHz: number } | null>` — Read current scope span
|
|
310
|
+
- `setScopeSpan(spanHz: number, options?: { receiver?: 0 | 1 }) => Promise<void>` — Set scope span using CI‑V `0x27 0x15`
|
|
309
311
|
- `waitForScopeFrame(options?: QueryOptions) => Promise<IcomScopeFrame | null>` — Wait for the next complete scope frame
|
|
310
312
|
|
|
311
313
|
`IcomScopeFrame` shape:
|
|
@@ -328,7 +330,7 @@ interface IcomScopeFrame {
|
|
|
328
330
|
|
|
329
331
|
Current implementation notes:
|
|
330
332
|
|
|
331
|
-
- Currently implements
|
|
333
|
+
- Currently implements basic on/off controls, `0x27 0x15` span read/write, and `0x27 00 00` scope data capture
|
|
332
334
|
- The parsing layer is decoupled from the UDP session layer and only depends on complete CI‑V frames
|
|
333
335
|
- Frequency fields are currently parsed with `freqLen=5` by default
|
|
334
336
|
- LAN aggregate waterfall payload splitting is not implemented yet; standard segment input is supported
|
|
@@ -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 } from '../types';
|
|
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 } from '../types';
|
|
2
2
|
import { IcomCiv } from './IcomCiv';
|
|
3
3
|
import { IcomAudio } from './IcomAudio';
|
|
4
4
|
import { IcomScopeService } from '../scope/IcomScopeService';
|
|
@@ -77,6 +77,12 @@ export declare class IcomControl {
|
|
|
77
77
|
sendCiv(data: Buffer): void;
|
|
78
78
|
enableScope(): Promise<void>;
|
|
79
79
|
disableScope(): Promise<void>;
|
|
80
|
+
readScopeSpan(options?: QueryOptions & {
|
|
81
|
+
receiver?: 0 | 1;
|
|
82
|
+
}): Promise<IcomScopeSpanInfo | null>;
|
|
83
|
+
setScopeSpan(spanHz: number, options?: {
|
|
84
|
+
receiver?: 0 | 1;
|
|
85
|
+
}): Promise<void>;
|
|
80
86
|
waitForScopeFrame(options?: QueryOptions): Promise<import("../types").IcomScopeFrame | null>;
|
|
81
87
|
/**
|
|
82
88
|
* Set PTT (Push-To-Talk) state
|
package/dist/rig/IcomControl.js
CHANGED
|
@@ -47,6 +47,7 @@ const bcd_1 = require("../utils/bcd");
|
|
|
47
47
|
const errors_1 = require("../utils/errors");
|
|
48
48
|
const smeter_1 = require("../utils/smeter");
|
|
49
49
|
const IcomScopeCommands_1 = require("../scope/IcomScopeCommands");
|
|
50
|
+
const IcomScopeParser_1 = require("../scope/IcomScopeParser");
|
|
50
51
|
const IcomScopeService_1 = require("../scope/IcomScopeService");
|
|
51
52
|
class IcomControl {
|
|
52
53
|
constructor(options) {
|
|
@@ -527,6 +528,28 @@ class IcomControl {
|
|
|
527
528
|
this.sendCiv(IcomScopeCommands_1.IcomScopeCommands.setScopeDataOutput(ctrAddr, rigAddr, false));
|
|
528
529
|
this.sendCiv(IcomScopeCommands_1.IcomScopeCommands.setScopeDisplay(ctrAddr, rigAddr, false));
|
|
529
530
|
}
|
|
531
|
+
async readScopeSpan(options) {
|
|
532
|
+
const timeoutMs = options?.timeout ?? 3000;
|
|
533
|
+
const receiver = options?.receiver ?? 0;
|
|
534
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
535
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
536
|
+
const req = IcomScopeCommands_1.IcomScopeCommands.readScopeSpan(ctrAddr, rigAddr, receiver);
|
|
537
|
+
const resp = await this.waitForCivFrame((frame) => IcomControl.matchCommandFrame(frame, 0x27, [0x15, receiver], ctrAddr, rigAddr), timeoutMs, () => this.sendCiv(req));
|
|
538
|
+
if (!resp || resp.length < 13) {
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
const spanHz = (0, IcomScopeParser_1.parseIcomBcdFreqLE)(resp.subarray(7, 12));
|
|
542
|
+
return {
|
|
543
|
+
receiver,
|
|
544
|
+
spanHz,
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
async setScopeSpan(spanHz, options) {
|
|
548
|
+
const receiver = options?.receiver ?? 0;
|
|
549
|
+
const ctrAddr = IcomConstants_1.DEFAULT_CONTROLLER_ADDR;
|
|
550
|
+
const rigAddr = this.civ.civAddress & 0xff;
|
|
551
|
+
this.sendCiv(IcomScopeCommands_1.IcomScopeCommands.setScopeSpan(ctrAddr, rigAddr, spanHz, receiver));
|
|
552
|
+
}
|
|
530
553
|
async waitForScopeFrame(options) {
|
|
531
554
|
const timeoutMs = options?.timeout ?? 3000;
|
|
532
555
|
return this.scope.waitForScopeFrame(timeoutMs);
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export declare const IcomScopeCommands: {
|
|
2
2
|
setScopeDataOutput(ctrAddr: number, rigAddr: number, enabled: boolean): Buffer;
|
|
3
3
|
setScopeDisplay(ctrAddr: number, rigAddr: number, enabled: boolean): Buffer;
|
|
4
|
+
readScopeSpan(ctrAddr: number, rigAddr: number, receiver?: 0 | 1): Buffer;
|
|
5
|
+
setScopeSpan(ctrAddr: number, rigAddr: number, spanHz: number, receiver?: 0 | 1): Buffer;
|
|
6
|
+
encodeScopeSpanHz(spanHz: number): Buffer;
|
|
4
7
|
};
|
|
@@ -11,5 +11,27 @@ exports.IcomScopeCommands = {
|
|
|
11
11
|
return Buffer.from([
|
|
12
12
|
0xfe, 0xfe, rigAddr & 0xff, ctrAddr & 0xff, 0x27, 0x10, enabled ? 0x01 : 0x00, 0xfd
|
|
13
13
|
]);
|
|
14
|
+
},
|
|
15
|
+
readScopeSpan(ctrAddr, rigAddr, receiver = 0) {
|
|
16
|
+
return Buffer.from([
|
|
17
|
+
0xfe, 0xfe, rigAddr & 0xff, ctrAddr & 0xff, 0x27, 0x15, receiver & 0xff, 0xfd
|
|
18
|
+
]);
|
|
19
|
+
},
|
|
20
|
+
setScopeSpan(ctrAddr, rigAddr, spanHz, receiver = 0) {
|
|
21
|
+
const bytes = exports.IcomScopeCommands.encodeScopeSpanHz(spanHz);
|
|
22
|
+
return Buffer.from([
|
|
23
|
+
0xfe, 0xfe, rigAddr & 0xff, ctrAddr & 0xff, 0x27, 0x15, receiver & 0xff, ...bytes, 0xfd
|
|
24
|
+
]);
|
|
25
|
+
},
|
|
26
|
+
encodeScopeSpanHz(spanHz) {
|
|
27
|
+
const safeSpanHz = Math.max(0, Math.round(spanHz));
|
|
28
|
+
const out = Buffer.alloc(5);
|
|
29
|
+
let remaining = safeSpanHz;
|
|
30
|
+
for (let i = 0; i < out.length; i++) {
|
|
31
|
+
const twoDigits = remaining % 100;
|
|
32
|
+
out[i] = ((((twoDigits / 10) | 0) & 0x0f) << 4) | (twoDigits % 10);
|
|
33
|
+
remaining = Math.floor(remaining / 100);
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
14
36
|
}
|
|
15
37
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -110,6 +110,10 @@ export interface IcomScopeFrame {
|
|
|
110
110
|
rawCivPayloads: Buffer[];
|
|
111
111
|
transport: IcomScopeTransport;
|
|
112
112
|
}
|
|
113
|
+
export interface IcomScopeSpanInfo {
|
|
114
|
+
receiver: 0 | 1;
|
|
115
|
+
spanHz: number;
|
|
116
|
+
}
|
|
113
117
|
/**
|
|
114
118
|
* Result of a meter reading operation (SWR, ALC, etc.)
|
|
115
119
|
* @deprecated Use specific types like SwrReading, AlcReading instead
|