Fix G2 position/RSSI parsers, document motor and DVB test results
Position parser now matches the actual Angle[0]/Angle[1] format instead of falling back to fragile raw-float extraction. RSSI parser uses a proper named-group regex matching the real firmware output format (Reads:<n> RSSI[avg: <v> cur: <v>]) — the old index-based approach would fail on the actual 5-field response. Motor test results: both axes move correctly, direction-dependent overshoot of 0.01-0.06 degrees confirmed. DVB subsystem explored: BCM4515 Rev B0, firmware v113.37, full command set documented including DiSEqC 2.x, transponder scanning, and streaming AGC/SNR. RSSI noise floor is ~500.
This commit is contained in:
parent
71ffafdd3f
commit
6b94f079aa
3 changed files with 178 additions and 25 deletions
|
|
@ -312,29 +312,24 @@ class CarryoutG2Protocol(FirmwareProtocol):
|
|||
def get_position(self) -> Position:
|
||||
"""Query dish position.
|
||||
|
||||
The G2 may return floats without AZ=/EL= labels, so we try the
|
||||
labeled format first and fall back to raw float extraction.
|
||||
G2 firmware 02.02.48 returns position as::
|
||||
|
||||
Angle[0] = 180.00
|
||||
Angle[1] = 45.00
|
||||
MOT>
|
||||
|
||||
Where Angle[0] is azimuth and Angle[1] is elevation.
|
||||
"""
|
||||
response = self._send("a")
|
||||
|
||||
# Try labeled format (AZ = / EL =) for compatibility
|
||||
az_match = re.search(r"AZ\s*=?\s*(\d+\.\d+)", response)
|
||||
el_match = re.search(r"EL\s*=?\s*(\d+\.\d+)", response)
|
||||
# G2 format: Angle[0] = <az>, Angle[1] = <el>
|
||||
az_match = re.search(r"Angle\[0\]\s*=\s*(-?\d+\.\d+)", response)
|
||||
el_match = re.search(r"Angle\[1\]\s*=\s*(-?\d+\.\d+)", response)
|
||||
|
||||
if az_match and el_match:
|
||||
sk_match = re.search(r"SK\s*=?\s*(\d+\.\d+)", response)
|
||||
return Position(
|
||||
azimuth=float(az_match.group(1)),
|
||||
elevation=float(el_match.group(1)),
|
||||
skew=float(sk_match.group(1)) if sk_match else None,
|
||||
)
|
||||
|
||||
# Fall back to raw float extraction (G2-style: just two numbers)
|
||||
floats = re.findall(r"\d+\.\d+", response)
|
||||
if len(floats) >= 2:
|
||||
return Position(
|
||||
azimuth=float(floats[0]),
|
||||
elevation=float(floats[1]),
|
||||
)
|
||||
|
||||
raise ValueError(f"Could not parse position from: {response!r}")
|
||||
|
|
@ -367,6 +362,12 @@ class CarryoutG2Protocol(FirmwareProtocol):
|
|||
def get_rssi(self, iterations: int = 10) -> RssiReading:
|
||||
"""Read averaged RSSI signal strength (DVB submenu).
|
||||
|
||||
Firmware response format::
|
||||
|
||||
iterations:5 interval(msec):20
|
||||
Reads:5 RSSI[avg: 500 cur: 500]
|
||||
DVB>
|
||||
|
||||
Args:
|
||||
iterations: Number of samples to average.
|
||||
|
||||
|
|
@ -377,13 +378,16 @@ class CarryoutG2Protocol(FirmwareProtocol):
|
|||
ValueError: If the RSSI response can't be parsed.
|
||||
"""
|
||||
response = self._send(f"rssi {iterations}")
|
||||
results = re.findall(r"\d+", response)
|
||||
|
||||
if len(results) >= 6:
|
||||
match = re.search(
|
||||
r"Reads:(\d+)\s+RSSI\[avg:\s*(\d+)\s+cur:\s*(\d+)\]",
|
||||
response,
|
||||
)
|
||||
if match:
|
||||
return RssiReading(
|
||||
reads=int(results[3]),
|
||||
average=int(results[4]),
|
||||
current=int(results[5]),
|
||||
reads=int(match.group(1)),
|
||||
average=int(match.group(2)),
|
||||
current=int(match.group(3)),
|
||||
)
|
||||
|
||||
raise ValueError(f"Could not parse RSSI from: {response!r}")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue