@@ -17,6 +17,50 @@ its data shown on the driver's dashboard in real time.
1717| ` lhre/dash/lapDelta ` | JSON number | seconds | ` -0.45 ` |
1818| ` lhre/dash/energyDelta ` | JSON number | Wh | ` 3.2 ` |
1919| ` lhre/dash/lapsRemaining ` | JSON number | laps (fractional) | ` 15.3 ` |
20+ | ` lhre/dash/targetPower ` | JSON number | kW | ` 32 ` |
21+ | ` lhre/dash/lapTrigger ` | JSON number | monotonic counter | ` 7 ` |
22+ | ` lhre/dash/sfGate ` | JSON ` [f64;4] ` | ` [lat1,lon1,lat2,lon2] ` | ` [30.39,-97.72,30.39,-97.73] ` |
23+
24+ ### Endurance pacing signals
25+
26+ ` targetPower ` and ` lapTrigger ` are published by the ** Dash** tab on the
27+ trackside-live page (` telemtry/analysis/database/viewer_tool ` ) over the broker's
28+ websockets listener (port ` 8080 ` ). They drive on-dash endurance pacing — the
29+ dash integrates CAN power locally and compares it to the budget, so only these
30+ two control values come off-car:
31+
32+ - ** ` targetPower ` ** — the live power budget (kW) the strategist dials in. The
33+ dash integrates real power against ` targetPower * elapsed ` per lap; the
34+ top energy bar runs green while under budget and red while over. It's a
35+ set-point, so the sender ** republishes it ~ 1 Hz** . Unlike the other fields it
36+ is ** held last-known on the dash across a dropout** (not nulled): instead the
37+ dash emits ` targetPowerStale: true ` to the frontend, which dims the bar and
38+ shows a "STALE" badge — a held budget beats a blank one for the driver.
39+ - ** ` lapTrigger ` ** — a monotonically increasing lap counter. On each ** increase**
40+ the dash pops a full-screen lap card (lap time + energy used that lap) and
41+ resets the per-lap energy integrator, so pacing error can't accumulate across
42+ laps. The dash keys off the rising edge, not the absolute value. This is now a
43+ ** fallback/override** : when an ` sfGate ` is loaded the car counts its own laps.
44+ ** Reverse channel (dash → trackside).** dashd also * publishes* so the strategist
45+ can confirm the uplink and mirror the driver's screen:
46+
47+ - ** ` lhre/dash/state ` ** — JSON snapshot at ~ 2 Hz of what the driver sees (speed,
48+ power, soc, temperature, lap count, and the on-car pacing: ` lapEnergyWh ` ,
49+ ` budgetDeltaWh ` , ` lapNumber ` , last-lap time/energy). The Dash tab renders this
50+ as a live mirror; if it goes silent for >3 s the panel flags the uplink down.
51+ - ** ` lhre/dash/ack/{targetPower,lapTrigger,sfGate} ` ** — retained echoes published
52+ the moment dashd ingests each control, so trackside sees "the car heard 32 kW
53+ 2 s ago" rather than just "I sent it." Energy integration is authoritative
54+ on-car (survives a chromium reload), so these are the same numbers, not a
55+ re-derivation.
56+
57+ - ** ` sfGate ` ** — the start/finish line as ` [lat1, lon1, lat2, lon2] ` , published
58+ ** retained, QoS 1** from the Dash tab's "Push S/F to car" button (sourced from
59+ the Track Builder gate). Once loaded, dashd watches ` dynamics.gps ` and bumps
60+ the lap counter when the car's path crosses the line — so ** the per-lap reset
61+ no longer depends on the link at all.** The gate is cached to disk
62+ (` DASHD_SFGATE_PATH ` , default ` /tmp/BEVO_dash_sfgate.json ` ) so it also survives
63+ a reboot if the broker drops its retained copy.
2064
2165## Payload format
2266
@@ -56,4 +100,8 @@ mosquitto_pub -h 18.191.225.118 -t "lhre/dash/lapDelta" -m "-0.45"
56100mosquitto_pub -h 18.191.225.118 -t " lhre/dash/lapDelta" -m " -0.45"
57101mosquitto_pub -h 18.191.225.118 -t " lhre/dash/energyDelta" -m " 3.2"
58102mosquitto_pub -h 18.191.225.118 -t " lhre/dash/lapsRemaining" -m " 15.3"
103+
104+ # Endurance pacing: set a 32 kW budget, then trigger a lap card:
105+ mosquitto_pub -h 18.191.225.118 -t " lhre/dash/targetPower" -m " 32"
106+ mosquitto_pub -h 18.191.225.118 -t " lhre/dash/lapTrigger" -m " 1"
59107```
0 commit comments