evcc icon indicating copy to clipboard operation
evcc copied to clipboard

Persist savings

Open thierolm opened this issue 2 years ago • 33 comments

Persists the savings statistics after restart in a lightwight BoltDB (https://pkg.go.dev/github.com/boltdb/[email protected]). DB file evcc_savings.db is stored in OS temp directory. Statistics can be resetted by simply deleting the db file.

Fix https://github.com/evcc-io/evcc/issues/2919

thierolm avatar Apr 01 '22 23:04 thierolm

Mist, hab' schon wieder Porzellan zerschlagen :-/

thierolm avatar Apr 02 '22 00:04 thierolm

Fehlende Error Behandlung wird noch eingebaut. Warte aber erst mal euer generelles Feedback zur Lösung ab.

thierolm avatar Apr 02 '22 00:04 thierolm

Würd es nicht Sinn ergeben, ein Interface für den Store zu bauen, dann könnte man später auch andere DB Implementierungen unterstützen und würde es nicht auf boltdb einschränken… nur so ein Gedanke. 😇

xantalor avatar Apr 02 '22 00:04 xantalor

Thank you for getting this going!! Happy day! :)

RTTTC avatar Apr 02 '22 05:04 RTTTC

Würd es nicht Sinn ergeben, ein Interface für den Store zu bauen, dann könnte man später auch andere DB Implementierungen unterstützen und würde es nicht auf boltdb einschränken… nur so ein Gedanke. 😇

Die store Funktionen bilden ja quasi das generische Interface. Diese kann man dann zukünftig auch in store.go so erweitern, dass man verschiedene Datenbanken anbinden kann.

Mein Focus ist im ersten Schritt eine einfache, lean, lightweight Lösung ...

thierolm avatar Apr 02 '22 09:04 thierolm

Ich mag die Idee mit dem `UserCacheDir. Wo würde das unter Linux landen? Teilen sich alle Settings eine DB bzw. eine Datei oder werden das mehrere? Eine wär für Docker wünschenswert.

andig avatar Apr 02 '22 17:04 andig

Bzw. gem. https://github.com/golang/go/issues/29960 erscheint mir UserConfigDir fast noch geeigneter?

andig avatar Apr 02 '22 17:04 andig

Ggf. wäre es auch schön, ein menschenlesbares Dateiformat zu nutzen (yaml haben wir schon...). Das würde es auch ermöglichen, mal Daten aus unterschiedlichen Quellen zusammen zu bringen etc. Die Entscheidung für ein Dateiformat lässt sich natürlich auch später noch ändern.

/cc @xantalor wär das auch für die MB Tokens nutzbar? Sind Ordner und Zugriffsrechte hinreichend sicher?

andig avatar Apr 02 '22 17:04 andig

Würd es nicht Sinn ergeben, ein Interface für den Store zu bauen, dann könnte man später auch andere DB Implementierungen unterstützen und würde es nicht auf boltdb einschränken… nur so ein Gedanke. 😇

Das lässt sich ja jederzeit nachreichen. Wir bauen ja hier kein API an das wir gebunden sind :)

andig avatar Apr 02 '22 17:04 andig

Ich mag die Idee mit dem `UserCacheDir. Wo würde das unter Linux landen?

$HOME/.cache

thierolm avatar Apr 02 '22 22:04 thierolm

Bin mal auf den Nachfolger des boltDB Repos geswitched: https://github.com/etcd-io/bbolt Das Readme dort ist sehr informativ.

thierolm avatar Apr 02 '22 23:04 thierolm

