Fleet Telemetry
Fleet telemetry API with B-tree indexed lookups and a chained severity/alert UDF pipeline
One app.py with 1 table, 3 computed columns, 7 HTTP routes. Needs pixeltable[serve]>=0.7.14. Updated 2026-09-27.
app.py
"""Fleet Telemetry API built with Pixeltable.pxt schema update app.py fleetpxt service run app.py fleet"""import pixeltable as pxtimport pixeltable.functions as pxtffrom pixeltable.serving import FastAPIRouterfrom udfs import alert_label, severity_score, vehicle_tag# ---- tables ----TableModel = pxt.model_base()class Readings(TableModel, name='readings', has_default_idxs=False):id = pxt.Column(value=pxtf.uuid.uuid7(), primary_key=True)vehicle_id: pxt.Stringfleet: pxt.Stringstatus: pxt.String # moving / idle / parkedrecorded_at: pxt.String # ISO-8601, sortablespeed_kph: pxt.Floatengine_temp_c: pxt.Floatfuel_pct: pxt.Float | Noneseverity = severity_score(speed_kph, engine_temp_c, fuel_pct)alert = alert_label(severity) # chained on another computed columntag = vehicle_tag(fleet, vehicle_id)__indexes__ = [pxt.BtreeIndex(vehicle_id), pxt.BtreeIndex(fleet),pxt.BtreeIndex(status), pxt.BtreeIndex(recorded_at)]# ---- queries ----@pxt.querydef vehicle_history(vehicle_id: str):"""All readings for one vehicle, newest first (uses the vehicle_id index)."""return Readings.where(Readings.vehicle_id == vehicle_id).select(Readings.recorded_at, Readings.speed_kph, Readings.engine_temp_c, Readings.severity, Readings.alert).order_by(Readings.recorded_at, asc=False)@pxt.querydef alerts_since(since: str):"""Non-ok readings recorded at or after a timestamp (uses the recorded_at index)."""return Readings.where((Readings.recorded_at >= since) & (Readings.alert != 'ok')).select(Readings.tag, Readings.recorded_at, Readings.severity, Readings.alert).order_by(Readings.severity, asc=False)@pxt.querydef fleet_board(fleet: str, status: str):"""Vehicles in a fleet with a given status (fleet + status indexes)."""return Readings.where((Readings.fleet == fleet) & (Readings.status == status)).select(Readings.vehicle_id, Readings.recorded_at, Readings.alert).order_by(Readings.vehicle_id)# ---- routes ----telemetry_api = FastAPIRouter(name='telemetry_api')telemetry_api.add_insert_route(Readings, path='/readings',inputs=[Readings.vehicle_id, Readings.fleet, Readings.status, Readings.recorded_at, Readings.speed_kph,Readings.engine_temp_c, Readings.fuel_pct],outputs=[Readings.id, Readings.severity, Readings.alert],)telemetry_api.add_update_route(Readings, path='/readings/correct',inputs=[Readings.speed_kph, Readings.engine_temp_c, Readings.fuel_pct],outputs=[Readings.id, Readings.severity, Readings.alert])telemetry_api.add_delete_route(Readings, path='/readings/delete')telemetry_api.add_compute_route(Readings, path='/score',inputs=[Readings.speed_kph, Readings.engine_temp_c, Readings.fuel_pct],outputs=[Readings.severity, Readings.alert])telemetry_api.add_query_route(path='/vehicles/history', query=vehicle_history, method='get')telemetry_api.add_query_route(path='/alerts', query=alerts_since, method='get')telemetry_api.add_query_route(path='/fleets/board', query=fleet_board, method='get')
What app.py declares
Each row links to its line.
- runs on insert
- stored
- index
- route
- idvehicle_idfleetstatusrecorded_atspeed_kphengine_temp_cfuel_pct
- severity = severity_score(speed_kph, engine_temp_c, fuel_pct)L26
- alert = alert_label(severity)L27
- tag = vehicle_tag(fleet, vehicle_id)L28
- B-tree index on vehicle_idL30
- B-tree index on fleetL30
- B-tree index on statusL31
- B-tree index on recorded_atL31
serves telemetry_api
- POST/readingsinsert, readingstakes vehicle_id, fleet, status, recorded_at, speed_kph, engine_temp_c, fuel_pct; returns id, severity, alertL61
- POST/readings/correctupdate, readingstakes speed_kph, engine_temp_c, fuel_pct; returns id, severity, alertL67
- POST/readings/deletedelete, readingsL70
- POST/scorecompute, readingstakes speed_kph, engine_temp_c, fuel_pct; returns severity, alertL71
- GET/vehicles/historyquery, vehicle_historytakes vehicle_idL74
- GET/alertsquery, alerts_sincetakes sinceL75
- GET/fleets/boardquery, fleet_boardtakes fleet, statusL76
Run it
Needs uv. The routes then answer on port 8000.
terminal
git clone https://github.com/pierrebrunelle/pixeltable-fleet-telemetrycd pixeltable-fleet-telemetryuv syncuv run pxt schema update app.py fleetuv run python seed.py fleetuv run pxt service run app.py fleet --port 8000
Related apps
- Forge Heat CyclesForge heat-cycle registry API: B-tree indexes, chained risk UDFs, and parallel shop-floor writersShares: B-tree indexes, UDFs
- Climbing Route ToposClimbing-route topo registry API: photo uploads with thumbnails, grayscale copies, grade bands and index-backed crag lookupsShares: B-tree indexes, UDFs
- Warehouse Pick ListsWarehouse pick-list REST API: units, pick zones, waves and tote labels as incremental computed columns over Json order linesShares: B-tree indexes, UDFs