feat: add realtime GNSS monitor with telemetry websocket
All checks were successful
Deploy to Production / deploy (push) Successful in 1m10s

This commit is contained in:
魏风
2026-03-20 11:48:04 +08:00
parent e8846f4831
commit e81aadcd99
16 changed files with 1951 additions and 22 deletions

View File

@@ -0,0 +1,127 @@
from datetime import datetime, timezone
from fastapi.testclient import TestClient
from sqlmodel import Session
from app.core.config import settings
from app.models import TerminalDeviceState
def _seed_device_state(
db: Session, device_id: str, snr_values: list[int] | None = None
) -> None:
state = db.get(TerminalDeviceState, device_id)
if state is None:
state = TerminalDeviceState(device_id=device_id)
signal_values = snr_values if snr_values is not None else [28, 31, 36, 41, 44]
state.fix_status = "5"
state.lat = 31.359591
state.lon = 120.714489
state.alt_m = 52.1
state.satellites_used = 17
state.satellite_signal_summary = {
"satellites_in_view": 22,
"snr_values": signal_values,
"constellations": {
"GPS": {"count": 8, "used_in_navigation": 6},
"BeiDou": {"count": 10, "used_in_navigation": 8},
"Galileo": {"count": 4, "used_in_navigation": 3},
},
"satellites": [
{
"satellite_id": "G05",
"constellation": "GPS",
"azimuth_deg": 121,
"elevation_deg": 29,
"snr_dbhz": 37,
"used_in_navigation": True,
}
],
}
state.last_event_time = datetime.now(timezone.utc)
db.add(state)
db.commit()
def test_read_telemetry_latest(
client: TestClient, superuser_token_headers: dict[str, str], db: Session
) -> None:
device_id = "device-api-001"
_seed_device_state(db, device_id)
response = client.get(
f"{settings.API_V1_STR}/telemetry/latest",
headers=superuser_token_headers,
)
assert response.status_code == 200
payload = response.json()
assert "generated_at" in payload
assert len(payload["devices"]) >= 1
device = next(item for item in payload["devices"] if item["device_id"] == device_id)
assert device["fix_status"] == "5"
assert device["signal_health"]["level"] == "poor"
def test_signal_health_levels_based_on_count_of_40_plus_signals(
client: TestClient, superuser_token_headers: dict[str, str], db: Session
) -> None:
_seed_device_state(db, "device-health-good", [40] * 20 + [15] * 3)
_seed_device_state(db, "device-health-fair", [40] * 10 + [20] * 3)
_seed_device_state(db, "device-health-poor", [40] * 9 + [39])
response = client.get(
f"{settings.API_V1_STR}/telemetry/latest",
headers=superuser_token_headers,
params={"limit": 200},
)
assert response.status_code == 200
devices = {item["device_id"]: item for item in response.json()["devices"]}
assert devices["device-health-good"]["signal_health"]["level"] == "good"
assert devices["device-health-fair"]["signal_health"]["level"] == "fair"
assert devices["device-health-poor"]["signal_health"]["level"] == "poor"
def test_signal_health_uses_satellite_level_values_for_ucenter_view(
client: TestClient, superuser_token_headers: dict[str, str], db: Session
) -> None:
state = db.get(TerminalDeviceState, "device-health-ucenter")
if state is None:
state = TerminalDeviceState(device_id="device-health-ucenter")
state.fix_status = "5"
state.satellite_signal_summary = {
# u-center signal bars are per-satellite bars, not per-frequency points
"snr_values": [41] * 9 + [30] * 4,
# keep raw CN0 points for diagnostics, but health should follow bar view
"cn0_values": [41] * 20 + [25] * 5,
}
db.add(state)
db.commit()
response = client.get(
f"{settings.API_V1_STR}/telemetry/latest",
headers=superuser_token_headers,
params={"device_id": "device-health-ucenter"},
)
assert response.status_code == 200
device = response.json()["devices"][0]
assert device["signal_health"]["strong_signal_count"] == 9
assert device["signal_health"]["level"] == "poor"
def test_telemetry_websocket_stream(
client: TestClient, superuser_token_headers: dict[str, str], db: Session
) -> None:
_seed_device_state(db, "device-api-002")
token = superuser_token_headers["Authorization"].split(" ", 1)[1]
with client.websocket_connect(
f"{settings.API_V1_STR}/telemetry/ws?token={token}"
) as websocket:
payload = websocket.receive_json()
assert "generated_at" in payload
assert len(payload["devices"]) >= 1

