ka9q-python 3.9.0__tar.gz → 3.10.0__tar.gz
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.
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/CHANGELOG.md +35 -0
- {ka9q_python-3.9.0/ka9q_python.egg-info → ka9q_python-3.10.0}/PKG-INFO +38 -61
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/README.md +37 -60
- ka9q_python-3.10.0/docs/API_REFERENCE.md +848 -0
- ka9q_python-3.10.0/docs/ARCHITECTURE.md +363 -0
- ka9q_python-3.10.0/docs/CLI_GUIDE.md +288 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/docs/GETTING_STARTED.md +20 -6
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/docs/INSTALLATION.md +34 -14
- ka9q_python-3.10.0/docs/MULTI_STREAM.md +280 -0
- ka9q_python-3.10.0/docs/RECIPES.md +511 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/docs/RTP_TIMING_SUPPORT.md +31 -59
- ka9q_python-3.10.0/docs/SECURITY.md +54 -0
- ka9q_python-3.10.0/docs/TESTING_GUIDE.md +199 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/docs/TUI_GUIDE.md +28 -7
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/cli.py +4 -2
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/compat.py +1 -1
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/control.py +96 -9
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/status.py +6 -1
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/tui.py +256 -14
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/types.py +2 -1
- {ka9q_python-3.9.0 → ka9q_python-3.10.0/ka9q_python.egg-info}/PKG-INFO +38 -61
- ka9q_python-3.10.0/ka9q_python.egg-info/SOURCES.txt +95 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q_radio_compat +1 -1
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/pyproject.toml +1 -1
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/setup.py +1 -1
- ka9q_python-3.10.0/tests/test_decode_description.py +46 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_encode_socket.py +41 -51
- ka9q_python-3.10.0/tests/test_lifetime.py +175 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_native_discovery.py +4 -1
- ka9q_python-3.9.0/RELEASE_NOTES_v3.5.0.md +0 -75
- ka9q_python-3.9.0/docs/API_REFERENCE.md +0 -1438
- ka9q_python-3.9.0/docs/ARCHITECTURE.md +0 -534
- ka9q_python-3.9.0/docs/CHANGELOG.md +0 -378
- ka9q_python-3.9.0/docs/CROSS_PLATFORM_SUPPORT.md +0 -251
- ka9q_python-3.9.0/docs/DISTRIBUTION_RECOMMENDATION.md +0 -343
- ka9q_python-3.9.0/docs/MULTI_HOMED_QUICK_REF.md +0 -305
- ka9q_python-3.9.0/docs/NATIVE_DISCOVERY.md +0 -276
- ka9q_python-3.9.0/docs/PYPI_PUBLICATION_GUIDE.md +0 -404
- ka9q_python-3.9.0/docs/QUICK_REFERENCE.md +0 -233
- ka9q_python-3.9.0/docs/RTP_RECORDER_PASS_ALL_PACKETS.md +0 -512
- ka9q_python-3.9.0/docs/RTP_TIMING_IMPLEMENTATION.md +0 -439
- ka9q_python-3.9.0/docs/SECURITY.md +0 -876
- ka9q_python-3.9.0/docs/SSRC_COLLISION_PREVENTION.md +0 -1000
- ka9q_python-3.9.0/docs/TESTING_GUIDE.md +0 -347
- ka9q_python-3.9.0/docs/TESTING_SUMMARY.md +0 -133
- ka9q_python-3.9.0/docs/TEST_RESULTS.md +0 -262
- ka9q_python-3.9.0/docs/WEB_UI_ENHANCEMENT_GUIDE.md +0 -412
- ka9q_python-3.9.0/docs/WEB_UI_ENHANCEMENT_IMPLEMENTED.md +0 -184
- ka9q_python-3.9.0/docs/WEB_UI_ESCAPE_SEQUENCE_FIX.md +0 -78
- ka9q_python-3.9.0/docs/WEB_UI_FUNCTIONALITY_REVIEW.md +0 -355
- ka9q_python-3.9.0/docs/WEB_UI_IMPLEMENTATION_STATUS.md +0 -356
- ka9q_python-3.9.0/docs/WEB_UI_INTERACTIVE_COMPLETE.md +0 -333
- ka9q_python-3.9.0/docs/development/CHANGES_SUMMARY.md +0 -304
- ka9q_python-3.9.0/docs/development/CHANNEL_CLEANUP_ADDITION.md +0 -136
- ka9q_python-3.9.0/docs/development/CHANNEL_CLEANUP_COMPLETE.md +0 -224
- ka9q_python-3.9.0/docs/development/CHANNEL_TUNING_DIAGNOSTICS.md +0 -495
- ka9q_python-3.9.0/docs/development/CODE_REVIEW_RECOMMENDATIONS.md +0 -456
- ka9q_python-3.9.0/docs/development/CODE_REVIEW_SUMMARY.md +0 -318
- ka9q_python-3.9.0/docs/development/COMMIT_SUMMARY.md +0 -212
- ka9q_python-3.9.0/docs/development/CRITICAL_FIXES_CHECKLIST.md +0 -295
- ka9q_python-3.9.0/docs/development/FINAL_SUMMARY.md +0 -469
- ka9q_python-3.9.0/docs/development/FIXES_SUMMARY.md +0 -89
- ka9q_python-3.9.0/docs/development/GIT_STATUS_SUMMARY.md +0 -109
- ka9q_python-3.9.0/docs/development/IMPLEMENTATION_COMPLETE.md +0 -441
- ka9q_python-3.9.0/docs/development/IMPLEMENTATION_STATUS.md +0 -444
- ka9q_python-3.9.0/docs/development/IMPLEMENTATION_SUMMARY.md +0 -70
- ka9q_python-3.9.0/docs/development/IMPLEMENTATION_SUMMARY_v2.2.0.md +0 -348
- ka9q_python-3.9.0/docs/development/IMPROVEMENTS_IMPLEMENTED.md +0 -454
- ka9q_python-3.9.0/docs/development/MULTI_HOMED_ACTION_PLAN.md +0 -304
- ka9q_python-3.9.0/docs/development/MULTI_HOMED_IMPLEMENTATION_COMPLETE.md +0 -330
- ka9q_python-3.9.0/docs/development/MULTI_HOMED_SUPPORT_REVIEW.md +0 -471
- ka9q_python-3.9.0/docs/development/PACKAGE_STATUS.md +0 -257
- ka9q_python-3.9.0/docs/development/PACKAGE_VERIFICATION.md +0 -238
- ka9q_python-3.9.0/docs/development/PERFORMANCE_FIXES_APPLIED.md +0 -428
- ka9q_python-3.9.0/docs/development/PERFORMANCE_REVIEW.md +0 -762
- ka9q_python-3.9.0/docs/development/PERFORMANCE_REVIEW_V2.md +0 -776
- ka9q_python-3.9.0/docs/development/PERFORMANCE_SUMMARY.md +0 -203
- ka9q_python-3.9.0/docs/development/QUICK_ACTION_ITEMS.md +0 -370
- ka9q_python-3.9.0/docs/development/QUICK_START_DIAGNOSIS.md +0 -319
- ka9q_python-3.9.0/docs/development/RELEASE_CHECKLIST_v3.0.0.md +0 -133
- ka9q_python-3.9.0/docs/development/SUMMARY.md +0 -291
- ka9q_python-3.9.0/docs/development/SUMMARY_WEB_UI_FIXES.md +0 -153
- ka9q_python-3.9.0/docs/development/TUNE_IMPLEMENTATION.md +0 -291
- ka9q_python-3.9.0/docs/development/WEBUI_SUMMARY.md +0 -411
- ka9q_python-3.9.0/docs/development/WEB_UI_ENHANCEMENTS_COMPLETE.md +0 -198
- ka9q_python-3.9.0/docs/features/CONTROL_COMPARISON.md +0 -201
- ka9q_python-3.9.0/docs/features/DESTINATION_AWARE_CHANNELS.md +0 -73
- ka9q_python-3.9.0/docs/features/NEW_FEATURES.md +0 -239
- ka9q_python-3.9.0/docs/features/RADIOD_FEATURES_SUMMARY.md +0 -261
- ka9q_python-3.9.0/docs/features/RTP_DESTINATION_FEATURE.md +0 -237
- ka9q_python-3.9.0/docs/releases/GITHUB_RELEASE_INSTRUCTIONS.md +0 -196
- ka9q_python-3.9.0/docs/releases/GITHUB_RELEASE_v2.2.0.md +0 -275
- ka9q_python-3.9.0/docs/releases/GITHUB_RELEASE_v2.4.0.md +0 -269
- ka9q_python-3.9.0/docs/releases/GITHUB_RELEASE_v2.5.0.md +0 -241
- ka9q_python-3.9.0/docs/releases/GITHUB_RELEASE_v3.0.0.md +0 -148
- ka9q_python-3.9.0/docs/releases/GITHUB_RELEASE_v3.1.0.md +0 -139
- ka9q_python-3.9.0/docs/releases/GITHUB_RELEASE_v3.2.0.md +0 -116
- ka9q_python-3.9.0/docs/releases/RELEASE_NOTES.md +0 -244
- ka9q_python-3.9.0/docs/releases/RELEASE_NOTES_v2.1.0.md +0 -291
- ka9q_python-3.9.0/docs/releases/RELEASE_NOTES_v2.2.0.md +0 -554
- ka9q_python-3.9.0/docs/releases/RELEASE_NOTES_v2.3.0.md +0 -297
- ka9q_python-3.9.0/docs/releases/RELEASE_NOTES_v2.4.0.md +0 -545
- ka9q_python-3.9.0/docs/releases/RTP_TIMING_RELEASE_NOTES.md +0 -281
- ka9q_python-3.9.0/ka9q_python.egg-info/SOURCES.txt +0 -160
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/LICENSE +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/MANIFEST.in +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/advanced_features_demo.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/channel_cleanup_example.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/codar_oceanography.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/diagnostics/diagnose_packets.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/diagnostics/repro_utc_bug.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/discover_example.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/grape_integration_example.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/hf_band_scanner.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/multi_stream_smoke.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/rtp_recorder_example.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/simple_am_radio.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/stream_example.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/superdarn_recorder.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/test_channel_operations.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/test_improvements.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/test_timing_fields.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/tune.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/examples/tune_example.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/__init__.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/addressing.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/discovery.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/exceptions.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/managed_stream.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/monitor.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/multi_stream.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/pps_calibrator.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/resequencer.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/rtp_recorder.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/stream.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/stream_quality.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q/utils.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q_python.egg-info/dependency_links.txt +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q_python.egg-info/entry_points.txt +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q_python.egg-info/requires.txt +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/ka9q_python.egg-info/top_level.txt +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/scripts/sync_types.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/setup.cfg +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/__init__.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/conftest.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_addressing.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_channel_verification.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_create_split_encoding.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_decode_functions.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_encode_functions.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_ensure_channel_encoding.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_integration.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_iq_20khz_f32.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_listen_multicast.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_managed_stream_recovery.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_monitor.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_multihomed.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_performance_fixes.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_protocol_compat.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_remove_channel.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_rtp_recorder.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_security_features.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_ssrc_dest_unit.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_ssrc_encoding_unit.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_ssrc_radiod_host_unit.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_status_decoder.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_ttl_warning.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_tune.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_tune_cli.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_tune_debug.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_tune_live.py +0 -0
- {ka9q_python-3.9.0 → ka9q_python-3.10.0}/tests/test_tune_method.py +0 -0
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.10.0] - 2026-04-30
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Channel-lifetime keep-alive** (radiod 0f8b622+): support for ka9q-radio's new self-destruct timer, which lets a channel declare a lifetime in radiod main-loop frames (~50 Hz at the default 20 ms blocktime); 0 means infinite, >0 decrements every frame and destroys the channel at zero. This gives crash-resilient cleanup — if a client dies, its channels expire on their own instead of lingering on radiod.
|
|
8
|
+
- `RadiodControl.set_channel_lifetime(ssrc, lifetime)` — explicit poll that sends the LIFETIME tag, suitable as a periodic keep-alive.
|
|
9
|
+
- `RadiodControl.create_channel(..., lifetime=None)` — optional kwarg; sends LIFETIME on the creation packet when provided.
|
|
10
|
+
- `RadiodControl.ensure_channel(..., lifetime=None)` — passes through to `create_channel`; on the reuse path, calls `set_channel_lifetime` so the value is enforced regardless of the channel's prior state.
|
|
11
|
+
- `RadiodControl.tune(..., lifetime=None)` — optional kwarg; LIFETIME is included in the multi-parameter command buffer.
|
|
12
|
+
- `_decode_status_response()` exposes received LIFETIME as `status['lifetime']`; `ChannelStatus.lifetime` field.
|
|
13
|
+
- **`StatusType.LIFETIME = 117`** in `ka9q/types.py` (synced from ka9q-radio commit `5498aef`).
|
|
14
|
+
- **`StatusType.DESCRIPTION` decode** in `_decode_status_response()`: incoming front-end / channel description strings are now surfaced as `status['description']` (the encode side already existed via `set_description`).
|
|
15
|
+
|
|
16
|
+
### Backward Compatibility
|
|
17
|
+
|
|
18
|
+
- Default behavior unchanged: omitting `lifetime` produces a wire packet with no LIFETIME tag, so pre-`0f8b622` radiod stays compatible and existing clients see no change. Channels created without LIFETIME inherit radiod's template default (0 = infinite) and live until destroyed.
|
|
19
|
+
|
|
20
|
+
### Tests
|
|
21
|
+
|
|
22
|
+
- 10 new unit tests in `tests/test_lifetime.py` cover encode-presence on each entry point, encode-absence when omitted, and validation of negative / non-int inputs.
|
|
23
|
+
- Refreshed stale `tests/test_encode_socket.py` to match the current 6-byte wire format that radiod's `decode_socket()` actually expects.
|
|
24
|
+
- Hardened `tests/test_native_discovery.py::test_native_discovery_with_valid_packet` to mock `RadiodControl._connect`, removing the DNS dependency on `test.local`.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## [3.9.0] - 2026-04-15
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- **`ka9q` CLI** (`ka9q/cli.py`): new console entry point `ka9q` (declared via `[project.scripts]`), exposing channel discovery, tune, create, destroy, and status commands against a running radiod.
|
|
33
|
+
- **Textual TUI** (`ka9q/tui.py`): an interactive Textual app for browsing channels and tuning interactively, with radiod and SSRC pickers. Optional install via `pip install ka9q-python[tui]`.
|
|
34
|
+
- **Typed `ChannelStatus` decoder** (`ka9q/status.py`): a typed dataclass view over the dict returned by `_decode_status_response`, so callers can use attribute access and IDE-completable fields instead of dict keys.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
3
38
|
## [3.8.0] - 2026-04-12
|
|
4
39
|
|
|
5
40
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ka9q-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.10.0
|
|
4
4
|
Summary: Python interface for ka9q-radio control and monitoring
|
|
5
5
|
Home-page: https://github.com/mijahauan/ka9q-python
|
|
6
6
|
Author: Michael Hauan AC0G
|
|
@@ -60,15 +60,15 @@ Control radiod channels for any application: AM/FM/SSB radio, WSPR monitoring, S
|
|
|
60
60
|
|
|
61
61
|
## Features
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
- **Complete radiod API** — all 110+ TLV status/command parameters exposed, generated from ka9q-radio's C headers
|
|
64
|
+
- **Four stream abstractions** — `RTPRecorder` (raw packets), `RadiodStream` (samples + gap handling), `ManagedStream` (self-healing single channel), `MultiStream` (shared socket, many SSRCs)
|
|
65
|
+
- **Typed status decoder** — `ChannelStatus`, `FrontendStatus`, `PllStatus`, etc. with dotted-path field access
|
|
66
|
+
- **Precise RTP timing** — GPS_TIME / RTP_TIMESNAP for sample-accurate wallclock timestamps
|
|
67
|
+
- **LAN discovery** — enumerate radiod instances and their active channels via mDNS
|
|
68
|
+
- **CLI + TUI** — `ka9q list / query / set / tui` for interactive and scripted control
|
|
69
|
+
- **Multi-homed** — explicit interface selection for hosts with multiple NICs
|
|
70
|
+
- **Protocol drift detection** — pinned to a specific ka9q-radio commit, with a sync script
|
|
71
|
+
- **Pure Python** — NumPy is the only runtime dependency
|
|
72
72
|
|
|
73
73
|
## Installation
|
|
74
74
|
|
|
@@ -215,6 +215,7 @@ monitor.monitor_channel(
|
|
|
215
215
|
preset="usb",
|
|
216
216
|
sample_rate=12000
|
|
217
217
|
)
|
|
218
|
+
```
|
|
218
219
|
|
|
219
220
|
### Channel Cleanup (frequency = 0)
|
|
220
221
|
|
|
@@ -293,63 +294,39 @@ It auto-skips if `../ka9q-radio` is not present, so CI environments without the
|
|
|
293
294
|
|
|
294
295
|
## Documentation
|
|
295
296
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
- **[API Reference](docs/API_REFERENCE.md)
|
|
299
|
-
- **[
|
|
300
|
-
- **[
|
|
301
|
-
- **[
|
|
302
|
-
- **[
|
|
303
|
-
- **[
|
|
304
|
-
- **[
|
|
305
|
-
- **[Changelog](
|
|
306
|
-
- **[Release Notes](docs/releases/)**: Release-specific notes and instructions.
|
|
297
|
+
- **[Getting Started](docs/GETTING_STARTED.md)** — first-run walkthrough
|
|
298
|
+
- **[Recipes](docs/RECIPES.md)** — task-oriented cookbook: LAN probing, fixed-channel pipelines (WSPR/PSK/FT8/timing), nimble SWL-style retuning, and using ka9q-python across different SDRs
|
|
299
|
+
- **[API Reference](docs/API_REFERENCE.md)** — every public class, method, and function
|
|
300
|
+
- **[Architecture](docs/ARCHITECTURE.md)** — module layout, threading, protocol
|
|
301
|
+
- **[CLI Guide](docs/CLI_GUIDE.md)** — `ka9q list / query / set / tui` command reference
|
|
302
|
+
- **[TUI Guide](docs/TUI_GUIDE.md)** — the Textual terminal UI
|
|
303
|
+
- **[MultiStream Guide](docs/MULTI_STREAM.md)** — shared-socket multi-channel receiver
|
|
304
|
+
- **[RTP Timing](docs/RTP_TIMING_SUPPORT.md)** — GPS_TIME / RTP_TIMESNAP for sample-accurate timestamps
|
|
305
|
+
- **[Installation](docs/INSTALLATION.md)** · **[Testing](docs/TESTING_GUIDE.md)** · **[Security](docs/SECURITY.md)**
|
|
306
|
+
- **[Changelog](CHANGELOG.md)**
|
|
307
307
|
|
|
308
308
|
## Examples
|
|
309
309
|
|
|
310
|
-
See
|
|
311
|
-
|
|
312
|
-
-
|
|
313
|
-
-
|
|
314
|
-
-
|
|
315
|
-
-
|
|
316
|
-
-
|
|
317
|
-
-
|
|
318
|
-
-
|
|
319
|
-
-
|
|
320
|
-
-
|
|
321
|
-
- **`superdarn_recorder.py`** - Ionospheric radar monitoring
|
|
322
|
-
- **`codar_oceanography.py`** - Ocean current radar
|
|
323
|
-
- **`hf_band_scanner.py`** - Dynamic frequency scanner
|
|
324
|
-
- **`wspr_monitor.py`** - Weak signal propagation reporter
|
|
310
|
+
See [`examples/`](examples/) for runnable scripts:
|
|
311
|
+
|
|
312
|
+
- [`simple_am_radio.py`](examples/simple_am_radio.py) — minimal AM listener
|
|
313
|
+
- [`discover_example.py`](examples/discover_example.py) — channel discovery on the LAN
|
|
314
|
+
- [`stream_example.py`](examples/stream_example.py) — `RadiodStream` sample callback
|
|
315
|
+
- [`rtp_recorder_example.py`](examples/rtp_recorder_example.py) — precise-timing RTP recorder
|
|
316
|
+
- [`multi_stream_smoke.py`](examples/multi_stream_smoke.py) — `MultiStream` multi-SSRC receiver
|
|
317
|
+
- [`hf_band_scanner.py`](examples/hf_band_scanner.py) — dynamic band scanner
|
|
318
|
+
- [`channel_cleanup_example.py`](examples/channel_cleanup_example.py) — teardown via frequency=0
|
|
319
|
+
- [`tune.py`](examples/tune.py) — interactive tuning utility
|
|
320
|
+
- [`superdarn_recorder.py`](examples/superdarn_recorder.py), [`codar_oceanography.py`](examples/codar_oceanography.py), [`grape_integration_example.py`](examples/grape_integration_example.py) — domain-specific recorders
|
|
325
321
|
|
|
326
322
|
## Use Cases
|
|
327
323
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
-
|
|
331
|
-
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
- WSPR propagation studies
|
|
335
|
-
- SuperDARN ionospheric radar
|
|
336
|
-
- CODAR ocean current mapping
|
|
337
|
-
- Meteor scatter
|
|
338
|
-
- EME (moonbounce)
|
|
339
|
-
|
|
340
|
-
### Digital Modes
|
|
341
|
-
- FT8/FT4 monitoring
|
|
342
|
-
- RTTY/PSK decoding
|
|
343
|
-
- DRM digital radio
|
|
344
|
-
- HF fax reception
|
|
345
|
-
|
|
346
|
-
### Satellite Operations
|
|
347
|
-
- Downlink reception
|
|
348
|
-
- Doppler tracking
|
|
349
|
-
- Multi-frequency monitoring
|
|
350
|
-
|
|
351
|
-
### Custom Applications
|
|
352
|
-
**No assumptions!** Use for anything SDR-related.
|
|
324
|
+
See [docs/RECIPES.md](docs/RECIPES.md) for worked examples of:
|
|
325
|
+
|
|
326
|
+
- **LAN probing** — enumerate radiod instances and their active channels
|
|
327
|
+
- **Fixed-channel pipelines** — WSPR, PSK/FT8, HF timing (bundled band plans, `MultiStream`); see companion projects `wspr-recorder`, `psk-recorder`, `hf-timestd`
|
|
328
|
+
- **Nimble channel switching** — single-channel SWL-style retuning driven from the CLI or an app
|
|
329
|
+
- **SDR portability** — ka9q-python talks to `radiod`, which talks to the SDR; reporting frontend capabilities via `FrontendStatus`. Primary tested frontend is the RX888; AirspyR2 and Airspy HF+ support is in development.
|
|
353
330
|
|
|
354
331
|
## License
|
|
355
332
|
|
|
@@ -23,15 +23,15 @@ Control radiod channels for any application: AM/FM/SSB radio, WSPR monitoring, S
|
|
|
23
23
|
|
|
24
24
|
## Features
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
- **Complete radiod API** — all 110+ TLV status/command parameters exposed, generated from ka9q-radio's C headers
|
|
27
|
+
- **Four stream abstractions** — `RTPRecorder` (raw packets), `RadiodStream` (samples + gap handling), `ManagedStream` (self-healing single channel), `MultiStream` (shared socket, many SSRCs)
|
|
28
|
+
- **Typed status decoder** — `ChannelStatus`, `FrontendStatus`, `PllStatus`, etc. with dotted-path field access
|
|
29
|
+
- **Precise RTP timing** — GPS_TIME / RTP_TIMESNAP for sample-accurate wallclock timestamps
|
|
30
|
+
- **LAN discovery** — enumerate radiod instances and their active channels via mDNS
|
|
31
|
+
- **CLI + TUI** — `ka9q list / query / set / tui` for interactive and scripted control
|
|
32
|
+
- **Multi-homed** — explicit interface selection for hosts with multiple NICs
|
|
33
|
+
- **Protocol drift detection** — pinned to a specific ka9q-radio commit, with a sync script
|
|
34
|
+
- **Pure Python** — NumPy is the only runtime dependency
|
|
35
35
|
|
|
36
36
|
## Installation
|
|
37
37
|
|
|
@@ -178,6 +178,7 @@ monitor.monitor_channel(
|
|
|
178
178
|
preset="usb",
|
|
179
179
|
sample_rate=12000
|
|
180
180
|
)
|
|
181
|
+
```
|
|
181
182
|
|
|
182
183
|
### Channel Cleanup (frequency = 0)
|
|
183
184
|
|
|
@@ -256,63 +257,39 @@ It auto-skips if `../ka9q-radio` is not present, so CI environments without the
|
|
|
256
257
|
|
|
257
258
|
## Documentation
|
|
258
259
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
- **[API Reference](docs/API_REFERENCE.md)
|
|
262
|
-
- **[
|
|
263
|
-
- **[
|
|
264
|
-
- **[
|
|
265
|
-
- **[
|
|
266
|
-
- **[
|
|
267
|
-
- **[
|
|
268
|
-
- **[Changelog](
|
|
269
|
-
- **[Release Notes](docs/releases/)**: Release-specific notes and instructions.
|
|
260
|
+
- **[Getting Started](docs/GETTING_STARTED.md)** — first-run walkthrough
|
|
261
|
+
- **[Recipes](docs/RECIPES.md)** — task-oriented cookbook: LAN probing, fixed-channel pipelines (WSPR/PSK/FT8/timing), nimble SWL-style retuning, and using ka9q-python across different SDRs
|
|
262
|
+
- **[API Reference](docs/API_REFERENCE.md)** — every public class, method, and function
|
|
263
|
+
- **[Architecture](docs/ARCHITECTURE.md)** — module layout, threading, protocol
|
|
264
|
+
- **[CLI Guide](docs/CLI_GUIDE.md)** — `ka9q list / query / set / tui` command reference
|
|
265
|
+
- **[TUI Guide](docs/TUI_GUIDE.md)** — the Textual terminal UI
|
|
266
|
+
- **[MultiStream Guide](docs/MULTI_STREAM.md)** — shared-socket multi-channel receiver
|
|
267
|
+
- **[RTP Timing](docs/RTP_TIMING_SUPPORT.md)** — GPS_TIME / RTP_TIMESNAP for sample-accurate timestamps
|
|
268
|
+
- **[Installation](docs/INSTALLATION.md)** · **[Testing](docs/TESTING_GUIDE.md)** · **[Security](docs/SECURITY.md)**
|
|
269
|
+
- **[Changelog](CHANGELOG.md)**
|
|
270
270
|
|
|
271
271
|
## Examples
|
|
272
272
|
|
|
273
|
-
See
|
|
274
|
-
|
|
275
|
-
-
|
|
276
|
-
-
|
|
277
|
-
-
|
|
278
|
-
-
|
|
279
|
-
-
|
|
280
|
-
-
|
|
281
|
-
-
|
|
282
|
-
-
|
|
283
|
-
-
|
|
284
|
-
- **`superdarn_recorder.py`** - Ionospheric radar monitoring
|
|
285
|
-
- **`codar_oceanography.py`** - Ocean current radar
|
|
286
|
-
- **`hf_band_scanner.py`** - Dynamic frequency scanner
|
|
287
|
-
- **`wspr_monitor.py`** - Weak signal propagation reporter
|
|
273
|
+
See [`examples/`](examples/) for runnable scripts:
|
|
274
|
+
|
|
275
|
+
- [`simple_am_radio.py`](examples/simple_am_radio.py) — minimal AM listener
|
|
276
|
+
- [`discover_example.py`](examples/discover_example.py) — channel discovery on the LAN
|
|
277
|
+
- [`stream_example.py`](examples/stream_example.py) — `RadiodStream` sample callback
|
|
278
|
+
- [`rtp_recorder_example.py`](examples/rtp_recorder_example.py) — precise-timing RTP recorder
|
|
279
|
+
- [`multi_stream_smoke.py`](examples/multi_stream_smoke.py) — `MultiStream` multi-SSRC receiver
|
|
280
|
+
- [`hf_band_scanner.py`](examples/hf_band_scanner.py) — dynamic band scanner
|
|
281
|
+
- [`channel_cleanup_example.py`](examples/channel_cleanup_example.py) — teardown via frequency=0
|
|
282
|
+
- [`tune.py`](examples/tune.py) — interactive tuning utility
|
|
283
|
+
- [`superdarn_recorder.py`](examples/superdarn_recorder.py), [`codar_oceanography.py`](examples/codar_oceanography.py), [`grape_integration_example.py`](examples/grape_integration_example.py) — domain-specific recorders
|
|
288
284
|
|
|
289
285
|
## Use Cases
|
|
290
286
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
-
|
|
294
|
-
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
- WSPR propagation studies
|
|
298
|
-
- SuperDARN ionospheric radar
|
|
299
|
-
- CODAR ocean current mapping
|
|
300
|
-
- Meteor scatter
|
|
301
|
-
- EME (moonbounce)
|
|
302
|
-
|
|
303
|
-
### Digital Modes
|
|
304
|
-
- FT8/FT4 monitoring
|
|
305
|
-
- RTTY/PSK decoding
|
|
306
|
-
- DRM digital radio
|
|
307
|
-
- HF fax reception
|
|
308
|
-
|
|
309
|
-
### Satellite Operations
|
|
310
|
-
- Downlink reception
|
|
311
|
-
- Doppler tracking
|
|
312
|
-
- Multi-frequency monitoring
|
|
313
|
-
|
|
314
|
-
### Custom Applications
|
|
315
|
-
**No assumptions!** Use for anything SDR-related.
|
|
287
|
+
See [docs/RECIPES.md](docs/RECIPES.md) for worked examples of:
|
|
288
|
+
|
|
289
|
+
- **LAN probing** — enumerate radiod instances and their active channels
|
|
290
|
+
- **Fixed-channel pipelines** — WSPR, PSK/FT8, HF timing (bundled band plans, `MultiStream`); see companion projects `wspr-recorder`, `psk-recorder`, `hf-timestd`
|
|
291
|
+
- **Nimble channel switching** — single-channel SWL-style retuning driven from the CLI or an app
|
|
292
|
+
- **SDR portability** — ka9q-python talks to `radiod`, which talks to the SDR; reporting frontend capabilities via `FrontendStatus`. Primary tested frontend is the RX888; AirspyR2 and Airspy HF+ support is in development.
|
|
316
293
|
|
|
317
294
|
## License
|
|
318
295
|
|