ka9q-python 3.26.0__py3-none-any.whl → 3.26.2__py3-none-any.whl
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/control.py +39 -4
- ka9q/status.py +10 -6
- ka9q/stream.py +6 -5
- {ka9q_python-3.26.0.dist-info → ka9q_python-3.26.2.dist-info}/METADATA +1 -1
- {ka9q_python-3.26.0.dist-info → ka9q_python-3.26.2.dist-info}/RECORD +9 -9
- {ka9q_python-3.26.0.dist-info → ka9q_python-3.26.2.dist-info}/WHEEL +1 -1
- {ka9q_python-3.26.0.dist-info → ka9q_python-3.26.2.dist-info}/entry_points.txt +0 -0
- {ka9q_python-3.26.0.dist-info → ka9q_python-3.26.2.dist-info}/licenses/LICENSE +0 -0
- {ka9q_python-3.26.0.dist-info → ka9q_python-3.26.2.dist-info}/top_level.txt +0 -0
ka9q/control.py
CHANGED
|
@@ -910,7 +910,11 @@ class RadiodControl:
|
|
|
910
910
|
Sends TLV-encoded commands to radiod's control socket to create
|
|
911
911
|
and configure channels.
|
|
912
912
|
"""
|
|
913
|
-
|
|
913
|
+
|
|
914
|
+
# ensure_channel(): pause between status polls while waiting for radiod
|
|
915
|
+
# to report the requested OUTPUT_ENCODING.
|
|
916
|
+
_ENCODING_SETTLE_POLL_S = 0.1
|
|
917
|
+
|
|
914
918
|
def __init__(self, status_address: str, max_commands_per_sec: int = 100,
|
|
915
919
|
interface: Optional[str] = None,
|
|
916
920
|
client_id: Optional[str] = None):
|
|
@@ -2072,9 +2076,40 @@ class RadiodControl:
|
|
|
2072
2076
|
f"Channel SSRC {ssrc} not verified within {timeout}s. "
|
|
2073
2077
|
f"Requested: {frequency_hz/1e6:.3f} MHz, {preset}, {sample_rate} Hz"
|
|
2074
2078
|
)
|
|
2075
|
-
#
|
|
2076
|
-
#
|
|
2077
|
-
#
|
|
2079
|
+
# create_channel() sends OUTPUT_ENCODING as a separate command after
|
|
2080
|
+
# the create, so the first status can predate it and report the
|
|
2081
|
+
# preset's encoding. Streams pick their decoder from
|
|
2082
|
+
# ChannelInfo.encoding; a stale S16 on an F32 stream decodes 4-byte
|
|
2083
|
+
# floats as 2-byte ints — noise-like garbage at "100% completeness".
|
|
2084
|
+
# Keep polling until radiod reports the requested encoding. If it
|
|
2085
|
+
# still differs at the deadline, return what radiod reports (the
|
|
2086
|
+
# stream must decode what is on the wire) and say so loudly.
|
|
2087
|
+
if encoding != 0 and channel.encoding != encoding:
|
|
2088
|
+
deadline = time.monotonic() + timeout
|
|
2089
|
+
stale = channel.encoding
|
|
2090
|
+
while time.monotonic() < deadline:
|
|
2091
|
+
time.sleep(self._ENCODING_SETTLE_POLL_S)
|
|
2092
|
+
fresh = self.poll_channel(
|
|
2093
|
+
ssrc, expected_freq=frequency_hz,
|
|
2094
|
+
timeout=max(0.1, min(1.0, deadline - time.monotonic())),
|
|
2095
|
+
frequency_tolerance=frequency_tolerance,
|
|
2096
|
+
)
|
|
2097
|
+
if fresh is not None:
|
|
2098
|
+
channel = fresh
|
|
2099
|
+
if channel.encoding == encoding:
|
|
2100
|
+
break
|
|
2101
|
+
if channel.encoding == encoding:
|
|
2102
|
+
logger.info(
|
|
2103
|
+
"ensure_channel: SSRC %s encoding settled %s -> %s",
|
|
2104
|
+
ssrc, stale, channel.encoding,
|
|
2105
|
+
)
|
|
2106
|
+
else:
|
|
2107
|
+
logger.error(
|
|
2108
|
+
"ensure_channel: SSRC %s still reports encoding %s after "
|
|
2109
|
+
"%.1fs (requested %s); returning radiod's value",
|
|
2110
|
+
ssrc, channel.encoding, timeout, encoding,
|
|
2111
|
+
)
|
|
2112
|
+
# A rate/preset divergence is logged
|
|
2078
2113
|
# but not fatal — the channel exists at the requested frequency.
|
|
2079
2114
|
# An ABSENT preset is not a divergence. radiod may decline to echo
|
|
2080
2115
|
# PRESET at all (write-only from the nopreset branch on), and a label
|
ka9q/status.py
CHANGED
|
@@ -88,16 +88,20 @@ class FrontendStatus:
|
|
|
88
88
|
"""Absolute input power in dBm if the front-end is calibrated."""
|
|
89
89
|
if self.if_power is None or self.rf_level_cal is None:
|
|
90
90
|
return None
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
if not math.isfinite(self.rf_level_cal): # radiod's "not calibrated"
|
|
92
|
+
return None
|
|
93
|
+
# Term for term what radiod's control.c displays as "Input":
|
|
94
|
+
# if_power + lna + mixer + if_gain + |rf_atten| - rf_gain + rf_level_cal
|
|
95
|
+
# Keep it identical to control.c, even where a sign looks odd.
|
|
96
|
+
dbm = self.if_power + self.rf_level_cal
|
|
93
97
|
for v in (self.lna_gain, self.mixer_gain, self.if_gain):
|
|
94
98
|
if v is not None:
|
|
95
|
-
|
|
99
|
+
dbm += v
|
|
96
100
|
if self.rf_atten is not None:
|
|
97
|
-
|
|
101
|
+
dbm += abs(self.rf_atten)
|
|
98
102
|
if self.rf_gain is not None:
|
|
99
|
-
|
|
100
|
-
return
|
|
103
|
+
dbm -= self.rf_gain
|
|
104
|
+
return dbm
|
|
101
105
|
|
|
102
106
|
|
|
103
107
|
@dataclass
|
ka9q/stream.py
CHANGED
|
@@ -129,11 +129,12 @@ def parse_rtp_samples(
|
|
|
129
129
|
if floats is None:
|
|
130
130
|
return None
|
|
131
131
|
if is_iq:
|
|
132
|
-
#
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
#
|
|
132
|
+
# Decode with the encoding the channel reports. A wrong value
|
|
133
|
+
# here corrupts silently: the bee1 2026-05-15 T6/TSL3 "F32→S16
|
|
134
|
+
# downgrade" and codar-sounder's 2026-11-01 garbage IQ were both
|
|
135
|
+
# a stale encoding from ensure_channel (status read before the
|
|
136
|
+
# separate OUTPUT_ENCODING command landed), not radiod changing
|
|
137
|
+
# the encoding. ensure_channel now waits for it to settle.
|
|
137
138
|
if len(floats) % 2 != 0:
|
|
138
139
|
logger.warning(f"Odd number of samples in IQ payload: {len(floats)}")
|
|
139
140
|
return None
|
|
@@ -3,7 +3,7 @@ ka9q/_multicast.py,sha256=U6pCiH1ruy3i5yv7B_rRhkakokwnetu1Nd3009nAI5w,3343
|
|
|
3
3
|
ka9q/addressing.py,sha256=GaHLeTwRpsmJawRAROoj-AqALcVkqO6Jq4_th9u7fjE,2681
|
|
4
4
|
ka9q/cli.py,sha256=nfU4hqScqjJtuWBBraPxUb-37cvjY_qtZkNIxr9GzRU,15040
|
|
5
5
|
ka9q/compat.py,sha256=uiU-wkQ1p88fcfPYRdqU1QxHiunmQPIhM5CXkW_5GMs,436
|
|
6
|
-
ka9q/control.py,sha256=
|
|
6
|
+
ka9q/control.py,sha256=RbiK9Wwn6E9tNQZX6rbJyPRM3YJXwDSpDaBd3QkXyKw,158132
|
|
7
7
|
ka9q/discovery.py,sha256=-jGcDczuwEQmmJRogc2hR22PUKT2qxWkPgy_ffd9Cdk,28615
|
|
8
8
|
ka9q/exceptions.py,sha256=_P8rok_tTmRMu-lLRhS95kv8FRK5PEY80_6jIux2mWM,474
|
|
9
9
|
ka9q/managed_stream.py,sha256=gHvGcQgJF5FCOzVp7V6vcIp75NLGnOHgClGR24i9_No,18842
|
|
@@ -15,16 +15,16 @@ ka9q/resequencer.py,sha256=m_OWattFpqIugSqWr6aadsmUeoJIPkfINKfPi6gp_sg,17300
|
|
|
15
15
|
ka9q/rtp_recorder.py,sha256=-YpG9mleoGjEd5voPSxnGcdVsFvyxSgOJ8f7ZaXGcT0,23210
|
|
16
16
|
ka9q/slot_clock.py,sha256=9OuE1qMHJ5YBHfNPtQSguj_KHgkU9iAXfhOLEk-1B78,13468
|
|
17
17
|
ka9q/spectrum_stream.py,sha256=utMhpH8hkkwOSD1WpKb4r0YHm3isDF0TvYMq-jJJFwY,11458
|
|
18
|
-
ka9q/status.py,sha256=
|
|
18
|
+
ka9q/status.py,sha256=ufrw-8pPvOs9YjRlR3W8cWWsfA23utdR-eMddyuokKU,28421
|
|
19
19
|
ka9q/status_listener.py,sha256=20l9aHii263myYlO8mmSgI_tUcchUwLwgh69Dx-1UQY,20045
|
|
20
|
-
ka9q/stream.py,sha256=
|
|
20
|
+
ka9q/stream.py,sha256=TvEcQorlRWZ9_MoyN0apXlrZaLtlheU7V2RP0yR-hIk,33197
|
|
21
21
|
ka9q/stream_quality.py,sha256=YrKa07PzDi4xeF5tubwpDvSTs5eHu0G7mOa12iIINrs,8222
|
|
22
22
|
ka9q/tui.py,sha256=ryL5CxfYkVzXhsCy1hw9GP3ya8hDbZTccfkc_uJtrDQ,27182
|
|
23
23
|
ka9q/types.py,sha256=woWL_ShotZnYUYsR4RBL2wu13S1MTkkJC9_-9IVh14g,7514
|
|
24
24
|
ka9q/utils.py,sha256=fFR_sYIpeDyPaFlXzN6jCiGhYlssvrMMVx4z6vyhqcc,7107
|
|
25
|
-
ka9q_python-3.26.
|
|
26
|
-
ka9q_python-3.26.
|
|
27
|
-
ka9q_python-3.26.
|
|
28
|
-
ka9q_python-3.26.
|
|
29
|
-
ka9q_python-3.26.
|
|
30
|
-
ka9q_python-3.26.
|
|
25
|
+
ka9q_python-3.26.2.dist-info/licenses/LICENSE,sha256=mjz-l5TVsO9j7Jqt1gfLvTWtZK_HL9sZRRpsHaq4Qv8,1074
|
|
26
|
+
ka9q_python-3.26.2.dist-info/METADATA,sha256=s80doU296SSsQAQg8UBa2rYHI5nBGwGOzIYhW561_Qo,14637
|
|
27
|
+
ka9q_python-3.26.2.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
28
|
+
ka9q_python-3.26.2.dist-info/entry_points.txt,sha256=Wt5Q4OMUKHaf4KdsZXWsjSBpbHVuTtt3pypVIHi7eRk,39
|
|
29
|
+
ka9q_python-3.26.2.dist-info/top_level.txt,sha256=FUTLZDtQpJGenGPPlN34E5QpQi_oaiLB6LuzgHblBNE,5
|
|
30
|
+
ka9q_python-3.26.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|