448
backend/tests/mqtt/nmea.txt Normal file
View File

@@ -0,0 +1,448 @@
$GNRMC,015903.000,A,3121.575445,N,12042.869341,E,0.015,51.12,080126,,E,A,V*48
$GNGGA,015903.000,3121.575445,N,12042.869341,E,1,17,1.09,51.800,M,0.000,M,,*79
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,38,16,47,239,00,26,74,310,29,1*55
$GPGSV,3,2,9,27,11,189,00,28,50,056,42,29,23,053,44,31,59,357,39,1*5A
$GPGSV,3,3,9,32,34,146,20,1*6A
$GPGSV,3,1,9,03,24,284,00,04,16,319,36,16,47,239,00,26,74,310,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,357,00,8*5F
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,39,25,37,278,00,26,22,058,40,1*77
$GBGSV,8,5,29,33,58,251,00,34,12,157,00,35,11,059,40,38,17,196,00,1*71
$GBGSV,8,6,29,39,62,002,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7F
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,38,25,37,278,00,26,22,058,34,33,58,251,00,4*7B
$GBGSV,4,2,13,34,12,157,00,35,11,059,37,38,17,196,00,39,62,002,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,37,19,13,135,00,7*4B
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,36,75,13,044,43,1*47
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015903.000,0.86,8.38,1.39,81.42,32.311,7.315,13.683*43
$GNSVD,0,0,0,118,22,22*40
$GNRMC,015904.000,A,3121.575704,N,12042.869303,E,0.050,334.82,080126,,E,A,V*77
$GNGGA,015904.000,3121.575704,N,12042.869303,E,1,17,1.09,51.838,M,0.000,M,,*75
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,38,16,47,239,00,26,74,310,29,1*55
$GPGSV,3,2,9,27,11,189,00,28,50,056,42,29,23,053,44,31,59,357,39,1*5A
$GPGSV,3,3,9,32,34,146,19,1*60
$GPGSV,3,1,9,03,24,284,00,04,16,319,36,16,47,239,00,26,74,310,30,8*5A
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,357,00,8*5F
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,39,25,37,278,00,26,22,058,41,1*76
$GBGSV,8,5,29,33,58,251,00,34,12,157,00,35,11,059,40,38,17,196,00,1*71
$GBGSV,8,6,29,39,62,002,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7F
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,38,25,37,278,00,26,22,058,34,33,58,251,00,4*7B
$GBGSV,4,2,13,34,12,157,00,35,11,059,37,38,17,196,00,39,62,002,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,37,19,13,135,00,7*4B
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,43,1*44
$GLGSV,2,2,8,76,53,352,42,77,39,277,00,85,09,055,41,86,08,112,00,1*48
$GNGST,015904.000,0.93,8.38,1.38,81.41,32.302,7.294,13.653*45
$GNSVD,-1,2,0,350,68,71*68
$GNRMC,015905.000,A,3121.575859,N,12042.869263,E,0.039,345.46,080126,,E,A,V*77
$GNGGA,015905.000,3121.575859,N,12042.869263,E,1,17,1.09,51.796,M,0.000,M,,*7F
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,38,16,47,239,00,26,74,310,29,1*55
$GPGSV,3,2,9,27,11,189,00,28,50,056,42,29,23,053,44,31,59,357,39,1*5A
$GPGSV,3,3,9,32,34,146,19,1*60
$GPGSV,3,1,9,03,24,284,00,04,16,319,36,16,47,239,00,26,74,310,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,357,00,8*5F
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,39,25,37,278,00,26,22,058,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,059,40,38,17,196,00,1*70
$GBGSV,8,6,29,39,62,002,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7F
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,058,34,33,58,250,00,4*7B
$GBGSV,4,2,13,34,12,157,00,35,11,059,37,38,17,196,00,39,62,002,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,37,19,13,135,00,7*4B
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,43,1*44
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015905.000,0.68,8.41,1.37,81.41,32.384,7.264,13.612*45
$GNSVD,0,1,0,409,76,76*44
$GNRMC,015906.000,A,3121.576069,N,12042.869216,E,0.042,336.34,080126,,E,A,V*73
$GNGGA,015906.000,3121.576069,N,12042.869216,E,1,17,1.09,51.776,M,0.000,M,,*78
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,38,16,47,239,00,26,74,310,29,1*55
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,45,31,59,357,39,1*5A
$GPGSV,3,3,9,32,34,146,20,1*6A
$GPGSV,3,1,9,03,24,284,00,04,16,319,36,16,47,239,00,26,74,310,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,357,00,8*5F
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,39,25,37,278,00,26,22,058,41,1*76
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,059,40,38,17,196,00,1*70
$GBGSV,8,6,29,39,62,002,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7F
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,058,34,33,58,250,00,4*7B
$GBGSV,4,2,13,34,12,157,00,35,11,059,37,38,17,196,00,39,62,002,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,43,1*44
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015906.000,0.55,8.42,1.36,81.36,32.417,7.258,13.592*43
$GNSVD,0,2,0,407,84,79*4B
$GNRMC,015907.000,A,3121.576167,N,12042.869218,E,0.058,344.47,080126,,E,A,V*79
$GNGGA,015907.000,3121.576167,N,12042.869218,E,1,17,1.09,51.827,M,0.000,M,,*73
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,38,16,47,239,00,26,74,311,29,1*54
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,45,31,59,358,39,1*55
$GPGSV,3,3,9,32,34,146,20,1*6A
$GPGSV,3,1,9,03,24,284,00,04,16,319,36,16,47,239,00,26,74,311,31,8*5A
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,39,25,37,278,00,26,22,058,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,059,40,38,17,196,00,1*70
$GBGSV,8,6,29,39,62,002,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7F
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,058,34,33,58,250,00,4*7B
$GBGSV,4,2,13,34,12,157,00,35,11,059,36,38,17,196,00,39,62,002,37,4*74
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,44,1*43
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015907.000,0.74,8.46,1.36,81.39,32.556,7.267,13.652*4D
$GNSVD,0,2,1,351,70,80*43
$GNRMC,015908.000,A,3121.576274,N,12042.869205,E,0.037,270.24,080126,,E,A,V*71
$GNGGA,015908.000,3121.576274,N,12042.869205,E,1,17,1.09,51.877,M,0.000,M,,*74
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,38,16,47,239,00,26,74,311,29,1*54
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,44,31,59,358,39,1*54
$GPGSV,3,3,9,32,34,146,20,1*6A
$GPGSV,3,1,9,03,24,284,00,04,16,319,36,16,47,239,00,26,74,311,31,8*5A
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,39,25,37,278,00,26,22,058,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,059,40,38,17,196,00,1*70
$GBGSV,8,6,29,39,62,002,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7F
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,38,25,37,278,00,26,22,058,34,33,58,250,00,4*7A
$GBGSV,4,2,13,34,12,157,00,35,11,059,36,38,17,196,00,39,62,002,37,4*74
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,39,19,13,135,00,1*43
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,43,1*44
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015908.000,0.73,8.42,1.35,81.41,32.460,7.222,13.595*40
$GNSVD,-1,0,8,345,70,74*6A
$GNRMC,015909.000,A,3121.576447,N,12042.869168,E,0.038,223.29,080126,,E,A,V*7A
$GNGGA,015909.000,3121.576447,N,12042.869168,E,1,17,1.09,51.981,M,0.000,M,,*73
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,39,16,47,239,00,26,74,311,30,1*5D
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,44,31,59,358,39,1*54
$GPGSV,3,3,9,32,34,146,20,1*6A
$GPGSV,3,1,9,03,24,284,00,04,16,319,36,16,47,239,00,26,74,311,31,8*5A
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,39,25,37,278,00,26,22,058,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,059,40,38,17,196,00,1*70
$GBGSV,8,6,29,39,62,002,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7F
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,058,34,33,58,250,00,4*7B
$GBGSV,4,2,13,34,12,157,00,35,11,059,36,38,17,196,00,39,62,002,37,4*74
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,44,1*43
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015909.000,0.79,8.42,1.35,81.34,32.445,7.223,13.571*45
$GNSVD,-1,-1,10,379,80,76*7D
$GNRMC,015910.000,A,3121.576443,N,12042.869180,E,0.053,156.87,080126,,E,A,V*78
$GNGGA,015910.000,3121.576443,N,12042.869180,E,1,17,1.09,52.067,M,0.000,M,,*7B
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,39,16,47,239,00,26,74,311,30,1*5D
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,44,31,59,358,39,1*54
$GPGSV,3,3,9,32,34,146,19,1*60
$GPGSV,3,1,9,03,24,284,00,04,16,319,37,16,47,239,00,26,74,311,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,38,25,37,278,00,26,22,059,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,059,40,38,17,196,00,1*70
$GBGSV,8,6,29,39,62,002,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7F
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,059,34,33,58,250,00,4*7A
$GBGSV,4,2,13,34,12,157,00,35,11,059,37,38,17,196,00,39,62,002,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,44,1*43
$GLGSV,2,2,8,76,53,352,42,77,39,277,00,85,09,055,41,86,08,112,00,1*48
$GNGST,015910.000,0.96,8.50,1.36,81.36,32.672,7.253,13.641*4F
$GNSVD,1,-2,8,400,77,78*65
$GNRMC,015911.000,A,3121.576500,N,12042.869206,E,0.064,148.17,080126,,E,A,V*70
$GNGGA,015911.000,3121.576500,N,12042.869206,E,1,17,1.09,52.146,M,0.000,M,,*73
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,39,16,47,239,00,26,74,311,30,1*5D
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,45,31,59,358,40,1*5B
$GPGSV,3,3,9,32,34,146,19,1*60
$GPGSV,3,1,9,03,24,284,00,04,16,319,37,16,47,239,00,26,74,311,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,38,25,37,278,00,26,22,059,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,059,40,38,17,196,00,1*70
$GBGSV,8,6,29,39,62,003,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7E
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,059,34,33,58,250,00,4*7A
$GBGSV,4,2,13,34,12,157,00,35,11,059,37,38,17,196,00,39,62,003,37,4*74
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,34,75,13,044,43,1*45
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015911.000,0.75,8.51,1.34,81.40,32.724,7.216,13.607*40
$GNSVD,1,-2,6,394,71,77*68
$GNRMC,015912.000,A,3121.576672,N,12042.869211,E,0.050,221.67,080126,,E,A,V*7F
$GNGGA,015912.000,3121.576672,N,12042.869211,E,1,17,1.09,52.182,M,0.000,M,,*78
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,39,16,47,239,00,26,74,311,30,1*5D
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,44,31,59,358,40,1*5A
$GPGSV,3,3,9,32,34,146,20,1*6A
$GPGSV,3,1,9,03,24,284,00,04,16,319,37,16,47,239,00,26,74,311,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,38,25,37,278,00,26,22,059,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,058,40,38,17,196,00,1*71
$GBGSV,8,6,29,39,62,003,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7E
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,38,25,37,278,00,26,22,059,34,33,58,250,00,4*7B
$GBGSV,4,2,13,34,12,157,00,35,11,058,37,38,17,196,00,39,62,003,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,34,75,13,044,43,1*45
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015912.000,0.81,8.56,1.33,81.41,32.863,7.193,13.598*4E
$GNSVD,-1,-1,2,463,81,80*4A
$GNRMC,015913.000,A,3121.576893,N,12042.869268,E,0.038,116.71,080126,,E,A,V*7F
$GNGGA,015913.000,3121.576893,N,12042.869268,E,1,17,1.09,52.385,M,0.000,M,,*73
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,39,16,47,239,00,26,74,311,30,1*5D
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,45,31,59,358,39,1*55
$GPGSV,3,3,9,32,34,146,21,1*6B
$GPGSV,3,1,9,03,24,284,00,04,16,319,37,16,47,239,00,26,74,311,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,38,25,37,278,00,26,22,059,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,058,40,38,17,196,00,1*71
$GBGSV,8,6,29,39,62,003,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7E
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,059,34,33,58,250,00,4*7A
$GBGSV,4,2,13,34,12,157,00,35,11,058,37,38,17,196,00,39,62,003,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,40,19,13,135,00,1*4D
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,34,75,13,044,43,1*45
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015913.000,0.85,8.57,1.32,81.45,32.915,7.164,13.564*44
$GNSVD,1,0,3,396,70,75*43
$GNRMC,015914.000,A,3121.576888,N,12042.869261,E,0.042,124.95,080126,,E,A,V*7D
$GNGGA,015914.000,3121.576888,N,12042.869261,E,1,17,1.09,52.400,M,0.000,M,,*7D
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,39,16,47,239,00,26,74,311,29,1*55
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,45,31,59,358,40,1*5B
$GPGSV,3,3,9,32,34,146,22,1*68
$GPGSV,3,1,9,03,24,284,00,04,16,319,37,16,47,239,00,26,74,311,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,38,25,37,278,00,26,22,059,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,058,40,38,17,196,00,1*71
$GBGSV,8,6,29,39,62,003,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7E
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,059,34,33,58,250,00,4*7A
$GBGSV,4,2,13,34,12,157,00,35,11,058,37,38,17,196,00,39,62,003,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,39,19,13,135,00,1*43
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,43,1*44
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015914.000,1.04,8.64,1.32,81.48,33.129,7.180,13.627*4E
$GNSVD,1,-1,2,115,20,22*60
$GNRMC,015915.000,A,3121.576930,N,12042.869269,E,0.082,170.97,080126,,E,A,V*79
$GNGGA,015915.000,3121.576930,N,12042.869269,E,1,17,1.09,52.478,M,0.000,M,,*79
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,39,16,47,239,00,26,74,311,30,1*5D
$GPGSV,3,2,9,27,11,189,00,28,50,056,43,29,23,053,45,31,59,358,40,1*5B
$GPGSV,3,3,9,32,34,146,23,1*69
$GPGSV,3,1,9,03,24,284,00,04,16,319,37,16,47,239,00,26,74,311,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,38,25,37,278,00,26,22,059,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,058,40,38,17,196,00,1*71
$GBGSV,8,6,29,39,62,003,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7E
$GBGSV,8,7,29,44,23,105,00,50,09,164,00,59,48,145,00,60,33,239,00,1*76
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,38,25,37,278,00,26,22,059,34,33,58,250,00,4*7B
$GBGSV,4,2,13,34,12,157,00,35,11,058,37,38,17,196,00,39,62,003,37,4*75
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,105,00,4*7A
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,39,19,13,135,00,1*43
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,275,00,67,21,329,35,75,13,044,43,1*44
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015915.000,1.04,8.66,1.32,81.53,33.219,7.158,13.611*47
$GNSVD,0,-4,0,372,67,69*69
$GNRMC,015916.000,A,3121.576981,N,12042.869285,E,0.093,164.37,080126,,E,A,V*7D
$GNGGA,015916.000,3121.576981,N,12042.869285,E,1,17,1.09,52.469,M,0.000,M,,*72
$GPGSA,A,3,04,26,28,29,31,32,,,,,,,1.54,1.09,1.08,1*1C
$GBGSA,A,3,06,24,26,35,39,41,,,,,,,1.54,1.09,1.08,4*04
$GAGSA,A,3,09,,,,,,,,,,,,1.54,1.09,1.08,3*04
$GLGSA,A,3,67,75,76,85,,,,,,,,,1.54,1.09,1.08,2*0E
$GPGSV,3,1,9,03,24,284,00,04,16,319,38,16,47,239,00,26,74,311,29,1*54
$GPGSV,3,2,9,27,11,189,00,28,50,056,42,29,23,053,45,31,59,358,39,1*54
$GPGSV,3,3,9,32,34,146,23,1*69
$GPGSV,3,1,9,03,24,284,00,04,16,319,37,16,47,239,00,26,74,311,31,8*5B
$GPGSV,3,2,9,27,11,189,00,28,50,056,00,29,23,053,00,31,59,358,00,8*50
$GPGSV,3,3,9,32,34,146,00,8*61
$GBGSV,8,1,29,01,44,140,00,02,38,237,00,03,52,199,00,04,32,124,00,1*78
$GBGSV,8,2,29,05,16,257,00,06,59,332,33,07,31,184,00,08,25,209,00,1*71
$GBGSV,8,3,29,09,50,309,00,10,20,194,00,12,17,131,00,13,30,222,00,1*7A
$GBGSV,8,4,29,14,50,202,00,24,59,014,38,25,37,278,00,26,22,059,40,1*77
$GBGSV,8,5,29,33,58,250,00,34,12,157,00,35,11,058,40,38,17,196,00,1*71
$GBGSV,8,6,29,39,62,003,35,40,29,169,00,41,28,312,37,42,29,177,00,1*7E
$GBGSV,8,7,29,44,23,104,00,50,09,164,00,59,48,145,00,60,33,239,00,1*77
$GBGSV,8,8,29,61,51,199,00,1*4F
$GBGSV,4,1,13,24,59,014,39,25,37,278,00,26,22,059,34,33,58,250,00,4*7A
$GBGSV,4,2,13,34,12,157,00,35,11,058,36,38,17,196,00,39,62,003,37,4*74
$GBGSV,4,3,13,40,29,169,00,41,28,312,29,42,29,177,00,44,23,104,00,4*7B
$GBGSV,4,4,13,50,09,164,00,4*4E
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,38,19,13,135,00,7*44
$GAGSV,2,2,5,31,78,255,00,7*79
$GAGSV,2,1,5,04,69,130,00,06,81,329,00,09,54,320,39,19,13,135,00,1*43
$GAGSV,2,2,5,31,78,255,00,1*7F
$GLGSV,2,1,8,65,39,176,00,66,72,274,00,67,21,329,35,75,13,044,43,1*45
$GLGSV,2,2,8,76,53,352,43,77,39,277,00,85,09,055,41,86,08,112,00,1*49
$GNGST,015916.000,1.05,8.75,1.31,81.60,33.492,7.151,13.627*4D
$GNSVD,1,-4,-1,478,76,80*4E

