Help us shape the future of Go! Take the 2026 Go Developer Survey

analytics

package
v0.36.10 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package analytics hosts local, deterministic analyses over the user's driving and charging history. Nothing in this package calls an LLM or leaves the backend — these are pure-Go heuristics used to power UI affordances (Home vs. Public vs. Fast charging badges, anomaly flags, etc.).

Charging-location classification has two axes:

  1. Session peak power. Anything at or above FastMinKW is treated as DC fast charging (EA, Supercharger, RAN L3, etc.) and goes into a single "Fast" bucket regardless of where it happened. The threshold (default 50 kW) is the de-facto line between AC L2 and DCFC — no production L2 charger exceeds ~22 kW.

  2. Location, for everything *below* the Fast threshold. Those sessions are DBSCAN-clustered on (lat, lon); the single largest cluster becomes "Home" (your driveway / apartment L2), and every other slow session — other L1/L2 stops, random friend's-house plug-ins, singleton noise — is "Public".

DBSCAN is chosen over k-means for the location step because:

  • the number of clusters is unknown (we want to discover it);
  • one-off public charging sessions are genuine outliers and shouldn't warp a centroid the way k-means would;
  • ~200m is a natural epsilon for "same parking lot / driveway".

The distance metric is haversine on (lat, lon) so clusters behave the same at any latitude. We keep the implementation small and dependency-free rather than pulling in a geo library.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ChargePoint

type ChargePoint struct {
	ID             string
	Lat, Lon       float64
	EnergyAddedKWh float64
	// MaxPowerKW is the peak kW observed during the session. When >=
	// Params.FastMinKW the charge is bucketed as Fast regardless of
	// location. Zero means unknown — those sessions fall through to
	// location clustering.
	MaxPowerKW float64
}

ChargePoint is the minimal projection of a charge session needed to classify it. Store.Charge is denormalised into this shape at the API boundary so analytics stays decoupled from the SQL schema.

type Cluster

type Cluster struct {
	Label       ClusterLabel
	Centroid    LatLon // mean of member coordinates
	MemberIDs   []string
	Sessions    int
	EnergyKWh   float64
	RadiusMeter float64 // max member distance from centroid
}

Cluster is a group of charges sharing a category. For Home / Public it's a geographic cluster; for Fast it's a power-defined bucket whose "centroid" is the mean of its members' coordinates (useful for a map pin only if the fast stops happen to cluster geographically).

func ClusterCharges

func ClusterCharges(points []ChargePoint, p Params) []Cluster

ClusterCharges classifies charges into Home / Public / Fast / Unknown.

Flow:

  1. Partition inputs into Fast (MaxPowerKW >= FastMinKW), GPS-less (Unknown), and the remaining located-slow pool.
  2. DBSCAN the slow pool with the haversine metric.
  3. Label the largest slow cluster Home; everything else slow — smaller clusters AND noise singletons — is Public.
  4. Emit one aggregate Fast cluster (if any fast sessions exist) and one Unknown cluster (if any no-GPS sessions exist).

Returned slice is ordered largest-first by session count, with Unknown last.

type ClusterLabel

type ClusterLabel string

ClusterLabel is the human-readable category assigned after classification. Three outcomes are possible for GPS-tagged charges: Home (largest location cluster of slow sessions), Public (everything else slow and located), Fast (peak power >= threshold). Charges missing a GPS fix land in LabelUnknown.

const (
	LabelHome    ClusterLabel = "Home"
	LabelPublic  ClusterLabel = "Public"
	LabelFast    ClusterLabel = "Fast"
	LabelUnknown ClusterLabel = "" // used for charges with no GPS fix
)

type LatLon

type LatLon struct {
	Lat, Lon float64
}

LatLon is a simple coordinate pair.

type Params

type Params struct {
	// EpsilonMeters is the neighbourhood radius used by DBSCAN.
	EpsilonMeters float64
	// MinPoints is the minimum cluster size for DBSCAN. Points in a
	// neighbourhood smaller than this are marked as noise and show
	// up as singleton Public clusters.
	MinPoints int
	// FastMinKW is the peak-power threshold at which a session is
	// classified as Fast regardless of location. 50 kW cleanly
	// separates the fastest AC L2 hardware (~22 kW) from DCFC.
	FastMinKW float64
}

Params controls both steps of classification.

func DefaultParams

func DefaultParams() Params

DefaultParams is the tuning the UI uses by default.

Jump to

Keyboard shortcuts

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