Documentation
¶
Overview ¶
Package tripweather corrects a Rivian trip plan's per-waypoint SoC curve for weather conditions Rivian's planner doesn't see. The gateway models pack + base efficiency from the account-side vehicle config, but its `planTripWithMultiStopV2` operation accepts no weather inputs — so a cold day or a strong headwind silently turns a "comfortable 5% arrival margin" plan into a stranded one.
Adjust takes the plan's waypoint sequence plus a parallel slice of per-leg weather snapshots, applies an energy multiplier per leg, and re-runs the cumulative SoC subtraction. The output mirrors the input shape (corrected ArrivalSoC per waypoint) plus a top-level flag for whether the corrected final arrival is below the user's target floor.
The multiplier model lives here as pure functions so it can be unit-tested without booting Postgres or hitting Open-Meteo. See docs/ROADMAP.md "Weather-aware range adjustment" for what's in v1 and what's deferred.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Multiplier ¶
Multiplier returns the per-leg energy multiplier for the given weather snapshot. A return value of 1.0 means "no adjustment"; 1.15 means "this leg needs 15% more energy than Rivian planned".
Model (see docs/ROADMAP.md for the underlying empirical sources):
cold: 1 + 0.008 * max(0, 21 - apparent_temp_C) // 30% loss at -7C heat: 1 + 0.004 * max(0, apparent_temp_C - 27) // A/C draw wind: 1 + 0.012 * clamp(headwind_kph, -30, 30) // drag, symmetric wet: × 1.05 when precip_mm > 0.5 // coarse on/off
Factors are multiplicative so a cold + headwind + wet leg compounds. nil snapshot returns 1.0.
Types ¶
type Adjustment ¶
type Adjustment struct {
AdjustedArrivalSoC []float64
Multipliers []float64
// BelowTarget is true when the final corrected arrival SoC is
// below TargetArrivalSoCPercent. Caller renders the warning chip
// based on this single boolean — keeps the SPA decision local.
BelowTarget bool
// FinalArrivalSoC is a convenience alias for the last entry of
// AdjustedArrivalSoC so callers don't have to index.
FinalArrivalSoC float64
}
Adjustment is the output. AdjustedArrivalSoC[i] is the corrected SoC at waypoint i, in percent. Multipliers[i] is the leg multiplier for the leg ending at waypoint i+1 (so Multipliers has len == len-1 of the waypoint slice). For the origin waypoint, AdjustedArrivalSoC equals the input StartingSoC.
func Adjust ¶
func Adjust(startingSoC float64, waypointArrivalSoC []float64, legs []Leg, targetArrivalSoC, baseMultiplier float64) *Adjustment
Adjust re-runs the cumulative SoC subtraction with per-leg multipliers applied. startingSoC + waypointArrivalSoC describe the uncorrected plan; len(legs) must equal len(waypointArrivalSoC) (one leg per arrival), and waypointArrivalSoC[i] is the SoC Rivian forecast at waypoint i+1 (origin is implied).
targetArrivalSoC is the user's floor; the returned BelowTarget is true when the corrected final arrival is below it.
baseMultiplier is a trip-wide multiplier applied to every leg's consumption on top of the per-leg weather multiplier. Pass 1.0 when there's no profile correction. Profile contribution (wheels, tires, accessories, payload) comes through here from internal/tripprofile so the pipeline stays single-pass.