View File

@@ -25,3 +25,24 @@ def test_parse_mixed_payload_returns_rtcm_summary() -> None:
event_types = {event["event_type"] for event in events}
assert "rtcm_summary" in event_types
def test_parse_nmea_sentences_extracts_satellite_details_and_used_ids() -> None:
payload = (
b"$GPGSA,A,3,02,05,12,,,,,,,,,,1.50,0.90,1.20*00\r\n"
b"$GPGSV,1,1,04,02,17,213,40,05,29,121,37,12,66,314,44,25,14,048,39*71\r\n"
)
events = parse_nmea_sentences(payload)
gsa_event = next(event for event in events if event["event_type"] == "nmea_gsa")
gsv_event = next(event for event in events if event["event_type"] == "nmea_gsv")
assert gsa_event["payload"]["used_satellite_ids"] == ["02", "05", "12"]
assert gsv_event["payload"]["constellation"] == "GPS"
assert len(gsv_event["payload"]["satellites"]) == 4
assert gsv_event["payload"]["satellites"][0] == {
"satellite_id": "02",
"elevation_deg": 17,
"azimuth_deg": 213,
"snr_dbhz": 40,
}

View File

@@ -85,3 +85,65 @@ def test_worker_marks_failed_without_retry_schedule(monkeypatch) -> None:
def test_schema_excludes_terminal_observation_event_table() -> None:
assert "terminal_observation_event" not in SQLModel.metadata.tables
def test_ingest_and_parse_real_nmea_sample() -> None:
from pathlib import Path
sample_path = Path(__file__).parent / "nmea.txt"
payload = sample_path.read_bytes()
with _session() as session:
raw = insert_raw_message(
session=session,
device_id="device-real-sample",
topic="terminal/device-real-sample/raw",
payload=payload,
qos=1,
retain=False,
)
processed = process_pending_batch(session=session, batch_size=10)
assert processed == 1
refreshed = session.get(TerminalMessageRaw, raw.id)
assert refreshed is not None
assert refreshed.parsed_at is not None
assert refreshed.parse_error is None
state = session.get(TerminalDeviceState, "device-real-sample")
assert state is not None
assert state.lat is not None
assert state.lon is not None
def test_worker_builds_satellite_distribution_summary() -> None:
payload = (
b"$GNGGA,123519,3723.2475,N,12158.3416,W,4,12,0.8,10.0,M,-25.0,M,,*65\r\n"
b"$GPGSA,A,3,02,05,12,,,,,,,,,,1.50,0.90,1.20*00\r\n"
b"$GPGSV,1,1,04,02,17,213,40,05,29,121,37,12,66,314,44,25,14,048,39*71\r\n"
)
with _session() as session:
insert_raw_message(
session=session,
device_id="device-gsv",
topic="terminal/device-gsv/raw",
payload=payload,
qos=1,
retain=False,
)
processed = process_pending_batch(session=session, batch_size=10)
assert processed == 1
state = session.get(TerminalDeviceState, "device-gsv")
assert state is not None
assert state.fix_status == "4"
summary = state.satellite_signal_summary
assert summary is not None
assert summary["satellites_in_view"] == 4
assert summary["snr_values"] == [40, 37, 44, 39]
assert summary["used_satellite_ids"] == ["02", "05", "12"]
assert summary["constellations"]["GPS"]["count"] == 4
assert summary["constellations"]["GPS"]["used_in_navigation"] == 3