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

plugreminder

package
v0.40.22 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package plugreminder sends the "Plug in tonight?" push: an opt-in, once a day, when the truck is parked at the saved home place, not plugged in, and below the SoC the user set. It is a user-scheduled utility (DA's ruling): it goes out between the user's chosen time and 22:00 local, outside the 09-20 quiet-hours window and the monthly budget, only to accounts whose browser stored a time zone, and every send is recorded through internal/engage.

A sweep runs every 10 minutes on every replica; the engage claim on (account, plug_in_reminder, local date) makes that safe.

Index

Constants

View Source
const (
	HomeRadiusM    = 150.0
	MaxStateAge    = 15 * time.Minute
	SuppressWindow = 2 * time.Hour
	// WindowEndMinutes is 22:00 local: no reminder at or after it.
	WindowEndMinutes = 22 * 60
	SweepEvery       = 10 * time.Minute
)

Rules (growth's spec, DA's ruling).

View Source
const Kind = "plug_in_reminder"

Kind is the engage kind of this message.

Variables

This section is empty.

Functions

func Decide

func Decide(s Snap, homeLat, homeLon float64, thresholdPct int, now time.Time) bool

Decide applies the parked, at-home, unplugged and low-charge rules to one vehicle's latest state; ok is true when the vehicle qualifies.

Types

type Candidate

type Candidate struct {
	User         uuid.UUID
	Timezone     string
	ThresholdPct int
	RemindAtMin  int // minutes after local midnight
}

Candidate is an account that may be due a reminder: it has the reminder on for a device and a stored zone.

type HomeFunc

type HomeFunc func(ctx context.Context, uid uuid.UUID) (lat, lon float64, ok bool, err error)

HomeFunc reads the account's saved home place.

type Job

type Job struct {
	Source Source
	Engage *engage.Engage
	Now    func() time.Time
	Logger *slog.Logger
	// On reads the live per-device switch: some subscription still has the
	// reminder on.
	On func(ctx context.Context, uid uuid.UUID) (bool, error)
	// Deliver sends the push to the devices that have it on.
	Deliver func(ctx context.Context, uid uuid.UUID, soc, threshold int) error
}

Job is the sweep.

func (*Job) Run

func (j *Job) Run(ctx context.Context)

Run sweeps now and then every SweepEvery until ctx ends.

func (*Job) Sweep

func (j *Job) Sweep(ctx context.Context) (Stats, error)

Sweep evaluates every candidate once.

type Snap

type Snap struct {
	Vehicle  string
	At       time.Time
	SoCPct   float64
	Lat, Lon float64
	Gear     string
	SpeedMph float64
	Plugged  bool
}

Snap is a vehicle's latest recorded state.

type Source

type Source interface {
	// Candidates are the accounts with the reminder on and a stored zone.
	Candidates(ctx context.Context) ([]Candidate, error)
	// Home is the saved home place; ok=false when there is none.
	Home(ctx context.Context, uid uuid.UUID) (lat, lon float64, ok bool, err error)
	// Latest is each of the account's vehicles' newest state recorded since.
	Latest(ctx context.Context, uid uuid.UUID, since time.Time) ([]Snap, error)
	// RecentlyPlugged: any of the account's vehicles was plugged in at any
	// recorded moment since, or a charge started at home since.
	RecentlyPlugged(ctx context.Context, uid uuid.UUID, homeLat, homeLon float64, since time.Time) (bool, error)
}

Source reads what the rules need.

func NewSource

func NewSource(db *sql.DB, home HomeFunc, skip uuid.UUID) Source

NewSource reads from Postgres. skip is excluded from the candidates (the demo user); home reads the settings.

type Stats

type Stats struct{ Considered, InWindow, Due, Sent, Suppressed int }

Stats is what one sweep did.

Jump to

Keyboard shortcuts

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