feat: log OBD speed before GPS fix so rolling starts aren't lost

- _log_loop: when GPS has no fix but OBD speed > 1, write speed-only rows
  (NULL coordinates) instead of dropping the motion
- insert_tracking: accept None gps_x/gps_y -> NULL GPSX/GPSY
- app_trip: keep NULL-coord rows through normalize; _segment returns 0 for
  missing coords; route_points drops them (no position to draw)
- tests: speed-only rows build a trip with max speed + zero distance
- docs: FEAT-12 + readme note; server already filters NULL-GPS safely
This commit is contained in:
Mathieu Moran
2026-08-13 02:02:45 -04:00
parent fa8ae0001a
commit 3d49764855
5 changed files with 64 additions and 6 deletions
+16
View File
@@ -115,6 +115,22 @@ class TripBuilderTest(unittest.TestCase):
self.assertEqual(trips[0]["start_tracking_id"], 1)
self.assertEqual(trips[0]["end_tracking_id"], 5)
def test_speed_only_rows_without_gps_build_trip(self):
started = datetime(2026, 1, 1, 8)
rows = [
(index + 1, started + timedelta(seconds=index * 5), None, None, 30)
for index in range(4)
]
trips = app_trip.build_trip_summaries(rows)
self.assertEqual(len(trips), 1)
self.assertEqual(trips[0]["start_tracking_id"], 1)
self.assertEqual(trips[0]["end_tracking_id"], 4)
self.assertEqual(trips[0]["distance_km"], 0)
self.assertEqual(trips[0]["max_speed_kmh"], 30)
self.assertEqual(trips[0]["point_count"], 4)
def test_clock_rollback_does_not_merge_motion_episodes(self):
first = self.rows_for_route(
[(45.5, -73.5), (45.5, -73.5)],