evccdb

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jan 30, 2026 License: MIT Imports: 9 Imported by: 0

README

evccdb

A Go package for selective backup, restore, and transfer of evcc SQLite database data. Supports transferring data between database instances and selective export/import of configuration or metrics.

Features

  • Selective Transfer: Transfer configuration tables or metrics independently
  • JSON Export/Import: Human-readable JSON format for backups and data exchange
  • Rename: Rename loadpoints/vehicles across all tables (sessions, settings, configs)
  • Delete Sessions: Remove session data for specific loadpoints or vehicles
  • Schema-Aware: Dynamically detects and handles schema differences between databases
  • Dry-Run Mode: Preview operations without making changes
  • Transaction Safety: Atomic operations with automatic rollback on error
  • CLI Tool: Command-line interface for common operations
  • Progress Tracking: Optional callbacks to monitor transfer progress

Installation

Library
go get github.com/iseeberg79/evccdb
CLI Tool
go install github.com/iseeberg79/evccdb/cmd/evccdb@latest

Quick Start

Export Configuration
evccdb export --source evcc.db --output backup.json --mode config
Import Configuration
evccdb import --source backup.json --target new-evcc.db --mode config
Transfer Between Databases
evccdb transfer --from old.db --to new.db --mode config
Preview Transfer (Dry Run)
evccdb transfer --from old.db --to new.db --mode config --dry-run

Transfer Modes

Config Mode (--mode config)

Transfers configuration tables: settings, configs, caches

Use case: Migrate user configuration to a new installation

Example:

evccdb transfer --from old.db --to new.db --mode config
Metrics Mode (--mode metrics)

Transfers metrics tables: meters, sessions, grid_sessions

Use case: Migrate historical data to a new installation

Example:

evccdb transfer --from old.db --to new.db --mode metrics
All Mode (--mode all)

Transfers all tables

Use case: Complete database clone/backup

Example:

evccdb transfer --from old.db --to new.db --mode all

Custom Tables

Transfer specific tables by name:

evccdb transfer --from old.db --to new.db --tables settings,configs

Verbose Output

Show transfer progress:

evccdb transfer --from old.db --to new.db --mode config --verbose

Library Usage

Basic Example
package main

import (
    "context"
    "github.com/iseeberg79/evccdb"
)

func main() {
    // Open source and destination databases
    src, _ := evccdb.Open("old.db")
    defer src.Close()

    dst, _ := evccdb.Open("new.db")
    defer dst.Close()

    // Transfer configuration tables
    ctx := context.Background()
    opts := evccdb.TransferOptions{
        Mode: evccdb.TransferConfig,
    }

    evccdb.Transfer(ctx, src, dst, opts)
}
Export to JSON
import (
    "os"
    "github.com/iseeberg79/evccdb"
)

client, _ := evccdb.Open("evcc.db")
defer client.Close()

f, _ := os.Create("backup.json")
defer f.Close()

opts := evccdb.TransferOptions{
    Mode: evccdb.TransferConfig,
}

client.ExportJSON(f, opts)
Import from JSON
import (
    "os"
    "github.com/iseeberg79/evccdb"
)

client, _ := evccdb.Open("evcc.db")
defer client.Close()

f, _ := os.Open("backup.json")
defer f.Close()

opts := evccdb.TransferOptions{
    Mode: evccdb.TransferConfig,
}

client.ImportJSON(f, opts)
With Progress Tracking
opts := evccdb.TransferOptions{
    Mode: evccdb.TransferConfig,
    OnProgress: func(table string, count int) {
        fmt.Printf("Transferred %s: %d rows\n", table, count)
    },
}

evccdb.Transfer(ctx, src, dst, opts)
Rename Loadpoint/Vehicle
client, _ := evccdb.Open("evcc.db")
defer client.Close()

ctx := context.Background()

// Rename loadpoint across sessions, settings, and configs
result, _ := client.RenameLoadpoint(ctx, "Garage", "Carport")
fmt.Printf("Renamed: %d sessions, %d settings, %d configs\n",
    result.Sessions, result.Settings, result.Configs)

// Rename vehicle
client.RenameVehicle(ctx, "e-Golf", "ID.4")

// Dry run (preview without changes)
result, _ = client.RenameLoadpointDryRun(ctx, "OldName", "NewName")
Delete Sessions
client, _ := evccdb.Open("evcc.db")
defer client.Close()

