Documentation
¶
Overview ¶
Package tripmultiday orchestrates a multi-day trip plan over Rivian's planTripWithMultiStopV2. Rivian's planner is single-day: it computes one origin → destination route with charging stops, but has no concept of "sleep here, depart tomorrow."
The orchestrator chains N+1 single-day plans (N overnight stops), daisied on departure SoC. Between days, an overnight L2 model projects how much the vehicle will charge while parked:
post_charge_pct = arrival_pct + (L2_kW × parked_hours / pack_kWh) × 100 departure_pct = min(post_charge_pct, max_overnight_soc_pct)
When the overnight has no L2 (rural friend's house), departure SoC equals arrival SoC. The user picks the daily route knowing the constraint.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Day ¶
type Day struct {
Index int `json:"index"` // 1-based.
Plan *rivian.TripPlan `json:"plan"` // single-day plan from Rivian.
DepartureSoC float64 `json:"departure_soc"` // SoC at day start.
ArrivalSoC float64 `json:"arrival_soc"` // SoC at day end (route 0).
Overnight *OvernightResult `json:"overnight,omitempty"`
}
Day is one day's plan plus the overnight that ends it.
type OvernightResult ¶
type OvernightResult struct {
Name string `json:"name,omitempty"`
ParkedHours float64 `json:"parked_hours"`
L2KW float64 `json:"l2_kw"`
AddedKWh float64 `json:"added_kwh"`
PostChargeSoCPct float64 `json:"post_charge_soc_pct"`
// Capped reports that the L2 had more energy on offer than the
// max-overnight cap allowed; departure SoC sits at the cap.
Capped bool `json:"capped"`
}
OvernightResult is the post-charge state at the end of a day. Always nil on the final day (destination day has no overnight).
type OvernightStop ¶
type OvernightStop struct {
Waypoint
// Name is purely cosmetic ("Holiday Inn Express"); never sent to
// Rivian, surfaced back in the response so the SPA can label the
// day boundary.
Name string
// ParkedHours is how long the vehicle is plugged in overnight.
// 0 falls back to a conservative 10 hours.
ParkedHours float64
// L2KW is the available AC charging power in kW. 0 means no
// charging at this stop — arrival SoC carries through to the next
// day's departure unchanged.
L2KW float64
}
OvernightStop describes a sleep stop between two days.
type Planner ¶
type Planner interface {
PlanTrip(ctx context.Context, in rivian.PlanTripInput) (*rivian.TripPlan, error)
}
Planner is the rivian.Client subset we need. Defined here so tests can plug a fake without dragging the whole client.
type Request ¶
type Request struct {
// Account-level inputs (forwarded to every leg's PlanTrip call).
VehicleID string
HasAdapter *bool
DriveMode string
// PackKWh is the vehicle's usable pack capacity, in kWh. Required
// to compute overnight L2 SoC gain.
PackKWh float64
// StartingSoC is the SoC at the *start of day 1*.
StartingSoC float64
// Origin is day 1's start point.
Origin Waypoint
// Overnights are sleep stops, in order. Each marks the end of one
// day and the start of the next.
Overnights []OvernightStop
// Destination is the trip's final endpoint (end of day N+1).
Destination Waypoint
// MaxOvernightSoCPct caps the post-overnight SoC. 0 defaults to 80%
// the moment any overnight has an L2 hookup; ignored when no
// overnight charges.
MaxOvernightSoCPct float64
// TargetArrivalSoCPct is forwarded to every leg. Same semantics as
// the single-day plan-trip handler.
TargetArrivalSoCPct *float64
NetworkPreferences []rivian.NetworkPreference
}
Request is the orchestrator's input.
type Response ¶
Response is the aggregated multi-day plan.
type Totals ¶
type Totals struct {
DistanceMeters float64 `json:"distance_meters"`
DriveDurationSec int `json:"drive_duration_sec"`
ChargingDurationSec int `json:"charging_duration_sec"`
}
Totals summarises the chained-day plan so the SPA can show one "Trip total: X mi, Y h drive, Z stops" line above the day cards.