Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2915,6 +2915,9 @@ if(PYTHON3_EXECUTABLE)
add_test(NAME aether_mcp_field_mapping
COMMAND ${PYTHON3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/tools/test_aether_mcp.py)
add_test(NAME automation_probe_field_mapping
COMMAND ${PYTHON3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/tools/test_automation_probe.py)
# Bridge docs must stay in sync with the verb registry (#4174 Phase 3):
# fail CI if the generated verb table drifts or a detail heading is dup'd.
add_test(NAME bridge_docs_check
Expand Down Expand Up @@ -3258,6 +3261,26 @@ target_link_libraries(flex_backend_lifecycle_test PRIVATE aethercore Qt6::Core)
set_target_properties(flex_backend_lifecycle_test PROPERTIES AUTOMOC ON)
add_test(NAME flex_backend_lifecycle_test COMMAND flex_backend_lifecycle_test)

# A pending client dBm request must retain a mismatching radio range for timeout
# reconciliation and yield before a radio-authoritative band-stack restore.
add_executable(panadapter_dbm_range_test tests/panadapter_dbm_range_test.cpp)
target_include_directories(panadapter_dbm_range_test PRIVATE src)
target_link_libraries(panadapter_dbm_range_test PRIVATE aethercore Qt6::Core)
set_target_properties(panadapter_dbm_range_test PROPERTIES AUTOMOC ON)
add_test(NAME panadapter_dbm_range_test COMMAND panadapter_dbm_range_test)

# The bridge preserves dragAt, target-tune, memory-recall, and authenticated
# positional requests across its bare and JSON protocol forms.
add_executable(automation_drag_at_test tests/automation_drag_at_test.cpp)
target_include_directories(automation_drag_at_test PRIVATE src)
target_link_libraries(automation_drag_at_test PRIVATE
aethercore Qt6::Core Qt6::Network Qt6::Widgets
)
set_target_properties(automation_drag_at_test PROPERTIES AUTOMOC ON)
add_test(NAME automation_drag_at_test COMMAND automation_drag_at_test)
set_tests_properties(automation_drag_at_test PROPERTIES
ENVIRONMENT "QT_QPA_PLATFORM=offscreen")

# aetherd RFC 2.3 template — pan decode/normalize chain (incl. wnb_level guard).
add_executable(aetherd_pan_decode_test tests/aetherd_pan_decode_test.cpp)
target_include_directories(aetherd_pan_decode_test PRIVATE src)
Expand Down
50 changes: 48 additions & 2 deletions docs/automation-bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ current state as `readOnly`, and the MCP server surfaces it in
- `dumpTree`
- `grab SpectrumWidget /tmp/pan.png`
- `{"cmd":"grab","target":"SpectrumWidget","path":"/tmp/pan.png"}`
- `{"cmd":"grab","args":"SpectrumWidget /tmp/pan.png","token":"..."}`
(the optional `args` string uses the same positional parser as a bare
command, which is useful when authenticated requests also need a token)
- **Discovery:** on startup the app writes the resolved socket path to
`${TMPDIR:-/tmp}/aethersdr-automation.json`, so you never have to guess the
platform-specific endpoint:
Expand Down Expand Up @@ -260,6 +263,7 @@ transmit-gated verbs (refused unless `AETHER_AUTOMATION_ALLOW_TX=1` — see
| **Drive** | [`invoke <target> <action> [v]`](#invoke) | Click/toggle/set/selectRow/submit/trigger a control (TX-guarded). |
| | [`close <target>`](#close) | Close the target's top-level window. |
| | [`drag <target> "<dx> <dy>"`](#drag-alias-mouse) | Synthesize press→move→release (alias `mouse`). |
| | [`dragAt <target> "<x> <y> <dx> <dy> [modifiers]"`](#dragat) | Drag from a target-local point with optional keyboard modifiers. |
| | [`showMenu <target>`](#showmenu-alias-openmenu) | Pop a button's drop-down menu (alias `openMenu`). |
| | [`contextMenu <target> [x y]`](#contextmenu) | Trigger a custom right-click menu. |
| | [`rightClick <target> [x y]`](#rightclick) | Trigger a mousePressEvent-based right-click menu. |
Expand Down Expand Up @@ -289,6 +293,8 @@ transmit-gated verbs (refused unless `AETHER_AUTOMATION_ALLOW_TX=1` — see
| **Connection** | [`connect …`](#connect--disconnect) | list / show / hide / local / ip / wait. |
| | [`disconnect`](#connect--disconnect) | Normal user disconnect. |
| **Tuning & slices** | [`tune <mhz>`](#tune) | Set the active slice frequency (VFO; not keying). |
| | [`targettune <mhz>`](#targettune) | Absolute tune through the commanded-target and band-stack path. |
| | [`memory activate <index> [panId]`](#memory) | Recall a radio memory through the normal UI policy. |
| | [`slice <action>`](#slice) | add/remove/select/tx/mode/diversity/centerlock/txant/rxant/rxsource. |
| **GPS fixtures** | [`gps fixture <6000\|8000>`](#gps) | Disconnected-only GPS status fixture using each production wire format. |
| **Display / pans** | [`pan <action>`](#pan) | create / center / close a panadapter. |
Expand Down Expand Up @@ -982,6 +988,29 @@ Refused with `refused: slice A is VFO-locked` when the slice is locked. To
recenter the *pan* (band change) rather than move the slice within it, use
[`pan center`](#pan).

### `targettune`
Tune through the same absolute-target policy used by typed frequency entry and
other commanded jumps. Unlike `tune`, this can preselect a different band stack
before applying the final frequency, so it is the bridge path for testing
radio-authoritative band restores. RX/config only and honors VFO lock and SWR
sweep guards.

```json
→ {"cmd":"targettune","value":"146.520"}
← {"ok":true,"targetTune":146.52,"sliceId":0,"letter":"A"}
```

### `memory`
Recall a radio memory through `MainWindow::activateMemorySpot()`, including its
cross-band preselection and delayed reveal behavior. The optional `panId`
selects the target pan; omit it to use the active/preferred slice. RX/config
only.

```json
→ {"cmd":"memory","action":"activate","value":"12 0x40000000"}
← {"ok":true,"memory":"activate","index":12,"panId":"0x40000000"}
```

### `slice`
Slice lifecycle, mode, diversity, Center Lock, TX assignment, antennas, and
receive source. All actions are RX/config — none keys the transmitter.
Expand Down Expand Up @@ -1084,6 +1113,20 @@ computed once from the press point (a `QSizeGrip` moves as the window resizes, s
re-mapping mid-drag would overshoot) — a `140 90` grip drag grows the window by
exactly 140×90.

### `dragAt`
Synthesize a drag from an exact target-local point. Optional modifiers are a
comma- or plus-separated combination of `control`, `meta`, `shift`, and `alt`
(`cmd`/`command` and `option` are accepted aliases). This reaches custom-widget
gestures whose behavior depends on both position and a held modifier. As with
`clickAt`, the drag is refused when the target or an ancestor is marked as a
TX-keying control unless transmit automation is explicitly enabled.

```json
→ {"cmd":"dragAt","target":"SpectrumWidget","value":"1564 100 0 300 meta"}
← {"ok":true,"target":"SpectrumWidget","class":"SpectrumWidget",
"x":1564,"y":100,"dx":0,"dy":300,"modifiers":268435456}
```

### `hover`
Synthesize a pointer **hover** over a widget (no button pressed, unlike `drag`)
so hover-driven UI is provable end-to-end. The bare form fires a `QEnterEvent`
Expand Down Expand Up @@ -1849,7 +1892,7 @@ Actions:

| action | value | effect |
|---|---|---|
| `snapshot` | optional pan target | Read `live`, current center/bandwidth MHz, waterfall/DSS history row counts, visible DSS row count, and the current front-row peak bin. |
| `snapshot` | optional pan target | Read `live`, current center/bandwidth MHz, waterfall/DSS history row counts, visible DSS row count, the current front-row peak bin/min/max/span, localized plateau metrics (`dssVisibleFrontMinValueBins`, `dssVisibleFrontLongestFlatRunBins`, and visible maxima), and flat/non-flat visible-row counts. |
| `reset` | `native` or `kiwi` | Clear the selected stream's current/history rows and make that stream active for subsequent injection. |
| `inject` | `<count> <firstPeakBin> <stepBin> [native\|kiwi [rowLowMhz rowHighMhz]]` | Add synthetic rows with one strong peak per row. `count` is rejected if it exceeds the retained waterfall history capacity. Native injection adds one fallback-style waterfall/DSS row per input row; Kiwi injection drives `updateKiwiSdrWaterfallRow()`. Kiwi frame arguments override the source row's frequency span, so tests can cover partial-overlap rows. |
| `scrollback` | `<offsetRows>` | Enter waterfall history mode and rebuild the 3D surface using the same offset. |
Expand Down Expand Up @@ -2230,7 +2273,7 @@ lands.
The complete registry, generated from the `add(...)` table in `AutomationServer.cpp` by `tools/gen_bridge_docs.py`. CI fails if this drifts from the code.

<!-- BEGIN GENERATED VERB TABLE (tools/gen_bridge_docs.py) -->
<!-- Do not edit by hand — run tools/gen_bridge_docs.py. 47 verbs. -->
<!-- Do not edit by hand — run tools/gen_bridge_docs.py. 50 verbs. -->

| Verb | Aliases | Description |
|---|---|---|
Expand All @@ -2244,6 +2287,7 @@ The complete registry, generated from the `add(...)` table in `AutomationServer.
| `tooltip` | — | tooltip <target> [hide\|text…] — force-show a native tooltip |
| `scrollTo` | `ensureVisible` | scrollTo <target> — scroll a widget into its scroll-area viewport |
| `drag` | `mouse` | drag <target> <dx> <dy> — synthesize press→move→release |
| `dragAt` | — | dragAt <target> <x> <y> <dx> <dy> [control\|meta\|shift\|alt,...] |
| `showMenu` | `openMenu` | showMenu <target> — pop a button's drop-down menu |
| `contextMenu` | — | contextMenu <target> [x y] — Qt context-menu path |
| `rightClick` | — | rightClick <target> [x y] — mousePressEvent menu path |
Expand All @@ -2259,6 +2303,8 @@ The complete registry, generated from the `add(...)` table in `AutomationServer.
| `gps` | — | gps <fixture\|clearfixture> [6000\|8000] — disconnected GPS test data |
| `waveform` | — | waveform <start\|stop\|unregister\|resync> [args] — digital-voice service |
| `tune` | — | tune <mhz> — set the active slice frequency |
| `targettune` | — | targettune <mhz> — absolute tune through band-stack preselection |
| `memory` | — | memory activate <index> [panId] — recall a radio memory |
| `cwx` | — | cwx <send\|speed\|stop> [args] — CWX keyer (send is TX-gated) |
| `record` | — | record <start\|stop\|status\|path\|dir> [args] |
| `testtone` | — | testtone <on\|off> [freqHz levelDb] |
Expand Down
Loading
Loading