ctx := context.Background()

// Count sessions before deleting
count, _ := client.CountLoadpointSessions(ctx, "OldLoadpoint")
fmt.Printf("Found %d sessions\n", count)

// Delete sessions for a loadpoint
deleted, _ := client.DeleteLoadpointSessions(ctx, "OldLoadpoint")
fmt.Printf("Deleted %d sessions\n", deleted)

// Delete sessions for a vehicle
client.DeleteVehicleSessions(ctx, "OldVehicle")
Transfer with Renames
opts := evccdb.TransferOptions{
    Mode: evccdb.TransferAll,
    LoadpointRenames: []evccdb.RenameMapping{
        {OldName: "Garage", NewName: "Carport"},
    },
    VehicleRenames: []evccdb.RenameMapping{
        {OldName: "e-Golf", NewName: "ID.4"},
    },
}

evccdb.Transfer(ctx, src, dst, opts)

Schema Compatibility

The library handles schema differences gracefully:

  • New columns in destination: Retain their DEFAULT values
  • Missing columns in destination: Data is skipped with a warning
  • Extra columns in source: Ignored, only common columns transferred
  • Type mismatches: Data is transferred as-is (SQLite is flexible)

This approach allows transferring between different evcc versions without requiring exact schema matches.

Database Schema

Configuration Tables

settings - Key-value pairs (e.g., savings.started, savings.gridCharged)

key    | value
-------|-------
string | string

configs - Device and service configurations

id       | class | type   | value  | title  | icon   | product
---------|-------|--------|--------|--------|--------|--------
integer  | int   | string | string | string | string | string

caches - Cache entries

key    | value
-------|-------
string | string
Metrics Tables

meters - Time-series meter readings

meter   | ts       | val
--------|----------|--------
integer | datetime | float64

sessions - Charging sessions

id        | created  | finished | loadpoint | identifier | vehicle | ...
----------|----------|----------|-----------|------------|---------|----
integer   | datetime | datetime | string    | string     | string  | ...

grid_sessions - Grid power sessions

id      | created  | finished | type   | grid_power | limit_power
--------|----------|----------|--------|------------|------------
integer | datetime | datetime | string | float64    | float64

Command Reference

export

Export database tables to JSON.

Flags:
  --source string    Source database file (required)
  --output string    Output JSON file (required)
  --mode string      Transfer mode: config, metrics, all (default "config")
  --tables string    Comma-separated table names (overrides mode)
  --verbose          Show progress

Examples:

# Export configuration (settings, configs, caches)
evccdb export --source evcc.db --output config-backup.json --mode config --verbose

# Export session/metrics data (meters, sessions, grid_sessions)
evccdb export --source evcc.db --output metrics-backup.json --mode metrics --verbose

# Export everything
evccdb export --source evcc.db --output full-backup.json --mode all

# Export specific tables only
evccdb export --source evcc.db --output sessions-only.json --tables sessions
evccdb export --source evcc.db --output sessions-meters.json --tables sessions,meters
import

Import JSON data into database.

Flags:
  --source string    Source JSON file (required)
  --target string    Target database file (required)
  --mode string      Transfer mode: config, metrics, all (default "config")
  --tables string    Comma-separated table names (overrides mode)
  --verbose          Show progress

Examples:

# Import configuration
evccdb import --source config-backup.json --target evcc.db --mode config

# Import session data
evccdb import --source metrics-backup.json --target evcc.db --mode metrics

# Import specific tables from a full backup
evccdb import --source full-backup.json --target evcc.db --tables sessions
transfer

Transfer data between databases.

Flags:
  --from string              Source database file (required)
  --to string                Target database file (required)
  --mode string              Transfer mode: config, metrics, all (default "config")
  --tables string            Comma-separated table names (overrides mode)
  --rename-loadpoint string  Rename loadpoints: OldName:NewName,Old2:New2
  --rename-vehicle string    Rename vehicles: OldName:NewName,Old2:New2
  --dry-run                  Show what would be transferred without doing it
  --verbose                  Show progress

Examples:

# Basic transfer
evccdb transfer --from old.db --to new.db --mode config --dry-run

