ka9q-python 3.8.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.
Files changed (172) hide show
  1. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/CHANGELOG.md +35 -0
  2. {ka9q_python-3.8.0/ka9q_python.egg-info → ka9q_python-3.10.0}/PKG-INFO +40 -60
  3. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/README.md +37 -59
  4. ka9q_python-3.10.0/docs/API_REFERENCE.md +848 -0
  5. ka9q_python-3.10.0/docs/ARCHITECTURE.md +363 -0
  6. ka9q_python-3.10.0/docs/CLI_GUIDE.md +288 -0
  7. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/docs/GETTING_STARTED.md +20 -6
  8. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/docs/INSTALLATION.md +34 -14
  9. ka9q_python-3.10.0/docs/MULTI_STREAM.md +280 -0
  10. ka9q_python-3.10.0/docs/RECIPES.md +511 -0
  11. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/docs/RTP_TIMING_SUPPORT.md +31 -59
  12. ka9q_python-3.10.0/docs/SECURITY.md +54 -0
  13. ka9q_python-3.10.0/docs/TESTING_GUIDE.md +199 -0
  14. ka9q_python-3.10.0/docs/TUI_GUIDE.md +169 -0
  15. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/__init__.py +21 -1
  16. ka9q_python-3.10.0/ka9q/cli.py +340 -0
  17. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/compat.py +1 -1
  18. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/control.py +259 -9
  19. ka9q_python-3.10.0/ka9q/status.py +653 -0
  20. ka9q_python-3.10.0/ka9q/tui.py +758 -0
  21. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/types.py +2 -1
  22. {ka9q_python-3.8.0 → ka9q_python-3.10.0/ka9q_python.egg-info}/PKG-INFO +40 -60
  23. ka9q_python-3.10.0/ka9q_python.egg-info/SOURCES.txt +95 -0
  24. ka9q_python-3.10.0/ka9q_python.egg-info/entry_points.txt +2 -0
  25. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q_python.egg-info/requires.txt +3 -0
  26. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q_radio_compat +1 -1
  27. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/pyproject.toml +7 -1
  28. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/setup.py +1 -1
  29. ka9q_python-3.10.0/tests/test_decode_description.py +46 -0
  30. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_encode_socket.py +41 -51
  31. ka9q_python-3.10.0/tests/test_lifetime.py +175 -0
  32. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_native_discovery.py +4 -1
  33. ka9q_python-3.10.0/tests/test_status_decoder.py +161 -0
  34. ka9q_python-3.8.0/RELEASE_NOTES_v3.5.0.md +0 -75
  35. ka9q_python-3.8.0/docs/API_REFERENCE.md +0 -1438
  36. ka9q_python-3.8.0/docs/ARCHITECTURE.md +0 -534
  37. ka9q_python-3.8.0/docs/CHANGELOG.md +0 -354
  38. ka9q_python-3.8.0/docs/CROSS_PLATFORM_SUPPORT.md +0 -251
  39. ka9q_python-3.8.0/docs/DISTRIBUTION_RECOMMENDATION.md +0 -343
  40. ka9q_python-3.8.0/docs/MULTI_HOMED_QUICK_REF.md +0 -305
  41. ka9q_python-3.8.0/docs/NATIVE_DISCOVERY.md +0 -276
  42. ka9q_python-3.8.0/docs/PYPI_PUBLICATION_GUIDE.md +0 -404
  43. ka9q_python-3.8.0/docs/QUICK_REFERENCE.md +0 -233
  44. ka9q_python-3.8.0/docs/RTP_RECORDER_PASS_ALL_PACKETS.md +0 -512
  45. ka9q_python-3.8.0/docs/RTP_TIMING_IMPLEMENTATION.md +0 -439
  46. ka9q_python-3.8.0/docs/SECURITY.md +0 -876
  47. ka9q_python-3.8.0/docs/SSRC_COLLISION_PREVENTION.md +0 -1000
  48. ka9q_python-3.8.0/docs/TESTING_GUIDE.md +0 -347
  49. ka9q_python-3.8.0/docs/TESTING_SUMMARY.md +0 -133
  50. ka9q_python-3.8.0/docs/TEST_RESULTS.md +0 -262
  51. ka9q_python-3.8.0/docs/WEB_UI_ENHANCEMENT_GUIDE.md +0 -412
  52. ka9q_python-3.8.0/docs/WEB_UI_ENHANCEMENT_IMPLEMENTED.md +0 -184
  53. ka9q_python-3.8.0/docs/WEB_UI_ESCAPE_SEQUENCE_FIX.md +0 -78
  54. ka9q_python-3.8.0/docs/WEB_UI_FUNCTIONALITY_REVIEW.md +0 -355
  55. ka9q_python-3.8.0/docs/WEB_UI_IMPLEMENTATION_STATUS.md +0 -356
  56. ka9q_python-3.8.0/docs/WEB_UI_INTERACTIVE_COMPLETE.md +0 -333
  57. ka9q_python-3.8.0/docs/development/CHANGES_SUMMARY.md +0 -304
  58. ka9q_python-3.8.0/docs/development/CHANNEL_CLEANUP_ADDITION.md +0 -136
  59. ka9q_python-3.8.0/docs/development/CHANNEL_CLEANUP_COMPLETE.md +0 -224
  60. ka9q_python-3.8.0/docs/development/CHANNEL_TUNING_DIAGNOSTICS.md +0 -495
  61. ka9q_python-3.8.0/docs/development/CODE_REVIEW_RECOMMENDATIONS.md +0 -456
  62. ka9q_python-3.8.0/docs/development/CODE_REVIEW_SUMMARY.md +0 -318
  63. ka9q_python-3.8.0/docs/development/COMMIT_SUMMARY.md +0 -212
  64. ka9q_python-3.8.0/docs/development/CRITICAL_FIXES_CHECKLIST.md +0 -295
  65. ka9q_python-3.8.0/docs/development/FINAL_SUMMARY.md +0 -469
  66. ka9q_python-3.8.0/docs/development/FIXES_SUMMARY.md +0 -89
  67. ka9q_python-3.8.0/docs/development/GIT_STATUS_SUMMARY.md +0 -109
  68. ka9q_python-3.8.0/docs/development/IMPLEMENTATION_COMPLETE.md +0 -441
  69. ka9q_python-3.8.0/docs/development/IMPLEMENTATION_STATUS.md +0 -444
  70. ka9q_python-3.8.0/docs/development/IMPLEMENTATION_SUMMARY.md +0 -70
  71. ka9q_python-3.8.0/docs/development/IMPLEMENTATION_SUMMARY_v2.2.0.md +0 -348
  72. ka9q_python-3.8.0/docs/development/IMPROVEMENTS_IMPLEMENTED.md +0 -454
  73. ka9q_python-3.8.0/docs/development/MULTI_HOMED_ACTION_PLAN.md +0 -304
  74. ka9q_python-3.8.0/docs/development/MULTI_HOMED_IMPLEMENTATION_COMPLETE.md +0 -330
  75. ka9q_python-3.8.0/docs/development/MULTI_HOMED_SUPPORT_REVIEW.md +0 -471
  76. ka9q_python-3.8.0/docs/development/PACKAGE_STATUS.md +0 -257
  77. ka9q_python-3.8.0/docs/development/PACKAGE_VERIFICATION.md +0 -238
  78. ka9q_python-3.8.0/docs/development/PERFORMANCE_FIXES_APPLIED.md +0 -428
  79. ka9q_python-3.8.0/docs/development/PERFORMANCE_REVIEW.md +0 -762
  80. ka9q_python-3.8.0/docs/development/PERFORMANCE_REVIEW_V2.md +0 -776
  81. ka9q_python-3.8.0/docs/development/PERFORMANCE_SUMMARY.md +0 -203
  82. ka9q_python-3.8.0/docs/development/QUICK_ACTION_ITEMS.md +0 -370
  83. ka9q_python-3.8.0/docs/development/QUICK_START_DIAGNOSIS.md +0 -319
  84. ka9q_python-3.8.0/docs/development/RELEASE_CHECKLIST_v3.0.0.md +0 -133
  85. ka9q_python-3.8.0/docs/development/SUMMARY.md +0 -291
  86. ka9q_python-3.8.0/docs/development/SUMMARY_WEB_UI_FIXES.md +0 -153
  87. ka9q_python-3.8.0/docs/development/TUNE_IMPLEMENTATION.md +0 -291
  88. ka9q_python-3.8.0/docs/development/WEBUI_SUMMARY.md +0 -411
  89. ka9q_python-3.8.0/docs/development/WEB_UI_ENHANCEMENTS_COMPLETE.md +0 -198
  90. ka9q_python-3.8.0/docs/features/CONTROL_COMPARISON.md +0 -201
  91. ka9q_python-3.8.0/docs/features/DESTINATION_AWARE_CHANNELS.md +0 -73
  92. ka9q_python-3.8.0/docs/features/NEW_FEATURES.md +0 -239
  93. ka9q_python-3.8.0/docs/features/RADIOD_FEATURES_SUMMARY.md +0 -261
  94. ka9q_python-3.8.0/docs/features/RTP_DESTINATION_FEATURE.md +0 -237
  95. ka9q_python-3.8.0/docs/releases/GITHUB_RELEASE_INSTRUCTIONS.md +0 -196
  96. ka9q_python-3.8.0/docs/releases/GITHUB_RELEASE_v2.2.0.md +0 -275
  97. ka9q_python-3.8.0/docs/releases/GITHUB_RELEASE_v2.4.0.md +0 -269
  98. ka9q_python-3.8.0/docs/releases/GITHUB_RELEASE_v2.5.0.md +0 -241
  99. ka9q_python-3.8.0/docs/releases/GITHUB_RELEASE_v3.0.0.md +0 -148
  100. ka9q_python-3.8.0/docs/releases/GITHUB_RELEASE_v3.1.0.md +0 -139
  101. ka9q_python-3.8.0/docs/releases/GITHUB_RELEASE_v3.2.0.md +0 -116
  102. ka9q_python-3.8.0/docs/releases/RELEASE_NOTES.md +0 -244
  103. ka9q_python-3.8.0/docs/releases/RELEASE_NOTES_v2.1.0.md +0 -291
  104. ka9q_python-3.8.0/docs/releases/RELEASE_NOTES_v2.2.0.md +0 -554
  105. ka9q_python-3.8.0/docs/releases/RELEASE_NOTES_v2.3.0.md +0 -297
  106. ka9q_python-3.8.0/docs/releases/RELEASE_NOTES_v2.4.0.md +0 -545
  107. ka9q_python-3.8.0/docs/releases/RTP_TIMING_RELEASE_NOTES.md +0 -281
  108. ka9q_python-3.8.0/ka9q_python.egg-info/SOURCES.txt +0 -154
  109. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/LICENSE +0 -0
  110. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/MANIFEST.in +0 -0
  111. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/advanced_features_demo.py +0 -0
  112. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/channel_cleanup_example.py +0 -0
  113. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/codar_oceanography.py +0 -0
  114. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/diagnostics/diagnose_packets.py +0 -0
  115. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/diagnostics/repro_utc_bug.py +0 -0
  116. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/discover_example.py +0 -0
  117. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/grape_integration_example.py +0 -0
  118. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/hf_band_scanner.py +0 -0
  119. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/multi_stream_smoke.py +0 -0
  120. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/rtp_recorder_example.py +0 -0
  121. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/simple_am_radio.py +0 -0
  122. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/stream_example.py +0 -0
  123. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/superdarn_recorder.py +0 -0
  124. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/test_channel_operations.py +0 -0
  125. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/test_improvements.py +0 -0
  126. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/test_timing_fields.py +0 -0
  127. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/tune.py +0 -0
  128. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/examples/tune_example.py +0 -0
  129. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/addressing.py +0 -0
  130. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/discovery.py +0 -0
  131. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/exceptions.py +0 -0
  132. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/managed_stream.py +0 -0
  133. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/monitor.py +0 -0
  134. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/multi_stream.py +0 -0
  135. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/pps_calibrator.py +0 -0
  136. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/resequencer.py +0 -0
  137. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/rtp_recorder.py +0 -0
  138. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/stream.py +0 -0
  139. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/stream_quality.py +0 -0
  140. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q/utils.py +0 -0
  141. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q_python.egg-info/dependency_links.txt +0 -0
  142. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/ka9q_python.egg-info/top_level.txt +0 -0
  143. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/scripts/sync_types.py +0 -0
  144. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/setup.cfg +0 -0
  145. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/__init__.py +0 -0
  146. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/conftest.py +0 -0
  147. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_addressing.py +0 -0
  148. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_channel_verification.py +0 -0
  149. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_create_split_encoding.py +0 -0
  150. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_decode_functions.py +0 -0
  151. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_encode_functions.py +0 -0
  152. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_ensure_channel_encoding.py +0 -0
  153. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_integration.py +0 -0
  154. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_iq_20khz_f32.py +0 -0
  155. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_listen_multicast.py +0 -0
  156. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_managed_stream_recovery.py +0 -0
  157. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_monitor.py +0 -0
  158. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_multihomed.py +0 -0
  159. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_performance_fixes.py +0 -0
  160. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_protocol_compat.py +0 -0
  161. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_remove_channel.py +0 -0
  162. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_rtp_recorder.py +0 -0
  163. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_security_features.py +0 -0
  164. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_ssrc_dest_unit.py +0 -0
  165. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_ssrc_encoding_unit.py +0 -0
  166. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_ssrc_radiod_host_unit.py +0 -0
  167. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_ttl_warning.py +0 -0
  168. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_tune.py +0 -0
  169. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_tune_cli.py +0 -0
  170. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_tune_debug.py +0 -0
  171. {ka9q_python-3.8.0 → ka9q_python-3.10.0}/tests/test_tune_live.py +0 -0
  172. {ka9q_python-3.8.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.8.0
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
@@ -28,6 +28,8 @@ Requires-Dist: numpy>=1.24.0
28
28
  Provides-Extra: dev
29
29
  Requires-Dist: pytest>=7.0.0; extra == "dev"
30
30
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
31
+ Provides-Extra: tui
32
+ Requires-Dist: textual>=0.50; extra == "tui"
31
33
  Dynamic: author
32
34
  Dynamic: home-page
33
35
  Dynamic: license-file
@@ -58,15 +60,15 @@ Control radiod channels for any application: AM/FM/SSB radio, WSPR monitoring, S
58
60
 
59
61
  ## Features
60
62
 
61
- **Zero assumptions** - Works for any SDR application
62
- **Complete API** - All 85+ radiod parameters exposed
63
- **Channel control** - Create, configure, discover channels
64
- **RTP recording** - Generic recorder with timing support and state machine
65
- **Precise timing** - GPS_TIME/RTP_TIMESNAP for accurate timestamps
66
- **Multi-homed support** - Works on systems with multiple network interfaces
67
- **Pure Python** - No compiled dependencies
68
- **Well tested** - Comprehensive test coverage
69
- **Documented** - Comprehensive examples and API reference included
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
70
72
 
71
73
  ## Installation
72
74
 
@@ -213,6 +215,7 @@ monitor.monitor_channel(
213
215
  preset="usb",
214
216
  sample_rate=12000
215
217
  )
218
+ ```
216
219
 
217
220
  ### Channel Cleanup (frequency = 0)
218
221
 
@@ -291,62 +294,39 @@ It auto-skips if `../ka9q-radio` is not present, so CI environments without the
291
294
 
292
295
  ## Documentation
293
296
 
294
- For detailed information, please refer to the documentation in the `docs/` directory:
295
-
296
- - **[API Reference](docs/API_REFERENCE.md)**: Full details on all classes, methods, and functions.
297
- - **[RTP Timing Support](docs/RTP_TIMING_SUPPORT.md)**: Guide to RTP timing and synchronization.
298
- - **[Architecture](docs/ARCHITECTURE.md)**: Overview of the library's design and structure.
299
- - **[Installation Guide](docs/INSTALLATION.md)**: Detailed installation instructions.
300
- - **[Testing Guide](docs/TESTING_GUIDE.md)**: Information on how to run the test suite.
301
- - **[Security Considerations](docs/SECURITY.md)**: Important security information regarding the ka9q-radio protocol.
302
- - **[Changelog](docs/CHANGELOG.md)**: A log of all changes for each version.
303
- - **[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)**
304
307
 
305
308
  ## Examples
306
309
 
307
- See the `examples/` directory for complete applications:
308
-
309
- - **High-Level API**: `ensure_channel()` handles the complexity of checking existing channels, creating new ones only when necessary, and verifying configurations.
310
- - **Destination-Aware Channels**: Support for unique per-application multicast destinations and deterministic IP generation.
311
- - **Stream Sharing**: Deterministic SSRC allocation allows multiple independent applications to share `radiod` streams efficiently.
312
- - **`discover_example.py`** - Channel discovery methods (native Python and control utility)
313
- - **`tune.py`** - Interactive channel tuning utility (Python implementation of ka9q-radio's tune)
314
- - **`tune_example.py`** - Programmatic examples of using the tune() method
315
- - **`rtp_recorder_example.py`** - Complete RTP recorder with timing and state machine
316
- - **`test_timing_fields.py`** - Verify GPS_TIME/RTP_TIMESNAP timing fields
317
- - **`simple_am_radio.py`** - Minimal AM broadcast listener
318
- - **`superdarn_recorder.py`** - Ionospheric radar monitoring
319
- - **`codar_oceanography.py`** - Ocean current radar
320
- - **`hf_band_scanner.py`** - Dynamic frequency scanner
321
- - **`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
322
321
 
323
322
  ## Use Cases
324
323
 
325
- ### AM/FM/SSB Radio
326
- - Broadcast monitoring
327
- - Ham radio operation
328
- - Shortwave listening
329
-
330
- ### Scientific Research
331
- - WSPR propagation studies
332
- - SuperDARN ionospheric radar
333
- - CODAR ocean current mapping
334
- - Meteor scatter
335
- - EME (moonbounce)
336
-
337
- ### Digital Modes
338
- - FT8/FT4 monitoring
339
- - RTTY/PSK decoding
340
- - DRM digital radio
341
- - HF fax reception
342
-
343
- ### Satellite Operations
344
- - Downlink reception
345
- - Doppler tracking
346
- - Multi-frequency monitoring
347
-
348
- ### Custom Applications
349
- **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.
350
330
 
351
331
  ## License
352
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
- **Zero assumptions** - Works for any SDR application
27
- **Complete API** - All 85+ radiod parameters exposed
28
- **Channel control** - Create, configure, discover channels
29
- **RTP recording** - Generic recorder with timing support and state machine
30
- **Precise timing** - GPS_TIME/RTP_TIMESNAP for accurate timestamps
31
- **Multi-homed support** - Works on systems with multiple network interfaces
32
- **Pure Python** - No compiled dependencies
33
- **Well tested** - Comprehensive test coverage
34
- **Documented** - Comprehensive examples and API reference included
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,62 +257,39 @@ It auto-skips if `../ka9q-radio` is not present, so CI environments without the
256
257
 
257
258
  ## Documentation
258
259
 
259
- For detailed information, please refer to the documentation in the `docs/` directory:
260
-
261
- - **[API Reference](docs/API_REFERENCE.md)**: Full details on all classes, methods, and functions.
262
- - **[RTP Timing Support](docs/RTP_TIMING_SUPPORT.md)**: Guide to RTP timing and synchronization.
263
- - **[Architecture](docs/ARCHITECTURE.md)**: Overview of the library's design and structure.
264
- - **[Installation Guide](docs/INSTALLATION.md)**: Detailed installation instructions.
265
- - **[Testing Guide](docs/TESTING_GUIDE.md)**: Information on how to run the test suite.
266
- - **[Security Considerations](docs/SECURITY.md)**: Important security information regarding the ka9q-radio protocol.
267
- - **[Changelog](docs/CHANGELOG.md)**: A log of all changes for each version.
268
- - **[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)**
269
270
 
270
271
  ## Examples
271
272
 
272
- See the `examples/` directory for complete applications:
273
-
274
- - **High-Level API**: `ensure_channel()` handles the complexity of checking existing channels, creating new ones only when necessary, and verifying configurations.
275
- - **Destination-Aware Channels**: Support for unique per-application multicast destinations and deterministic IP generation.
276
- - **Stream Sharing**: Deterministic SSRC allocation allows multiple independent applications to share `radiod` streams efficiently.
277
- - **`discover_example.py`** - Channel discovery methods (native Python and control utility)
278
- - **`tune.py`** - Interactive channel tuning utility (Python implementation of ka9q-radio's tune)
279
- - **`tune_example.py`** - Programmatic examples of using the tune() method
280
- - **`rtp_recorder_example.py`** - Complete RTP recorder with timing and state machine
281
- - **`test_timing_fields.py`** - Verify GPS_TIME/RTP_TIMESNAP timing fields
282
- - **`simple_am_radio.py`** - Minimal AM broadcast listener
283
- - **`superdarn_recorder.py`** - Ionospheric radar monitoring
284
- - **`codar_oceanography.py`** - Ocean current radar
285
- - **`hf_band_scanner.py`** - Dynamic frequency scanner
286
- - **`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
287
284
 
288
285
  ## Use Cases
289
286
 
290
- ### AM/FM/SSB Radio
291
- - Broadcast monitoring
292
- - Ham radio operation
293
- - Shortwave listening
294
-
295
- ### Scientific Research
296
- - WSPR propagation studies
297
- - SuperDARN ionospheric radar
298
- - CODAR ocean current mapping
299
- - Meteor scatter
300
- - EME (moonbounce)
301
-
302
- ### Digital Modes
303
- - FT8/FT4 monitoring
304
- - RTTY/PSK decoding
305
- - DRM digital radio
306
- - HF fax reception
307
-
308
- ### Satellite Operations
309
- - Downlink reception
310
- - Doppler tracking
311
- - Multi-frequency monitoring
312
-
313
- ### Custom Applications
314
- **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.
315
293
 
316
294
  ## License
317
295