overnight

package
v0.40.18 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package overnight suggests where to sleep at the end of a planned day: hotel Level 2 chargers from the NREL listing near the point where the day's drive budget runs out. It is archive-only (no Rivian call) and a static snapshot: a listed charger may be in use, broken or guests-only, so callers present these as "listed, not guaranteed".

Index

Constants

View Source
const (
	DefaultBudgetHours = 8.0
	MaxPathPoints      = 20000
)

Defaults and limits.

View Source
const (
	KindHotel      = "hotel"
	KindCampground = "campground"
)

Kinds of stay a candidate can be.

View Source
const (
	ConnJ1772    = "j1772"
	ConnNEMA1450 = "nema_14_50"
	ConnTT30     = "nema_tt_30"
	ConnNEMA520  = "nema_5_20"
)

Connectors a candidate is reached through.

View Source
const (
	Attribution           = "Data: Recreation.gov (RIDB), CC BY 4.0; filtered by Rivolt"
	AttributionSourceURL  = "https://catalog.data.gov/dataset/recreation-information-database-ridb"
	AttributionLicenseURL = "https://creativecommons.org/licenses/by/4.0/"
)

The credit CC BY 4.0 needs for the Recreation.gov data: the name, a link to the licence and to the source, and a note that we changed it (we keep a few facts per campground and plan the power ourselves). A page shows Attribution with "Recreation.gov (RIDB)" linked to AttributionSourceURL and "CC BY 4.0" linked to AttributionLicenseURL.

View Source
const (
	OSMAttribution        = "© OpenStreetMap contributors"
	OSMAttributionURL     = "https://www.openstreetmap.org/copyright"
	OSMAttributionLicense = "https://opendatacommons.org/licenses/odbl/"
)

Fast charger pairing and the OpenStreetMap credit for the fallback stays.

Variables

View Source
var ErrBadRequest = errors.New("invalid overnight request")

ErrBadRequest marks input the suggestion cannot work from.

Functions

This section is empty.

Types

type Archive

type Archive interface {
	QueryCorridor(path [][2]float64, filter chargers.Filter, opts chargers.QueryCorridorOptions) ([]chargers.POI, error)
}

Archive is the part of chargers.Archive used here.

type Candidate

type Candidate struct {
	Name         string  `json:"name"`
	Lat          float64 `json:"lat"`
	Lon          float64 `json:"lon"`
	EntityID     string  `json:"entity_id,omitempty"`
	FacilityType string  `json:"facility_type,omitempty"`
	// Kind is KindHotel or KindCampground.
	Kind string `json:"kind"`
	// Connector, NeedsAdapter, ElectricSites, Sites, ReservationRequired, Fee,
	// Source, SourceURL, AsOf and Attribution are set for campgrounds. A 30 A
	// TT-30 site needs an adapter Rivian's Portable Charger does not ship.
	// ReservationRequired is null when the listing does not say.
	Connector           string `json:"connector,omitempty"`
	NeedsAdapter        bool   `json:"needs_adapter,omitempty"`
	ElectricSites       int    `json:"electric_sites,omitempty"`
	Sites               int    `json:"sites,omitempty"`
	ReservationRequired *bool  `json:"reservation_required,omitempty"`
	Fee                 string `json:"fee,omitempty"`
	Source              string `json:"source,omitempty"`
	SourceURL           string `json:"source_url,omitempty"`
	AsOf                string `json:"asof,omitempty"`
	Attribution         string `json:"attribution,omitempty"`
	// L2KW is the listed power, or the assumed 7 kW when the listing has none
	// (then L2KWAssumed is true and the UI says so).
	L2KW        float64 `json:"l2_kw"`
	L2KWAssumed bool    `json:"l2_kw_assumed"`
	L2Count     int     `json:"l2_count,omitempty"`
	// DetourM is the extra distance to go there and back to the route.
	DetourM float64 `json:"detour_m"`
	// AlongM is how far along the day's route the stop is.
	AlongM float64 `json:"along_m"`
	// DCFCNearby is the closest fast charger within a few miles, if any.
	DCFCNearby *DCFC `json:"dcfc_nearby"`
}

Candidate is one suggested overnight stop.

type DCFC

type DCFC struct {
	Name       string  `json:"name,omitempty"`
	DistanceM  float64 `json:"distance_m"`
	MaxPowerKW float64 `json:"max_power_kw,omitempty"`
}

DCFC is a fast charger near a candidate, for a morning top-up.

type FallbackStay added in v0.40.0