# Transfer with renames
evccdb transfer --from old.db --to new.db --mode all \
    --rename-loadpoint "Garage:Carport" \
    --rename-vehicle "e-Golf:ID.4"
rename

Rename loadpoints or vehicles across all tables (sessions, settings, configs).

Flags:
  --db string         Database file (required)
  --loadpoint string  Rename loadpoints: OldName:NewName,Old2:New2
  --vehicle string    Rename vehicles: OldName:NewName,Old2:New2
  --dry-run           Show what would be renamed without doing it
  --verbose           Show detailed output

Examples:

# Preview rename
evccdb rename --db evcc.db --loadpoint "Garage:Carport" --dry-run

# Rename loadpoint
evccdb rename --db evcc.db --loadpoint "Garage:Carport" --verbose

# Rename vehicle
evccdb rename --db evcc.db --vehicle "e-Golf:ID.4"

# Multiple renames
evccdb rename --db evcc.db --loadpoint "Garage:Carport,eBikes:E-Bikes"
delete

Delete session data for specific loadpoints or vehicles.

Warning: Make sure evcc is stopped before running this command.

Flags:
  --db string         Database file (required)
  --loadpoint string  Delete sessions for loadpoints: Name1,Name2
  --vehicle string    Delete sessions for vehicles: Name1,Name2
  --dry-run           Show what would be deleted without doing it
  -y, --yes           Skip confirmation prompt
  --verbose           Show detailed output

Examples:

# Preview deletion
evccdb delete --db evcc.db --loadpoint "OldLoadpoint" --dry-run

# Delete sessions (with confirmation prompt)
evccdb delete --db evcc.db --loadpoint "OldLoadpoint"

# Delete without confirmation (for scripts)
evccdb delete --db evcc.db --loadpoint "OldLoadpoint" -y

# Delete multiple
evccdb delete --db evcc.db --loadpoint "LP1,LP2" --vehicle "Vehicle1"

Testing

Run tests:

go test -v ./...

Run tests with coverage:

go test -v -race -coverprofile=coverage.out ./...

Run only unit tests (skip integration tests):

go test -v -short ./...

License

MIT - See LICENSE file for details

Contributing

This project is part of the evcc ecosystem. For issues and feature requests, please use the project issue tracker.

Disclaimer

Use at own risk. Actions taken cannot be undone. Create backups before doing modifications and ensure no parallel access on database file.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Transfer

func Transfer(ctx context.Context, src, dst *Client, opts TransferOptions) error

Transfer transfers data from source to destination database based on options

func ValidateIdentifier

func ValidateIdentifier(name string) error

ValidateIdentifier checks if a string is safe to use as a SQL identifier

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client represents a connection to an evcc SQLite database

func Open

func Open(path string) (*Client, error)

Open opens a connection to an evcc SQLite database

func (*Client) Close

func (c *Client) Close() error

Close closes the database connection

func (*Client) CopyTablesTo

func (c *Client) CopyTablesTo(ctx context.Context, dst *Client, tables []string) error

CopyTablesTo copies specific tables from source to destination

func (*Client) CountLoadpointSessions

func (c *Client) CountLoadpointSessions(ctx context.Context, loadpoint string) (int, error)

CountLoadpointSessions counts sessions for a specific loadpoint

func (*Client) CountVehicleSessions

func (c *Client) CountVehicleSessions(ctx context.Context, vehicle string) (int, error)

CountVehicleSessions counts sessions for a specific vehicle

func (*Client) DeleteLoadpointSessions

func (c *Client) DeleteLoadpointSessions(ctx context.Context, loadpoint string) (int, error)

DeleteLoadpointSessions deletes all sessions for a specific loadpoint

func (*Client) DeleteVehicleSessions

func (c *Client) DeleteVehicleSessions(ctx context.Context, vehicle string) (int, error)

DeleteVehicleSessions deletes all sessions for a specific vehicle

func (*Client) ExportJSON

func (c *Client) ExportJSON(w io.Writer, opts TransferOptions) error

ExportJSON exports selected tables to JSON

func (*Client) GetAllTables

func (c *Client) GetAllTables() []string

GetAllTables returns all known tables

func (*Client) GetConfigTables

func (c *Client) GetConfigTables() []string

GetConfigTables returns the list of configuration tables

func (*Client) GetMetricsTables

func (c *Client) GetMetricsTables() []string

