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