Code ist auf os.UserConfiDir geändert ($HOME/.config). Als bucket habe ich in der aktuellen Version "simple" gesetzt. Damit kann @naltatis zukünftig innerhalb der savings noch differenzieren, indem er andere Bucket Namen verwendet (dazu muss ich allerdings noch den CreateBucketIfNotExists Aufruf auslagern, und in die Put, Get und Delete Funktion auslagern, damit man ein neues Bucket ohne Probleme nutzen kann.

Beschreibung von Buckets: Buckets are collections of key/value pairs within the database. All keys in a bucket must be unique.

thierolm avatar Apr 03 '22 09:04 thierolm

Ich komme nochmal hier drauf zurück:

Ggf. wäre es auch schön, ein menschenlesbares Dateiformat zu nutzen

Wie wäre es denn, JSON zu nutzen? Hier gehts ja nicht um Performance. Ein einziges JSON Dict würde den Zweck ja auch erfüllen, selbst wenn es immer komplett gespeichert werden müsste.

Vorteil: man käme auch mit anderen/einfachen Werkzeugen an die Daten.

andig avatar Apr 03 '22 09:04 andig

Ich würde die Parameter pro Modul/Package in einer eigenen DB persistieren. Aktuell sind es nur die savings die in /home/xxxx/.config/evcc_savings.db persistiert werden. Innerhalb dieser savings db, kann sich @naltatis austoben ... ;-)

Für andere Modul/Package Parameter/Configs sollten dann eigene DBs angelegt werden (bspw evcc_config.db).

@andig : Ich finde, dass wir diese evcc "Registry"-Daten nicht im Klartext (bspw. yaml) ablegen sollten. Für ein Backup oder Austausch würde ich dann eher die Möglichkeit einbauen über das Frontend einen Dump zu erzeugen (siehe https://github.com/etcd-io/bbolt#database-backups). Kann man auch als Funktion ins evcc CLI einbauen.

thierolm avatar Apr 03 '22 09:04 thierolm

Kann man auch als Funktion ins evcc CLI einbauen.

Export, import, merge? Wär mir viel zu kompliziert.

Ich finde, dass wir diese evcc "Registry"-Daten nicht im Klartext (bspw. yaml) ablegen sollten.

Warum?

PS.: hier ist eine schöne Kriegsgeschichte dazu: https://tailscale.com/blog/an-unlikely-database-migration/

andig avatar Apr 03 '22 09:04 andig

OK, d.h. du schlägst die JSONMutexDB vor, oder etcd?

JSONMutexDB: The object holding all the data was wrapped in a sync.Mutex, all accesses went through it, and on edit the whole structure was passed to json.Marshal and written to disk. This gave us data model persistence in ~20 lines of Go.

thierolm avatar Apr 03 '22 10:04 thierolm

Warum?

Falls Passwörter und Tokens im Store landen.

thierolm avatar Apr 03 '22 10:04 thierolm

Ggf. wäre es auch schön, ein menschenlesbares Dateiformat zu nutzen (yaml haben wir schon...). Das würde es auch ermöglichen, mal Daten aus unterschiedlichen Quellen zusammen zu bringen etc. Die Entscheidung für ein Dateiformat lässt sich natürlich auch später noch ändern.

/cc @xantalor wär das auch für die MB Tokens nutzbar? Sind Ordner und Zugriffsrechte hinreichend sicher?

Da das Token/RefreshToken schon ziemlich sensibel sind, wäre ich nicht wirklich glücklich über diese Umsetzung aber als ersten start kann man das schon machen.

xantalor avatar Apr 03 '22 12:04 xantalor

Ggf. wäre es auch schön, ein menschenlesbares Dateiformat zu nutzen (yaml haben wir schon...). Das würde es auch ermöglichen, mal Daten aus unterschiedlichen Quellen zusammen zu bringen etc. Die Entscheidung für ein Dateiformat lässt sich natürlich auch später noch ändern. /cc @xantalor wär das auch für die MB Tokens nutzbar? Sind Ordner und Zugriffsrechte hinreichend sicher?

Da das Token/RefreshToken schon ziemlich sensibel sind, wäre ich nicht wirklich glücklich über diese Umsetzung aber als ersten start kann man das schon machen.

Ein anderes Dateiformat macht es nicht sicherer (security by obscurity?). In jedem Fall sollten wir aber die Rechte der Datei korrekt setzen. Bei SSH ist das m.W. 0600?

andig avatar Apr 03 '22 13:04 andig

Bei SSH ist das m.W. 0600?

Ja, gibt nur dem anlegenden User Lese- und Schreibrechte. Keine Leserechte für die UserGruppe und Others.

thierolm avatar Apr 03 '22 13:04 thierolm

Ggf. wäre es auch schön, ein menschenlesbares Dateiformat zu nutzen (yaml haben wir schon...). Das würde es auch ermöglichen, mal Daten aus unterschiedlichen Quellen zusammen zu bringen etc. Die Entscheidung für ein Dateiformat lässt sich natürlich auch später noch ändern. /cc @xantalor wär das auch für die MB Tokens nutzbar? Sind Ordner und Zugriffsrechte hinreichend sicher?

Da das Token/RefreshToken schon ziemlich sensibel sind, wäre ich nicht wirklich glücklich über diese Umsetzung aber als ersten start kann man das schon machen.

Ein anderes Dateiformat macht es nicht sicherer (security by obscurity?). In jedem Fall sollten wir aber die Rechte der Datei korrekt setzen. Bei SSH ist das m.W. 0600?

Hatte da eher an eine geschütze und/oder encrypted DB gedacht ;) Die Berechtigung sollte passen.

