hamlib 0.1.5 → 0.1.6

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
@@ -4,6 +4,7 @@ A comprehensive Node.js wrapper for [Hamlib](https://hamlib.github.io/) - contro
4
4
 
5
5
  ## 🚀 Features
6
6
 
7
+ - **Async/Await Support**: All operations are asynchronous and non-blocking for optimal performance
7
8
  - **Built-in Methods**: Complete radio control API including memory channels, RIT/XIT, scanning, levels, functions, and more
8
9
  - **303+ Supported Radios**: Works with Yaesu, Icom, Kenwood, Elecraft, FlexRadio, and many more
9
10
  - **Multi-platform**: Pre-built binaries for Windows x64, Linux x64/ARM64, macOS ARM64
@@ -11,6 +12,25 @@ A comprehensive Node.js wrapper for [Hamlib](https://hamlib.github.io/) - contro
11
12
  - **TypeScript Support**: Full type definitions and IntelliSense
12
13
  - **Modern JavaScript**: CommonJS and ES Modules support
13
14
 
15
+ ## ⚡ Async Operations
16
+
17
+ **All radio control operations are asynchronous** to prevent blocking the Node.js event loop during I/O operations:
18
+
19
+ ```javascript
20
+ // ✅ Correct - Using async/await
21
+ await rig.setFrequency(144390000);
22
+ const frequency = await rig.getFrequency();
23
+
24
+ // ✅ Correct - Using Promises
25
+ rig.setFrequency(144390000)
26
+ .then(() => rig.getFrequency())
27
+ .then(freq => console.log('Frequency:', freq))
28
+ .catch(err => console.error('Error:', err));
29
+
30
+ // ❌ Incorrect - Operations are no longer synchronous
31
+ // rig.setFrequency(144390000); // This won't work as expected
32
+ ```
33
+
14
34
  ## 📦 Quick Start
15
35
 
16
36
  ```bash
@@ -20,25 +40,29 @@ npm install node-hamlib
20
40
  ```javascript
21
41
  const { HamLib } = require('node-hamlib');
22
42
 
23
- // Find your radio model
24
- const rigs = HamLib.getSupportedRigs();
25
- console.log('Supported radios:', rigs.length);
43
+ async function controlRadio() {
44
+ // Find your radio model
45
+ const rigs = HamLib.getSupportedRigs();
46
+ console.log('Supported radios:', rigs.length);
26
47
 
27
- // Connect to radio
28
- const rig = new HamLib(1035, '/dev/ttyUSB0'); // FT-991A
29
- rig.open();
48
+ // Connect to radio
49
+ const rig = new HamLib(1035, '/dev/ttyUSB0'); // FT-991A
50
+ await rig.open();
30
51
 
31
- // Basic control
32
- rig.setFrequency(144390000); // 144.39 MHz
33
- rig.setMode('FM');
34
- rig.setPtt(true);
52
+ // Basic control
53
+ await rig.setFrequency(144390000); // 144.39 MHz
54
+ await rig.setMode('FM');
55
+ await rig.setPtt(true);
35
56
 
36
- // Get status
37
- console.log('Frequency:', rig.getFrequency());
38
- console.log('Mode:', rig.getMode());
39
- console.log('Signal:', rig.getStrength());
57
+ // Get status
58
+ console.log('Frequency:', await rig.getFrequency());
59
+ console.log('Mode:', await rig.getMode());
60
+ console.log('Signal:', await rig.getStrength());
40
61
 
41
- rig.close();
62
+ await rig.close();
63
+ }
64
+
65
+ controlRadio().catch(console.error);
42
66
  ```
43
67
 
44
68
  ## 📡 Complete API Reference
@@ -74,9 +98,9 @@ const rig = new HamLib(1035, 'localhost:4532'); // rigctld
74
98
  #### `open()` / `close()` / `destroy()`
75
99
  Connection control
76
100
  ```javascript
77
- rig.open(); // Open connection
78
- rig.close(); // Close (can reopen)
79
- rig.destroy(); // Destroy permanently
101
+ await rig.open(); // Open connection
102
+ await rig.close(); // Close (can reopen)
103
+ await rig.destroy(); // Destroy permanently
80
104
  ```
81
105
 
82
106
  #### `getConnectionInfo()`
@@ -93,22 +117,22 @@ console.log('Status:', info.status);
93
117
  #### Frequency Control
94
118
  ```javascript
95
119
  // Set frequency (Hz)
96
- rig.setFrequency(144390000);
97
- rig.setFrequency(144390000, 'VFO-A');
120
+ await rig.setFrequency(144390000);
121
+ await rig.setFrequency(144390000, 'VFO-A');
98
122
 
99
123
  // Get frequency
100
- const freq = rig.getFrequency();
101
- const freqA = rig.getFrequency('VFO-A');
124
+ const freq = await rig.getFrequency();
125
+ const freqA = await rig.getFrequency('VFO-A');
102
126
  ```
103
127
 
104
128
  #### Mode Control
105
129
  ```javascript
106
130
  // Set mode
107
- rig.setMode('FM');
108
- rig.setMode('USB', 'wide');
131
+ await rig.setMode('FM');
132
+ await rig.setMode('USB', 'wide');
109
133
 
110
134
  // Get mode
111
- const mode = rig.getMode();
135
+ const mode = await rig.getMode();
112
136
  console.log('Mode:', mode.mode);
113
137
  console.log('Bandwidth:', mode.bandwidth);
114
138
  ```
@@ -116,22 +140,22 @@ console.log('Bandwidth:', mode.bandwidth);
116
140
  #### VFO Control
117
141
  ```javascript
118
142
  // Set VFO
119
- rig.setVfo('VFO-A');
120
- rig.setVfo('VFO-B');
143
+ await rig.setVfo('VFO-A');
144
+ await rig.setVfo('VFO-B');
121
145
 
122
146
  // Get current VFO
123
- const vfo = rig.getVfo();
147
+ const vfo = await rig.getVfo();
124
148
  ```
125
149
 
126
150
  #### PTT Control
127
151
  ```javascript
128
- rig.setPtt(true); // Transmit
129
- rig.setPtt(false); // Receive
152
+ await rig.setPtt(true); // Transmit
153
+ await rig.setPtt(false); // Receive
130
154
  ```
131
155
 
132
156
  #### Signal Monitoring
133
157
  ```javascript
134
- const strength = rig.getStrength();
158
+ const strength = await rig.getStrength();
135
159
  console.log('Signal strength:', strength);
136
160
  ```
137
161
 
@@ -406,39 +430,48 @@ async function radioControl() {
406
430
  const rig = new HamLib(ft991a.rigModel, '/dev/ttyUSB0');
407
431
 
408
432
  try {
409
- rig.open();
433
+ await rig.open();
410
434
  console.log('Connected to', rig.getConnectionInfo().port);
411
435
 
412
436
  // Set up radio
413
- rig.setFrequency(144390000);
414
- rig.setMode('FM');
415
- rig.setLevel('RFPOWER', 0.5);
416
- rig.setFunction('NB', true);
437
+ await rig.setFrequency(144390000);
438
+ await rig.setMode('FM');
439
+ await rig.setLevel('RFPOWER', 0.5);
440
+ await rig.setFunction('NB', true);
417
441
 
418
442
  // Store memory channel
419
- rig.setMemoryChannel(1, {
443
+ await rig.setMemoryChannel(1, {
420
444
  frequency: 144390000,
421
445
  mode: 'FM',
422
446
  description: 'Local Repeater'
423
447
  });
424
448
 
425
449
  // Monitor signal
426
- setInterval(() => {
427
- const freq = rig.getFrequency();
428
- const mode = rig.getMode();
429
- const strength = rig.getStrength();
430
-
431
- console.log(`${freq/1000000} MHz ${mode.mode} S:${strength}`);
450
+ const monitorInterval = setInterval(async () => {
451
+ try {
452
+ const freq = await rig.getFrequency();
453
+ const mode = await rig.getMode();
454
+ const strength = await rig.getStrength();
455
+
456
+ console.log(`${freq/1000000} MHz ${mode.mode} S:${strength}`);
457
+ } catch (err) {
458
+ console.error('Monitor error:', err.message);
459
+ }
432
460
  }, 1000);
433
461
 
462
+ // Stop monitoring after 30 seconds
463
+ setTimeout(() => {
464
+ clearInterval(monitorInterval);
465
+ }, 30000);
466
+
434
467
  } catch (error) {
435
468
  console.error('Error:', error.message);
436
469
  } finally {
437
- rig.close();
470
+ await rig.close();
438
471
  }
439
472
  }
440
473
 
441
- radioControl();
474
+ radioControl().catch(console.error);
442
475
  ```
443
476
 
444
477
  ## 📋 Supported Radios
package/index.d.ts CHANGED
@@ -224,25 +224,25 @@ declare class HamLib {
224
224
  * Must be called before other operations
225
225
  * @throws Throws error when connection fails
226
226
  */
227
- open(): void;
227
+ open(): Promise<number>;
228
228
 
229
229
  /**
230
230
  * Set VFO (Variable Frequency Oscillator)
231
231
  * @param vfo VFO identifier, typically 'VFO-A' or 'VFO-B'
232
232
  * @throws Throws error when device doesn't support or operation fails
233
233
  */
234
- setVfo(vfo: VFO): void;
234
+ setVfo(vfo: VFO): Promise<number>;
235
235
 
236
236
  /**
237
237
  * Set frequency
238
238
  * @param frequency Frequency value in hertz
239
239
  * @param vfo Optional VFO to set frequency on ('VFO-A' or 'VFO-B'). If not specified, uses current VFO
240
240
  * @example
241
- * rig.setFrequency(144390000); // Set to 144.39MHz on current VFO
242
- * rig.setFrequency(144390000, 'VFO-A'); // Set to 144.39MHz on VFO-A
243
- * rig.setFrequency(144390000, 'VFO-B'); // Set to 144.39MHz on VFO-B
241
+ * await rig.setFrequency(144390000); // Set to 144.39MHz on current VFO
242
+ * await rig.setFrequency(144390000, 'VFO-A'); // Set to 144.39MHz on VFO-A
243
+ * await rig.setFrequency(144390000, 'VFO-B'); // Set to 144.39MHz on VFO-B
244
244
  */
245
- setFrequency(frequency: number, vfo?: VFO): void;
245
+ setFrequency(frequency: number, vfo?: VFO): Promise<number>;
246
246
 
247
247
  /**
248
248
  * Set radio mode
@@ -250,60 +250,60 @@ declare class HamLib {
250
250
  * @param bandwidth Optional bandwidth setting ('narrow', 'wide', or default)
251
251
  * @note Operates on the current VFO (RIG_VFO_CURR)
252
252
  * @example
253
- * rig.setMode('USB');
254
- * rig.setMode('FM', 'narrow');
253
+ * await rig.setMode('USB');
254
+ * await rig.setMode('FM', 'narrow');
255
255
  */
256
- setMode(mode: RadioMode, bandwidth?: 'narrow' | 'wide'): void;
256
+ setMode(mode: RadioMode, bandwidth?: 'narrow' | 'wide'): Promise<number>;
257
257
 
258
258
  /**
259
259
  * Set PTT (Push-to-Talk) status
260
260
  * @param state true to enable PTT, false to disable PTT
261
261
  * @note Operates on the current VFO (RIG_VFO_CURR)
262
262
  */
263
- setPtt(state: boolean): void;
263
+ setPtt(state: boolean): Promise<number>;
264
264
 
265
265
  /**
266
266
  * Get current VFO
267
267
  * @returns Current VFO identifier
268
268
  */
269
- getVfo(): string;
269
+ getVfo(): Promise<string>;
270
270
 
271
271
  /**
272
272
  * Get current frequency
273
273
  * @param vfo Optional VFO to get frequency from ('VFO-A' or 'VFO-B'). If not specified, uses current VFO
274
274
  * @returns Current frequency value in hertz
275
275
  * @example
276
- * rig.getFrequency(); // Get frequency from current VFO
277
- * rig.getFrequency('VFO-A'); // Get frequency from VFO-A
278
- * rig.getFrequency('VFO-B'); // Get frequency from VFO-B
276
+ * await rig.getFrequency(); // Get frequency from current VFO
277
+ * await rig.getFrequency('VFO-A'); // Get frequency from VFO-A
278
+ * await rig.getFrequency('VFO-B'); // Get frequency from VFO-B
279
279
  */
280
- getFrequency(vfo?: VFO): number;
280
+ getFrequency(vfo?: VFO): Promise<number>;
281
281
 
282
282
  /**
283
283
  * Get current radio mode
284
284
  * @returns Object containing mode and bandwidth information
285
285
  * @note Operates on the current VFO (RIG_VFO_CURR)
286
286
  */
287
- getMode(): ModeInfo;
287
+ getMode(): Promise<ModeInfo>;
288
288
 
289
289
  /**
290
290
  * Get current signal strength
291
291
  * @returns Signal strength value
292
292
  * @note Operates on the current VFO (RIG_VFO_CURR)
293
293
  */
294
- getStrength(): number;
294
+ getStrength(): Promise<number>;
295
295
 
296
296
  /**
297
297
  * Close connection to device
298
298
  * Does not destroy object, can re-establish connection by calling open()
299
299
  */
300
- close(): void;
300
+ close(): Promise<number>;
301
301
 
302
302
  /**
303
303
  * Destroy connection to device
304
304
  * Should delete object reference after calling to enable garbage collection
305
305
  */
306
- destroy(): void;
306
+ destroy(): Promise<number>;
307
307
 
308
308
  /**
309
309
  * Get connection information
package/lib/index.js CHANGED
@@ -35,8 +35,16 @@ class HamLib {
35
35
  * Must be called before other operations
36
36
  * @throws {Error} Throws error when connection fails
37
37
  */
38
- open() {
39
- return this._nativeInstance.open();
38
+ async open() {
39
+ return new Promise((resolve, reject) => {
40
+ this._nativeInstance.open((err, result) => {
41
+ if (err) {
42
+ reject(new Error(err.message || 'Failed to open connection'));
43
+ } else {
44
+ resolve(result);
45
+ }
46
+ });
47
+ });
40
48
  }
41
49
 
42
50
  /**
@@ -44,8 +52,16 @@ class HamLib {
44
52
  * @param {string} vfo - VFO identifier ('VFO-A' or 'VFO-B')
45
53
  * @throws {Error} Throws error when device doesn't support or operation fails
46
54
  */
47
- setVfo(vfo) {
48
- return this._nativeInstance.setVfo(vfo);
55
+ async setVfo(vfo) {
56
+ return new Promise((resolve, reject) => {
57
+ this._nativeInstance.setVfo(vfo, (err, result) => {
58
+ if (err) {
59
+ reject(new Error(err.message || 'Failed to set VFO'));
60
+ } else {
61
+ resolve(result);
62
+ }
63
+ });
64
+ });
49
65
  }
50
66
 
51
67
  /**
@@ -53,11 +69,26 @@ class HamLib {
53
69
  * @param {number} frequency - Frequency in hertz
54
70
  * @param {string} [vfo] - Optional VFO ('VFO-A' or 'VFO-B')
55
71
  */
56
- setFrequency(frequency, vfo) {
57
- if (vfo) {
58
- return this._nativeInstance.setFrequency(frequency, vfo);
59
- }
60
- return this._nativeInstance.setFrequency(frequency);
72
+ async setFrequency(frequency, vfo) {
73
+ return new Promise((resolve, reject) => {
74
+ if (vfo) {
75
+ this._nativeInstance.setFrequency(frequency, vfo, (err, result) => {
76
+ if (err) {
77
+ reject(new Error(err.message || 'Failed to set frequency'));
78
+ } else {
79
+ resolve(result);
80
+ }
81
+ });
82
+ } else {
83
+ this._nativeInstance.setFrequency(frequency, (err, result) => {
84
+ if (err) {
85
+ reject(new Error(err.message || 'Failed to set frequency'));
86
+ } else {
87
+ resolve(result);
88
+ }
89
+ });
90
+ }
91
+ });
61
92
  }
62
93
 
63
94
  /**
@@ -65,27 +96,58 @@ class HamLib {
65
96
  * @param {string} mode - Radio mode ('USB', 'LSB', 'FM', 'PKTFM', etc.)
66
97
  * @param {string} [bandwidth] - Optional bandwidth ('narrow', 'wide')
67
98
  */
68
- setMode(mode, bandwidth) {
69
- if (bandwidth) {
70
- return this._nativeInstance.setMode(mode, bandwidth);
71
- }
72
- return this._nativeInstance.setMode(mode);
99
+ async setMode(mode, bandwidth) {
100
+ return new Promise((resolve, reject) => {
101
+ if (bandwidth) {
102
+ this._nativeInstance.setMode(mode, bandwidth, (err, result) => {
103
+ if (err) {
104
+ reject(new Error(err.message || 'Failed to set mode'));
105
+ } else {
106
+ resolve(result);
107
+ }
108
+ });
109
+ } else {
110
+ this._nativeInstance.setMode(mode, (err, result) => {
111
+ if (err) {
112
+ reject(new Error(err.message || 'Failed to set mode'));
113
+ } else {
114
+ resolve(result);
115
+ }
116
+ });
117
+ }
118
+ });
73
119
  }
74
120
 
75
121
  /**
76
122
  * Set PTT (Push-to-Talk) status
77
123
  * @param {boolean} state - true to enable PTT, false to disable
78
124
  */
79
- setPtt(state) {
80
- return this._nativeInstance.setPtt(state);
125
+ async setPtt(state) {
126
+ return new Promise((resolve, reject) => {
127
+ this._nativeInstance.setPtt(state, (err, result) => {
128
+ if (err) {
129
+ reject(new Error(err.message || 'Failed to set PTT'));
130
+ } else {
131
+ resolve(result);
132
+ }
133
+ });
134
+ });
81
135
  }
82
136
 
83
137
  /**
84
138
  * Get current VFO
85
139
  * @returns {string} Current VFO identifier
86
140
  */
87
- getVfo() {
88
- return this._nativeInstance.getVfo();
141
+ async getVfo() {
142
+ return new Promise((resolve, reject) => {
143
+ this._nativeInstance.getVfo((err, result) => {
144
+ if (err) {
145
+ reject(new Error(err.message || 'Failed to get VFO'));
146
+ } else {
147
+ resolve(result);
148
+ }
149
+ });
150
+ });
89
151
  }
90
152
 
91
153
  /**
@@ -93,43 +155,90 @@ class HamLib {
93
155
  * @param {string} [vfo] - Optional VFO ('VFO-A' or 'VFO-B')
94
156
  * @returns {number} Current frequency in hertz
95
157
  */
96
- getFrequency(vfo) {
97
- if (vfo) {
98
- return this._nativeInstance.getFrequency(vfo);
99
- }
100
- return this._nativeInstance.getFrequency();
158
+ async getFrequency(vfo) {
159
+ return new Promise((resolve, reject) => {
160
+ if (vfo) {
161
+ this._nativeInstance.getFrequency(vfo, (err, result) => {
162
+ if (err) {
163
+ reject(new Error(err.message || 'Failed to get frequency'));
164
+ } else {
165
+ resolve(result);
166
+ }
167
+ });
168
+ } else {
169
+ this._nativeInstance.getFrequency((err, result) => {
170
+ if (err) {
171
+ reject(new Error(err.message || 'Failed to get frequency'));
172
+ } else {
173
+ resolve(result);
174
+ }
175
+ });
176
+ }
177
+ });
101
178
  }
102
179
 
103
180
  /**
104
181
  * Get current radio mode
105
182
  * @returns {Object} Object containing mode and bandwidth information
106
183
  */
107
- getMode() {
108
- return this._nativeInstance.getMode();
184
+ async getMode() {
185
+ return new Promise((resolve, reject) => {
186
+ this._nativeInstance.getMode((err, result) => {
187
+ if (err) {
188
+ reject(new Error(err.message || 'Failed to get mode'));
189
+ } else {
190
+ resolve(result);
191
+ }
192
+ });
193
+ });
109
194
  }
110
195
 
111
196
  /**
112
197
  * Get current signal strength
113
198
  * @returns {number} Signal strength value
114
199
  */
115
- getStrength() {
116
- return this._nativeInstance.getStrength();
200
+ async getStrength() {
201
+ return new Promise((resolve, reject) => {
202
+ this._nativeInstance.getStrength((err, result) => {
203
+ if (err) {
204
+ reject(new Error(err.message || 'Failed to get signal strength'));
205
+ } else {
206
+ resolve(result);
207
+ }
208
+ });
209
+ });
117
210
  }
118
211
 
119
212
  /**
120
213
  * Close connection to device
121
214
  * Connection can be re-established by calling open()
122
215
  */
123
- close() {
124
- return this._nativeInstance.close();
216
+ async close() {
217
+ return new Promise((resolve, reject) => {
218
+ this._nativeInstance.close((err, result) => {
219
+ if (err) {
220
+ reject(new Error(err.message || 'Failed to close connection'));
221
+ } else {
222
+ resolve(result);
223
+ }
224
+ });
225
+ });
125
226
  }
126
227
 
127
228
  /**
128
229
  * Destroy connection to device
129
230
  * Object reference should be deleted after calling this
130
231
  */
131
- destroy() {
132
- return this._nativeInstance.destroy();
232
+ async destroy() {
233
+ return new Promise((resolve, reject) => {
234
+ this._nativeInstance.destroy((err, result) => {
235
+ if (err) {
236
+ reject(new Error(err.message || 'Failed to destroy connection'));
237
+ } else {
238
+ resolve(result);
239
+ }
240
+ });
241
+ });
133
242
  }
134
243
 
135
244
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hamlib",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Node.js wrapper for hamlib radio control library",
5
5
  "main": "index.js",
6
6
  "module": "lib/index.mjs",
Binary file
Binary file
Binary file