GetMetricsTables returns the list of metrics tables

func (*Client) GetRowCount

func (c *Client) GetRowCount(table string) (int, error)

GetRowCount returns the number of rows in a table

func (*Client) GetTableColumns

func (c *Client) GetTableColumns(table string) ([]ColumnInfo, error)

GetTableColumns returns the columns for a table

func (*Client) GetTables

func (c *Client) GetTables() ([]string, error)

GetTables returns a list of all tables in the database

func (*Client) ImportJSON

func (c *Client) ImportJSON(r io.Reader, opts TransferOptions) error

ImportJSON imports data from a JSON export file

func (*Client) RenameLoadpoint

func (c *Client) RenameLoadpoint(ctx context.Context, oldName, newName string) (RenameResult, error)

RenameLoadpoint updates a loadpoint name across all tables

func (*Client) RenameLoadpointDryRun

func (c *Client) RenameLoadpointDryRun(ctx context.Context, oldName, newName string) (RenameResult, error)

RenameLoadpointDryRun returns the counts of what would be renamed without making changes

func (*Client) RenameVehicle

func (c *Client) RenameVehicle(ctx context.Context, oldName, newName string) (RenameResult, error)

RenameVehicle updates a vehicle name across all tables

func (*Client) RenameVehicleDryRun

func (c *Client) RenameVehicleDryRun(ctx context.Context, oldName, newName string) (RenameResult, error)

RenameVehicleDryRun returns the counts of what would be renamed without making changes

func (*Client) ResolveTables

func (c *Client) ResolveTables(opts TransferOptions) ([]string, error)

ResolveTables returns the list of tables based on the transfer mode

func (*Client) TableExists

func (c *Client) TableExists(name string) (bool, error)

TableExists checks if a table exists in the database

type ColumnInfo

type ColumnInfo struct {
	Name    string
	Type    string
	NotNull bool
	Default *string
	Primary bool
}

ColumnInfo represents information about a column

type Config

type Config struct {
	ID      int
	Class   int
	Type    string
	Value   string
	Title   string
	Icon    string
	Product string
}

Config represents a device or service configuration

type ExportFormat

type ExportFormat struct {
	Version    string         `json:"version"`
	ExportedAt string         `json:"exported_at"`
	Tables     map[string]any `json:"tables"`
}

ExportFormat is the JSON structure for export/import

type Exporter

type Exporter interface {
	ExportJSON(w io.Writer, opts TransferOptions) error
}

Exporter defines the export interface

type GridSession

type GridSession struct {
	ID         int
	Created    string
	Finished   *string
	Type       string
	GridPower  *float64
	LimitPower *float64
}

GridSession represents a grid power session

type Importer

type Importer interface {
	ImportJSON(r io.Reader, opts TransferOptions) error
}

Importer defines the import interface

type Meter

type Meter struct {
	Meter int
	Ts    string
	Val   float64
}

Meter represents a meter reading at a specific time

type RenameMapping

type RenameMapping struct {
	OldName string
	NewName string
}

RenameMapping defines a name transformation

type RenameResult

type RenameResult struct {
	Sessions int
	Settings int
	Configs  int
}

RenameResult contains the counts of renamed rows per table

type Session

type Session struct {
	ID              int
	Created         string
	Finished        *string
	Loadpoint       string
	Identifier      *string
	Vehicle         *string
	OdometerStart   *float64
	MeterStartKwh   *float64
	MeterEndKwh     *float64
	ChargedKwh      *float64
	SolarPercentage *float64
	Price           *float64
	PricePerKwh     *float64
	Co2PerKwh       *float64
	ChargeDuration  *int
}

Session represents a charging session

type Setting

type Setting struct {
	Key   string
	Value string
}

Setting represents a key-value configuration pair

type TransferMode

type TransferMode int

TransferMode specifies which tables to transfer

const (
	TransferConfig TransferMode = iota
	TransferMetrics
	TransferAll
)

type TransferOptions

type TransferOptions struct {
	Mode             TransferMode
	Tables           []string
	DryRun           bool
	OnProgress       func(table string, count int)
	LoadpointRenames []RenameMapping
	VehicleRenames   []RenameMapping
}

TransferOptions configures transfer behavior

Directories

Path Synopsis
cmd
evccdb command

Jump to

Keyboard shortcuts

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