@tx5dr/contracts 2.0.0 → 2.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/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schema/__tests__/assisted-queue.schema.test.js +1 -0
- package/dist/schema/__tests__/assisted-queue.schema.test.js.map +1 -1
- package/dist/schema/__tests__/meter.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/meter.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/meter.schema.test.js +27 -0
- package/dist/schema/__tests__/meter.schema.test.js.map +1 -0
- package/dist/schema/__tests__/operator-context-report.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/operator-context-report.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/operator-context-report.schema.test.js +70 -0
- package/dist/schema/__tests__/operator-context-report.schema.test.js.map +1 -0
- package/dist/schema/__tests__/plugin-market.schema.test.js +107 -3
- package/dist/schema/__tests__/plugin-market.schema.test.js.map +1 -1
- package/dist/schema/__tests__/qso.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/qso.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/qso.schema.test.js +70 -0
- package/dist/schema/__tests__/qso.schema.test.js.map +1 -0
- package/dist/schema/__tests__/radio-power-support.test.js +4 -1
- package/dist/schema/__tests__/radio-power-support.test.js.map +1 -1
- package/dist/schema/__tests__/radio.schema.test.js +52 -1
- package/dist/schema/__tests__/radio.schema.test.js.map +1 -1
- package/dist/schema/__tests__/remote-access.schema.test.js +1 -1
- package/dist/schema/__tests__/remote-access.schema.test.js.map +1 -1
- package/dist/schema/__tests__/spectrum.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/spectrum.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/spectrum.schema.test.js +107 -0
- package/dist/schema/__tests__/spectrum.schema.test.js.map +1 -0
- package/dist/schema/__tests__/strategy-transmission.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/strategy-transmission.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/strategy-transmission.schema.test.js +95 -0
- package/dist/schema/__tests__/strategy-transmission.schema.test.js.map +1 -0
- package/dist/schema/api-response.schema.d.ts +235 -0
- package/dist/schema/api-response.schema.d.ts.map +1 -1
- package/dist/schema/api-response.schema.js +9 -0
- package/dist/schema/api-response.schema.js.map +1 -1
- package/dist/schema/auth.schema.d.ts +2 -2
- package/dist/schema/cpu-profile.schema.d.ts +2 -2
- package/dist/schema/device-ui.schema.d.ts +10 -10
- package/dist/schema/image-radio.schema.d.ts +2597 -0
- package/dist/schema/image-radio.schema.d.ts.map +1 -0
- package/dist/schema/image-radio.schema.js +283 -0
- package/dist/schema/image-radio.schema.js.map +1 -0
- package/dist/schema/logbook.schema.d.ts +203 -15
- package/dist/schema/logbook.schema.d.ts.map +1 -1
- package/dist/schema/logbook.schema.js +1 -0
- package/dist/schema/logbook.schema.js.map +1 -1
- package/dist/schema/mode.schema.d.ts +2 -0
- package/dist/schema/mode.schema.d.ts.map +1 -1
- package/dist/schema/mode.schema.js +16 -0
- package/dist/schema/mode.schema.js.map +1 -1
- package/dist/schema/openwebrx.schema.d.ts +2 -2
- package/dist/schema/operator.schema.d.ts +2676 -0
- package/dist/schema/operator.schema.d.ts.map +1 -1
- package/dist/schema/operator.schema.js +4 -19
- package/dist/schema/operator.schema.js.map +1 -1
- package/dist/schema/plugin.schema.d.ts +1780 -475
- package/dist/schema/plugin.schema.d.ts.map +1 -1
- package/dist/schema/plugin.schema.js +108 -12
- package/dist/schema/plugin.schema.js.map +1 -1
- package/dist/schema/qso.schema.d.ts +239 -1
- package/dist/schema/qso.schema.d.ts.map +1 -1
- package/dist/schema/qso.schema.js +61 -0
- package/dist/schema/qso.schema.js.map +1 -1
- package/dist/schema/radio-capability.schema.d.ts +1 -1
- package/dist/schema/radio-capability.schema.d.ts.map +1 -1
- package/dist/schema/radio-capability.schema.js +1 -0
- package/dist/schema/radio-capability.schema.js.map +1 -1
- package/dist/schema/radio-power.schema.d.ts +15 -0
- package/dist/schema/radio-power.schema.d.ts.map +1 -1
- package/dist/schema/radio-profile.schema.d.ts +251 -0
- package/dist/schema/radio-profile.schema.d.ts.map +1 -1
- package/dist/schema/radio-profile.schema.js +7 -0
- package/dist/schema/radio-profile.schema.js.map +1 -1
- package/dist/schema/radio.schema.d.ts +174 -3
- package/dist/schema/radio.schema.d.ts.map +1 -1
- package/dist/schema/radio.schema.js +31 -2
- package/dist/schema/radio.schema.js.map +1 -1
- package/dist/schema/rigctld.schema.d.ts +6 -6
- package/dist/schema/slot-info.schema.d.ts +13 -0
- package/dist/schema/slot-info.schema.d.ts.map +1 -1
- package/dist/schema/slot-info.schema.js +2 -1
- package/dist/schema/slot-info.schema.js.map +1 -1
- package/dist/schema/spectrum-config.schema.d.ts +638 -0
- package/dist/schema/spectrum-config.schema.d.ts.map +1 -0
- package/dist/schema/spectrum-config.schema.js +129 -0
- package/dist/schema/spectrum-config.schema.js.map +1 -0
- package/dist/schema/spectrum.schema.d.ts +1313 -20
- package/dist/schema/spectrum.schema.d.ts.map +1 -1
- package/dist/schema/spectrum.schema.js +72 -0
- package/dist/schema/spectrum.schema.js.map +1 -1
- package/dist/schema/transmission.schema.d.ts +7 -0
- package/dist/schema/transmission.schema.d.ts.map +1 -1
- package/dist/schema/tx-audio-input.schema.d.ts +8 -0
- package/dist/schema/tx-audio-input.schema.d.ts.map +1 -0
- package/dist/schema/tx-audio-input.schema.js +19 -0
- package/dist/schema/tx-audio-input.schema.js.map +1 -0
- package/dist/schema/voice.schema.d.ts +1 -1
- package/dist/schema/voice.schema.d.ts.map +1 -1
- package/dist/schema/voice.schema.js +1 -1
- package/dist/schema/voice.schema.js.map +1 -1
- package/dist/schema/websocket.schema.d.ts +27480 -2525
- package/dist/schema/websocket.schema.d.ts.map +1 -1
- package/dist/schema/websocket.schema.js +298 -11
- package/dist/schema/websocket.schema.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/schema/__tests__/assisted-queue.schema.test.ts +1 -0
- package/src/schema/__tests__/meter.schema.test.ts +28 -0
- package/src/schema/__tests__/operator-context-report.schema.test.ts +77 -0
- package/src/schema/__tests__/plugin-market.schema.test.ts +116 -2
- package/src/schema/__tests__/qso.schema.test.ts +91 -0
- package/src/schema/__tests__/radio-power-support.test.ts +4 -1
- package/src/schema/__tests__/radio.schema.test.ts +60 -1
- package/src/schema/__tests__/remote-access.schema.test.ts +1 -1
- package/src/schema/__tests__/spectrum.schema.test.ts +119 -0
- package/src/schema/__tests__/strategy-transmission.schema.test.ts +106 -0
- package/src/schema/api-response.schema.ts +11 -0
- package/src/schema/image-radio.schema.ts +342 -0
- package/src/schema/logbook.schema.ts +1 -0
- package/src/schema/mode.schema.ts +16 -0
- package/src/schema/operator.schema.ts +4 -19
- package/src/schema/plugin.schema.ts +119 -13
- package/src/schema/qso.schema.ts +71 -0
- package/src/schema/radio-capability.schema.ts +1 -0
- package/src/schema/radio-profile.schema.ts +7 -0
- package/src/schema/radio.schema.ts +35 -2
- package/src/schema/slot-info.schema.ts +2 -1
- package/src/schema/spectrum-config.schema.ts +156 -0
- package/src/schema/spectrum.schema.ts +89 -0
- package/src/schema/tx-audio-input.schema.ts +22 -0
- package/src/schema/voice.schema.ts +1 -1
- package/src/schema/websocket.schema.ts +383 -12
- package/test/image-radio-schema.test.ts +107 -0
- package/test/plugin-slot-schema.test.ts +31 -0
- package/CLAUDE.md +0 -41
|
@@ -20,7 +20,11 @@ import type {
|
|
|
20
20
|
PluginSystemSnapshot,
|
|
21
21
|
} from './plugin.schema.js';
|
|
22
22
|
import { ModeDescriptorSchema } from './mode.schema.js';
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
QSORecordSchema,
|
|
25
|
+
QSOPersistencePolicySchema,
|
|
26
|
+
TargetSelectionPriorityModeSchema,
|
|
27
|
+
} from './qso.schema.js';
|
|
24
28
|
import {
|
|
25
29
|
LogBookStatisticsSchema,
|
|
26
30
|
LogbookHealthSchema,
|
|
@@ -36,10 +40,27 @@ import { CWDecoderEventSchema, CWDecoderStatusSchema, type CWDecoderEvent, type
|
|
|
36
40
|
import { CapabilityListSchema, CapabilityStateSchema, WriteCapabilityPayloadSchema } from './radio-capability.schema.js';
|
|
37
41
|
import { RadioPowerStateEventSchema } from './radio-power.schema.js';
|
|
38
42
|
import { AudioSidecarStatusPayloadSchema } from './audio-sidecar.schema.js';
|
|
39
|
-
import { SpectrumCapabilitiesSchema, SpectrumFrameSchema, SpectrumKindSchema, SpectrumSessionControlActionSchema, SpectrumSessionControlIdSchema, SpectrumSessionStateSchema } from './spectrum.schema.js';
|
|
43
|
+
import { SpectrumCapabilitiesSchema, SpectrumFrameSchema, SpectrumKindSchema, SpectrumSessionControlActionSchema, SpectrumSessionControlIdSchema, SpectrumSessionStateSchema, SpectrumViewportSchema } from './spectrum.schema.js';
|
|
40
44
|
import type { RealtimeSettingsResponseData } from './realtime.schema.js';
|
|
41
45
|
import type { AndroidOperatorAudioStatus } from './android-operator-audio.schema.js';
|
|
42
46
|
import { ClockStatusSummarySchema } from './system.schema.js';
|
|
47
|
+
import {
|
|
48
|
+
ImageRadioStatusSchema,
|
|
49
|
+
ImageRxEventSchema,
|
|
50
|
+
ImageRxSubscriptionSchema,
|
|
51
|
+
FaxCalibrationCommandResultSchema,
|
|
52
|
+
FaxCalibrationResetCommandSchema,
|
|
53
|
+
FaxCalibrationSetCommandSchema,
|
|
54
|
+
SstvTxCancelCommandSchema,
|
|
55
|
+
SstvTxCommandResultSchema,
|
|
56
|
+
SstvTxStartCommandSchema,
|
|
57
|
+
SstvTxStatusSchema,
|
|
58
|
+
type ImageRadioStatus,
|
|
59
|
+
type ImageRxEvent,
|
|
60
|
+
type FaxCalibrationCommandResult,
|
|
61
|
+
type SstvTxCommandResult,
|
|
62
|
+
type SstvTxStatus,
|
|
63
|
+
} from './image-radio.schema.js';
|
|
43
64
|
|
|
44
65
|
// WebSocket消息类型枚举
|
|
45
66
|
export enum WSMessageType {
|
|
@@ -55,6 +76,16 @@ export enum WSMessageType {
|
|
|
55
76
|
STOP_ENGINE = 'stopEngine',
|
|
56
77
|
GET_STATUS = 'getStatus',
|
|
57
78
|
SET_MODE = 'setMode',
|
|
79
|
+
SUBSCRIBE_IMAGE_RX = 'subscribeImageRx',
|
|
80
|
+
IMAGE_RADIO_STATUS = 'imageRadioStatus',
|
|
81
|
+
IMAGE_RX_EVENT = 'imageRxEvent',
|
|
82
|
+
SSTV_TX_START = 'sstvTxStart',
|
|
83
|
+
SSTV_TX_CANCEL = 'sstvTxCancel',
|
|
84
|
+
SSTV_TX_STATUS = 'sstvTxStatus',
|
|
85
|
+
SSTV_TX_COMMAND_RESULT = 'sstvTxCommandResult',
|
|
86
|
+
FAX_CALIBRATION_SET = 'faxCalibrationSet',
|
|
87
|
+
FAX_CALIBRATION_RESET = 'faxCalibrationReset',
|
|
88
|
+
FAX_CALIBRATION_COMMAND_RESULT = 'faxCalibrationCommandResult',
|
|
58
89
|
|
|
59
90
|
// ===== 引擎事件 =====
|
|
60
91
|
MODE_CHANGED = 'modeChanged',
|
|
@@ -67,6 +98,7 @@ export enum WSMessageType {
|
|
|
67
98
|
SPECTRUM_FRAME = 'spectrumFrame',
|
|
68
99
|
SPECTRUM_SESSION_STATE_CHANGED = 'spectrumSessionStateChanged',
|
|
69
100
|
INVOKE_SPECTRUM_CONTROL = 'invokeSpectrumControl',
|
|
101
|
+
SPECTRUM_VIEWPORT_CHANGED = 'spectrumViewportChanged',
|
|
70
102
|
DECODE_ERROR = 'decodeError',
|
|
71
103
|
SYSTEM_STATUS = 'systemStatus',
|
|
72
104
|
BOOTSTRAP_STATUS_CHANGED = 'bootstrapStatusChanged',
|
|
@@ -80,6 +112,8 @@ export enum WSMessageType {
|
|
|
80
112
|
OPERATOR_STATUS_UPDATE = 'operatorStatusUpdate',
|
|
81
113
|
SET_OPERATOR_CONTEXT = 'setOperatorContext',
|
|
82
114
|
SET_OPERATOR_RUNTIME_STATE = 'setOperatorRuntimeState',
|
|
115
|
+
SET_OPERATOR_STREAM_STATE = 'setOperatorStreamState',
|
|
116
|
+
INVOKE_OPERATOR_STRATEGY_ACTION = 'invokeOperatorStrategyAction',
|
|
83
117
|
SET_OPERATOR_RUNTIME_SLOT_CONTENT = 'setOperatorRuntimeSlotContent',
|
|
84
118
|
SET_OPERATOR_TRANSMIT_CYCLES = 'setOperatorTransmitCycles',
|
|
85
119
|
START_OPERATOR = 'startOperator',
|
|
@@ -254,7 +288,7 @@ export const SystemStatusSchema = z.object({
|
|
|
254
288
|
connectionHealthy: z.boolean(),
|
|
255
289
|
}).optional(),
|
|
256
290
|
/** 引擎模式:digital(FT8/FT4)、voice(语音通联)或 cw(莫尔斯码) */
|
|
257
|
-
engineMode: z.enum(['digital', 'voice', 'cw']).default('digital'),
|
|
291
|
+
engineMode: z.enum(['digital', 'voice', 'cw', 'image']).default('digital'),
|
|
258
292
|
/** 当前电台调制模式(语音模式下使用,如 USB/LSB/FM/AM) */
|
|
259
293
|
currentRadioMode: z.string().optional(),
|
|
260
294
|
/** 引擎状态机当前状态 */
|
|
@@ -344,10 +378,11 @@ export const DecodeErrorInfoSchema = z.object({
|
|
|
344
378
|
/**
|
|
345
379
|
* Current dial-frequency projection broadcast to plugins and clients.
|
|
346
380
|
*
|
|
347
|
-
* `frequency` is RF dial
|
|
348
|
-
* `band` and `description` are display labels; `radioMode` is the
|
|
349
|
-
* modulation when known. `
|
|
350
|
-
*
|
|
381
|
+
* `frequency` is the logical RF dial target in hertz; `mode` is the TX-5DR
|
|
382
|
+
* engine mode; `band` and `description` are display labels; `radioMode` is the
|
|
383
|
+
* underlying modulation when known. `observedFrequency` is the latest physical
|
|
384
|
+
* readback. `source` distinguishes application changes from radio observations;
|
|
385
|
+
* `revision` and `connectionGeneration` reject stale events.
|
|
351
386
|
*/
|
|
352
387
|
export const FrequencyStateSchema = z.object({
|
|
353
388
|
frequency: z.number(),
|
|
@@ -357,6 +392,20 @@ export const FrequencyStateSchema = z.object({
|
|
|
357
392
|
radioMode: z.string().optional(),
|
|
358
393
|
radioConnected: z.boolean(),
|
|
359
394
|
source: z.enum(['program', 'radio']).optional(),
|
|
395
|
+
/** Monotonic operating-state revision for stale-event suppression. */
|
|
396
|
+
revision: z.number().int().nonnegative().optional(),
|
|
397
|
+
/** Physical CAT session identity associated with this snapshot. */
|
|
398
|
+
connectionGeneration: z.number().int().nonnegative().optional(),
|
|
399
|
+
/** Physical confirmation status for the requested operating state. */
|
|
400
|
+
confirmation: z.enum(['confirmed', 'pending', 'mismatch', 'offline']).optional(),
|
|
401
|
+
/** Last frequency read back from the physical radio, when available. */
|
|
402
|
+
observedFrequency: z.number().optional(),
|
|
403
|
+
/** Requested logical frequency when it differs from the observed value. */
|
|
404
|
+
requestedFrequency: z.number().optional(),
|
|
405
|
+
/** Correlates a snapshot with one programmatic operating-state mutation. */
|
|
406
|
+
operationId: z.string().optional(),
|
|
407
|
+
/** Physical radio-mode confirmation status. */
|
|
408
|
+
modeConfirmation: z.enum(['confirmed', 'unconfirmed', 'unknown']).optional(),
|
|
360
409
|
});
|
|
361
410
|
|
|
362
411
|
export const SpectrumControlInvocationSchema = z.object({
|
|
@@ -371,7 +420,7 @@ export const PTTStatusSchema = z.object({
|
|
|
371
420
|
operatorIds: z.array(z.string()),
|
|
372
421
|
phase: z.enum(['idle', 'starting', 'on_air', 'draining', 'stopping', 'unknown']).optional(),
|
|
373
422
|
frameId: z.string().optional(),
|
|
374
|
-
source: z.enum(['digital', 'voice', 'voice-keyer', 'cw', 'tune-tone', 'manual', 'test']).optional(),
|
|
423
|
+
source: z.enum(['digital', 'voice', 'voice-keyer', 'cw', 'sstv', 'tune-tone', 'manual', 'test']).optional(),
|
|
375
424
|
});
|
|
376
425
|
|
|
377
426
|
export const TuneToneStartPayloadSchema = z.object({
|
|
@@ -409,8 +458,103 @@ export const StrategyRuntimeContextSchema = z.object({
|
|
|
409
458
|
});
|
|
410
459
|
export type StrategyRuntimeContext = z.infer<typeof StrategyRuntimeContextSchema>;
|
|
411
460
|
|
|
461
|
+
export const StrategyStateOptionSchema = z.object({
|
|
462
|
+
id: z.string().min(1),
|
|
463
|
+
label: z.string().min(1).optional(),
|
|
464
|
+
transmitText: z.string().optional(),
|
|
465
|
+
});
|
|
466
|
+
export type StrategyStateOption = z.infer<typeof StrategyStateOptionSchema>;
|
|
467
|
+
|
|
468
|
+
export const StrategyActionInputSchema = z.discriminatedUnion('kind', [
|
|
469
|
+
z.object({
|
|
470
|
+
kind: z.literal('text'),
|
|
471
|
+
label: z.string().optional(),
|
|
472
|
+
value: z.string().optional(),
|
|
473
|
+
placeholder: z.string().optional(),
|
|
474
|
+
maxLength: z.number().int().positive().optional(),
|
|
475
|
+
}),
|
|
476
|
+
z.object({
|
|
477
|
+
kind: z.enum(['number', 'audio-frequency']),
|
|
478
|
+
label: z.string().optional(),
|
|
479
|
+
value: z.number().optional(),
|
|
480
|
+
min: z.number().optional(),
|
|
481
|
+
max: z.number().optional(),
|
|
482
|
+
step: z.number().positive().optional(),
|
|
483
|
+
unit: z.string().optional(),
|
|
484
|
+
spectrumPick: z.boolean().optional(),
|
|
485
|
+
}),
|
|
486
|
+
]);
|
|
487
|
+
|
|
488
|
+
export const StrategyActionDescriptorSchema = z.object({
|
|
489
|
+
id: z.string().min(1),
|
|
490
|
+
label: z.string().min(1),
|
|
491
|
+
description: z.string().optional(),
|
|
492
|
+
icon: z.string().optional(),
|
|
493
|
+
tone: z.enum(['default', 'primary', 'success', 'warning', 'danger']).optional(),
|
|
494
|
+
presentation: z.enum(['primary', 'secondary', 'menu', 'segmented']).optional(),
|
|
495
|
+
groupId: z.string().optional(),
|
|
496
|
+
selected: z.boolean().optional(),
|
|
497
|
+
disabledReason: z.string().optional(),
|
|
498
|
+
previewText: z.string().optional(),
|
|
499
|
+
confirmation: z.object({
|
|
500
|
+
title: z.string().min(1),
|
|
501
|
+
description: z.string().optional(),
|
|
502
|
+
confirmLabel: z.string().optional(),
|
|
503
|
+
cancelLabel: z.string().optional(),
|
|
504
|
+
}).optional(),
|
|
505
|
+
input: StrategyActionInputSchema.optional(),
|
|
506
|
+
navigation: z.object({
|
|
507
|
+
kind: z.literal('plugin-page'),
|
|
508
|
+
pageId: z.string().min(1),
|
|
509
|
+
}).optional(),
|
|
510
|
+
});
|
|
511
|
+
export type StrategyActionDescriptor = z.infer<typeof StrategyActionDescriptorSchema>;
|
|
512
|
+
|
|
513
|
+
export const StrategyAttentionSchema = z.object({
|
|
514
|
+
id: z.string().min(1),
|
|
515
|
+
tone: z.enum(['info', 'warning', 'danger', 'success']),
|
|
516
|
+
title: z.string().min(1),
|
|
517
|
+
description: z.string().optional(),
|
|
518
|
+
params: z.record(z.string(), z.union([z.string(), z.number()])).optional(),
|
|
519
|
+
notify: z.boolean().optional(),
|
|
520
|
+
expiresAt: z.number().optional(),
|
|
521
|
+
actionIds: z.array(z.string()).optional(),
|
|
522
|
+
});
|
|
523
|
+
export type StrategyAttention = z.infer<typeof StrategyAttentionSchema>;
|
|
524
|
+
|
|
525
|
+
export const StrategyCompletionProjectionSchema = z.object({
|
|
526
|
+
state: z.enum(['not-ready', 'ready', 'committing', 'committed', 'failed']),
|
|
527
|
+
label: z.string().optional(),
|
|
528
|
+
recordId: z.string().optional(),
|
|
529
|
+
});
|
|
530
|
+
export type StrategyCompletionProjection = z.infer<typeof StrategyCompletionProjectionSchema>;
|
|
531
|
+
|
|
532
|
+
export const StrategyStreamSnapshotSchema = z.object({
|
|
533
|
+
streamId: z.string().min(1),
|
|
534
|
+
currentState: z.string(),
|
|
535
|
+
targetCallsign: z.string().optional(),
|
|
536
|
+
targetGrid: z.string().optional(),
|
|
537
|
+
audioFrequencyHz: z.number().min(0).max(5000),
|
|
538
|
+
qsoLifecycleEpoch: z.number().int().nonnegative(),
|
|
539
|
+
stateOptions: z.array(StrategyStateOptionSchema).optional(),
|
|
540
|
+
actions: z.array(StrategyActionDescriptorSchema).optional(),
|
|
541
|
+
attentions: z.array(StrategyAttentionSchema).optional(),
|
|
542
|
+
completion: StrategyCompletionProjectionSchema.optional(),
|
|
543
|
+
lastReceivedText: z.string().optional(),
|
|
544
|
+
nextTransmitText: z.string().optional(),
|
|
545
|
+
});
|
|
546
|
+
export type StrategyStreamSnapshot = z.infer<typeof StrategyStreamSnapshotSchema>;
|
|
547
|
+
|
|
548
|
+
export const StrategyTransmissionSchema = z.object({
|
|
549
|
+
streamId: z.string().min(1),
|
|
550
|
+
text: z.string().min(1),
|
|
551
|
+
audioFrequencyHz: z.number().min(0).max(5000),
|
|
552
|
+
});
|
|
553
|
+
export type StrategyTransmission = z.infer<typeof StrategyTransmissionSchema>;
|
|
554
|
+
|
|
412
555
|
export const AssistedQueueDisplayStateSchema = z.enum([
|
|
413
556
|
'TX1', 'TX2', 'TX3', 'TX4', 'TX5', 'engaged', 'closing', 'paused', 'no-response', 'later', 'review',
|
|
557
|
+
'candidate', 'authorized', 'dupe',
|
|
414
558
|
]);
|
|
415
559
|
export const AssistedQueuePauseReasonSchema = z.enum(['target-busy', 'stale']);
|
|
416
560
|
export const AssistedQueueToneSchema = z.enum(['neutral', 'active', 'success', 'warning', 'danger']);
|
|
@@ -430,10 +574,18 @@ export const AssistedQueueRowSchema = z.object({
|
|
|
430
574
|
targetGrid: z.string().optional(),
|
|
431
575
|
lastSnr: z.number().optional(),
|
|
432
576
|
lastHeardCyclesAgo: z.number().int().nonnegative().optional(),
|
|
577
|
+
lastHeardCycle: z.union([z.literal(0), z.literal(1)]).optional(),
|
|
578
|
+
streamId: z.string().optional(),
|
|
579
|
+
audioFrequencyHz: z.number().optional(),
|
|
580
|
+
authorizationId: z.string().optional(),
|
|
581
|
+
actions: z.array(StrategyActionDescriptorSchema).optional(),
|
|
433
582
|
});
|
|
434
583
|
export const AssistedQueueSnapshotSchema = z.object({
|
|
435
584
|
version: z.number().int().nonnegative(),
|
|
436
585
|
activeEntryId: z.string().optional(),
|
|
586
|
+
activeEntryIds: z.array(z.string()).optional(),
|
|
587
|
+
maxActiveStreams: z.number().int().min(1).max(5).optional(),
|
|
588
|
+
requestedMaxActiveStreams: z.number().int().min(1).max(5).optional(),
|
|
437
589
|
rows: z.array(AssistedQueueRowSchema),
|
|
438
590
|
});
|
|
439
591
|
export type AssistedQueueDisplayState = z.infer<typeof AssistedQueueDisplayStateSchema>;
|
|
@@ -443,6 +595,63 @@ export type AssistedQueueIcon = z.infer<typeof AssistedQueueIconSchema>;
|
|
|
443
595
|
export type AssistedQueueRow = z.infer<typeof AssistedQueueRowSchema>;
|
|
444
596
|
export type AssistedQueueSnapshot = z.infer<typeof AssistedQueueSnapshotSchema>;
|
|
445
597
|
|
|
598
|
+
/** Null clears an unsettable runtime report field over JSON/WebSocket. */
|
|
599
|
+
export const OperatorContextReportFieldSchema = z.number().nullish();
|
|
600
|
+
|
|
601
|
+
export const StrategyMessagePresentationToneSchema = z.enum([
|
|
602
|
+
'neutral', 'primary', 'secondary', 'success', 'warning', 'danger',
|
|
603
|
+
]);
|
|
604
|
+
export const StrategyMessagePresentationBadgeSchema = z.object({
|
|
605
|
+
label: z.string().min(1),
|
|
606
|
+
tone: StrategyMessagePresentationToneSchema,
|
|
607
|
+
});
|
|
608
|
+
export const StrategyMessagePresentationTokenMatchSchema = z.object({
|
|
609
|
+
firstTokenIn: z.array(z.string().min(1)).optional(),
|
|
610
|
+
anyTokenIn: z.array(z.string().min(1)).optional(),
|
|
611
|
+
});
|
|
612
|
+
export const StrategyMessagePresentationClassSchema = z.object({
|
|
613
|
+
badge: StrategyMessagePresentationBadgeSchema.optional(),
|
|
614
|
+
badges: z.array(StrategyMessagePresentationBadgeSchema).optional(),
|
|
615
|
+
row: z.object({
|
|
616
|
+
tone: StrategyMessagePresentationToneSchema,
|
|
617
|
+
background: z.enum(['none', 'soft']).optional(),
|
|
618
|
+
accent: z.boolean().optional(),
|
|
619
|
+
}).optional(),
|
|
620
|
+
emphasisWhen: z.array(StrategyMessagePresentationTokenMatchSchema).min(1).optional(),
|
|
621
|
+
textDecoration: z.literal('line-through').optional(),
|
|
622
|
+
opacity: z.enum(['normal', 'muted']).optional(),
|
|
623
|
+
});
|
|
624
|
+
export const StrategyMessagePresentationProjectionSchema = z.object({
|
|
625
|
+
revision: z.number().int().nonnegative(),
|
|
626
|
+
mode: z.enum(['replace-logbook', 'augment']),
|
|
627
|
+
subject: z.literal('sender-callsign'),
|
|
628
|
+
partitionBy: z.enum(['band', 'mode', 'none']),
|
|
629
|
+
eligiblePartitions: z.array(z.string()).optional(),
|
|
630
|
+
defaultClass: z.string().optional(),
|
|
631
|
+
classes: z.record(z.string(), StrategyMessagePresentationClassSchema),
|
|
632
|
+
assignments: z.array(z.object({
|
|
633
|
+
subject: z.string().min(1),
|
|
634
|
+
partition: z.string().optional(),
|
|
635
|
+
classId: z.string().min(1),
|
|
636
|
+
})),
|
|
637
|
+
noveltyRules: z.array(z.object({
|
|
638
|
+
fact: z.literal('grid-field-2'),
|
|
639
|
+
knownValuesByPartition: z.record(z.string(), z.array(z.string().min(1))),
|
|
640
|
+
classId: z.string().min(1),
|
|
641
|
+
})).optional(),
|
|
642
|
+
tagRules: z.array(z.object({
|
|
643
|
+
id: z.string().min(1),
|
|
644
|
+
match: StrategyMessagePresentationTokenMatchSchema,
|
|
645
|
+
badge: StrategyMessagePresentationBadgeSchema,
|
|
646
|
+
})).optional(),
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
export type StrategyMessagePresentationTone = z.infer<typeof StrategyMessagePresentationToneSchema>;
|
|
650
|
+
export type StrategyMessagePresentationBadge = z.infer<typeof StrategyMessagePresentationBadgeSchema>;
|
|
651
|
+
export type StrategyMessagePresentationTokenMatch = z.infer<typeof StrategyMessagePresentationTokenMatchSchema>;
|
|
652
|
+
export type StrategyMessagePresentationClass = z.infer<typeof StrategyMessagePresentationClassSchema>;
|
|
653
|
+
export type StrategyMessagePresentationProjection = z.infer<typeof StrategyMessagePresentationProjectionSchema>;
|
|
654
|
+
|
|
446
655
|
export const StrategyRuntimeSnapshotSchema = z.object({
|
|
447
656
|
currentState: z.string(),
|
|
448
657
|
slots: z.object({
|
|
@@ -456,8 +665,32 @@ export const StrategyRuntimeSnapshotSchema = z.object({
|
|
|
456
665
|
context: StrategyRuntimeContextSchema.optional(),
|
|
457
666
|
availableSlots: z.array(z.string()).optional(),
|
|
458
667
|
qsoLifecycleEpoch: z.number().int().nonnegative().optional(),
|
|
668
|
+
streams: z.array(StrategyStreamSnapshotSchema).optional(),
|
|
459
669
|
queue: AssistedQueueSnapshotSchema.optional(),
|
|
670
|
+
actions: z.array(StrategyActionDescriptorSchema).optional(),
|
|
671
|
+
attentions: z.array(StrategyAttentionSchema).optional(),
|
|
672
|
+
messagePresentation: StrategyMessagePresentationProjectionSchema.optional(),
|
|
673
|
+
transmitGate: z.object({
|
|
674
|
+
allowed: z.literal(false),
|
|
675
|
+
reason: z.string().min(1),
|
|
676
|
+
actionId: z.string().optional(),
|
|
677
|
+
}).optional(),
|
|
460
678
|
});
|
|
679
|
+
|
|
680
|
+
export const StrategyActionTargetSchema = z.discriminatedUnion('kind', [
|
|
681
|
+
z.object({ kind: z.literal('runtime') }),
|
|
682
|
+
z.object({
|
|
683
|
+
kind: z.literal('stream'),
|
|
684
|
+
streamId: z.string().min(1),
|
|
685
|
+
lifecycleEpoch: z.number().int().nonnegative(),
|
|
686
|
+
}),
|
|
687
|
+
z.object({
|
|
688
|
+
kind: z.literal('queue-entry'),
|
|
689
|
+
entryId: z.string().min(1),
|
|
690
|
+
queueVersion: z.number().int().nonnegative(),
|
|
691
|
+
}),
|
|
692
|
+
]);
|
|
693
|
+
export type StrategyActionTarget = z.infer<typeof StrategyActionTargetSchema>;
|
|
461
694
|
export type StrategyRuntimeSnapshot = z.infer<typeof StrategyRuntimeSnapshotSchema>;
|
|
462
695
|
|
|
463
696
|
export const LevelMeterDisplayStyleSchema = z.enum([
|
|
@@ -515,11 +748,12 @@ export const MeterDataSchema = z.object({
|
|
|
515
748
|
raw: z.number(),
|
|
516
749
|
percent: z.number(),
|
|
517
750
|
alert: z.boolean(),
|
|
751
|
+
unit: z.enum(['percent', 'dbfs']).optional(),
|
|
518
752
|
}).nullable(),
|
|
519
753
|
level: LevelMeterReadingSchema.nullable(),
|
|
520
754
|
power: z.object({
|
|
521
755
|
raw: z.number(),
|
|
522
|
-
percent: z.number(),
|
|
756
|
+
percent: z.number().nullable(),
|
|
523
757
|
watts: z.number().nullable(), // 绝对瓦数(仅当电台支持 RFPOWER_METER_WATTS 时非 null)
|
|
524
758
|
maxWatts: z.number().nullable(), // 当前频率+模式对应的量程瓦数
|
|
525
759
|
}).nullable(),
|
|
@@ -566,6 +800,56 @@ export const WSModeChangedMessageSchema = WSBaseMessageSchema.extend({
|
|
|
566
800
|
data: ModeDescriptorSchema,
|
|
567
801
|
});
|
|
568
802
|
|
|
803
|
+
export const WSSubscribeImageRxMessageSchema = WSBaseMessageSchema.extend({
|
|
804
|
+
type: z.literal(WSMessageType.SUBSCRIBE_IMAGE_RX),
|
|
805
|
+
data: ImageRxSubscriptionSchema,
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
export const WSImageRadioStatusMessageSchema = WSBaseMessageSchema.extend({
|
|
809
|
+
type: z.literal(WSMessageType.IMAGE_RADIO_STATUS),
|
|
810
|
+
data: ImageRadioStatusSchema,
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
export const WSImageRxEventMessageSchema = WSBaseMessageSchema.extend({
|
|
814
|
+
type: z.literal(WSMessageType.IMAGE_RX_EVENT),
|
|
815
|
+
data: ImageRxEventSchema,
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
export const WSSstvTxStartMessageSchema = WSBaseMessageSchema.extend({
|
|
819
|
+
type: z.literal(WSMessageType.SSTV_TX_START),
|
|
820
|
+
data: SstvTxStartCommandSchema,
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
export const WSSstvTxCancelMessageSchema = WSBaseMessageSchema.extend({
|
|
824
|
+
type: z.literal(WSMessageType.SSTV_TX_CANCEL),
|
|
825
|
+
data: SstvTxCancelCommandSchema,
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
export const WSSstvTxStatusMessageSchema = WSBaseMessageSchema.extend({
|
|
829
|
+
type: z.literal(WSMessageType.SSTV_TX_STATUS),
|
|
830
|
+
data: SstvTxStatusSchema,
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
export const WSSstvTxCommandResultMessageSchema = WSBaseMessageSchema.extend({
|
|
834
|
+
type: z.literal(WSMessageType.SSTV_TX_COMMAND_RESULT),
|
|
835
|
+
data: SstvTxCommandResultSchema,
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
export const WSFaxCalibrationSetMessageSchema = WSBaseMessageSchema.extend({
|
|
839
|
+
type: z.literal(WSMessageType.FAX_CALIBRATION_SET),
|
|
840
|
+
data: FaxCalibrationSetCommandSchema,
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
export const WSFaxCalibrationResetMessageSchema = WSBaseMessageSchema.extend({
|
|
844
|
+
type: z.literal(WSMessageType.FAX_CALIBRATION_RESET),
|
|
845
|
+
data: FaxCalibrationResetCommandSchema,
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
export const WSFaxCalibrationCommandResultMessageSchema = WSBaseMessageSchema.extend({
|
|
849
|
+
type: z.literal(WSMessageType.FAX_CALIBRATION_COMMAND_RESULT),
|
|
850
|
+
data: FaxCalibrationCommandResultSchema,
|
|
851
|
+
});
|
|
852
|
+
|
|
569
853
|
export const WSSlotStartMessageSchema = WSBaseMessageSchema.extend({
|
|
570
854
|
type: z.literal(WSMessageType.SLOT_START),
|
|
571
855
|
data: SlotInfoSchema,
|
|
@@ -590,9 +874,15 @@ export const WSSubscribeSpectrumMessageSchema = WSBaseMessageSchema.extend({
|
|
|
590
874
|
type: z.literal(WSMessageType.SUBSCRIBE_SPECTRUM),
|
|
591
875
|
data: z.object({
|
|
592
876
|
kind: SpectrumKindSchema.nullable(),
|
|
877
|
+
viewport: SpectrumViewportSchema.optional(),
|
|
593
878
|
}),
|
|
594
879
|
});
|
|
595
880
|
|
|
881
|
+
export const WSSpectrumViewportChangedMessageSchema = WSBaseMessageSchema.extend({
|
|
882
|
+
type: z.literal(WSMessageType.SPECTRUM_VIEWPORT_CHANGED),
|
|
883
|
+
data: SpectrumViewportSchema.nullable(),
|
|
884
|
+
});
|
|
885
|
+
|
|
596
886
|
export const WSSpectrumSubscriptionChangedMessageSchema = WSBaseMessageSchema.extend({
|
|
597
887
|
type: z.literal(WSMessageType.SPECTRUM_SUBSCRIPTION_CHANGED),
|
|
598
888
|
data: z.object({
|
|
@@ -707,10 +997,13 @@ export const OperatorStatusSchema = z.object({
|
|
|
707
997
|
isTransmitting: z.boolean(), // 是否已授予策略自动发射许可(发射开关状态)
|
|
708
998
|
isInActivePTT: z.boolean().optional(), // 该操作员的音频是否正在被实际播放
|
|
709
999
|
hasTransmitIntent: z.boolean().optional(), // 当前策略是否有可在合法周期发射的有效内容
|
|
1000
|
+
currentTransmissions: z.array(StrategyTransmissionSchema).optional(),
|
|
710
1001
|
currentSlot: z.string().optional(),
|
|
711
1002
|
context: z.object({
|
|
712
1003
|
myCall: z.string(),
|
|
713
1004
|
myGrid: z.string(),
|
|
1005
|
+
/** Canonical active target set; `targetCall` remains the primary compatibility field. */
|
|
1006
|
+
targetCalls: z.array(z.string()).optional(),
|
|
714
1007
|
targetCall: z.string(),
|
|
715
1008
|
targetGrid: z.string().optional(),
|
|
716
1009
|
frequency: z.number().optional(),
|
|
@@ -776,8 +1069,8 @@ export const WSSetOperatorContextMessageSchema = WSBaseMessageSchema.extend({
|
|
|
776
1069
|
targetCallsign: z.string().optional(),
|
|
777
1070
|
targetGrid: z.string().optional(),
|
|
778
1071
|
frequency: z.number().optional(),
|
|
779
|
-
reportSent:
|
|
780
|
-
reportReceived:
|
|
1072
|
+
reportSent: OperatorContextReportFieldSchema,
|
|
1073
|
+
reportReceived: OperatorContextReportFieldSchema,
|
|
781
1074
|
}),
|
|
782
1075
|
}),
|
|
783
1076
|
});
|
|
@@ -793,6 +1086,27 @@ export const WSSetOperatorRuntimeStateMessageSchema = WSBaseMessageSchema.extend
|
|
|
793
1086
|
}),
|
|
794
1087
|
});
|
|
795
1088
|
|
|
1089
|
+
/** Sets one strategy-owned stream to a protocol-approved state. */
|
|
1090
|
+
export const WSSetOperatorStreamStateMessageSchema = WSBaseMessageSchema.extend({
|
|
1091
|
+
type: z.literal(WSMessageType.SET_OPERATOR_STREAM_STATE),
|
|
1092
|
+
data: z.object({
|
|
1093
|
+
operatorId: z.string(),
|
|
1094
|
+
streamId: z.string().min(1),
|
|
1095
|
+
stateId: z.string().min(1),
|
|
1096
|
+
expectedLifecycleEpoch: z.number().int().nonnegative(),
|
|
1097
|
+
}),
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
export const WSInvokeOperatorStrategyActionMessageSchema = WSBaseMessageSchema.extend({
|
|
1101
|
+
type: z.literal(WSMessageType.INVOKE_OPERATOR_STRATEGY_ACTION),
|
|
1102
|
+
data: z.object({
|
|
1103
|
+
operatorId: z.string().min(1),
|
|
1104
|
+
target: StrategyActionTargetSchema,
|
|
1105
|
+
actionId: z.string().min(1),
|
|
1106
|
+
payload: z.unknown().optional(),
|
|
1107
|
+
}),
|
|
1108
|
+
});
|
|
1109
|
+
|
|
796
1110
|
/**
|
|
797
1111
|
* 设置操作员运行时槽位内容消息
|
|
798
1112
|
*/
|
|
@@ -965,6 +1279,8 @@ export type WSOperatorsListMessage = z.infer<typeof WSOperatorsListMessageSchema
|
|
|
965
1279
|
export type WSOperatorStatusUpdateMessage = z.infer<typeof WSOperatorStatusUpdateMessageSchema>;
|
|
966
1280
|
export type WSSetOperatorContextMessage = z.infer<typeof WSSetOperatorContextMessageSchema>;
|
|
967
1281
|
export type WSSetOperatorRuntimeStateMessage = z.infer<typeof WSSetOperatorRuntimeStateMessageSchema>;
|
|
1282
|
+
export type WSSetOperatorStreamStateMessage = z.infer<typeof WSSetOperatorStreamStateMessageSchema>;
|
|
1283
|
+
export type WSInvokeOperatorStrategyActionMessage = z.infer<typeof WSInvokeOperatorStrategyActionMessageSchema>;
|
|
968
1284
|
export type WSSetOperatorRuntimeSlotContentMessage = z.infer<typeof WSSetOperatorRuntimeSlotContentMessageSchema>;
|
|
969
1285
|
export type WSSetOperatorTransmitCyclesMessage = z.infer<typeof WSSetOperatorTransmitCyclesMessageSchema>;
|
|
970
1286
|
export type WSStartOperatorMessage = z.infer<typeof WSStartOperatorMessageSchema>;
|
|
@@ -1551,12 +1867,23 @@ export const WSMessageSchema = z.discriminatedUnion('type', [
|
|
|
1551
1867
|
WSPongMessageSchema,
|
|
1552
1868
|
// 服务端到客户端
|
|
1553
1869
|
WSModeChangedMessageSchema,
|
|
1870
|
+
WSSubscribeImageRxMessageSchema,
|
|
1871
|
+
WSImageRadioStatusMessageSchema,
|
|
1872
|
+
WSImageRxEventMessageSchema,
|
|
1873
|
+
WSSstvTxStartMessageSchema,
|
|
1874
|
+
WSSstvTxCancelMessageSchema,
|
|
1875
|
+
WSSstvTxStatusMessageSchema,
|
|
1876
|
+
WSSstvTxCommandResultMessageSchema,
|
|
1877
|
+
WSFaxCalibrationSetMessageSchema,
|
|
1878
|
+
WSFaxCalibrationResetMessageSchema,
|
|
1879
|
+
WSFaxCalibrationCommandResultMessageSchema,
|
|
1554
1880
|
WSSlotStartMessageSchema,
|
|
1555
1881
|
WSSubWindowMessageSchema,
|
|
1556
1882
|
WSSlotPackUpdatedMessageSchema,
|
|
1557
1883
|
WSSpectrumCapabilitiesMessageSchema,
|
|
1558
1884
|
WSSubscribeSpectrumMessageSchema,
|
|
1559
1885
|
WSSpectrumSubscriptionChangedMessageSchema,
|
|
1886
|
+
WSSpectrumViewportChangedMessageSchema,
|
|
1560
1887
|
WSSpectrumFrameMessageSchema,
|
|
1561
1888
|
WSSpectrumSessionStateChangedMessageSchema,
|
|
1562
1889
|
WSInvokeSpectrumControlMessageSchema,
|
|
@@ -1581,6 +1908,8 @@ export const WSMessageSchema = z.discriminatedUnion('type', [
|
|
|
1581
1908
|
WSOperatorStatusUpdateMessageSchema,
|
|
1582
1909
|
WSSetOperatorContextMessageSchema,
|
|
1583
1910
|
WSSetOperatorRuntimeStateMessageSchema,
|
|
1911
|
+
WSSetOperatorStreamStateMessageSchema,
|
|
1912
|
+
WSInvokeOperatorStrategyActionMessageSchema,
|
|
1584
1913
|
WSSetOperatorRuntimeSlotContentMessageSchema,
|
|
1585
1914
|
WSSetOperatorTransmitCyclesMessageSchema,
|
|
1586
1915
|
WSStartOperatorMessageSchema,
|
|
@@ -1679,6 +2008,7 @@ export type WSSlotPackUpdatedMessage = z.infer<typeof WSSlotPackUpdatedMessageSc
|
|
|
1679
2008
|
export type WSSpectrumCapabilitiesMessage = z.infer<typeof WSSpectrumCapabilitiesMessageSchema>;
|
|
1680
2009
|
export type WSSubscribeSpectrumMessage = z.infer<typeof WSSubscribeSpectrumMessageSchema>;
|
|
1681
2010
|
export type WSSpectrumSubscriptionChangedMessage = z.infer<typeof WSSpectrumSubscriptionChangedMessageSchema>;
|
|
2011
|
+
export type WSSpectrumViewportChangedMessage = z.infer<typeof WSSpectrumViewportChangedMessageSchema>;
|
|
1682
2012
|
export type WSSpectrumFrameMessage = z.infer<typeof WSSpectrumFrameMessageSchema>;
|
|
1683
2013
|
export type WSSpectrumSessionStateChangedMessage = z.infer<typeof WSSpectrumSessionStateChangedMessageSchema>;
|
|
1684
2014
|
export type WSInvokeSpectrumControlMessage = z.infer<typeof WSInvokeSpectrumControlMessageSchema>;
|
|
@@ -1696,7 +2026,9 @@ export type WSGetStatusMessage = z.infer<typeof WSGetStatusMessageSchema>;
|
|
|
1696
2026
|
|
|
1697
2027
|
export const TransmitRequestSchema = z.object({
|
|
1698
2028
|
operatorId: z.string(),
|
|
2029
|
+
streamId: z.string().min(1).optional(),
|
|
1699
2030
|
transmission: z.string(),
|
|
2031
|
+
audioFrequencyHz: z.number().min(0).max(5000).optional(),
|
|
1700
2032
|
/** 是否覆盖同一操作员在同一时隙的现有 TX 帧(自动重决策时为 true) */
|
|
1701
2033
|
replaceExisting: z.boolean().optional(),
|
|
1702
2034
|
source: z.enum(['standard-qso', 'plugin', 'late-decode', 'operator-edit', 'manual']).optional(),
|
|
@@ -1707,6 +2039,20 @@ export const TransmitRequestSchema = z.object({
|
|
|
1707
2039
|
|
|
1708
2040
|
export type TransmitRequest = z.infer<typeof TransmitRequestSchema>;
|
|
1709
2041
|
|
|
2042
|
+
export const TransmitBatchRequestSchema = z.object({
|
|
2043
|
+
operatorId: z.string(),
|
|
2044
|
+
transmissions: z.array(z.object({
|
|
2045
|
+
streamId: z.string().min(1),
|
|
2046
|
+
transmission: z.string(),
|
|
2047
|
+
audioFrequencyHz: z.number().min(0).max(5000),
|
|
2048
|
+
})).max(5),
|
|
2049
|
+
replaceExisting: z.boolean().optional(),
|
|
2050
|
+
source: z.enum(['standard-qso', 'plugin', 'late-decode', 'operator-edit', 'manual']).optional(),
|
|
2051
|
+
reason: z.string().optional(),
|
|
2052
|
+
decisionEpoch: z.number().int().nonnegative().optional(),
|
|
2053
|
+
});
|
|
2054
|
+
export type TransmitBatchRequest = z.infer<typeof TransmitBatchRequestSchema>;
|
|
2055
|
+
|
|
1710
2056
|
// ===== 前端应用事件接口 =====
|
|
1711
2057
|
|
|
1712
2058
|
/**
|
|
@@ -1714,6 +2060,8 @@ export type TransmitRequest = z.infer<typeof TransmitRequestSchema>;
|
|
|
1714
2060
|
*/
|
|
1715
2061
|
export const TransmissionCompleteInfoSchema = z.object({
|
|
1716
2062
|
operatorId: z.string(),
|
|
2063
|
+
streamId: z.string().optional(),
|
|
2064
|
+
trackId: z.string().optional(),
|
|
1717
2065
|
success: z.boolean(),
|
|
1718
2066
|
frameId: z.string().optional(),
|
|
1719
2067
|
physicalConfirmed: z.boolean().optional(),
|
|
@@ -1747,9 +2095,11 @@ export interface DigitalRadioEngineEvents {
|
|
|
1747
2095
|
|
|
1748
2096
|
// 发射相关事件
|
|
1749
2097
|
requestTransmit: (request: TransmitRequest) => void;
|
|
2098
|
+
requestTransmitBatch: (request: TransmitBatchRequest) => void;
|
|
1750
2099
|
transmissionComplete: (info: TransmissionCompleteInfo) => void;
|
|
1751
2100
|
transmissionLog: (data: {
|
|
1752
2101
|
operatorId: string;
|
|
2102
|
+
streamId: string;
|
|
1753
2103
|
frameId: string;
|
|
1754
2104
|
revision: number;
|
|
1755
2105
|
playbackGeneration: number;
|
|
@@ -1791,6 +2141,11 @@ export interface DigitalRadioEngineEvents {
|
|
|
1791
2141
|
// PTT状态控制事件
|
|
1792
2142
|
pttStatusChanged: (data: PTTStatus) => void;
|
|
1793
2143
|
tuneToneStatusChanged: (data: TuneToneStatus) => void;
|
|
2144
|
+
imageRadioStatus: (data: ImageRadioStatus) => void;
|
|
2145
|
+
imageRxEvent: (data: ImageRxEvent) => void;
|
|
2146
|
+
sstvTxStatus: (data: SstvTxStatus) => void;
|
|
2147
|
+
sstvTxCommandResult: (data: SstvTxCommandResult) => void;
|
|
2148
|
+
faxCalibrationCommandResult: (data: FaxCalibrationCommandResult) => void;
|
|
1794
2149
|
|
|
1795
2150
|
// 电台数值表事件
|
|
1796
2151
|
meterData: (data: MeterData) => void;
|
|
@@ -1824,7 +2179,7 @@ export interface DigitalRadioEngineEvents {
|
|
|
1824
2179
|
|
|
1825
2180
|
// Profile 管理事件
|
|
1826
2181
|
profileChanged: (data: z.infer<typeof ProfileChangedEventSchema>) => void;
|
|
1827
|
-
profileListUpdated: (data: { profiles: z.infer<typeof RadioProfileSchema>[]; activeProfileId: string | null }) => void;
|
|
2182
|
+
profileListUpdated: (data: { profiles: z.infer<typeof RadioProfileSchema>[]; activeProfileId: string | null; hasConfiguredProfiles?: boolean }) => void;
|
|
1828
2183
|
realtimeSettingsChanged: (data: RealtimeSettingsResponseData) => void;
|
|
1829
2184
|
|
|
1830
2185
|
// 认证事件
|
|
@@ -1890,10 +2245,18 @@ export interface DigitalRadioEngineEvents {
|
|
|
1890
2245
|
transmitStart: (slotInfo: z.infer<typeof SlotInfoSchema>) => void;
|
|
1891
2246
|
timingWarning: (data: { title: string; text: string }) => void;
|
|
1892
2247
|
operatorSlotChanged: (data: { operatorId: string; slot: string }) => void;
|
|
2248
|
+
operatorStreamStateChanged: (data: {
|
|
2249
|
+
operatorId: string;
|
|
2250
|
+
streamId: string;
|
|
2251
|
+
state: string;
|
|
2252
|
+
commandEpoch?: number;
|
|
2253
|
+
source?: 'manual' | 'plugin' | 'late-decode' | 'slot-auto';
|
|
2254
|
+
}) => void;
|
|
1893
2255
|
operatorSlotContentChanged: (data: { operatorId: string; slot: string; content: string }) => void;
|
|
1894
2256
|
operatorFrequencyChanged: (data: { operatorId: string; frequency: number }) => void;
|
|
1895
2257
|
operatorTransmitCyclesChanged: (data: {
|
|
1896
2258
|
operatorId: string;
|
|
2259
|
+
previousTransmitCycles?: number[];
|
|
1897
2260
|
transmitCycles: number[];
|
|
1898
2261
|
commandEpoch?: number;
|
|
1899
2262
|
source?: 'manual' | 'plugin' | 'late-decode' | 'slot-auto';
|
|
@@ -1901,15 +2264,23 @@ export interface DigitalRadioEngineEvents {
|
|
|
1901
2264
|
}) => void;
|
|
1902
2265
|
qsoLifecycleChanged: (data: {
|
|
1903
2266
|
operatorId: string;
|
|
2267
|
+
streamId?: string;
|
|
1904
2268
|
lifecycleEpoch: number;
|
|
1905
2269
|
runtimeGeneration?: number;
|
|
1906
2270
|
}) => void;
|
|
1907
2271
|
recordQSO: (data: {
|
|
1908
2272
|
operatorId: string;
|
|
2273
|
+
streamId?: string;
|
|
1909
2274
|
qsoLifecycleId?: string;
|
|
1910
2275
|
qsoLifecycleEpoch?: number;
|
|
1911
2276
|
qsoRuntimeGeneration?: number;
|
|
1912
2277
|
qsoRecord: z.infer<typeof QSORecordSchema>;
|
|
2278
|
+
persistencePolicy?: z.infer<typeof QSOPersistencePolicySchema>;
|
|
2279
|
+
destination?:
|
|
2280
|
+
| { kind: 'plugin-session'; sessionId: string }
|
|
2281
|
+
| { kind: 'plugin-session-key'; sessionKey: string };
|
|
2282
|
+
sourcePluginName?: string;
|
|
2283
|
+
metadata?: Record<string, unknown>;
|
|
1913
2284
|
retryAttemptId?: string;
|
|
1914
2285
|
resolve?: (record: z.infer<typeof QSORecordSchema>) => void;
|
|
1915
2286
|
reject?: (error: unknown) => void;
|