electrafi

package
v0.18.80 Latest Latest
Warning

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

Go to latest
Published: May 15, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package electrafi imports TeslaFi / ElectraFi polling-dump CSV files into Rivolt's drives and charges stores.

ElectraFi exports one row per poll (~60s cadence) with 144 columns of TeslaFi-schema snapshot data. Rivian-origin rows leave many Tesla- specific columns empty; the importer uses only the subset reliably populated by the Rivian integration:

Date, battery_level, battery_range, odometer, latitude, longitude,
speed, shift_state, charging_state, charger_power, charge_rate,
charge_energy_added, charge_miles_added_rated, charge_limit_soc,
driveNumber, chargeNumber

Drives and charges are derived by grouping rows by driveNumber and chargeNumber. Row-level noise (empty cells, header) is tolerated.

Index

Constants

View Source
const DefaultPackKWh = 131.0

DefaultPackKWh is the usable capacity we assume when the operator didn't pass a value. Matches the Rivian R1T/R1S Gen-2 Large pack (~131 kWh usable); adjust via Importer.PackKWh for Standard / Max.

Variables

This section is empty.

Functions

This section is empty.

Types

type Importer

type Importer struct {
	Drives  *drives.Store
	Charges *charges.Store
	Samples *samples.Store
	// VehicleID is the stable identifier assigned to every imported
	// session. The CSVs omit VIN so we synthesize one from the file
	// content if the operator didn't pass --vehicle-id.
	VehicleID string
	// PackKWh is the usable battery capacity, used to estimate
	// charger_power and charge_energy_added when those columns are
	// empty (ElectraFi stopped reporting them for some Rivian sessions
	// starting ~late-March 2026). Zero means "use DefaultPackKWh".
	PackKWh float64
	// Location is the timezone the CSV timestamps were recorded in.
	// ElectraFi/TeslaFi exports are local-without-zone; parsing them
	// as UTC (the pre-v0.4.2 behavior) shifts every timestamp by the
	// user's offset. Nil means UTC for backwards compatibility.
	Location *time.Location
	// OnProgress, when non-nil, is called periodically during a
	// single file import with a phase label and a row count so an
	// HTTP handler can emit heartbeats to the client. The callback
	// must not block (it's called from the row loop); the API
	// handler uses it to flush NDJSON lines.
	OnProgress func(phase string, rows int)
}

Importer runs against the three stores. Samples is optional — when nil, only derived sessions are written.

func (*Importer) Import

func (i *Importer) Import(ctx context.Context, path string) (Result, error)

Import reads path and upserts the derived drives & charges. Safe to run multiple times over the same file — session IDs are deterministic.

func (*Importer) ImportReader

func (i *Importer) ImportReader(ctx context.Context, name string, src io.Reader) (Result, error)

ImportReader is the same as Import but reads from an io.Reader rather than a file path. Used by the HTTP upload endpoint to stream an uploaded CSV without staging it to disk. `name` is used only as the seed for the synthetic vehicle ID and for error messages; the caller can pass the original upload filename or any stable label.

type Result

type Result struct {
	File        string
	Rows        int
	Samples     int
	Drives      int
	Charges     int
	SkippedRows int
}

Result summarizes what an import produced.

Jump to

Keyboard shortcuts

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