type FallbackStay struct {
	Name     string  `json:"name"`
	Lat      float64 `json:"lat"`
	Lon      float64 `json:"lon"`
	ID       string  `json:"id,omitempty"`
	Kind     string  `json:"kind"`
	Locality string  `json:"locality,omitempty"`
	// NoOnsiteCharger is always true: no charger is listed at this place.
	NoOnsiteCharger bool `json:"no_onsite_charger"`
	// FastCharger is the nearest DC fast charger in the listing (the first stop of the next day).
	FastCharger FastCharger `json:"fast_charger"`
	DetourM     float64     `json:"detour_m"`
	AlongM      float64     `json:"along_m"`
	// Source and Attribution credit OpenStreetMap, whose data this is.
	Source      string `json:"source"`
	Attribution string `json:"attribution"`
}

FallbackStay is a hotel or motel with no charger listed, offered only when no stay with a listed charger is in range. The truck does not charge overnight there: it arrives, sleeps and leaves on the same charge, and the next day starts at FastCharger.

type FastCharger added in v0.40.0

type FastCharger struct {
	Name       string  `json:"name,omitempty"`
	Lat        float64 `json:"lat"`
	Lon        float64 `json:"lon"`
	EntityID   string  `json:"entity_id,omitempty"`
	DistanceM  float64 `json:"distance_m"`
	MaxPowerKW float64 `json:"max_power_kw,omitempty"`
}

FastCharger is the DC fast charger a fallback stay is paired with.

type Lodging added in v0.40.0

type Lodging struct {
	Name     string
	Lat, Lon float64
	// ID is its OpenStreetMap element, "osm:node:123".
	ID       string
	Locality string
}

Lodging is a place to sleep from outside the charger listing.

type LodgingFinder added in v0.40.0

type LodgingFinder func(lat, lon, radiusKm float64) ([]Lodging, error)

LodgingFinder returns the hotels and motels within radiusKm of a point. A failure means none are known near it.

type Nearest added in v0.40.0

type Nearest struct {
	Before *NearestStay `json:"before,omitempty"`
	After  *NearestStay `json:"after,omitempty"`
}

Nearest is the closest listed stay on each side of the budget point, anywhere on the route. It is set only when the windows found no stay, so a screen can say "nearest listed stay: 160 mi back, about 2 h short of the day" instead of "none".

type NearestStay added in v0.40.0

type NearestStay struct {
	Candidate
	// DriveSec is the driving time from the start to the stay.
	DriveSec float64 `json:"drive_sec"`
	// OffsetSec is the driving time from the budget point, negative for a stay before it (a shorter day) and positive after it.
	OffsetSec float64 `json:"offset_sec"`
}

NearestStay is a listed stay found outside the searched windows.

type Request

type Request struct {
	// Path is the day's route as (lat, lon) pairs, start to end.
	Path [][2]float64
	// DriveSec is the route's driving time. 0 assumes 90 km/h.
	DriveSec float64
	// BudgetHours is the most driving in the day (0 uses the default of 8).
	// BudgetMiles, when positive, is used instead.
	BudgetHours float64
	BudgetMiles float64
	// Kinds are the stays to suggest: KindHotel, KindCampground. Empty means
	// hotels only, as before.
	Kinds []string
	// FindLodging, when set, lets the search fall back to hotels and motels with no charger listed (from OpenStreetMap), each paired
	// with the nearest fast charger, when no stay with a listed charger is in range. nil: no fallback.
	FindLodging LodgingFinder
}

Request describes one day's route and its drive budget.

type Result

type Result struct {
	Candidates []Candidate `json:"candidates"`
	Target     Target      `json:"target"`
	RouteM     float64     `json:"route_m"`
	// Nearest is set when Candidates is empty and the day does not fit in the budget; nil when no listed stay is on the route.
	Nearest *Nearest `json:"nearest,omitempty"`
	// FallbackStays are hotels and motels with no listed charger, each paired with the nearest fast charger, offered only when
	// Candidates is empty and the request allowed the lookup. Never ranked above a stay with a listed charger: there are none then.
	FallbackStays []FallbackStay `json:"fallback_stays,omitempty"`
}

Result is the suggestion.

func Suggest

func Suggest(a Archive, req Request) (*Result, error)

Suggest finds up to three hotel Level 2 stops near where the day's drive budget runs out. The result is deterministic for a given archive.

type Target

type Target struct {
	Lat    float64 `json:"lat"`
	Lon    float64 `json:"lon"`
	AlongM float64 `json:"along_m"`
	// ReachesEnd is true when the whole day fits in the budget; the stops are
	// then around the day's end.
	ReachesEnd bool `json:"reaches_end"`
	// WindowBeforeMin and WindowAfterMin are how many minutes of driving before and after the budget point the
	// search covered: the window that produced the stays, or the widest one tried when there are none.
	WindowBeforeMin float64 `json:"window_before_min"`
	WindowAfterMin  float64 `json:"window_after_min"`
}

Target is the point the budget reaches.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL