ngx-kel-agent 0.4.10 → 0.5.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.
@@ -1,244 +1,162 @@
1
+ import { Subject, BehaviorSubject, ReplaySubject } from 'rxjs';
1
2
  import * as i0 from '@angular/core';
2
3
  import { Injectable } from '@angular/core';
3
- import { BehaviorSubject, ReplaySubject, Subject } from 'rxjs';
4
4
  import { debounceTime, retryWhen, tap, delay } from 'rxjs/operators';
5
5
  import { webSocket } from 'rxjs/webSocket';
6
6
 
7
- class AgentService {
7
+ class AgentMessageService {
8
8
  constructor() {
9
- /** Whether we're connected to the agent. */
10
- this.connectedState$ = new BehaviorSubject(false);
11
- /* WSJT-X */
9
+ this.rxMessage$ = new Subject();
10
+ this.txMessage$ = new Subject();
11
+ }
12
+ }
13
+ AgentMessageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: AgentMessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
14
+ AgentMessageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: AgentMessageService, providedIn: 'root' });
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: AgentMessageService, decorators: [{
16
+ type: Injectable,
17
+ args: [{
18
+ providedIn: 'root',
19
+ }]
20
+ }], ctorParameters: function () { return []; } });
21
+
22
+ class WsjtxService {
23
+ constructor(messages) {
24
+ this.messages = messages;
12
25
  /** Whether we're getting any messages from WSJT-X. */
13
- this.wsjtxState$ = new BehaviorSubject(false);
26
+ this.connected$ = new BehaviorSubject(false);
14
27
  /** Subject for listening to WSJT-X "Heartbeat" messages. */
15
- this.wsjtxHeartbeat$ = new ReplaySubject(1);
28
+ this.heartbeat$ = new ReplaySubject(1);
16
29
  /** Subject for listening to WSJT-X "Status" messages. */
17
- this.wsjtxStatus$ = new ReplaySubject(1);
30
+ this.status$ = new ReplaySubject(1);
18
31
  /** Subject for listening to WSJT-X "Decode" messages. */
19
- this.wsjtxDecode$ = new Subject();
32
+ this.decode$ = new Subject();
20
33
  /** Subject for listening to WSJT-X "Clear" messages. */
21
- this.wsjtxClear$ = new Subject();
34
+ this.clear$ = new Subject();
22
35
  /** Subject for listening to WSJT-X "QsoLogged" messages. */
23
- this.wsjtxQsoLogged$ = new Subject();
36
+ this.qsoLogged$ = new Subject();
24
37
  /** Subject for listening to WSJT-X "Close" messages. */
25
- this.wsjtxClose$ = new Subject();
38
+ this.close$ = new Subject();
26
39
  /** Subject for listening to WSJT-X "WsprDecode" messages. */
27
- this.wsjtxWsprDecode$ = new Subject();
40
+ this.wsprDecode$ = new Subject();
28
41
  /** Subject for listening to WSJT-X "LoggedAdif" messages. */
29
- this.wsjtxLoggedAdif$ = new Subject();
30
- /* Hamlib */
31
- /** Whether we're getting any messages from Hamlib. */
32
- this.hamlibState$ = new BehaviorSubject(false);
33
- /** Subject for listening to Hamlib "RigState" messages. */
34
- this.hamlibRigState$ = new BehaviorSubject(null);
35
- this.defaultAgentHost = 'localhost';
36
- this.defaultAgentPort = 8081;
37
- this.localStorageHostKey = 'agent-host';
38
- this.localStoragePortKey = 'agent-port';
39
- this.agentHost = this.defaultAgentHost;
40
- this.agentPort = this.defaultAgentPort;
41
- this.agentWebSocketSubject = null;
42
- this.agentWebsocketSubscription = null;
42
+ this.loggedAdif$ = new Subject();
43
43
  this.wsjtxId = 'WSJT-X';
44
+ this.setupBehaviors();
44
45
  }
45
- init() {
46
- this.agentHost = this.getHost();
47
- this.agentPort = this.getPort();
48
- this.setupWsjtxBehaviors();
49
- this.setupHamlibBehaviors();
50
- this.connect();
51
- }
52
- setupWsjtxBehaviors() {
46
+ setupBehaviors() {
47
+ this.messages.rxMessage$.subscribe((msg) => this.handleMessage(msg));
53
48
  // if we haven't heard from WSJT-X in 15 seconds, consider it "down"
54
- this.wsjtxState$
49
+ this.connected$
55
50
  .pipe(debounceTime(15000))
56
- .subscribe(() => this.wsjtxState$.next(false));
51
+ .subscribe(() => this.connected$.next(false));
57
52
  // When WSJT-X announces it's closing, set it to "down" immediately
58
- this.wsjtxClose$.subscribe(() => {
59
- this.wsjtxState$.next(false);
53
+ this.close$.subscribe(() => {
54
+ this.connected$.next(false);
60
55
  });
61
56
  // When WSJT-X goes down, clear its persistent message subjects
62
- this.wsjtxState$.subscribe((isUp) => {
63
- if (!isUp) {
64
- this.wsjtxHeartbeat$.next(null);
65
- this.wsjtxStatus$.next(null);
66
- }
67
- });
68
- }
69
- setupHamlibBehaviors() {
70
- // if we haven't heard from Hamlib in 15 seconds, consider it down
71
- this.hamlibState$.pipe(debounceTime(15000)).subscribe(() => {
72
- this.hamlibState$.next(false);
73
- });
74
- // When Hamlib goes down, clear its persistent message subjects
75
- this.hamlibState$.subscribe((isUp) => {
57
+ this.connected$.subscribe((isUp) => {
76
58
  if (!isUp) {
77
- this.hamlibRigState$.next(null);
59
+ this.heartbeat$.next(null);
60
+ this.status$.next(null);
78
61
  }
79
62
  });
80
63
  }
81
- /** Connect (or reconnect) the websocket to the kel-agent server. */
82
- connect() {
83
- if (this.agentWebsocketSubscription) {
84
- this.agentWebsocketSubscription.unsubscribe();
85
- }
86
- this.agentHost = this.getHost();
87
- this.agentPort = this.getPort();
88
- const protocol = this.agentHost === 'localhost' ? 'ws://' : 'wss://';
89
- this.agentWebSocketSubject = webSocket({
90
- url: protocol + this.agentHost + ':' + this.agentPort + '/websocket',
91
- });
92
- this.connectedState$.next(true);
93
- this.agentWebsocketSubscription = this.agentWebSocketSubject
94
- .pipe(retryWhen((errors) =>
95
- // retry the websocket connection after 10 seconds
96
- errors.pipe(tap(() => this.connectedState$.next(false)), delay(10000))))
97
- .subscribe({
98
- next: (msg) => {
99
- this.connectedState$.next(true);
100
- this.handleMessage(msg);
101
- },
102
- error: () => this.connectedState$.next(false),
103
- complete: () => this.connectedState$.next(false),
104
- });
105
- }
106
64
  handleMessage(msg) {
107
- if (msg.wsjtx != null && msg.wsjtx.type != null) {
108
- this.wsjtxState$.next(true);
109
- this.wsjtxId = msg.wsjtx.payload.id;
110
- switch (msg.wsjtx.type) {
111
- case 'HeartbeatMessage':
112
- this.wsjtxHeartbeat$.next(msg.wsjtx.payload);
113
- return;
114
- case 'StatusMessage':
115
- this.wsjtxStatus$.next(msg.wsjtx.payload);
116
- return;
117
- case 'DecodeMessage':
118
- this.wsjtxDecode$.next(msg.wsjtx.payload);
119
- return;
120
- case 'ClearMessage':
121
- this.wsjtxClear$.next(msg.wsjtx.payload);
122
- return;
123
- case 'QsoLoggedMessage':
124
- this.wsjtxQsoLogged$.next(msg.wsjtx.payload);
125
- return;
126
- case 'CloseMessage':
127
- this.wsjtxClose$.next(msg.wsjtx.payload);
128
- return;
129
- case 'WSPRDecodeMessage':
130
- this.wsjtxWsprDecode$.next(msg.wsjtx.payload);
131
- return;
132
- case 'LoggedAdifMessage':
133
- this.wsjtxLoggedAdif$.next(msg.wsjtx.payload);
134
- return;
135
- }
65
+ if (!msg.wsjtx) {
66
+ return;
136
67
  }
137
- if (msg.hamlib !== null) {
138
- this.hamlibState$.next(true);
139
- switch (msg.hamlib.type) {
140
- case 'RigState':
141
- this.hamlibRigState$.next(msg.hamlib.payload);
142
- return;
143
- }
68
+ this.connected$.next(true);
69
+ this.wsjtxId = msg.wsjtx.payload.id;
70
+ switch (msg.wsjtx.type) {
71
+ case 'HeartbeatMessage':
72
+ this.heartbeat$.next(msg.wsjtx.payload);
73
+ return;
74
+ case 'StatusMessage':
75
+ this.status$.next(msg.wsjtx.payload);
76
+ return;
77
+ case 'DecodeMessage':
78
+ this.decode$.next(msg.wsjtx.payload);
79
+ return;
80
+ case 'ClearMessage':
81
+ this.clear$.next(msg.wsjtx.payload);
82
+ return;
83
+ case 'QsoLoggedMessage':
84
+ this.qsoLogged$.next(msg.wsjtx.payload);
85
+ return;
86
+ case 'CloseMessage':
87
+ this.close$.next(msg.wsjtx.payload);
88
+ return;
89
+ case 'WSPRDecodeMessage':
90
+ this.wsprDecode$.next(msg.wsjtx.payload);
91
+ return;
92
+ case 'LoggedAdifMessage':
93
+ this.loggedAdif$.next(msg.wsjtx.payload);
94
+ return;
144
95
  }
145
96
  }
146
- /** Get the currently configured kel-agent host. */
147
- getHost() {
148
- return localStorage.getItem(this.localStorageHostKey) || this.defaultAgentHost;
149
- }
150
- /** Get the currently configured kel-agent port. */
151
- getPort() {
152
- let portStr = localStorage.getItem(this.localStoragePortKey);
153
- if (portStr == null) {
154
- return this.defaultAgentPort;
155
- }
156
- let portNum = parseInt(portStr, 10);
157
- if (isNaN(portNum)) {
158
- return this.defaultAgentPort;
159
- }
160
- return portNum;
161
- }
162
- /** Set the kel-agent host. */
163
- setHost(host) {
164
- localStorage.setItem(this.localStorageHostKey, host);
165
- this.connect();
166
- }
167
- /** Set the kel-agent port. */
168
- setPort(port) {
169
- localStorage.setItem(this.localStoragePortKey, String(port));
170
- this.connect();
171
- }
172
97
  /** Send a command to WSJT-X to clear the Band Activity window. */
173
- sendWsjtxClearBandActivity() {
174
- var _a;
98
+ clearBandActivity() {
175
99
  const wsMsg = {
176
100
  wsjtx: {
177
101
  type: 'ClearMessage',
178
102
  payload: { id: this.wsjtxId, window: 0 },
179
103
  },
180
104
  };
181
- (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
105
+ this.messages.txMessage$.next(wsMsg);
182
106
  }
183
107
  /** Send a command to WSJT-X to clear the Rx Frequency window. */
184
- sendWsjtxClearRxFreqWindow() {
185
- var _a;
108
+ clearRxFreqWindow() {
186
109
  const wsMsg = {
187
110
  wsjtx: {
188
111
  type: 'ClearMessage',
189
112
  payload: { id: this.wsjtxId, window: 1 },
190
113
  },
191
114
  };
192
- (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
115
+ this.messages.txMessage$.next(wsMsg);
193
116
  }
194
117
  /** Send a command to WSJT-X to clear the Band Activity and Rx Frequency windows. */
195
- sendWsjtxClearAll() {
196
- var _a;
118
+ clearAll() {
197
119
  const wsMsg = {
198
120
  wsjtx: {
199
121
  type: 'ClearMessage',
200
122
  payload: { id: this.wsjtxId, window: 2 },
201
123
  },
202
124
  };
203
- (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
125
+ this.messages.txMessage$.next(wsMsg);
204
126
  }
205
127
  /** Send a command to WSJT-X to replay messages. Useful for a fresh client that wants to hear
206
128
  * previous WSJT-X decodes. */
207
- sendWsjtxReplay() {
208
- var _a;
129
+ replay() {
209
130
  const wsMsg = {
210
131
  wsjtx: {
211
132
  type: 'ReplayMessage',
212
133
  payload: { id: this.wsjtxId },
213
134
  },
214
135
  };
215
- (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
136
+ this.messages.txMessage$.next(wsMsg);
216
137
  }
217
138
  /** Send a command to WSJT-X to halt any transmissions immediately. */
218
- sendWsjtxHaltTxNow() {
219
- var _a;
139
+ haltTxNow() {
220
140
  const wsMsg = {
221
141
  wsjtx: {
222
142
  type: 'HaltTxMessage',
223
143
  payload: { id: this.wsjtxId, autoTxOnly: false },
224
144
  },
225
145
  };
226
- (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
146
+ this.messages.txMessage$.next(wsMsg);
227
147
  }
228
148
  /** Send a command to WSJT-X to stop auto-transmitting after finishing the current round. */
229
- sendWsjtxHaltTxAfterCurrent() {
230
- var _a;
149
+ haltTxAfterCurrent() {
231
150
  const wsMsg = {
232
151
  wsjtx: {
233
152
  type: 'HaltTxMessage',
234
153
  payload: { id: this.wsjtxId, autoTxOnly: true },
235
154
  },
236
155
  };
237
- (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
156
+ this.messages.txMessage$.next(wsMsg);
238
157
  }
239
158
  /** Send a command to WSJT-X to reply to the given decode. The message must include CQ or QRZ. */
240
- sendWsjtxReply(decode) {
241
- var _a;
159
+ reply(decode) {
242
160
  const wsMsg = {
243
161
  wsjtx: {
244
162
  type: 'ReplyMessage',
@@ -254,11 +172,10 @@ class AgentService {
254
172
  },
255
173
  },
256
174
  };
257
- (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
175
+ this.messages.txMessage$.next(wsMsg);
258
176
  }
259
177
  /** Send a command to WSJT-X to reply to the given decode. The message must include CQ or QRZ. */
260
- sendWsjtxHighlightCallsign(highlightMsg) {
261
- var _a;
178
+ highlightCallsign(highlightMsg) {
262
179
  highlightMsg.id = this.wsjtxId;
263
180
  const wsMsg = {
264
181
  wsjtx: {
@@ -266,32 +183,301 @@ class AgentService {
266
183
  payload: highlightMsg,
267
184
  },
268
185
  };
269
- (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
186
+ this.messages.txMessage$.next(wsMsg);
187
+ }
188
+ /**
189
+ * Send a command to WSJT-X to transmit the given free text. If the text is too long to be
190
+ * encoded in a single message, it may be silently truncated. */
191
+ sendFreeText(freeText) {
192
+ freeText.id = this.wsjtxId;
193
+ const wsMsg = {
194
+ wsjtx: {
195
+ type: 'FreeTextMessage',
196
+ payload: freeText,
197
+ },
198
+ };
199
+ this.messages.txMessage$.next(wsMsg);
200
+ }
201
+ /** Send a command to WSJT-X to set the local station's Maidenhead grid. This is temporary,
202
+ * lasting only as long as WSJT-X is running. */
203
+ setLocation(grid) {
204
+ const wsMsg = {
205
+ wsjtx: {
206
+ type: 'LocationMessage',
207
+ payload: {
208
+ id: this.wsjtxId,
209
+ location: grid,
210
+ },
211
+ },
212
+ };
213
+ this.messages.txMessage$.next(wsMsg);
214
+ }
215
+ /** Send a command to WSJT-X to switch to the named configuration. */
216
+ switchConfiguration(configName) {
217
+ const wsMsg = {
218
+ wsjtx: {
219
+ type: 'SwitchConfigurationMessage',
220
+ payload: {
221
+ id: this.wsjtxId,
222
+ configurationName: configName,
223
+ },
224
+ },
225
+ };
226
+ this.messages.txMessage$.next(wsMsg);
227
+ }
228
+ /** Send a command to WSJT-X to set the given configuration parameters. */
229
+ configure(config) {
230
+ config.id = this.wsjtxId;
231
+ const wsMsg = {
232
+ wsjtx: {
233
+ type: 'ConfigureMessage',
234
+ payload: config,
235
+ },
236
+ };
237
+ this.messages.txMessage$.next(wsMsg);
270
238
  }
271
239
  /** Given a decode message, format a string the same way as displayed in the WSJT-X Band
272
240
  * Activity/Rx Frequency windows. */
273
241
  static formatDecode(msg) {
274
- const secondsSinceMidnight = Math.floor(msg.time / 1000);
242
+ const timeStr = this.formatTime(msg.time);
243
+ return `${timeStr} ${msg.snr.toString().padStart(3)} ${msg.deltaTime
244
+ .toFixed(1)
245
+ .padStart(4)} ${msg.deltaFrequency.toString().padStart(4)} ~ ${msg.message}`;
246
+ }
247
+ /** Given a time in milliseconds since midnight UTC, format as HHMMSS. */
248
+ static formatTime(time) {
249
+ const secondsSinceMidnight = Math.floor(time / 1000);
275
250
  const hours = Math.floor(secondsSinceMidnight / 3600);
276
251
  const secondsSinceHour = secondsSinceMidnight - hours * 3600;
277
252
  const minutes = Math.floor(secondsSinceHour / 60);
278
253
  const seconds = secondsSinceHour - minutes * 60;
279
- const timeStr = `${hours.toString().padStart(2, '0')}${minutes
254
+ return `${hours.toString().padStart(2, '0')}${minutes
280
255
  .toString()
281
256
  .padStart(2, '0')}${seconds.toString().padStart(2, '0')}`;
282
- return `${timeStr} ${msg.snr.toString().padStart(3)} ${msg.deltaTime
283
- .toFixed(1)
284
- .padStart(4)} ${msg.deltaFrequency.toString().padStart(4)} ~ ${msg.message}`;
285
257
  }
286
258
  }
287
- AgentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: AgentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
259
+ WsjtxService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: WsjtxService, deps: [{ token: AgentMessageService }], target: i0.ɵɵFactoryTarget.Injectable });
260
+ WsjtxService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: WsjtxService, providedIn: 'root' });
261
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: WsjtxService, decorators: [{
262
+ type: Injectable,
263
+ args: [{
264
+ providedIn: 'root',
265
+ }]
266
+ }], ctorParameters: function () { return [{ type: AgentMessageService }]; } });
267
+
268
+ class HamlibService {
269
+ constructor(messages) {
270
+ this.messages = messages;
271
+ /** Whether we're getting any messages from Hamlib. */
272
+ this.connected$ = new BehaviorSubject(false);
273
+ /** Subject for listening to Hamlib "RigState" messages. */
274
+ this.rigState$ = new BehaviorSubject(null);
275
+ this.setupBehaviors();
276
+ }
277
+ setupBehaviors() {
278
+ this.messages.rxMessage$.subscribe((msg) => this.handleMessage(msg));
279
+ // if we haven't heard from Hamlib in 15 seconds, consider it down
280
+ this.connected$.pipe(debounceTime(15000)).subscribe(() => {
281
+ this.connected$.next(false);
282
+ });
283
+ // When Hamlib goes down, clear its persistent message subjects
284
+ this.connected$.subscribe((isUp) => {
285
+ if (!isUp) {
286
+ this.rigState$.next(null);
287
+ }
288
+ });
289
+ }
290
+ handleMessage(msg) {
291
+ if (!msg.hamlib) {
292
+ return;
293
+ }
294
+ this.connected$.next(true);
295
+ switch (msg.hamlib.type) {
296
+ case 'RigState':
297
+ this.rigState$.next(msg.hamlib.payload);
298
+ return;
299
+ }
300
+ }
301
+ }
302
+ HamlibService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: HamlibService, deps: [{ token: AgentMessageService }], target: i0.ɵɵFactoryTarget.Injectable });
303
+ HamlibService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: HamlibService, providedIn: 'root' });
304
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: HamlibService, decorators: [{
305
+ type: Injectable,
306
+ args: [{
307
+ providedIn: 'root',
308
+ }]
309
+ }], ctorParameters: function () { return [{ type: AgentMessageService }]; } });
310
+
311
+ class AgentService {
312
+ constructor(messages, hamlibService, wsjtxService) {
313
+ this.messages = messages;
314
+ this.hamlibService = hamlibService;
315
+ this.wsjtxService = wsjtxService;
316
+ /** Whether we're connected to the agent. */
317
+ this.connectedState$ = new BehaviorSubject(false);
318
+ this.defaultAgentHost = 'localhost';
319
+ this.defaultAgentPort = 8081;
320
+ this.localStorageHostKey = 'agent-host';
321
+ this.localStoragePortKey = 'agent-port';
322
+ this.agentHost = this.defaultAgentHost;
323
+ this.agentPort = this.defaultAgentPort;
324
+ this.agentWebSocketSubject = null;
325
+ this.agentWebsocketSubscription = null;
326
+ this.hamlibState$ = this.hamlibService.connected$;
327
+ this.hamlibRigState$ = this.hamlibService.rigState$;
328
+ this.wsjtxState$ = this.wsjtxService.connected$;
329
+ this.wsjtxHeartbeat$ = this.wsjtxService.heartbeat$;
330
+ this.wsjtxStatus$ = this.wsjtxService.status$;
331
+ this.wsjtxDecode$ = this.wsjtxService.decode$;
332
+ this.wsjtxClear$ = this.wsjtxService.clear$;
333
+ this.wsjtxQsoLogged$ = this.wsjtxService.qsoLogged$;
334
+ this.wsjtxClose$ = this.wsjtxService.close$;
335
+ this.wsjtxWsprDecode$ = this.wsjtxService.wsprDecode$;
336
+ this.wsjtxLoggedAdif$ = this.wsjtxService.loggedAdif$;
337
+ }
338
+ init() {
339
+ this.messages.txMessage$.subscribe((msg) => this.send(msg));
340
+ this.agentHost = this.getHost();
341
+ this.agentPort = this.getPort();
342
+ this.connect();
343
+ }
344
+ /** Connect (or reconnect) the websocket to the kel-agent server. */
345
+ connect() {
346
+ if (this.agentWebsocketSubscription) {
347
+ this.agentWebsocketSubscription.unsubscribe();
348
+ }
349
+ this.agentHost = this.getHost();
350
+ this.agentPort = this.getPort();
351
+ const protocol = this.agentHost === 'localhost' ? 'ws://' : 'wss://';
352
+ this.agentWebSocketSubject = webSocket({
353
+ url: protocol + this.agentHost + ':' + this.agentPort + '/websocket',
354
+ });
355
+ this.connectedState$.next(true);
356
+ this.agentWebsocketSubscription = this.agentWebSocketSubject
357
+ .pipe(retryWhen((errors) =>
358
+ // retry the websocket connection after 10 seconds
359
+ errors.pipe(tap(() => this.connectedState$.next(false)), delay(10000))))
360
+ .subscribe({
361
+ next: (msg) => {
362
+ this.connectedState$.next(true);
363
+ this.messages.rxMessage$.next(msg);
364
+ },
365
+ error: () => this.connectedState$.next(false),
366
+ complete: () => this.connectedState$.next(false),
367
+ });
368
+ }
369
+ /** Get the currently configured kel-agent host. */
370
+ getHost() {
371
+ return (localStorage.getItem(this.localStorageHostKey) || this.defaultAgentHost);
372
+ }
373
+ /** Get the currently configured kel-agent port. */
374
+ getPort() {
375
+ let portStr = localStorage.getItem(this.localStoragePortKey);
376
+ if (portStr == null) {
377
+ return this.defaultAgentPort;
378
+ }
379
+ let portNum = parseInt(portStr, 10);
380
+ if (isNaN(portNum)) {
381
+ return this.defaultAgentPort;
382
+ }
383
+ return portNum;
384
+ }
385
+ /** Set the kel-agent host. */
386
+ setHost(host) {
387
+ localStorage.setItem(this.localStorageHostKey, host);
388
+ this.connect();
389
+ }
390
+ /** Set the kel-agent port. */
391
+ setPort(port) {
392
+ localStorage.setItem(this.localStoragePortKey, String(port));
393
+ this.connect();
394
+ }
395
+ send(wsMsg) {
396
+ var _a;
397
+ (_a = this.agentWebSocketSubject) === null || _a === void 0 ? void 0 : _a.next(wsMsg);
398
+ }
399
+ /**
400
+ * Send a command to WSJT-X to clear the Band Activity window.
401
+ *
402
+ * @deprecated Use {@link WsjtxService.clearBandActivity} instead.
403
+ */
404
+ sendWsjtxClearBandActivity() {
405
+ this.wsjtxService.clearBandActivity();
406
+ }
407
+ /**
408
+ * Send a command to WSJT-X to clear the Rx Frequency window.
409
+ *
410
+ * @deprecated Use {@link WsjtxService.clearRxFreqWindow} instead.
411
+ */
412
+ sendWsjtxClearRxFreqWindow() {
413
+ this.wsjtxService.clearRxFreqWindow();
414
+ }
415
+ /**
416
+ * Send a command to WSJT-X to clear the Band Activity and Rx Frequency windows.
417
+ *
418
+ * @deprecated Use {@link WsjtxService.clearAll} instead.
419
+ */
420
+ sendWsjtxClearAll() {
421
+ this.wsjtxService.clearAll();
422
+ }
423
+ /**
424
+ * Send a command to WSJT-X to replay messages. Useful for a fresh client that wants to hear
425
+ * previous WSJT-X decodes.
426
+ *
427
+ * @deprecated Use {@link WsjtxService.replay} instead.
428
+ */
429
+ sendWsjtxReplay() {
430
+ this.wsjtxService.replay();
431
+ }
432
+ /**
433
+ * Send a command to WSJT-X to halt any transmissions immediately.
434
+ *
435
+ * @deprecated Use {@link WsjtxService.haltTxNow} instead.
436
+ */
437
+ sendWsjtxHaltTxNow() {
438
+ this.wsjtxService.haltTxNow();
439
+ }
440
+ /** Send a command to WSJT-X to stop auto-transmitting after finishing the current round.
441
+ *
442
+ * @deprecated Use {@link WsjtxService.haltTxAfterCurrent} instead.
443
+ */
444
+ sendWsjtxHaltTxAfterCurrent() {
445
+ this.wsjtxService.haltTxAfterCurrent();
446
+ }
447
+ /**
448
+ * Send a command to WSJT-X to reply to the given decode. The message must include CQ or QRZ.
449
+ *
450
+ * @deprecated Use {@link WsjtxService.reply} instead.
451
+ */
452
+ sendWsjtxReply(decode) {
453
+ this.wsjtxService.reply(decode);
454
+ }
455
+ /**
456
+ * Send a command to WSJT-X to reply to the given decode. The message must include CQ or QRZ.
457
+ *
458
+ * @deprecated Use {@link WsjtxService.highlightCallsign} instead.
459
+ */
460
+ sendWsjtxHighlightCallsign(highlightMsg) {
461
+ this.wsjtxService.highlightCallsign(highlightMsg);
462
+ }
463
+ /**
464
+ * Given a decode message, format a string the same way as displayed in the WSJT-X Band
465
+ * Activity/Rx Frequency windows.
466
+ *
467
+ * @deprecated Use {@link WsjtxService.formatDecode} instead.
468
+ */
469
+ static formatDecode(msg) {
470
+ return WsjtxService.formatDecode(msg);
471
+ }
472
+ }
473
+ AgentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: AgentService, deps: [{ token: AgentMessageService }, { token: HamlibService }, { token: WsjtxService }], target: i0.ɵɵFactoryTarget.Injectable });
288
474
  AgentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: AgentService, providedIn: 'root' });
289
475
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: AgentService, decorators: [{
290
476
  type: Injectable,
291
477
  args: [{
292
- providedIn: 'root'
478
+ providedIn: 'root',
293
479
  }]
294
- }], ctorParameters: function () { return []; } });
480
+ }], ctorParameters: function () { return [{ type: AgentMessageService }, { type: HamlibService }, { type: WsjtxService }]; } });
295
481
 
296
482
  /*
297
483
  * Public API Surface of ngx-kel-agent
@@ -303,5 +489,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImpor
303
489
  * Generated bundle index. Do not edit.
304
490
  */
305
491
 
306
- export { AgentService };
492
+ export { AgentMessageService, AgentService, HamlibService, WsjtxService };
307
493
  //# sourceMappingURL=ngx-kel-agent.mjs.map