xantalor avatar Apr 03 '22 13:04 xantalor

Hatte da eher an eine geschütze und/oder encrypted DB gedacht ;)

Wir können dazu auch auf https://github.com/jrapoport/chestnut switchen ...

thierolm avatar Apr 03 '22 13:04 thierolm

Kein Bedarf. Was für SSH gut genug ist sollte für uns auch erstmal reichen...

andig avatar Apr 03 '22 13:04 andig

Das MB Token gehört mMn genau an die gleiche Stelle, wo wir auch Passwörter und andere Vendor Tokens (Tesla) halten. Aktuell ist das die evcc.yaml. Wir werden für die Web-Konfiguration sowieso einen Weg brauchen diese Konfiguration zur Laufzeit zur verändern.

Wie steht ihr denn zu SQLite? Bei einer JSON/Yaml Datei kommen wir glaube ich relativ schnell an Probleme, wenn die Datenmengen größer werden (Ladelog, Historien). SQLite ist abgehangen und verbreitet genug, dass man im Notfall immer noch an die Daten kommt, auch wenn das Dateiformat nicht Plaintext ist. In der iOS/Mac Welt ist das inzwischen ja auch der Standard.

Eine extra Verschlüsselung würde ich auch eher nicht als sinnvoll sehen und mich hier auf die Sicherheitsmechanismen aufs OS verlassen.

naltatis avatar Apr 03 '22 16:04 naltatis

Die Aspekte zu SQLite werden auch in der von @andig erwähnten Kriegsgeschichte behandelt.

thierolm avatar Apr 03 '22 17:04 thierolm

JSON erlaubt Hierarchien, SQlite nicht. Lasst uns das Performanceproblem lösen wenn es eins wird.

andig avatar Apr 03 '22 17:04 andig

Soll ich den PR schließen? Bin noch nicht der go-Crack, der den JSONMutexDB Ansatz einfach aus der Hüfte schießt. ;-)

thierolm avatar Apr 03 '22 17:04 thierolm

Warum nicht einfach die Werte auf den MQTT Broker schreiben und nach einem Neustart schauen, ob da was steht, wenn ja, einfach übernehmen.

Nur so eine Idee.

Sebastian

ExecuteGK avatar Apr 10 '22 15:04 ExecuteGK

Warum nicht einfach die Werte auf den MQTT Broker schreiben und nach einem Neustart schauen, ob da was steht, wenn ja, einfach übernehmen.

Nur so eine Idee.

Sebastian

Hab gerade gesehen, das die ja schon auf dem Broker landen. Fehlt also nur das Zurücklesen nach dem Neustart.

Sebastian

ExecuteGK avatar Apr 10 '22 15:04 ExecuteGK

Nette Idee :). Rettet uns bei den Tokens aber nicht :O

andig avatar Apr 10 '22 15:04 andig