diff --git a/README.md b/README.md index d0fa60e..ea411af 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # Docs + +Bitte gehen Sie weiter, hier gibt es (noch) nichts zu sehen. diff --git a/_config.yml b/_config.yml index faa6eaa..9c71c9f 100644 --- a/_config.yml +++ b/_config.yml @@ -1,8 +1,29 @@ -title: Just the Docs Template -description: A starter template for a Jeykll site using the Just the Docs theme! +title: Dokumentation +description: Dokumentation für SOLECTRUS theme: just-the-docs -url: https://just-the-docs.github.io +url: https://docs.solectrus.de aux_links: - Template Repository: https://github.com/just-the-docs/just-the-docs-template + SOLECTRUS: https:/solectrus.de + +gh_edit_link: true # show or hide edit this page link +gh_edit_link_text: 'Diese Seite auf GitHub bearbeiten.' +gh_edit_repository: 'https://github.com/solectrus/docs' # the github URL for your repo +gh_edit_branch: "main" # the branch that your docs is served from +# gh_edit_source: docs # the source that your files originate from +gh_edit_view_mode: "tree" # "tree" or "edit" if you want the user to jump into the editor immediately + +callouts: + warning: + title: Warnung + color: red + + note: + title: Hinweis + color: green + +mermaid: + # Version of mermaid library + # Pick an available version from https://cdn.jsdelivr.net/npm/mermaid/ + version: "11.2.1" diff --git a/_includes/nav_footer_custom.html b/_includes/nav_footer_custom.html new file mode 100644 index 0000000..53585ae --- /dev/null +++ b/_includes/nav_footer_custom.html @@ -0,0 +1,3 @@ + diff --git a/_includes/search_placeholder_custom.html b/_includes/search_placeholder_custom.html new file mode 100644 index 0000000..cb3f365 --- /dev/null +++ b/_includes/search_placeholder_custom.html @@ -0,0 +1 @@ +Suchen diff --git a/_includes/toc_heading_custom.html b/_includes/toc_heading_custom.html new file mode 100644 index 0000000..7ea30d8 --- /dev/null +++ b/_includes/toc_heading_custom.html @@ -0,0 +1 @@ +

Inhalt

diff --git a/assets/images/architektur.svg b/assets/images/architektur.svg new file mode 100644 index 0000000..bba6ac7 --- /dev/null +++ b/assets/images/architektur.svg @@ -0,0 +1,324 @@ + + + + + + + + + + + + + + +
+
+
Forecast-Collector
+
+
+
Forecast-Coll... +
+ + + +
+
+
SENEC-Collector
+
+
+
SENEC-Collect... +
+ + + +
+
+
Dashboard
+
+
+
Dashboard +
+ + + + + + +
+
+
Redis

+
(Caching)
+
+
+
+
+
Redis... +
+ + + + + + +
+
+
InfluxDB v2
+
+
+
InfluxDB v2 +
+ + + + + + +
+
+
PostgreSQL

+
(Preise, Einstellungen)
+
+
+
+
PostgreSQL... +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
MQTT-Collector
+
+
+
MQTT-Collector +
+ + + + + + + +
+
+
CSV-
Importer
+
+
+
+
CSV-... +
+ + + + + + + + + + + +
+
+
Tibber-Collector
+
+
+
Tibber-Collec... +
+ + + +
+
+
Shelly-Collector
+
+
+
Shelly-Collec... +
+ + + + + + + +
+
+
SENEC Speicher
+
+
+
SENEC Speicher +
+ + + + + + + +
+
+
SENEC
Cloud
+
+
+
+
SENEC... +
+ + + + + + + +
+
+
forecast.solar
+
+
+
forecast.solar +
+ + + + + + + +
+
+
solcast.com
+
+
+
solcast.com +
+ + + + + + + +
+
+
CSV-
Dateien
+
+
+
+
CSV-... +
+ + + + + + + +
+
+
tibber
API
+
+
+
+
tibber... +
+ + + + + + + +
+
+
Shelly
Plug S
+
+
+
+
Shelly... +
+ + + + + + + +
+
+
Shelly
Pro 3EM
+
+
+
+
Shelly... +
+ + + + + + + +
+
+
MQTT
Broker
+
+
+
+
MQTT... +
+ + + + + + + +
+
+
Sonstige Geräte
+
+
+
Sonstige Gerä... +
+ + + + + + + + +
+
+
Power-Splitter
+
+
+
Power-Splitter +
+ + + + +
diff --git a/assets/images/ersparnis.png b/assets/images/ersparnis.png new file mode 100644 index 0000000..fa708bf Binary files /dev/null and b/assets/images/ersparnis.png differ diff --git a/assets/images/kosten.png b/assets/images/kosten.png new file mode 100644 index 0000000..cb613ec Binary files /dev/null and b/assets/images/kosten.png differ diff --git a/assets/images/login.png b/assets/images/login.png new file mode 100644 index 0000000..aa5fba2 Binary files /dev/null and b/assets/images/login.png differ diff --git a/assets/images/power-splitter-car.png b/assets/images/power-splitter-car.png new file mode 100644 index 0000000..bea663a Binary files /dev/null and b/assets/images/power-splitter-car.png differ diff --git a/assets/images/strompreise.png b/assets/images/strompreise.png new file mode 100644 index 0000000..7a8c18e Binary files /dev/null and b/assets/images/strompreise.png differ diff --git a/benutzung/administrator.md b/benutzung/administrator.md new file mode 100644 index 0000000..bcf9a05 --- /dev/null +++ b/benutzung/administrator.md @@ -0,0 +1,31 @@ +--- +title: Administrator-Zugang +layout: page +parent: Benutzung +--- + +Der Administrator-Zugang gewährleistet, dass nur autorisierte Benutzer bestimmte kritische Funktionen von SOLECTRUS ausführen können. Zu den gegenwärtig geschützten Funktionen gehören: + +- Festlegung der Strompreise, der Einspeisevergütung und weiterer Optionen +- Durchführung der Registrierung + +Ohne vorherigen Admin-Login hat ein Benutzer nur Lesezugriff und kann dementsprechend keine Einstellungen ändern. + +Login + +Übrigens: Wie du hier sehen kannst, ist es wirklich nur ein Passwort. Aus Gründen der Einfachheit gibt es keinen Benutzernamen oder E-Mail-Adresse. + +Diese Funktion ist besonders nützlich, wenn deine Installation von SOLECTRUS von mehreren Benutzern genutzt wird, insbesondere wenn sie über das Internet zugänglich ist. Als Administrator kannst du sicherstellen, dass niemand außer dir die Einstellungen ändert. + +### Festlegen und Ändern des Passwortes + +Das Passwort für den Administrator-Zugang wird während der Installation von SOLECTRUS festgelegt und befindet sich in der `.env`-Datei: + +```bash +# ... +# +# Password to login as administrator, required to manage settings like historical prices +ADMIN_PASSWORD=my-secret-login-password +``` + +Möchtest du das Passwort ändern, ist dies ausschließlich über die Bearbeitung der `.env`-Datei möglich. Nachdem du es dort geändert hast, muss SOLECTRUS neu gestartet werden, damit die Änderung wirksam wird. diff --git a/benutzung/ersparnis-berechnung.md b/benutzung/ersparnis-berechnung.md new file mode 100644 index 0000000..7e30ef7 --- /dev/null +++ b/benutzung/ersparnis-berechnung.md @@ -0,0 +1,74 @@ +--- +title: Ersparnis-Berechnung +layout: page +parent: Benutzung +--- + +# Berechnung der Ersparnis durch die Photovoltaikanlage + +## Die zwei Komponenten der Ersparnis + +Die Einsparung, die durch den Betrieb der PV-Anlage erzielt wird, besteht grundsätzlich aus zwei Komponenten: + +1. Einsparung durch Reduzierung des aus dem Netz bezogenen Stroms +2. Einsparung durch Erhalt einer Einspeisevergütung für den ins Netz abgegebenen Strom + +SOLECTRUS berechnet die Ersparnis aus einer Gegenüberstellung zweier Szenarien: Die aktuelle Situation (d.h. **mit** PV-Anlage) wird mit einem theoretischen Szenario verglichen, bei dem man **keine** PV-Anlage hat, aber den exakt gleichen Stromverbrauch verursacht. SOLECTRUS macht also einen Vorher-Nachher-Vergleich und bildet die Differenz. Das sieht dann so aus (im Beispiel für das Jahr 2022): + +Einsparung durch PV-Anlage + +## Berechnung der Ersparnis + +Die Berechnung erfolgt in drei Schritten: + +1. **Mit PV-Anlage**: Es werden zunächst die Kosten berechnet, die durch den Bezug von Strom tatsächlich entstehen (siehe auch die Erläuterungen zur [Kosten-Berechnung](/faq/kosten-berechnung/)). Der Betrag ist immer negativ, hier im Beispiel sind es `-386 €`. Außerdem erhält man eine Einspeisevergütung für den Überschuss (hier `624 €`, positiv). Zusammen ergibt das den "Solarpreis" als Summe, wobei die Vorzeichen zu beachten sind (hier: `-386 € + 624 € = 238 €`). Der Solarpreis ist meist positiv, kann aber je nach gewähltem Zeitraum auch negativ sein, z.B. im Winter, wenn der Strombezug mehr kostet als die Einspeisevergütung einbringt. + +2. **Ohne PV-Anlage**: Der Strom für den gesamten Verbrauch muss gekauft werden und es gibt natürlich keine Einspeisevergütung. Gerechnet wird `(Hausverbrauch + Wallbox) * Strompreis`. In Beispiel ergibt sich ein "Vergleichspreis" (immer negativ) mit den theoretischen Strombezugskosten von `1.857 €`. Berücksichtigt werden bei der Berechnung die sich im Zeitverlauf ändernden Strompreise. + +3. **Vergleich**: Die mit der PV-Anlage erzielte Ersparnis ist nun die Differenz zwischen Solarpreis und Vergleichspreis. Weil der Solarpreis sowohl positiv (Sommer) als auch negativ (Winter) sein kann, sind die Vorzeichen wichtig. Im Beispiel wird gerechnet: \ + `238 € - (- 1.857 €) = 2.095 €`. Das bedeutet: Dadurch, dass du eine PV-Anlage hast, hast du im gewählten Zeitraum 2095 € mehr im Geldbeutel, als wenn du keine PV-Anlage hättest. + +Zusammengefasst lässt sich die Formel wie folgt darstellen: + +``` +Ersparnis (€) = (Hausverbrauch + Wallbox - Strombezug) * Strompreis + + Einspeisung * Einspeisevergütung +``` + +Da sich der Strompreis im Zeitverlauf ändern kann, wird diese Berechnung für jeden Teilzeitraum einzeln durchgeführt und das Ganze dann aufsummiert. + +:::caution + +Diese Berechnungsformel unterscheidet sich von der SENEC-App, die in der aktuellen Version v4.3.2 aus mir nicht verständlichen Gründen die **Speicherentladung** (anstatt des **Strombezugs**) mit einbezieht und folgende Formel verwendet: + +``` +Ersparnis (€) = (Hausverbrauch + Wallbox + Speicherentladung) * Strompreis + + Einspeisung * Einspeisevergütung +``` + +Dies ist aus meiner Sicht **falsch** und ergibt eine zu hohe Ersparnis. + +::: + +## Anteil des Speichers an der Ersparnis + +Zum Schluss errechnet SOLECTRUS, welchen Anteil der Stromspeicher (Akku) an der Ersparnis hat: + +``` +Ersparnis durch Akku (€) = + Akkuentnahme (kWh) * Strompreis (€/kWh) + - Akkubeladung (kWh) * Einspeisevergütung (€/kWh) +``` + +Die Idee ist hier, dass man einerseits den aus dem Akku entnommenen Strom nicht kaufen muss, also den Strompreis einspart. Andererseits verliert man aber auch die Einspeisevergütung für die Strommenge, mit der man den Akku auflädt. Die Akku-Ersparnis ist also der Betrag, der gespart wird, weil man einen Akku hat - gegenüber der Situation, eine PV-Anlage ohne Akku zu betreiben. Anders ausgedrückt: Mit diesem Betrag amortisiert sich die Investition in den Akku.\ +Der Betrag wird schließlich noch prozentual ins Verhältnis zur vorher ausgerechneten Gesamtersparnis gesetzt. + +## Zugrunde liegende Annahmen + +Zu beachten ist, dass diese Berechnung die Anfangsinvestitionen in die PV-Anlage nicht berücksichtigt und auch Wartungskosten, Versicherungsprämien etc. nicht mit einfließen. + +Ebenfalls unberücksichtigt bleibt, dass der Speicher einen nicht unerheblichen Eigenverbrauch hat und somit der Hausverbrauch höher ist, als wenn man keine PV-Anlage bzw. keinen Stromspeicher hätte. diff --git a/benutzung/index.md b/benutzung/index.md new file mode 100644 index 0000000..49af4db --- /dev/null +++ b/benutzung/index.md @@ -0,0 +1,7 @@ +--- +title: Benutzung +layout: page +nav_order: 4 +--- + +todo diff --git a/benutzung/kosten-berechnung.md b/benutzung/kosten-berechnung.md new file mode 100644 index 0000000..e6413d8 --- /dev/null +++ b/benutzung/kosten-berechnung.md @@ -0,0 +1,73 @@ +--- +title: Kosten-Berechnung +layout: page +parent: Benutzung +--- + +# Berechnung der entstandenen Stromkosten + +SOLECTRUS berechnet Kosten, die für den Verbrauch von Strom anfallen, wobei zwischen Netzbezug und Eigenverbrauch unterschieden wird. Diese werden für den ausgewählten Zeitraum dargestellt, hier ein Beispiel: + +Kostenberechnung + +Teil der Kosten ist die entgangene Einspeisevergütung, die beim Eigenverbrauch entsteht, wenn der erzeugte Strom nicht ins Netz eingespeist wird. Dieser Teil der Berechnung ist optional und kann auch deaktiviert werden. + +:::note + +Die hier beschriebene Berechnung gilt ab Version `0.16.0`. Frühere Versionen haben die Kosten anders dargestellt. + +::: + +Berechnungsgrundlage sind die eingestellten Strompreise, die sich regelmäßig ändern können. Auch hierzu ein Beispiel: + +Strompreise + +Die Berechnung erfolgt in drei Schritten: + +1. Ermittlung der Strompreise, die für den ausgewählten Zeitraum gelten - hier also für ein Jahr. Hat sich der Preis im gewählten Zeitraum geändert, wird das berücksichtigt, indem der Zeitraum in einzelne Abschnitte aufgeteilt wird. Hier im Beispiel ist das der Fall: Der Strompreis bewegte sich zwischen `0,2545 €/kWh` und `0,3244 €/kWh`. Insgesamt hat sich der Preis zweimal geändert, es gab also drei verschiedene Preise. Somit sind drei Zeitabschnitte zu bilden. + +2. Für jeden Zeitabschnitt wird der Stromverbrauch in kWh aus den Messwerten ermittelt. Im Beispiel sind es aufsummiert `1.335 kWh`. Die Einzelverbräuche der Zeitabschnitte werden aus Gründen der Einfachheit nicht dargestellt. Gleiches gilt für den Eigenverbrauch, im Beispiel sind es `4.926 kWh`. + +3. Die Netzbezugskosten ergeben sich für jeden Zeitabschnitt durch Multiplikation von Stromverbrauch und Strompreis. Zum Schluss wird alles aufaddiert. Im Beispiel resultieren daraus `386 €`. Hinzu kommt die entgangene Einspeisevergütung, im Beispiel `418 €`. Die Gesamtkosten betragen also `804 €`. Diese Kosten sind entstanden, um die benötigten Verbraucher mit Strom zu versorgen. + +

Power-Splitter

+ +Mit dem [Power-Splitter](/features/#power-splitter) gibt es ein mächtiges Werkzeug, um die tatsächlichen Kosten der großen Verbraucher Haus, Wärmepumpe und E-Auto **separat** zu berechnen. + +Beim Verbrauch entsteht üblicherweise ein Mix aus Eigenverbrauch (grüner Strom) und Netzbezug. Diese Aufteilung wird vom Power-Splitter für jeden der großen Verbraucher ermittelt und aufsummiert. + +:::note + +Die Berechnung erfolgt ‐ grob skizziert ‐ in etwa so: + +Im Minutentakt wird der insgesamt bezogene Netzstrom (in Watt) ermittelt. Dieser wird anteilig auf die im gleichen Zeitabschnitt aktiven Verbraucher verteilt. Dabei wird das E-Auto erstrangig behandelt, da man dieses meist bewusst lädt. Der verbliebene Rest (sofern vorhanden) wird dann anteilig auf Haus und Wärmepumpe verteilt. + +Insgesamt ist damit für jede Minute bekannt, welcher Verbraucher welchen Anteil am Netzbezug hat. + +::: + +Aus dem Anteil werden dann die echten Stromkosten dieser Verbraucher ermittelt, die sich aus Netzbezug und entgangener Einspeisevergütung (optional) zusammensetzen. Hier ein Beispiel für das E-Auto in einem Jahr: + +Power-Splitter + +In diesem Beispiel hat das E-Auto etwa 2 MWh im Jahr über die Wallbox bezogen. 69% davon war grüner Strom, wurde also selbst über die PV-Anlage erzeugt. Der kleinere rote Teil des Balkens zeigt den Netzbezug an. + +Die Summe aus Netzbezug und entgangener Einspeisevergütung beträgt `314 €`, wobei die jeweils gültigen Strompreise berücksichtigt werden. So kennt man jetzt die Stromkosten für ein Jahr Autofahren. + +:::caution + +Zu beachten ist bei diesem Beispiel, dass externe Ladungen (z.B. an öffentlichen Ladesäulen) hier nicht berücksichtigt werden, da es dafür keine Messwerte gibt. Zukünftige Versionen werden diese Lücke schließen, indem externe Beladungen manuell erfasst werden können. + +::: diff --git a/benutzung/smartphone.md b/benutzung/smartphone.md new file mode 100644 index 0000000..6651170 --- /dev/null +++ b/benutzung/smartphone.md @@ -0,0 +1,25 @@ +--- +title: Smartphone +layout: page +parent: Benutzung +--- + +# Gibt es eine App für das Smartphone? + +Eine native App für Android und iOS gibt es derzeitig nicht. SOLECTRUS ist jedoch eine sogenannte PWA (Progressive Web App). Das bedeutet, dass es sich um eine normale Webanwendung handelt, die aber so aussieht und sich so verhält, als wäre sie eine native App. Das hat den Vorteil, dass SOLECTRUS auf allen Geräten funktioniert, die einen Browser unterstützen. Die Verwendung auf iPhone, iPad oder Android Geräten ist also kein Problem. Es gibt auch Berichte von Nutzern, die [SOLECTRUS auf einem (smarten) Kühlschrank verwenden](https://github.com/solectrus/solectrus/issues/2511#issuecomment-2052028943) - alles, was einen modernen Browser hat, kann SOLECTRUS anzeigen. + +Die Verwendung von SOLECTRUS als App auf einem Smartphone oder Tablet funktioniert folgendermaßen: + +## Auf iOS oder iPadOS + +1. Öffne SOLECTRUS im Browser auf dem iPhone oder iPad +2. Klicke auf das Symbol mit dem Quadrat und dem Pfeil nach oben +3. Wähle "Zum Home-Bildschirm" und bestätige den Namen +4. Fertig! + +## Auf Android + +1. Öffnet SOLECTRUS im Browser auf dem Smartphone oder Tablet +2. Tippe auf die drei Punkte rechts oben +3. Wähle "Zum Startbildschirm hinzufügen" und bestätige den Namen +4. Fertig! diff --git a/index.md b/index.md index 056bde4..c4ba81f 100644 --- a/index.md +++ b/index.md @@ -1,35 +1,17 @@ --- title: Home layout: home +nav_order: 1 --- -This is a _bare-minimum_ template to create a Jekyll site that uses the [Just the Docs] theme. You can easily set the created site to be published on [GitHub Pages] – the [README] file explains how to do that, along with other details. +# Willkommen! -If [Jekyll] is installed on your computer, you can also build and preview the created site _locally_. This lets you test changes before committing them, and avoids waiting for GitHub Pages.[^1] And you will be able to deploy your local build to a different platform than GitHub Pages. +Willkommen auf der Dokumentations-Website von **SOLECTRUS**. Hier findest du alles, was man zum Installieren, Konfigurieren und Aktualisieren von SOLECTRUS wissen muss. -More specifically, the created site: +SOLECTRUS ist ein Dashboard für die Überwachung von Solaranlagen. Es bietet eine einfache und intuitive Benutzeroberfläche, um die Leistung und den Status deiner Solaranlage zu überwachen. -- uses a gem-based approach, i.e. uses a `Gemfile` and loads the `just-the-docs` gem -- uses the [GitHub Pages / Actions workflow] to build and publish the site on GitHub Pages +Die Installation erfolgt üblicherweise auf einem kleinen Gerät wie einem Raspberry Pi unter Linux und Docker. Es hilft, wenn du zu beiden Themen bereits ein wenig Erfahrung hast. -Other than that, you're free to customize sites that you create with this template, however you like. You can easily change the versions of `just-the-docs` and Jekyll it uses, as well as adding further plugins. +Für Neueinsteiger ist der Konfigurator eine gute Wahl. Er führt dich Schritt für Schritt durch die Installation und Konfiguration von SOLECTRUS. -[Browse our documentation][Just the Docs] to learn more about how to use this theme. - -To get started with creating a site, simply: - -1. click "[use this template]" to create a GitHub repository -2. go to Settings > Pages > Build and deployment > Source, and select GitHub Actions - -If you want to maintain your docs in the `docs` directory of an existing project repo, see [Hosting your docs from an existing project repo](https://github.com/just-the-docs/just-the-docs-template/blob/main/README.md#hosting-your-docs-from-an-existing-project-repo) in the template README. - ---- - -[^1]: [It can take up to 10 minutes for changes to your site to publish after you push the changes to GitHub](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/creating-a-github-pages-site-with-jekyll#creating-your-site). - -[Just the Docs]: https://just-the-docs.github.io/just-the-docs/ -[GitHub Pages]: https://docs.github.com/en/pages -[README]: https://github.com/just-the-docs/just-the-docs-template/blob/main/README.md -[Jekyll]: https://jekyllrb.com -[GitHub Pages / Actions workflow]: https://github.blog/changelog/2022-07-27-github-pages-custom-github-actions-workflows-beta/ -[use this template]: https://github.com/just-the-docs/just-the-docs-template/generate +Wenn du eine bestehende Installation verändern oder erweitern möchtest, findest du hier in der Dokumentation alle Informationen, die du benötigst. Insbesondere wird jede einzelne Komponente von SOLECTRUS beschrieben. diff --git a/installation/configurator.md b/installation/configurator.md new file mode 100644 index 0000000..ddf9ddc --- /dev/null +++ b/installation/configurator.md @@ -0,0 +1,8 @@ +--- +title: Konfigurator +layout: page +parent: Installation +nav_order: 2 +--- + +todo diff --git a/installation/index.md b/installation/index.md new file mode 100644 index 0000000..d69a2b4 --- /dev/null +++ b/installation/index.md @@ -0,0 +1,49 @@ +--- +title: Installation +layout: page +nav_order: 2 +--- + +Für die Installation von SOLECTRUS ist ein wenig Erfahrung mit **Linux** und **Docker** sehr hilfreich. Wenn du weißt, wie du dich per SSH auf einen Linux-Server einloggst, dann wirst du die Installation bestimmt hinbekommen. Andernfalls solltest du vielleicht einen IT-Freund fragen, der dir hilft. + +Ausgangspunkt einer Installation ist der brandneue, interaktive Konfigurator, der den Einstieg leicht macht. Du kannst damit deine individuelle Konfiguration zusammenstellen und erhältst dann alles, was du benötigst: + +- `readme.md` mit einer individuellen Schritt-für-Schritt-Anleitung für die Installation mit Docker +- `compose.yaml` mit der Definition der benötigen Docker-Services +- `.env` für die Umgebungsvariablen mit den individuellen Einstellungen + +Mit der Anleitung und den beiden Konfigurationsdateien kannst du die Installation dann leicht über die Linux-Konsole durchführen. + +
+ Zum Konfigurator ❯ +
+ +## Überblick zur Architektur + +SOLECTRUS ist eine Webanwendung, die auf einem Server läuft und über den Browser aufgerufen wird. + +Zusätzlich gibt es weitere Komponenten, die im Hintergrund laufen und die Daten sammeln und verarbeiten. Üblicherweise benötigt man nicht alle Komponenten, sondern nur die, die für das eigene Setup notwendig sind. + +Architektur von SOLECTRUS + +Jede Komponente läuft in einem separaten Docker-Container. Hierzu gehören: + +- Dashboard-App, der Hauptbestandteil mit der Benutzeroberfläche +- InfluxDB, die Zeitreihendatenbank für Messwerte +- PostgreSQL, die Datenbank für alle anderen Daten (z.B. Strompreise und Einstellungen) +- Redis, In-Memory-Datenbank für bessere Performance durch Caching +- Verschiedene "Kollektoren", mit denen Messwerte eingesammelt werden. Es gibt beispielsweise den SENEC-Collector, der Daten vom SENEC-Speicher abruft. Es gibt aber auch den MQTT-Collector, der benötigt wird, wenn du Daten von einem MQTT-Broker abrufen möchtest. Spezielle Kollektoren für Tibber oder Shelly sind ebenfalls vorhanden. Ein Forecast-Collector ermöglicht eine Vorhersage der PV-Erzeugung. Die Kollektoren sind optional und können je nach Bedarf eingesetzt werden. +- CSV-Importer, der historische Messwerte im CSV-Format einmalig nach InfluxDB überträgt +- Power-Splitter, der die Aufteilung des Netzbezugs auf verschiedene Verbraucher berechnet + +Die Container sind in einem Docker-Netzwerk miteinander verbunden und kommunizieren untereinander. + +## Szenarien der Installation + +Es ist möglich (und in den meisten Fällen auch empfehlenswert), alle notwendigen Komponenten auf dem gleichen Gerät zu betreiben. Denkbar ist aber auch eine verteilte Installation, bei der nur einige Kollektoren auf dem eigenen Gerät laufen und alles andere extern in der Cloud. Letzteres ist beispielsweise bei der [Live-Demo](https://demo.solectrus.de) der Fall. + +Der Konfigurator ermöglicht drei grundsätzlich verschiedene Szenarien: + +- Lokale Installation (auf einem lokalen Linux-Server wie dem Raspberry Pi oder Synology NAS) +- Verteilte Installation (Datensammlung auf einem lokalen Linux-Server, Datenspeicherung und Dashboard auf einem Cloud-Server) +- Im Fall von SENEC ist eine reine Cloud-Installation möglich, bei der lokal gar kein Server notwendig ist, sondern die Messwerte direkt über eine API von SENEC abgerufen werden. diff --git a/installation/systemvoraussetzungen.md b/installation/systemvoraussetzungen.md new file mode 100644 index 0000000..5a066fe --- /dev/null +++ b/installation/systemvoraussetzungen.md @@ -0,0 +1,49 @@ +--- +title: Systemvoraussetzungen +description: Über die unterstützten Photovoltaik-Geräte und was außer Raspberry Pi noch in Frage kommt. +layout: page +parent: Installation +nav_order: 1 +--- + +Für den Betrieb von SOLECTRUS benötigst du neben der Photovoltaik-Anlage (optional mit Stromspeicher, Wärmepumpe und/oder Wallbox) oder einem Balkonkraftwerk lediglich einen kleinen Linux-Server. + +## Geräte über MQTT + +Über das Netzwerkprotokoll MQTT können beliebige Speicher, Wechselrichter, Wallboxen und Wärmepumpen integriert werden, sofern diese ein solches Auslesen von Messwerten ermöglichen. Hierfür ist zusätzliche Software notwendig, insbesondere ein MQTT-Broker. Erfolgreiche Installationen basieren auf [ioBroker](https://www.iobroker.net/) und [evcc](https://evcc.io), viele Nutzer betreiben SOLECTRUS jedoch auch in anderen Szenarien. Entscheidend ist, dass man per MQTT an die Messwerte herankommt. + +## Stromspeicher von SENEC + +SOLECTRUS unterstützt außerdem nativ die Stromspeicher **SENEC.Home V3 und V2.1**, deren Messwerte über die proprietäre `lala.cgi`-Schnittstelle direkt ausgelesen werden. Auch der **SENEC.Home 4** wird unterstützt – per Cloud-Anbindung über die App-API. + +## Linux-Server + +Zum Ausführen von SOLECTRUS wird ein kleiner Server mit einem **64bit-Linux**-Betriebssystem benötigt, der [Docker](https://www.docker.com/)-Container ausführen kann und rund um die Uhr (24/7) in Betrieb ist. + +Diesen Zwecke erfüllt beispielsweise ein [Raspberry Pi](https://de.wikipedia.org/wiki/Raspberry_Pi), aber es funktioniert auch mit vielen anderen Servern. Berichte über den erfolgreichen Einsatz von SOLECTRUS gibt es für: + +- Raspberry Pi 5 mit 8GB RAM +- Raspberry Pi 4 Model B Rev 1.4 mit 8GB RAM +- Raspberry Pi 400 +- Raspberry Pi 3 Model B +- Synology DS220+ mit 10GB RAM +- Synology DS218+ +- QNAP TS-264 mit 8GB RAM +- Windows 10/11 Pro mit Hyper-V und Debian-Linux +- Mac Mini mit Docker Desktop +- Lenovo ThinkCentre M73 mit Linux Mint +- Fujitsu Futro S920 mit Linux Mint + +:::note + +Diese Liste wird gerne erweitert. Wenn du SOLECTRUS auf einem anderen Gerät erfolgreich betreibst, schreibe bitte eine E-Mail an . Ich freue mich insbesondere über Berichte zu ungewöhnlichen Installationen. + +::: + +Beim Zugriff auf die SENEC-App-API kann SOLECTRUS auch auf einem beliebigen Cloud-Server betrieben werden, auf dem Docker installiert ist. Erfolgreich getestet wurde SOLECTRUS auf einem [Hetzner-Cloud](https://hetzner.cloud/?ref=NggV8HU9FqCz)-Server mit 2 vCPUs und 4GB RAM. 2GB RAM sollten jedoch auch ausreichen. **Eine solche Installation kommt gänzlich ohne ein lokales Gerät aus.** + +Es gibt jedoch auch Geräte, auf denen SOLECTRUS leider nicht funktioniert. Dazu gehören: + +- FritzBox +- Apple TimeCapsule (geschlossenes System, Installation von Docker nicht möglich) +- Alte Synology NAS wie z.B. DS216+ mit Linux-Kernel v3 (es wird mindestens **v4** benötigt) diff --git a/installation/troubleshooting/problemloesung.md b/installation/troubleshooting/problemloesung.md new file mode 100644 index 0000000..9218e6a --- /dev/null +++ b/installation/troubleshooting/problemloesung.md @@ -0,0 +1,102 @@ +--- +title: Problemlösung +layout: page +parent: Installation +--- + +# Was ist Docker? + +SOLECTRUS basiert auf [Docker](https://www.docker.com/). Docker ist eine Software, die es ermöglicht, Anwendungen in Containern zu betreiben. Ein Container ist eine leichtgewichtige, isolierte Umgebung, die alle notwendigen Abhängigkeiten enthält, um eine Anwendung auszuführen. Im Gegensatz zu virtuellen Maschinen teilen Container den gleichen Betriebssystemkern, laufen jedoch isoliert voneinander auf dem gleichen System. + +Docker ist ein phantastisches Werkzeug, um Anwendungen zu betreiben. Es ist jedoch auch recht komplex. Bei der Installation von SOLECTRUS kommen viele User erstmalig mit Docker in Berührung und haben Schwierigkeiten, die Funktionsweise zu verstehen. Dieses Dokument soll bei der Lösung häufiger Probleme helfen. + +# Was ist Docker Compose? + +[Docker Compose](https://docs.docker.com/compose/) ist ein Tool, das es ermöglicht, mehrere Docker-Container gleichzeitig zu starten. Es wird eine Datei mit den Definitionen der Container, (sog. "Services"), erstellt, die dann mit einem einzigen Befehl gestartet werden können. + +Je nach Version wird `docker-compose` (mit Bindestrich) oder `docker compose` (ohne Bindestrich) verwendet. In diesem Dokument wird `docker compose` verwendet, da dies die aktuelle Schreibweise ist. Falls du eine ältere Version von Docker Compose verwendest (z.B. weil du eine Synology NAS verwendest), ersetze `docker compose` durch `docker-compose`. + +Die Datei mit den Definitionen der Container kann entweder `docker-compose.yml` oder `compose.yml` heißen (oder jeweils mit `.yaml`). Neuere Versionen von Docker Compose verwenden den Namen [`compose.yaml`](https://docs.docker.com/compose/compose-application-model/#the-compose-file), die alten Bezeichnungen werden aber weiterhin unterstützt. In diesem Dokument wird `compose.yaml` verwendet. Entscheide dich für eine Schreibweise und bleibe dabei. + +# Was ist eine .env-Datei? + +Die `.env`-Datei ist eine Konfigurationsdatei, die Umgebungsvariablen für die Container enthält und somit Einstellungen für die Container bereitstellt. + +Sie wird von Docker Compose verwendet, um die Werte der Variablen in die Container zu übergeben. Die `.env`-Datei ist eine einfache Textdatei, die im selben Verzeichnis wie die `compose.yaml` liegt. + +# Protokoll der Docker-Container + +Jeder Docker-Container führt ein Protokoll (Log) über seine Aktivitäten. Dieses Protokoll ist **äußerst** hilfreich, um Fehler zu finden und zu beheben. Wer SOLECTRUS betreibt, sollte zumindest bei Problemen immer einen Blick in die Logs werfen. + +Wer in einem Issue oder Diskussionsforum um Hilfe bittet, sollte immer die Logs der betroffenen Container bereitstellen, möglichst reduziert auf die relevanten Zeilen. Das erleichtert es anderen, das Problem zu verstehen und zu lösen. + +Mit folgendem einfachen Befehl lassen sich sämtliche Logs der Container anzeigen - auszuführen im Verzeichnis, in dem die `compose.yaml` liegt: + +```bash +docker compose logs +``` + +Der Output kann allerdings unübersichtlich sein, da die Logs aller Container in einem Stream zusammengefasst werden. Um die Logs eines bestimmten Containers zu sehen, kann der Service-Name als Argument übergeben werden und so der Output gefiltert werden: + +```bash +docker compose logs +``` + +Ein paar Beispiele: + +```bash +docker compose logs dashboard +docker compose logs senec-collector +docker compose logs mqtt-collector +... +``` + +Der Output kann aber immer noch sehr umfangreich sein. Es kann sinnvoll sein, die Ausgabe zu begrenzen. + +Mit dem `--tail`-Argument lassen sich die letzten `n` Zeilen anzeigen, z.B. die letzten 50 Zeilen: + +```bash +docker compose logs --tail 50 +``` + +Mit dem `--since`-Argument lassen sich die Logs auf einen Zeitraum begrenzen, z.B. die letzten 2 Stunden: + +```bash +docker compose logs --since 2h +``` + +Außerdem kann mit dem `--follow`-Argument die Ausgabe live verfolgt werden, d.h. die Logs werden kontinuierlich aktualisiert, bis man mit Strg+C abbricht: + +```bash +docker compose logs --follow +``` + +Genaueres zu `docker compose logs` findet sich in der [offiziellen Dokumentation](https://docs.docker.com/reference/cli/docker/compose/logs/). + +Bei SOLECTRUS ist es so, dass beim Start von Container besondere Informationen in den Logs ausgegeben werden. Es kann also sinnvoll sein, die Container neu zu starten, bevor die Logs geprüft werden. + +# Neustart der Container + +Ein Neustart der Container gelingt am einfachsten mit folgendem Befehl: + +```bash +docker compose down +docker compose up -d +``` + +Etwaige Änderungen in der `compose.yaml` werden dabei berücksichtigt. + +# Update der Container + +Es ist sinnvoll, bei Problemen zunächst sicherzustellen, dass die Container auf dem neuesten Stand sind, also die aktuell verfügbare Version verwendet wird. Das geht mit folgendem Befehl: + +```bash +docker compose pull +docker compose up -d +``` + +Damit werden die neuesten Images der Container heruntergeladen (sofern vorhanden) und die Container neu gestartet (falls erforderlich). Basis ist dabei die Angabe unter `image:` in der `compose.yaml`. Docker prüft also, ob es ein neues Image zum angegebenen "Tag" gibt und lädt es herunter. Ein Tag ist eine Art Versionsnummer, die in der `compose.yaml` angegeben wird. Oft lautet sie `latest`, was bedeutet, dass immer die neueste Version verwendet werden soll. + +Übrigens führt eine manuelle Änderung in der compose-Datei (oder `.env`) nicht automatisch zu einem Update der Container. Dazu muss explizit der Befehl `docker compose up -d` ausgeführt werden. + +Die Installation von Updates kann übrigens auch [automatisiert](Updates-installieren) werden. diff --git a/installation/troubleshooting/sensor-configuration.md b/installation/troubleshooting/sensor-configuration.md new file mode 100644 index 0000000..a9fb40e --- /dev/null +++ b/installation/troubleshooting/sensor-configuration.md @@ -0,0 +1,89 @@ +--- +title: Umstellung auf neue Konfiguration +layout: page +parent: Troubleshooting +--- + +# Neue Konfiguration mit v0.15 + +Mit Version `0.15` wurde in SOLECTRUS eine neue Konfiguration eingeführt. Dieser Text soll erklären, warum das notwendig war, welche Vorteile es bringt und was bisherige Benutzer von SOLECTRUS tun sollten. + +Für neue Benutzer, die erst mit Version `0.15` einsteigen, ist das alles nicht relevant. Sie können SOLECTRUS mithilfe des [Konfigurators](https://configurator.solectrus.de/) installieren und müssen nichts umstellen. Der Konfigurator erzeugt automatisch die neue Konfiguration. + +## Warum überhaupt eine neue Konfiguration? + +Bislang orientierte sich SOLECTRUS begrifflich am Hersteller SENEC. Die ersten Versionen von SOLECTRUS unterstützten nur den SENEC-Speicher und verwendeten daher intern (insbesondere in der Datenbank InfluxDB) auch deren Bezeichnungen für einzelne Messwerte. Diese Bezeichnung wie z.B. `bat_fuel_charge` oder `bat_power_minus` oder `bat_power_plus` waren nicht immer selbsterklärend und führten zu Verwirrung. Es erschien mir anfangs aber als eine gute Idee, wenn die SENEC-Begriffe ein-zu-eins in SOLECTRUS wieder auftauchten. + +Mit Einführung der [MQTT-Anbindung](https://github.com/solectrus/mqtt-collector) und der Unterstützung von weiteren Herstellern wurde das aber zu einem unschönen Nachteil: Die Messwerte kamen nun aus verschiedenen Quellen (hießen also auch anders) und mussten in das Schema von SOLECTRUS gepresst werden, das auf SENEC basierte. Das führte nicht gerade zu einer übersichtlichen Konfiguration. + +Ich habe mich daher entschlossen, eine eigene Namensgebung einzuführen, die **herstellerunabhängig** ist und in sich konsistent ist. Die Messwerte nennen sich jetzt "Sensoren". Jeder Sensor hat einen eindeutigen Namen, der innerhalb von SOLECTRUS verwendet wird. + +## Was ist ein Sensor? + +Welche Sensoren es gibt, legt SOLECTRUS selbst fest. Derzeit gibt es genau diese 14: + +- `INVERTER_POWER` (erzeugte Leistung des Wechselrichters) +- `HOUSE_POWER` (Hausverbrauch) +- `GRID_IMPORT_POWER` (Netzbezug) +- `GRID_EXPORT_POWER` (Netzeinspeisung) +- `HEATPUMP_POWER` (Leistung der Wärmepumpe) +- `BATTERY_CHARGING_POWER` (Ladeleistung des Speichers) +- `BATTERY_DISCHARGING_POWER` (Entladeleistung des Speichers) +- `BATTERY_SOC` (Ladestand des Speichers) +- `WALLBOX_POWER` (Ladeleistung der Wallbox) +- `CASE_TEMP` (Temperatur des Speichers) +- `INVERTER_POWER_FORECAST` (prognostizierte PV-Leistung) +- `SYSTEM_STATUS` (Status des Speichers oder der Anlage) +- `SYSTEM_STATUS_OK` (Status des Speichers gilt als "OK") +- `GRID_EXPORT_LIMIT` (Einspeisebegrenzung) + +Zukünftige Versionen werden sicherlich weitere Sensoren einführen. + +## Kompatibilität mit älteren Versionen + +Ein bestehender SOLECTRUS-Nutzer hat eine InfluxDB, die mit den alten Bezeichnungen gefüllt ist. Da gibt es möglicherweise das Measurement `SENEC` mit dem Field `bat_power_plus`. + +Um dies anzugehen, wurde ein Mapping eingeführt, also eine Zuordnung von Sensor-Namen zu InfluxDB-Bezeichnungen. Diese Zwischenschicht wird in der `.env`-Datei konfiguriert. Ein Beispiel: + +```env +INFLUX_SENSOR_BATTERY_CHARGING_POWER=SENEC:bat_power_plus +``` + +Das ist folgendermaßen zu lesen: Der Sensor `BATTERY_CHARGING_POWER` ist im Measurement `SENEC` zu finden und dort im Field `bat_power_plus`. + +Damit können bestehende SOLECTRUS-Nutzer ihre gesammelten Messwerte weiter verwenden. Es sind nur die entsprechenden Einträge in der `.env`-Datei vorzunehmen. + +## Besonderheit bei MQTT + +Der MQTT-Collector ab [Version 0.2.0 ](https://github.com/solectrus/mqtt-collector/releases/tag/v0.2.0) profitiert sehr von dieser Umstellung. Er muss nämlich gar nicht wissen, welche Sensoren es in SOLECTRUS gibt. Er kann beliebige Messwerte empfangen, verarbeiten und in die InfluxDB schreiben. Der Collector muss sich an keinem vorgegebenen Namensschema orientieren, sondern die Messwerte können sinnvoll z.B. nach ihrer Quelle strukturiert werden. + +Für jedes Topic, das der MQTT-Collector abonniert, kann einzeln festgelegt werden, was mit den Messwerten geschehen soll und insbesondere wohin sie gespeichert werden sollen. Die Werte können insbesondere auf unterschiedliche Measurements verteilt werden, was früher nicht möglich war. + +Das bedeutet, dass auch Messwerte, die gar nichts mit einem Stromspeicher zu tun haben, sinnvoll mit dem MQTT-Collector gesammelt werden können. Beispiele sind der Stromverbrauch einer Wärmepumpe, der Kilometerstand eines E-Autos, die Außentemperatur, ein CO2-Emissionsfaktor etc. Zukünftige Versionen von SOLECTRUS können diese Werte dann sinnvoll verarbeiten. + +Auch sind jetzt Verarbeitungsschritte möglich, z.B. die Umrechnung oder die Extraktion von Werten aus verschachtelten JSON-Strukturen. Die Details dazu sind hier zu finden: +https://github.com/solectrus/mqtt-collector/wiki/Konfiguration + +## Anleitung zur Umstellung + +Ich habe bei der Entwicklung sehr darauf geachtet, dass die Umstellung so einfach wie möglich ist. Die meisten User werden nach dem Update gar nicht gemerkt haben, dass eine solche grundlegende Umstellung stattgefunden hat. Die alte Konfiguration wird nämlich weiterhin unterstützt und beim Start der Docker-Container automatisch in die neue Konfiguration überführt. + +Diese Fähigkeit wird aber vermutlich nicht auf Dauer bestehen bleiben. Es sind Altlasten, die ich gerne irgendwann über Bord werfen möchte. Im Docker-Log der Container werden daher Warnungen ausgegeben, wenn die alte Konfiguration noch verwendet wird. Außerdem, und das ist das Wichtigste, werden konkrete Hinweise gegeben, wie die Umstellung erfolgen kann. + +Ein Beispiel dazu: + +``` +Variables MQTT_TOPIC_BAT_POWER and MQTT_FLIP_BAT_POWER are deprecated. To remove this warning, please replace the variables by: + MAPPING_3_TOPIC=PV/SignedBat + MAPPING_3_FIELD_POSITIVE=bat_power_minus + MAPPING_3_FIELD_NEGATIVE=bat_power_plus + MAPPING_3_MEASUREMENT_POSITIVE=SUNGROW + MAPPING_3_MEASUREMENT_NEGATIVE=SUNGROW + MAPPING_3_TYPE=integer +``` + +Mit diesen Hinweisen kann man schrittweise von der alten auf die neue Konfiguration umstellen. + +--- + +(Dieser Text wird in der nächsten Zeit noch erweitert und verfeinert.) diff --git a/installation/updates.md b/installation/updates.md new file mode 100644 index 0000000..346fe68 --- /dev/null +++ b/installation/updates.md @@ -0,0 +1,142 @@ +--- +title: Updates +layout: page +parent: Installation +nav_order: 4 +--- + +# Installation von Updates + +Für SOLECTRUS erscheinen regelmäßig Updates, die neue Funktionen und Verbesserungen enthalten. Es ist sehr empfehlenswert, diese Updates zu installieren, um neue Funktionen, Verbesserungen und Fehlerkorrekturen zu erhalten. + +Sämtliche Bestandteile von SOLECTRUS werden in Form von Docker-Images bereitgestellt. In der `compose.yaml` (früher: `docker-compose.yml`) wird festgelegt, welche Versionen der Images verwendet werden. Üblicherweise steht dort die Angabe `latest`, was bedeutet, dass immer die neueste Version der Images angefordert wird. + +Dies bedeutet jedoch nicht, dass die neuesten Versionen auch jederzeit installiert werden. Ein Update muss explizit durchgeführt werden, was entweder manuell oder automatisch erfolgen kann. + +Eine Automatisierung dieses Vorgangs (mit dem Tool _Watchtower_) ist **sehr empfehlenswert**. Wenn deine Installation mit dem [SOLECTRUS-Konfigurator](https://configurator.solectrus.de/) eingerichtet wurde, hast du _Watchtower_ bereits installiert und kannst aufhören zu lesen. Wer schon länger dabei ist, sollte _Watchtower_ nachrüsten. + +## Manuelle Installation + +Gehe wie folgt vor, um Updates bei Verfügbarkeit manuell zu installieren: + +1. SSH-Login auf deinen Server, z. B. deinen Raspberry Pi. + +2. Wechsle in das Verzeichnis, in dem die `compose.yaml` (früher: `docker-compose.yml`) sowie die `.env`-Datei von SOLECTRUS liegen. + +3. Führe die folgenden zwei Befehle aus: + + ```bash + docker compose pull + docker compose up -d + ``` + +Fertig. Was passiert genau? Mit `pull` werden die neuesten Versionen der Docker-Images heruntergeladen, während mit `up -d` die Container neu gestartet werden. + +Diese Befehle aktualisieren sämtliche Docker-Container von SOLECTRUS – also das Dashboard, die Kollektoren, aber auch die Datenbanken InfluxDB und Redis. + +## Automatische Installation + +Updates möchte man nicht manuell immer wieder durchführen. Daher empfiehlt sich die Einrichtung eines kleinen Werkzeugs, das diesen Vorgang automatisiert. Hier kommt [Watchtower](https://containrrr.dev/watchtower/) ins Spiel. + +_Watchtower_ prüft einmal täglich, ob es neue Versionen der Docker-Images gibt und installiert diese dann automatisch. Wie in der Docker-Welt üblich, läuft _Watchtower_ selbst als Container. + +Die folgenden Schritte sind **einmalig** erforderlich, danach musst du dich mit Updates für SOLECTRUS nicht mehr beschäftigen. + +1. SSH-Login auf deinen Server, z. B. deinen Raspberry Pi. + +2. Bearbeite die `compose.yaml` (früher: `docker-compose.yml`). Es sind zwei Dinge zu tun: + + **A)** Hinzufügen des _Watchtower_-Containers. Ergänze im Bereich `services` den folgenden Abschnitt: + + ```yaml + watchtower: + image: containrrr/watchtower + environment: + - TZ + volumes: + - /var/run/docker.sock:/var/run/docker.sock + command: --scope solectrus --cleanup + restart: unless-stopped + logging: + options: + max-size: 10m + max-file: '3' + labels: + - com.centurylinklabs.watchtower.scope=solectrus + ``` + + Damit wird _Watchtower_ so konfiguriert, dass es nur die Container von SOLECTRUS aktualisiert. Die Option `--cleanup` sorgt dafür, dass nicht mehr benötigte Images automatisch gelöscht werden. + + **B)** Hinzufügen eines Labels zu den anderen Services, damit _Watchtower_ genau die Container von SOLECTRUS aktualisiert. + + Ergänze die folgenden zwei Zeilen bei jedem anderen Service in der `compose.yaml`: + + ```yaml + labels: + - com.centurylinklabs.watchtower.scope=solectrus + ``` + + Deine `compose.yaml` sollte (in gekürzter Form) in etwa so aussehen: + + ```yaml + services: + dashboard: + image: ghcr.io/solectrus/solectrus:latest + ... + labels: + - com.centurylinklabs.watchtower.scope=solectrus + influxdb: + image: influxdb:2.7-alpine + ... + labels: + - com.centurylinklabs.watchtower.scope=solectrus + postgresql: + image: postgres:16-alpine + ... + labels: + - com.centurylinklabs.watchtower.scope=solectrus + redis: + image: redis:7-alpine + ... + labels: + - com.centurylinklabs.watchtower.scope=solectrus + senec-collector: + image: ghcr.io/solectrus/senec-collector:latest + ... + labels: + - com.centurylinklabs.watchtower.scope=solectrus + watchtower: + image: containrrr/watchtower + environment: + - TZ + volumes: + - /var/run/docker.sock:/var/run/docker.sock + command: --scope solectrus --cleanup + restart: unless-stopped + logging: + options: + max-size: 10m + max-file: '3' + labels: + - com.centurylinklabs.watchtower.scope=solectrus + ``` + +3. Führe den folgenden Befehl aus: + +Damit _Watchtower_ läuft, muss es einmalig gestartet werden. Führe dazu den folgenden Befehl aus: + +```bash +docker compose up -d +``` + +Fertig. _Watchtower_ wird nun einmal täglich nach Updates suchen und diese automatisch installieren. + +## Probleme? + +Für den Fall, dass etwas nicht funktioniert, hier ein paar Tipps: + +- Bei älteren Versionen von Docker (z. B. auf einem Synology-NAS) muss `docker-compose` statt `docker compose` geschrieben werden, also mit Bindestrich. + +- YAML-Dateien (wie die `compose.yaml`) sind **sehr empfindlich** gegenüber falschen Einrückungen. Achte darauf, dass du beim Einkopieren der obigen Passagen keine überzähligen Leerzeichen einfügst oder entfernst. Jede neue Ebene wird mit genau zwei Leerzeichen eingerückt. + +- _Watchtower_ läuft einmal täglich, die erste Prüfung erfolgt 24 Stunden nach dem Start. Wenn du _Watchtower_ gerade erst eingerichtet hast, musst du für die erste Update-Prüfung einen Tag warten. diff --git a/komponenten/csv-importer/index.md b/komponenten/csv-importer/index.md new file mode 100644 index 0000000..69adec3 --- /dev/null +++ b/komponenten/csv-importer/index.md @@ -0,0 +1,17 @@ +--- +title: CSV-Importer +layout: page +parent: Komponenten +nav_order: 7 +--- + +Der **CSV-Importer** ist ein Werkzeug, das historische Messwerte im CSV-Format einmalig nach InfluxDB überträgt. Das ist nützlich, um nach der Installation direkt mit Daten arbeiten zu können, ohne auf die ersten Messwerte warten zu müssen. + +Unterstützt werden die Datenformate der Stromspeicher/Wechselrichter von: + +- SENEC +- Sungrow +- SolarEdge + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/csv-importer](https://github.com/solectrus/csv-importer) diff --git a/komponenten/csv-importer/konfiguration.md b/komponenten/csv-importer/konfiguration.md new file mode 100644 index 0000000..2c98b12 --- /dev/null +++ b/komponenten/csv-importer/konfiguration.md @@ -0,0 +1,48 @@ +--- +title: Konfiguration +layout: page +parent: CSV-Importer +--- + +## .env + +```properties +# Zeitzone +TZ=Europe/Berlin + +# Hostname of InfluxDB +INFLUX_HOST=influxdb + +# Schema (http/https) of InfluxDB +INFLUX_SCHEMA=http + +# Port of InfluxDB +INFLUX_PORT=8086 + +# Token for InfluxDB (requires write permissions) +INFLUX_TOKEN_WRITE=my + +# Organization for InfluxDB +INFLUX_ORG=solectrus + +# Bucket for InfluxDB +INFLUX_BUCKET=solectrus + +# Measurement for InfluxDB +INFLUX_MEASUREMENT_PV=SENEC + +# Timeout for InfluxDB connection (in seconds) +INFLUX_OPEN_TIMEOUT=30 + +# Timeout for InfluxDB read (in seconds) +INFLUX_READ_TIMEOUT=30 + +# Timeout for InfluxDB write (in seconds) +INFLUX_WRITE_TIMEOUT=30 + +# Folder where CSV files are located +IMPORT_FOLDER=/data + +# Pause after each imported file (in seconds) +IMPORT_PAUSE=0 +``` diff --git a/komponenten/dashboard/index.md b/komponenten/dashboard/index.md new file mode 100644 index 0000000..a1bdd3d --- /dev/null +++ b/komponenten/dashboard/index.md @@ -0,0 +1,9 @@ +--- +title: Dashboard +layout: page +parent: Komponenten +nav_order: 1 +--- + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/solectrus](https://github.com/solectrus/solectrus) diff --git a/komponenten/dashboard/konfiguration.md b/komponenten/dashboard/konfiguration.md new file mode 100644 index 0000000..500e686 --- /dev/null +++ b/komponenten/dashboard/konfiguration.md @@ -0,0 +1,266 @@ +--- +title: Konfiguration +layout: page +parent: Dashboard +--- + +## compose.yaml + +```yaml +services: + dashboard: + image: ghcr.io/solectrus/solectrus:latest + depends_on: + postgresql: + condition: service_healthy + influxdb: + condition: service_healthy + redis: + condition: service_healthy + links: + - postgresql + - influxdb + - redis + ports: + - 3000:3000 + environment: + - TZ + - APP_HOST + - FORCE_SSL + - SECRET_KEY_BASE + - INSTALLATION_DATE + - ADMIN_PASSWORD + - FRAME_ANCESTORS + - CO2_EMISSION_FACTOR + - DB_HOST=postgresql + - DB_PASSWORD=${POSTGRES_PASSWORD} + - DB_USER=postgres + - REDIS_URL + - INFLUX_HOST + - INFLUX_TOKEN=${INFLUX_TOKEN_READ} + - INFLUX_ORG + - INFLUX_BUCKET + - INFLUX_POLL_INTERVAL + - INFLUX_SENSOR_INVERTER_POWER + - INFLUX_SENSOR_HOUSE_POWER + - INFLUX_SENSOR_GRID_IMPORT_POWER + - INFLUX_SENSOR_GRID_EXPORT_POWER + - INFLUX_SENSOR_BATTERY_CHARGING_POWER + - INFLUX_SENSOR_BATTERY_DISCHARGING_POWER + - INFLUX_SENSOR_BATTERY_SOC + - INFLUX_SENSOR_WALLBOX_POWER + - INFLUX_SENSOR_WALLBOX_CAR_CONNECTED + - INFLUX_SENSOR_CASE_TEMP + - INFLUX_SENSOR_INVERTER_POWER_FORECAST + - INFLUX_SENSOR_SYSTEM_STATUS + - INFLUX_SENSOR_SYSTEM_STATUS_OK + - INFLUX_SENSOR_GRID_EXPORT_LIMIT + - INFLUX_SENSOR_HEATPUMP_POWER + - INFLUX_SENSOR_CAR_BATTERY_SOC + - INFLUX_EXCLUDE_FROM_HOUSE_POWER + healthcheck: + test: + - CMD-SHELL + - nc -z 127.0.0.1 3000 || exit 1 + interval: 30s + timeout: 10s + retries: 5 + start_period: 10s + restart: unless-stopped + logging: + options: + max-size: 10m + max-file: '3' + labels: + - com.centurylinklabs.watchtower.scope=solectrus + + influxdb: + # ... + + postgresql: + # ... + + redis: + # ... +``` + +## Umgebungsvariablen + +### Allgemeine Einstellungen + +- `TZ` (standardmäßig `Europe/Berlin`) + + Zeitzone gemäß [Liste](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) für die Darstellung und Berücksichtigung von Uhrzeiten. Wichtig für die korrekte Darstellung von Diagrammen und Statistiken. + +- `APP_HOST` + + Host der Anwendung. Darf eine IP-Adresse (z.B. `192.168.123.45`) oder eine Domain (z.B. `solectrus.example.com`) sein. Darf **kein** `http://` oder `https://` enthalten! + +- `FORCE_SSL` (standardmäßig `false`) + + Gibt an, ob die App automatisch auf `HTTPS` umleiten soll. Standardwert ist `false`. Dieser Wert darf nur dann auf `true` gesetzt werden, wenn man eine eigene Domain mit Reverse-Proxy und SSL-Zertifikat verwendet! In 95 % aller Fälle bleibt es also bei `false`. + +- `SECRET_KEY_BASE` + + Geheimer Schlüssel für die Verschlüsselung von Session-Cookies. Dieser Wert muss geheim bleiben und sichert das Admin-Passwort ab. Muss 128 Zeichen lang sein. + +- `ADMIN_PASSWORD` + + Zugangspasswort für den Administrator. Nur der Admin kann sich über die Web-Oberfläche anmelden und dort einige Einstellungen vornehmen (z.B. Bearbeiten von Strompreisen) + +- `INSTALLATION_DATE` + + Datum der Installation der PV-Anlage (wann die ersten Erträge erzielt wurden). Regelt die Navigation in der Web-Oberfläche. + +- `CO2_EMISSION_FACTOR` (standardmäßig `401` g/kWh, ab Version `0.15.1` verfügbar) + + Faktor zur Berechnung der CO₂-Emission aus der PV-Erzeugung. Angabe in g/kWh. + +### Zugriff auf InfluxDB + +- `INFLUX_HOST` + + Hostname des InfluxDB-Servers. Im Normalfall, wenn InfluxDB im gleichen Docker-Netzwerk läuft, ist das der Name des Containers (z.B. `influxdb`). Es kann aber auch ein externer InfluxDB-Server sein, z.B. `influxdb.example.com`. + +- `INFLUX_SCHEMA` (standardmäßig `http`) + + Schema für die Verbindung zu InfluxDB. Bei Verwendung einer externen InfluxDB, die über TLS abgesichert ist, muss dieser Wert auf `https` gesetzt werden. + +- `INFLUX_PORT` (standardmäßig `8086`) + + Port für die Verbindung zu InfluxDB. Bei Verwendung einer externen InfluxDB könnte eine Anpassung erforderlich sein, z.B. auf `443`. + +- `INFLUX_ORG` + + Organisation in InfluxDB, in der die Daten gespeichert werden. + +- `INFLUX_BUCKET` + + Bucket in InfluxDB, in der die Daten gespeichert werden. + +- `INFLUX_TOKEN` + + Token für den Zugriff auf InfluxDB. Dieser Token muss in InfluxDB erstellt werden und die Berechtigung haben, Daten aus dem angegebenen Bucket zu **lesen** (kein Schreibzugriff erforderlich). + +- `INFLUX_POLL_INTERVAL` (standardmäßig `5`) + + Intervall in Sekunden, in dem die App die Daten von InfluxDB abfragt und die Darstellung im Browser aktualisiert. Wenn der Werte zu klein ist (d.h. wenn Messwerte gar nicht so schnell in die InfluxDB gelangen), kommt es zur Fehlermeldung "Keine Verbindung" in der Web-Oberfläche. + +### Sensor-Konfiguration (ab Version 0.15) + +In InfluxDB werden die Messwerte in Form von Zeitreihen gespeichert. Jeder Messwert gehört zu einem "Measurement" und einem "Field". SOLECTRUS abstrahiert davon und definierten Sensoren. Über Umgebungsvariablen wird definiert, wo in der InfluxDB die Messwerte zu finden sind. + +Ein Sensor wird durch einen Namen identifiziert und einem "Measurement" und einem "Field" in InfluxDB zugeordnet. Die Umgebungsvariable gibt die Zuordnung mit einem Doppelpunkt getrennt an. Wenn beispielsweise die PV-Erzeugung im Measurement "SENEC" und dort im Field "inverter_power" erfolgt, sieht der Eintrag wie folgt aus: + +```env +INFLUX_SENSOR_INVERTER_POWER=SENEC:inverter_power +``` + +Jeder Sensor muss definiert werden, um keine Warnung im Protokoll zu provozieren. Wenn für einen Sensor keine Werte zur Verfügung stehen (weil man z.B. keine Wärmepumpe hat), muss der Sensor "leer" definiert werden, und zwar so: + +```env +INFLUX_SENSOR_HEATPUMP_POWER= +``` + +#### Verfügbare Sensoren + +- `INFLUX_SENSOR_INVERTER_POWER` + + PV-Erzeugung (Leistung des Wechselrichters) in Watt + +- `INFLUX_SENSOR_HOUSE_POWER` + + Hausverbrauch in Watt + +- `INFLUX_SENSOR_GRID_IMPORT_POWER` + + Strombezug aus dem Netz in Watt + +- `INFLUX_SENSOR_GRID_EXPORT_POWER` + + Stromabgabe ins Netz (Einspeisung) in Watt + +- `INFLUX_SENSOR_BATTERY_CHARGING_POWER` + + Ladeleistung des Batteriespeichers in Watt + +- `INFLUX_SENSOR_BATTERY_DISCHARGING_POWER` + + Entladeleistung des Batteriespeichers in Watt + +- `INFLUX_SENSOR_BATTERY_SOC` + + Ladestand des Batteriespeichers in Prozent + +- `INFLUX_SENSOR_WALLBOX_POWER` + + Ladeleistung der Wallbox (E-Auto) in Watt + +- `INFLUX_SENSOR_CASE_TEMP` + + Gehäuse-Temperatur des Wechselrichters (oder Stromspeichers) in °C + +- `INFLUX_SENSOR_INVERTER_POWER_FORECAST` + + Prognostizierte PV-Erzeugung in Watt + +- `INFLUX_SENSOR_SYSTEM_STATUS` + + Systemstatus (z.B. Fehlermeldungen) als Text + +- `INFLUX_SENSOR_SYSTEM_STATUS_OK` + + Kennzeichnung, ob der Systemstatus als "in Ordnung" aufgefasst werden soll (Darstellung als grüner Punkt) oder nicht (orangefarbener Punkt) + +- `INFLUX_SENSOR_GRID_EXPORT_LIMIT` + + Einspeiseleistungsbegrenzung in Prozent + +- `INFLUX_SENSOR_HEATPUMP_POWER` + + Leistung der Wärmepumpe in Watt + +- `INFLUX_SENSOR_WALLBOX_CAR_CONNECTED` (ab Version 0.17) + + Verbindungsstatus des E-Auto (True/False) + +- `INFLUX_SENSOR_CAR_BATTERY_SOC` (ab Version 0.17) + + Ladestand des E-Autos in Prozent + +#### Automatische Konfiguration / Fallback + +Wenn ein Sensor nicht definiert ist (z.B. weil die SOLECTRUS-Installation mit `v0.14.5` oder früher erfolgt ist), dann versucht SOLECTRUS, die Konfiguration automatisch zu vermittelt. Hierzu werden die früheren (und mittlerweile veralteten) Umgebungsvariablen `INFLUX_MEASUREMENT_PV` und `INFLUX_MEASUREMENT_FORECAST` verwendet. + +Im Docker-Protokoll finden sich dann Hinweise, welche Konfiguration vorgenommen wurde und wie man diese explizit in die `.env` schreiben kann. Diese sollte bei Gelegenheit gemacht werden, da zukünftige Versionen von SOLECTRUS die alte Konfiguration möglicherweise nicht mehr unterstützen werden. + +#### Erweiterte Sensor-Einstellungen + +- `INFLUX_EXCLUDE_FROM_HOUSE_POWER` (optional) + +Da der Hausverbrauch möglicherweise die Leistung von Wärmepumpe und/oder die Wallbox enthält, können Letztere aus dem Hausverbrauch herausgerechnet werden, um eine doppelte Zählung zu verhindern. Hierzu wird eine Liste von Sensoren angegeben, die aus dem Hausverbrauch ausgeschlossen werden sollen: + +```env +INFLUX_EXCLUDE_FROM_HOUSE_POWER=HEATPUMP_POWER,WALLBOX_POWER +``` + +Die Angabe erfolgt als Komma-separierte Liste von Sensor-Namen. + +### Erweiterte Einstellungen + +- `LOCKUP_CODEWORD` (optional) + + Codewort für die Sperrung der Web-Oberfläche. Wenn dieses Codewort gesetzt ist, lässt sich die Web-Oberfläche nur mit diesem Codewort entsperren. Wenn das Codewort leer ist, gibt es keine Sperrung. + +- `FRAME_ANCESTORS`(optional) + + Um die Einbettung der Web-Oberfläche in eine andere Webseite (per `iframe`) zu erlauben, kann hier die URL der übergeordneten Webseite angegeben werden. Beispiel: `https://example.com`. Standardmäßig erlaubt SOLECTRUS keine Einbettung. + +### Veraltete Angaben + +Frühere Versionen von SOLECTRUS haben folgende Umgebungsvariablen verwendet, die mittlerweile veraltet sind und gefahrlos entfernt werden können: + +- `INFLUX_MEASUREMENT_PV` (ersetzt durch neue Sensor-Konfiguration) +- `INFLUX_MEASUREMENT_FORECAST` (ersetzt durch neue Sensor-Konfiguration) +- `ELECTRICITY_PRICE` (Strompreise, wird jetzt in der Web-Oberfläche konfiguriert) +- `FEED_IN_TARIFF` (Einspeisevergütung, wird jetzt in der Web-Oberfläche konfiguriert) diff --git a/komponenten/forecast-collector/index.md b/komponenten/forecast-collector/index.md new file mode 100644 index 0000000..b64377d --- /dev/null +++ b/komponenten/forecast-collector/index.md @@ -0,0 +1,9 @@ +--- +title: Forecast-Collector +layout: page +parent: Komponenten +nav_order: 5 +--- + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/forecast-collector](https://github.com/solectrus/forecast-collector) diff --git a/komponenten/forecast-collector/konfiguration.md b/komponenten/forecast-collector/konfiguration.md new file mode 100644 index 0000000..aef8d9a --- /dev/null +++ b/komponenten/forecast-collector/konfiguration.md @@ -0,0 +1,7 @@ +--- +title: Konfiguration +layout: page +parent: Forecast-Collector +--- + +todo diff --git a/komponenten/index.md b/komponenten/index.md new file mode 100644 index 0000000..4f00535 --- /dev/null +++ b/komponenten/index.md @@ -0,0 +1,44 @@ +--- +title: Komponenten +layout: page +nav_order: 3 +has_toc: false +--- + +SOLECTRUS besteht aus etlichen Komponenten (Services), die jeweils als eigene Docker-Container betrieben werden. + +Für den Einsatz von SOLECTRUS ist eine `compose.yaml` zu erstellen, in der jeder benötigte Service definiert wird. Die Konfiguration der Services erfolgt über Umgebungsvariablen, die in einer `.env`-Datei definiert werden. Es sind alo genau diese zwei Dateien zu erstellen, deren Aufbau in den folgenden Unterseiten beschrieben wird. + +Die Services gliedern sich in verschiedene Kategorien: + +## Benutzeroberfläche + +Das browser-basierte Dashboard ist das zentrale Bedienelement von SOLECTRUS: + +- [Dashboard](dashboard) + +## Datensammlung (Collector) + +Messwerte werden von den Collectoren kontinuierlich gesammelt und in die Datenbank (InfluxDB) geschrieben: + +- [SENEC-Collector](senec-collector) +- [Tibber-Collector](tibber-collector) +- [MQTT-Collector](mqtt-collector) +- [Shelly-Collector](shelly-collector) +- [Forecast-Collector](forecast-collector) + +## Datenverarbeitung + +Einige Komponenten verarbeiten die gesammelten Daten weiter: + +- [Power-Splitter](power-splitter) +- [SENEC-Charger](senec-charger) +- [CSV-Importer](csv-importer) + +## Datenbanken + +Außerdem verwendet SOLECTRUS **drei** Datenbanken: + +- [InfluxDB](influxdb): Zeitreihendatenbank für Messwerte +- [PostgreSQL](postgresql): Relationale Datenbank für Einstellungen und Strompreise +- [Redis](redis): In-Memory-Datenbank für das Caching von Abfrageergebnissen diff --git a/komponenten/influxdb/index.md b/komponenten/influxdb/index.md new file mode 100644 index 0000000..454ab01 --- /dev/null +++ b/komponenten/influxdb/index.md @@ -0,0 +1,11 @@ +--- +title: InfluxDB +layout: page +parent: Komponenten +nav_order: 10 +--- + +SOLECTRUS speichert sämtliche Messwerte in der OpenSource-Zeitreihendatenbank **InfluxDB** ab. Es kommt die aktuelle Version **2.7** zum Einsatz, die Vorgängerversion v1 wird nicht unterstützt. + +Offizielles Docker-Image: \ +[https://hub.docker.com/\_/influxdb](https://hub.docker.com/_/influxdb) diff --git a/komponenten/influxdb/konfiguration.md b/komponenten/influxdb/konfiguration.md new file mode 100644 index 0000000..aa4fce1 --- /dev/null +++ b/komponenten/influxdb/konfiguration.md @@ -0,0 +1,67 @@ +--- +title: Konfiguration +layout: page +parent: InfluxDB +--- + +## compose.yaml + +```yaml +services: + influxdb: + image: influxdb:2.7-alpine + volumes: + - ${INFLUX_VOLUME_PATH}:/var/lib/influxdb2 + environment: + - TZ + - DOCKER_INFLUXDB_INIT_MODE=setup + - DOCKER_INFLUXDB_INIT_USERNAME=${INFLUX_USERNAME} + - DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUX_PASSWORD} + - DOCKER_INFLUXDB_INIT_ORG=${INFLUX_ORG} + - DOCKER_INFLUXDB_INIT_BUCKET=${INFLUX_BUCKET} + - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=${INFLUX_ADMIN_TOKEN} + command: influxd run --bolt-path /var/lib/influxdb2/influxd.bolt --engine-path /var/lib/influxdb2/engine --store disk + restart: unless-stopped + healthcheck: + test: + - CMD + - influx + - ping + interval: 30s + timeout: 10s + retries: 5 + start_period: 30s + logging: + options: + max-size: 10m + max-file: '3' + labels: + - com.centurylinklabs.watchtower.scope=solectrus + + watchtower: + # ... +``` + +## .env + +```properties +# Zeitzone +TZ=Europe/Berlin + +# Benutzername und Passwort für den Admin-Zugang +# Darf nach dem ersten Start nicht mehr geändert werden! +INFLUX_USERNAME=admin +INFLUX_PASSWORD=ExAmPl3PA55W0rD + +# Organisation und Bucket +# Darf nach dem ersten Start nicht mehr geändert werden! +INFLUX_ORG=solectrus +INFLUX_BUCKET=solectrus + +# Token für den Admin-Zugang +# Darf nach dem ersten Start nicht mehr geändert werden! +INFLUX_ADMIN_TOKEN=my-super-secret-admin-token + +# Volume für die Dateiablage +INFLUX_VOLUME_PATH=./influxdb +``` diff --git a/komponenten/mqtt-collector/index.md b/komponenten/mqtt-collector/index.md new file mode 100644 index 0000000..825acaf --- /dev/null +++ b/komponenten/mqtt-collector/index.md @@ -0,0 +1,37 @@ +--- +title: MQTT-Collector +layout: home +parent: Komponenten +nav_order: 3 +--- + +# Verwendung für SOLECTRUS + +Der MQTT-Collector abonniert Topics bei einem MQTT-Broker, verarbeitet die empfangenen Werte und schreibt sie in eine InfluxDB. Prinzipiell ist das unabhängig von SOLECTRUS, aber üblicherweise wird der Collector in SOLECTRUS-Umgebungen eingesetzt. SOLECTRUS bedient sich dann der Werte aus der InfluxDB. + +Für jedes abonnierte Topic, für das der MQTT-Collector Messwerte empfängt, wird einzeln über ein **Mapping** festgelegt, was mit den Werten geschehen soll und insbesondere wohin sie gespeichert werden sollen. + +```mermaid +graph LR + A[MQTT-Collector] -- Topic + Value --> B((MQTT-Mapping)) + B -- Measurement + Field + Value --> C[InfluxDB] + +``` + +Der Collector muss sich an kein vorgegebenes Namensschema halten, sondern die Messwerte können inhaltlich (z.B. nach ihrer Quelle) strukturiert werden. Die Bezeichnungen von Measurements und Fields in der InfluxDB sind also frei wählbar. + +Auch können Messwerte, die (noch) nicht von SOLECTRUS verarbeitet werden können, mit dem MQTT-Collector gesammelt werden können. Beispiele sind der Kilometerstand eines E-Autos, die Außentemperatur, ein CO2-Emissionsfaktor etc. Zukünftige Versionen von SOLECTRUS könnten diese Werte dann verarbeiten. + +Wie das Mapping im Detail zu definieren ist, wird in der [Konfiguration](Konfiguration.md) beschrieben. + +## Weiterverarbeitung in SOLECTRUS + +SOLECTRUS holt sich die Werte aus der InfluxDB, ohne zu wissen, woher sie kommen. Das SOLECTRUS-Dashboard ist also völlig unabhängig von der Quelle der Messwerte. SOLECTRUS definiert dabei Sensoren, über die die Werte abgerufen werden. Die Sensoren sind also die Schnittstelle zwischen SOLECTRUS und der InfluxDB. Für den MQTT-Collector sind die Sensoren aber irrelevant. + +```mermaid +graph LR + C[InfluxDB] -- Measurement + Field + Value --> D((Sensor-Mapping)) -- Sensor + Value --> E[Dashboard] +``` + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/mqtt-collector](https://github.com/solectrus/mqtt-collector) diff --git a/komponenten/mqtt-collector/konfiguration.md b/komponenten/mqtt-collector/konfiguration.md new file mode 100644 index 0000000..50a681e --- /dev/null +++ b/komponenten/mqtt-collector/konfiguration.md @@ -0,0 +1,214 @@ +--- +title: Konfiguration +layout: page +parent: MQTT-Collector +--- + +# Konfiguration über Umgebungsvariablen + +SOLECTRUS wird über Umgebungsvariablen konfiguriert. Diese stehen in der Datei `.env` im gleichen Verzeichnis wie die `compose.yml`. Jeder Container hat seine eigenen Variablen, mache Variablen werden von verschiedenen Containern benutzt. + +Es ist zu beachten, dass die Umgebungsvariablen nicht nur in der `.env` definiert werden, sondern auch in der `compose.yml` aufgeführt werden (als Auflistung im Abschnitt `environment` des Services `mqtt-collector`). Andernfalls sind sie für den Collector nicht erreichbar. + +Nach einer Bearbeitung von `.env` oder `compose.yml` müssen die Container neu erstellt werden, um die Änderungen zu übernehmen. Dies geschieht mit dem Befehl `docker compose up -d` (bei älteren Docker-Versionen `docker-compose up -d`, also mit Bindestrich). + +Es folgt eine Auflistung der für den MQTT-Collector definierten Umgebungsvariablen, gültig ab Version `v0.2.0`. + +## Zugang zum MQTT-Broker + +- `MQTT_HOST` + + Hostname des MQTT-Brokers. Dies kann die IP-Adresse des lokal erreichbaren ioBroker sein, aber auch die Domain eines extern erreichbaren Brokers. Darf **kein** `http://` oder `https://` enthalten! + +- `MQTT_PORT` + + Port des MQTT-Brokers. Meist ist das `1883`. + +- `MQTT_SSL` (standardmäßig `false`) + + Wenn der MQTT-Broker über TLS abgesichert ist, muss dieser Wert auf `true` gesetzt werden. Bei einem lokalen ioBroker ist das üblicherweise nicht der Fall, die Angabe kann dann entfallen oder auf `false` gesetzt werden. + +- `MQTT_USERNAME` (optional) + + Falls erforderlich: Benutzername für den Zugriff auf den MQTT-Broker. + +- `MQTT_PASSWORD` (optional) + + Falls erforderlich: Passwort für den Zugriff auf den MQTT-Broker. + +## Zugriff auf InfluxDB + +- `INFLUX_HOST` + + Hostname des InfluxDB-Servers. Im Normalfall, wenn InfluxDB im gleichen Docker-Netzwerk läuft, ist das der Name des Containers (z.B. `influxdb`). Es kann aber auch ein externer InfluxDB-Server sein, z.B. `influxdb.example.com`. + +- `INFLUX_SCHEMA` (standardmäßig `http`) + + Schema für die Verbindung zu InfluxDB. Bei Verwendung einer externen InfluxDB, die über TLS abgesichert ist, muss dieser Wert auf `https` gesetzt werden. + +- `INFLUX_PORT` (standardmäßig `8086`) + + Port für die Verbindung zu InfluxDB. Bei Verwendung einer externen InfluxDB könnte eine Anpassung erforderlich sein, z.B. auf `443`. + +- `INFLUX_ORG` + + Organisation in InfluxDB, in der die Daten gespeichert werden sollen. + +- `INFLUX_BUCKET` + + Bucket in InfluxDB, in der die Daten gespeichert werden sollen. + +- `INFLUX_TOKEN` + + Token für den Zugriff auf InfluxDB. Dieser Token muss in InfluxDB erstellt werden und die Berechtigung haben, Daten in den angegebenen Bucket zu **schreiben**. + +## Abonnieren von MQTT-Nachrichten + +Der MQTT-Collector kann Nachrichten von verschiedenen (beliebig vielen) Topics abonnieren, verarbeiten und dann in die InfluxDB schreiben. Dazu werden Zuordnungen ("Mappings") definiert und für jedes Mapping drei Dinge festgelegt: + +- Wo kommt der Wert her, also welches "Topic" muss abonniert werden? +- Welche Verarbeitung ist notwendig (Vorzeichen-Behandlung, Datentyp-Konvertierung, JSON-Extraktion, Formelbildung)? +- Wohin in der InfluxDB soll der ermittelte Wert geschrieben werden (Measurement und Field)? + +Jedes Mapping wird durch mehrere Umgebungsvariablen definiert, die mit dem Präfix `MAPPING_X_` beginnen, wobei `X` eine Zahl ab 0 sein sollte (was aber nicht zwingend ist). Sinnvoll, aber ebenfalls nicht zwingend ist, dass die Mappings in aufsteigender Reihenfolge definiert werden. + +### Mögliche Umgebungsvariable je Mapping + +Für jedes einzelne Mapping stehen verschiedene Umgebungsvariablen zur Verfügung, von denen einige optional sind: + +- `MAPPING_X_TOPIC` + + Das Topic, das abonniert werden soll, z.B. `senec/0/ENERGY/GUI_INVERTER_POWER`. + +- `MAPPING_X_JSON_KEY` (optional) + + Falls das Topic einen JSON-Payload (mit **nicht** verschachtelten key/value-Paaren) enthält, kann hier der Schlüssel angegeben werden, aus dem der Wert extrahiert werden soll. Ein Schlüssel ist immer ein String, z.B. `inverter_power`. + +- `MAPPING_X_JSON_PATH` (optional) + + Falls das Topic einen komplexen (z.B. verschachtelten) JSON-Payload enthält, kann hier der [JSONPath](https://goessner.net/articles/JsonPath/) angegeben werden, um den Wert zu extrahieren. Ein JSONPath beginnt immer mit `$.`, z.B. `$.example.foo.bar[2]`. + +- `MAPPING_X_JSON_FORMULA` (optional) + + Falls das Topic JSON liefert, kann ein Berechnungsschritt erfolgen, um den zu speichernden Messwert zu ermitteln. Hierzu muss eine Formel angegeben werden, die [einige mathematische Operationen](https://github.com/rubysolo/dentaku?tab=readme-ov-file#built-in-operators-and-functions) enthalten darf, z.B. `round({value} * 1.5`). + + Die geschweiften Klammern `{}` dienen dazu, Werte aus dem JSON-Payload zu referenzieren. Es können dabei einfache Schlüssel oder JSONPath verwendet werden. + +- `MAPPING_X_MEASUREMENT` + + Der Name des InfluxDB-Measurement, in das der Wert geschrieben werden soll (unabhängig davon, ob er positiv oder negativ ist). + +- `MAPPING_X_MEASUREMENT_POSITIVE` (optional) + + Name des InfluxDB-Measurement, in das der Wert geschrieben werden soll, wenn er **positiv** ist. Andernfalls (also wenn er negativ oder `0` ist), wird `0` geschrieben. + +- `MAPPING_X_MEASUREMENT_NEGATIVE` + + Der Name des InfluxDB-Measurement, in das der (absolute) Wert geschrieben werden soll, wenn er **negativ** ist. Andernfalls (also wenn er positiv oder `0` ist), wird `0` geschrieben. + +- `MAPPING_X_FIELD` + + Der Name des InfluxDB-Feldes, in das der Wert geschrieben werden soll. + +- `MAPPING_X_FIELD_POSITIVE` (optional) + + Name des InfluxDB-Field, in das der Wert geschrieben werden soll, wenn er **positiv** ist. Andernfalls (also wenn er negativ oder `0` ist), wird `0` geschrieben. + +- `MAPPING_X_FIELD_NEGATIVE` (optional) + + Name des InfluxDB-Field, in das der Wert geschrieben werden soll, wenn er **negativ** ist. Andernfalls (also wenn er positiv oder `0` ist), wird `0` geschrieben. + +- `MAPPING_X_TYPE` + + Der Datentyp des Feldes. Möglich sind: `integer`, `float`, `string` oder `boolean`. + +- `MAPPING_X_MIN` (optional, ab `v0.3.0`) + + Untererer Grenzwert für Messwerte. Wird ein Wert unterhalb dieses Grenzwerts empfangen, wird er ignoriert und **nicht** in die InfluxDB geschrieben. Nützlich für Ausreißer oder offensichtlich fehlerhafte Werte, die sonst die Statistik verfälschen würden. + +- `MAPPING_X_MAX` (optional, ab `v0.3.0`) + + Oberer Grenzwert für Messwerte. Wird ein Wert oberhalb dieses Grenzwerts empfangen, wird er ignoriert und **nicht** in die InfluxDB geschrieben. Nützlich für Ausreißer oder offensichtlich fehlerhafte Werte, die sonst die Statistik verfälschen würden. + +### Beispiele + +#### 1. Einfaches Mapping + +Topic wird abonniert, der erhaltene Wert wird unverändert als Float in die InfluxDB geschrieben: + +```env +MAPPING_0_TOPIC=senec/0/ENERGY/GUI_INVERTER_POWER +MAPPING_0_MEASUREMENT=PV +MAPPING_0_FIELD=inverter_power +MAPPING_0_TYPE=float +``` + +#### 2. Mapping mit Vorzeichen-Behandlung + +Wenn die Werte des Topics positiv oder negativ sein können, erfolgt hier eine Aufteilung. Positive Werte werden in `grid_import_power` geschrieben, negative Werte in `grid_export_power`. + +```env +MAPPING_1_TOPIC=senec/0/ENERGY/GUI_GRID_POW +MAPPING_1_MEASUREMENT_POSITIVE=PV +MAPPING_1_MEASUREMENT_NEGATIVE=PV +MAPPING_1_FIELD_POSITIVE=grid_import_power +MAPPING_1_FIELD_NEGATIVE=grid_export_power +MAPPING_1_TYPE=float +``` + +- Falls der empfangene Wert positiv ist (z.B. `1000`): `grid_import_power` wird auf `1000` gesetzt, `grid_export_power` auf `0`. +- Falls der empfangene Wert negativ ist (z.B. `-500`): `grid_import_power` wird auf `0` gesetzt, `grid_export_power` auf `500`. +- Falls der empfangene Wert `0` ist: `grid_import_power` und `grid_export_power` werden beide auf `0` gesetzt. + +#### 3. Mapping mit einfachem JSON-Payload + +Verwendung von `JSON_KEY`: + +```env +MAPPING_2_TOPIC=my/little/nuclear/plant +MAPPING_2_JSON_KEY=radiation_level +MAPPING_2_MEASUREMENT=nuclear_power_plant +MAPPING_2_FIELD=radiation_level +MAPPING_2_TYPE=float +``` + +Aus einem JSON von beispielsweise `{"radiation_level": 90.5, "reactivity": 0.7}` resultiert der Wert `90.5`. + +#### 4. Mapping mit komplexem JSON-Payload + +Verwendung von `JSON_PATH`: + +```env +MAPPING_3_TOPIC=go-e/ATTR +MAPPING_3_JSON_PATH=$.ccp[2] +MAPPING_3_MEASUREMENT=WALLBOX +MAPPING_3_FIELD=power +MAPPING_3_TYPE=float +``` + +Dies extrahiert den Wert aus einem Payload wie `{"ccp": [1,2,42,3]}`. In diesem Beispiel gibt es den Wert an der Stelle 2 (drittes Element) des Arrays `ccp` zurück, der `42` ist. + +#### 5. Mapping mit Formel + +```env +MAPPING_4_TOPIC=my/little/nuclear/plant +MAPPING_4_JSON_FORMULA="round({reactivity} * {radiation_level}) + 42" +MAPPING_4_MEASUREMENT=nuclear_power_plant +MAPPING_4_FIELD=danger_level +MAPPING_4_TYPE=float +``` + +Aus einem JSON von z.B. `{"radiation_level": 90.5, "reactivity": 0.7}` entsteht `danger_level` mit `round(0.7 * 90.5) + 42`, also `105`. + +#### 6. Mapping mit Grenzwerten + +```env +MAPPING_0_TOPIC=senec/0/ENERGY/GUI_INVERTER_POWER +MAPPING_0_MEASUREMENT=PV +MAPPING_0_FIELD=inverter_power +MAPPING_0_TYPE=float +MAPPING_0_MIN=5 +MAPPING_0_MAX=15000 +``` + +Werte unter `5` oder über `15000` werden ignoriert und nicht in die InfluxDB geschrieben. diff --git a/komponenten/postgresql/index.md b/komponenten/postgresql/index.md new file mode 100644 index 0000000..fca51a9 --- /dev/null +++ b/komponenten/postgresql/index.md @@ -0,0 +1,17 @@ +--- +title: PostgreSQL +layout: page +parent: Komponenten +nav_order: 11 +--- + +SOLECTRUS speichert sämtliche sonstigen Daten (Einstellungen, Strompreise, Registrierung) in der OpenSource-Datenbank **PostgreSQL** ab. Unterstützt wird die Version 12 oder höher, wobei für eine Neuinstallation die Version **16** empfohlen wird. + +PostgreSQL erscheint jährlich in einer neuen Major-Version. Ein Upgrade ist aber nicht so einfach vorzunehmen, weil es ein Backup/Restore erfordert. Da die Vorteile einer neuen Version überschaubar sind, kann problemlos bei einer älteren Version verblieben werden, für die es üblicherweise fünf Jahre lang Minor-Updates gibt. + +{: .warning } + +Keineswegs darf bei Verfügbarkeit einer neuen Version von PostgreSQL einfach die neue Versionsnummer in die `compose.yaml` eingetragen werden. PostgreSQL wird dann nicht mehr starten! + +Offizielles Docker-Image: \ +[https://hub.docker.com/\_/postgres](https://hub.docker.com/_/postgres) diff --git a/komponenten/postgresql/konfiguration.md b/komponenten/postgresql/konfiguration.md new file mode 100644 index 0000000..087af11 --- /dev/null +++ b/komponenten/postgresql/konfiguration.md @@ -0,0 +1,62 @@ +--- +title: Konfiguration +layout: page +parent: PostgreSQL +--- + +## compose.yaml + +```yaml +services: + postgresql: + image: postgres:16-alpine + environment: + - TZ + - POSTGRES_PASSWORD + volumes: + - ${DB_VOLUME_PATH}:/var/lib/postgresql/data + restart: unless-stopped + healthcheck: + test: + - CMD-SHELL + - pg_isready -U postgres + interval: 10s + timeout: 20s + retries: 5 + start_period: 60s + logging: + options: + max-size: 10m + max-file: '3' + labels: + - com.centurylinklabs.watchtower.scope=solectrus + + watchtower: + # ... +``` + +## Umgebungsvariablen + +- `TZ` + + Zeitzone gemäß [Liste](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) + +- `POSTGRES_PASSWORD` + + Passwort für den internen Benutzer `postgres`. Da die Datenbank nicht von außen erreichbar ist, ist das Passwort nicht sonderlich kritisch, es muss aber auf einen Wert gesetzt werden. + + Wird beim ersten Start gesetzt und darf danach nicht mehr geändert werden! + +- `DB_VOLUME_PATH` + + Pfad für die Dateiablage der Datenbank. + + Wird beim ersten Start angelegt und darf nicht mehr geändert werden. + +## Beispielhafte .env + +```properties +TZ=Europe/Berlin +POSTGRES_PASSWORD=geheimes-datenbank-passwort +DB_VOLUME_PATH=./postgresql +``` diff --git a/komponenten/power-splitter/index.md b/komponenten/power-splitter/index.md new file mode 100644 index 0000000..ac9d19d --- /dev/null +++ b/komponenten/power-splitter/index.md @@ -0,0 +1,97 @@ +--- +title: Power-Splitter +layout: page +parent: Komponenten +nav_order: 6 +--- + +# Verwendung für SOLECTRUS + +Der Power-Splitter analysiert den Stromverbrauch großer Verbraucher (E-Auto, Wärmepumpe, Haus). Der gemessene Verbrauch wird aufgeteilt in den Anteil, der mit Photovoltaik-Strom gedeckt wird und den Anteil, der aus dem Netz bezogen wird. Daraus ergeben sich interessante Einblicke in die Verbrauchskosten, die sonst so nicht möglich waren. + +Zunächst ein paar wichtige Hinweise: + +- Der Power-Splitter ergibt nur Sinn, wenn man ein E-Auto und/oder eine Wärmepumpe hat (also **nicht** zwingend beides) und erfolgreich an SOLECTRUS angebunden hat. Wer also **beides nicht** hat, für den ist es uninteressant, weil es dann nichts aufzuteilen gibt. + +- Die Berechnung erfolgt für sämtliche Verbrauchswerte von Wärmepumpe und/oder E-Auto, die in der InfluxDB vorhanden sind. Das bedeutet, dass nicht nur zukünftige Messwerte, sondern **auch die Messwerte der Vergangenheit** berücksichtigt werden. + +- Für die Berechnung kommt ein neuer Docker-Container (der eigentliche "Power-Splitter") zum Einsatz. Dieser läuft permanent im Hintergrund, berechnet die Aufteilung und schreibt sie in ein neues Measurement der InfluxDB. + +## Inbetriebnahme des Power-Splitters + +1. Stelle sicher, dass du ein E-Auto und/oder eine Wärmepumpe an SOLECTRUS angebunden hast. Deren Messwerte müssen also in deiner SOLECTRUS-Instanz sichtbar sein. + +2. Prüfe, ob die [neue Sensor-Konfiguration](https://github.com/solectrus/solectrus/wiki/Konfiguration#sensor-konfiguration) bei dir vorhanden ist. Das ist der Fall, wenn du zur Installation den neuen [Konfigurator](https://configurator.solectrus.de/) verwendet hast. Wenn du schon länger mit dabei ist, hast du vermutlich noch die alte Konfiguration (von Version `0.14.5` oder früher), das muss vorher [angepasst werden](https://github.com/solectrus/solectrus/wiki/Umstellung-auf-neue-Sensor%E2%80%90Konfiguration). + + Das bedeutet: Beim Start der Docker-Container von SOLECTRUS dürfen keine Warnungen bezüglich fehlender Sensoren im Log erscheinen. Falls doch, müssen diese zunächst behoben werden. Im Log steht genau, wie das geht. + + Es müssen also folgende ENV-Variablen (mit Werten) in der `.env`-Datei enthalten sein: + + - `INFLUX_SENSOR_GRID_IMPORT_POWER` + - `INFLUX_SENSOR_HOUSE_POWER` + - `INFLUX_SENSOR_WALLBOX_POWER` und/oder `INFLUX_SENSOR_HEATPUMP_POWER` + + Mehr [Infos zur Konfiguration](https://github.com/solectrus/power-splitter/wiki/Konfiguration) finden sich in einem separaten Artikel. + + Üblicherweise gibt es weitere Sensoren in der `.env`, die sind für den Power-Splitter aber nicht relevant. + +3. Stelle sicher, dass du Version `0.16.0` oder neuer von SOLECTRUS verwendest. + +4. Jetzt kommt der wichtigste Punkt: Bearbeite die `docker-compose.yml` (oder `compose.yml`) und ergänze den Power-Splitter als zusätzlichen Service. Achte unbedingt (!) auf die richtige Einrückung mit Leerzeichen. + + ```yaml + services: + # ... + power-splitter: + image: ghcr.io/solectrus/power-splitter:latest + labels: + - com.centurylinklabs.watchtower.scope=solectrus + environment: + - TZ + - INFLUX_HOST + - INFLUX_SCHEMA + - INFLUX_TOKEN=${INFLUX_ADMIN_TOKEN} + - INFLUX_PORT + - INFLUX_ORG + - INFLUX_BUCKET + - INFLUX_SENSOR_GRID_IMPORT_POWER + - INFLUX_SENSOR_HOUSE_POWER + - INFLUX_SENSOR_WALLBOX_POWER + - INFLUX_SENSOR_HEATPUMP_POWER + - INFLUX_EXCLUDE_FROM_HOUSE_POWER + - POWER_SPLITTER_INTERVAL + - REDIS_URL=redis://redis:6379/1 + links: + - influxdb + - redis + depends_on: + influxdb: + condition: service_healthy + redis: + condition: service_healthy + restart: unless-stopped + ``` + + Der Power-Splitter liest aus der InfluxDB die Messwerte der Verbraucher sowie des Netzbezugs und schreibt die Aufteilung in ein neues Measurement mit der (unveränderlichen) Bezeichnung `power_splitter`. + + Wichtig beim `INFLUX_TOKEN` ist, dass dieses sowohl zum Schreiben als auch zum Lesen berechtigt. Du kannst das Admin-Token nehmen (wie oben angegeben) oder selbst ein neues Token im InfluxDB-Frontend anlegen (letzteres lohnt sich aber nur für bei hohen Sicherheitsanforderungen). + + Die `REDIS_URL` wird benötigt, um nach dem ersten Durchlauf einmalig den Cache leeren zu können. + + Wenn du eine verteilte Installation betreibst (Lokal + Cloud), solltest du den Service auf dem Cloud-Host installieren - also da, wo die InfluxDB läuft. Das reduziert den Traffic. + +5. Starte die Container erneut mit `docker compose up -d`, diesmal wird der Power-Splitter mit gestartet. + + Wenn sich die Container gar nicht starten lassen sollten, hast du vermutlich den Service nicht richtig in die `docker-compose.yml` (oder `compose.yml`) eingefügt. Prüfe insbesondere die Einrückung, das ist bei YAML-Dateien äußerst wichtig. + + Verfolge nun die Log-Ausgabe des neuen Containers mit folgendem Befehl:\ + `docker compose logs power-splitter -f` (kann beendet werden mit `Strg+C`) + + Wenn du irgendwelche Fehlermeldungen siehst, kümmere dich zunächst darum, bevor du fortfährst. + + Wenn alles fehlerfrei läuft, wird der Power-Splitter zunächst die Daten der Vergangenheit bearbeiten, anschließend im Hintergrund weiterlaufen und jeweils den aktuellen Tag berechnen. Dies lässt sich alles genau im Log nachvollziehen. Es ist empfehlenswert, das zu tun. Nach einer gewissen Zeit (abhängig von Rechenpower und Datenmenge) wird die Berechnung der Vergangenheit abgeschlossen sein. + +Geschafft :-) Wenn du in SOLECTRUS jetzt einen Zeitraum auswählst (Tag/Woche/Monat/Jahr/Gesamt), siehst du bei Haus, E-Auto und Wärmepumpe (sofern vorhanden) jeweils im Tooltip die Aufteilung des Verbrauchs. Außerdem erscheinen deren Diagramme in einer gestapelten Darstellung. + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/power-splitter](https://github.com/solectrus/power-splitter) diff --git a/komponenten/power-splitter/konfiguration.md b/komponenten/power-splitter/konfiguration.md new file mode 100644 index 0000000..cbd156e --- /dev/null +++ b/komponenten/power-splitter/konfiguration.md @@ -0,0 +1,61 @@ +--- +title: Konfiguration +layout: page +parent: Power-Splitter +--- + +# Konfiguration über Umgebungsvariablen + +SOLECTRUS wird über Umgebungsvariablen konfiguriert. Diese stehen in der Datei `.env` im gleichen Verzeichnis wie die `compose.yml`. Jeder Container hat seine eigenen Variablen, mache Variablen werden von verschiedenen Containern benutzt. + +Es ist zu beachten, dass die Umgebungsvariablen nicht nur in der `.env` definiert werden, sondern auch in der `compose.yml` aufgeführt werden (als Auflistung im Abschnitt `environment` des Services `power-splitter`). Andernfalls sind sie für den Collector nicht erreichbar. + +Nach einer Bearbeitung von `.env` oder `compose.yml` müssen die Container neu erstellt werden, um die Änderungen zu übernehmen. Dies geschieht mit dem Befehl `docker compose up -d` (bei älteren Docker-Versionen `docker-compose up -d`, also mit Bindestrich). + +Es folgt eine Auflistung der für den Power-Splitter definierten Umgebungsvariablen. + +## Zugriff auf InfluxDB + +- `INFLUX_HOST` + + Hostname des InfluxDB-Servers. Im Normalfall, wenn InfluxDB im gleichen Docker-Netzwerk läuft, ist das der Name des Containers (z.B. `influxdb`). Es kann aber auch ein externer InfluxDB-Server sein, z.B. `influxdb.example.com`. + +- `INFLUX_SCHEMA` (standardmäßig `http`) + + Schema für die Verbindung zu InfluxDB. Bei Verwendung einer externen InfluxDB, die über TLS abgesichert ist, muss dieser Wert auf `https` gesetzt werden. + +- `INFLUX_PORT` (standardmäßig `8086`) + + Port für die Verbindung zu InfluxDB. Bei Verwendung einer externen InfluxDB könnte eine Anpassung erforderlich sein, z.B. auf `443`. + +- `INFLUX_ORG` + + Organisation in InfluxDB, in der die Daten gespeichert werden sollen. + +- `INFLUX_BUCKET` + + Bucket in InfluxDB, in der die Daten gespeichert werden sollen. + +- `INFLUX_TOKEN` + + Token für den Zugriff auf InfluxDB. Dieser Token muss in InfluxDB erstellt werden und die Berechtigung haben, Daten in den angegebenen Bucket zu **lesen** und zu **schreiben**. Der Einfachheit kann man das `INFLUX_ADMIN_TOKEN` nehmen. + +## Sensor-Mapping + +Der Power-Splitter benötigt Zugriff auf einige Sensoren, die auch vom Dashboard werden. Im Einzelnen sind dies: + +- `INFLUX_SENSOR_GRID_IMPORT_POWER` +- `INFLUX_SENSOR_HOUSE_POWER` +- `INFLUX_SENSOR_WALLBOX_POWER` +- `INFLUX_SENSOR_HEATPUMP_POWER` +- `INFLUX_EXCLUDE_FROM_HOUSE_POWER` + +Es genügt also, wenn man diese fünf Variablen in der compoose.yml aufführt und somit den Zugriff ermöglicht. Es ist nicht notwendig und auch nicht sinnvoll, für den Power-Splitter eigene Werte zu definieren. + +## Optionales + +- `POWER_SPLITTER_INTERVAL` (standardmäßig `3600` = 1 Stunde, Minimum `300` = 5 Minuten) + + Häufigkeit der Berechnung durch den Power-Splitter. Bei kleineren Werten wird der Power-Splitter häufiger ausgeführt, was nicht zu einer genaueren Berechnung führt, aber zu einer erhöhten Aktualität. Bemerken wird man den Unterschied nur in der Anzeige des aktuellen Tages im Dashboard. Beim Standardwert von `3600` ist der dargestellte Wert um bis zu einer Stunde veraltet. + + Ein niedriger Wert führt zu einer etwas höheren Auslastung des Systems, die Standardvorgabe ist daher konservativ gewählt. diff --git a/komponenten/redis/index.md b/komponenten/redis/index.md new file mode 100644 index 0000000..a1fb0b5 --- /dev/null +++ b/komponenten/redis/index.md @@ -0,0 +1,23 @@ +--- +title: Redis +layout: page +parent: Komponenten +nav_order: 12 +--- + +SOLECTRUS speichert Cache-Daten in der OpenSource-Datenbank **Redis** ab. Unterstützt wird die Version 5 oder höher, wobei die aktuelle Version **7** empfohlen wird. + +Redis hält sämtliche Daten im Arbeitsspeicher, wodurch es sehr schnell ist. Es ist daher ideal für das Caching geeignet. + +SOLECTRUS nutzt Redis insbesondere, um InfluxDB zu entlasten. Jede Abfrage an InfluxDB wird eine gewisse Zeit (oder dauerhaft) im Cache gespeichert. + +Wenn Redis beendet wird, gehen die Daten nicht verloren, sondern Redis speichert sie in einer Datei ab. Beim nächsten Start werden die Daten wieder eingelesen. Das ist der einzige Grund, warum Redis ein Volume für die Dateiablage benötigt. + +Der Cache kann bei Bedarf auch gelöscht werden: + +```shell +docker compose exec redis redis-cli FLUSHALL +``` + +Offizielles Docker-Image: \ +[https://hub.docker.com/\_/redis](https://hub.docker.com/_/redis) diff --git a/komponenten/redis/konfiguration.md b/komponenten/redis/konfiguration.md new file mode 100644 index 0000000..ebd1f08 --- /dev/null +++ b/komponenten/redis/konfiguration.md @@ -0,0 +1,48 @@ +--- +title: Konfiguration +layout: page +parent: Redis +--- + +## compose.yaml + +```yaml +services: + redis: + image: redis:7-alpine + environment: + - TZ + volumes: + - ${REDIS_VOLUME_PATH}:/data + restart: unless-stopped + healthcheck: + test: + - CMD + - redis-cli + - ping + interval: 10s + timeout: 20s + retries: 5 + start_period: 60s + logging: + options: + max-size: 10m + max-file: '3' + labels: + - com.centurylinklabs.watchtower.scope=solectrus + + watchtower: + # ... +``` + +## Umgebungsvariablen + +- `REDIS_VOLUME_PATH` + + Pfad für die Dateiablage der Datenbank, genutzt nur für die Persistenz beim Herunterfahren. + +## Beispielhafte .env + +```properties +REDIS_VOLUME_PATH=./redis +``` diff --git a/komponenten/senec-charger/index.md b/komponenten/senec-charger/index.md new file mode 100644 index 0000000..82ce6a9 --- /dev/null +++ b/komponenten/senec-charger/index.md @@ -0,0 +1,25 @@ +--- +title: SENEC-Charger +layout: page +parent: Komponenten +nav_order: 8 +--- + +Der **SENEC-Charger** ist eine Komponente, die einen SENEC-Stromspeicher bei Verwendung eines dynamischen Stromtarifs (von [Tibber](https://tibber.com/de)) aus dem Netz belädt, wenn dies lohnenswert ist. + +Die Beladung erfolgt unter folgenden Bedingungen: + +- Der Strompreis ist gerade besonders günstig (ermittelt über den [Tibber-Collector](/komponenten/tibber-collector/)) +- Es ist nur wenig Solarstrom zu erwarten (ermittelt über den [Forecast-Collector/](/komponenten/forecast-collector/)) +- Der Speicher ist leer + +Ob die Bedingung erfüllt ist, wird in regelmäßigen Abständen überprüft (normalerweise stündlich). Es Docker-Log wird genau protokolliert und begründet, ob eine Netzbeladung ausgelöst wurde oder nicht. + +Der SENEC-Charger kann auch im "Trockenlauf" betrieben werden, d.h. es wird nur simuliert, ob der Speicher beladen werden würde. + +{: .note } + +Da für die Beladung des Speichers ein direkter Zugriff auf den SENEC-Stromspeicher notwendig ist, funktioniert dies leider nicht mit dem Home 4 oder neuer. Es wird ausschließlich der SENEC V2.1 und V3 unterstützt. + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/senec-charger](https://github.com/solectrus/senec-charger) diff --git a/komponenten/senec-charger/konfiguration.md b/komponenten/senec-charger/konfiguration.md new file mode 100644 index 0000000..76d3c17 --- /dev/null +++ b/komponenten/senec-charger/konfiguration.md @@ -0,0 +1,87 @@ +--- +title: Konfiguration +layout: page +parent: SENEC-Charger +--- + +Der SENEC-Charger wird in das Gesamt-Setup von Solectrus integriert, d.h. die bestehenden Dateien `compose.yaml` und `.env` müssen erweitert werden. Hier nur die relevanten Teile: + +## compose.yaml + +```yaml +services: + senec-charger: + image: ghcr.io/solectrus/senec-charger:latest + depends_on: + influxdb: + condition: service_healthy + links: + - influxdb + environment: + - TZ + - SENEC_HOST + - SENEC_SCHEMA + - CHARGER_INTERVAL + - CHARGER_PRICE_MAX + - CHARGER_PRICE_TIME_RANGE + - CHARGER_FORECAST_THRESHOLD + - CHARGER_DRY_RUN + - INFLUX_HOST=influxdb + - INFLUX_TOKEN=${INFLUX_TOKEN_READ} + - INFLUX_ORG + - INFLUX_BUCKET + - INFLUX_MEASUREMENT_PRICES + - INFLUX_MEASUREMENT_FORECAST + restart: unless-stopped + + influxdb: + # ... + + tibber-collector: + # ... + + forecast-collector: + # ... +``` + +## .env + +```properties +# Verbindung zum SENEC.Home V3 oder V2.1 +SENEC_HOST=192.168.1.1 +SENEC_SCHEMA=https + +# Intervall in Sekunden für die Überprüfung des Ladevorgangs +CHARGER_INTERVAL=3600 + +# Maximaler Durchschnittspreis pro kWh im Vergleich zum Durchschnittspreis in der nahen Zukunft (bis zu 24 Stunden) +CHARGER_PRICE_MAX=70 + +# Wie lange braucht der Akku für eine volle Ladung? +CHARGER_PRICE_TIME_RANGE=4 + +# Ab welchem erwarteten PV-Ertrag (in kWh) in den nächsten 24 Stunden sollte das Laden NICHT aus dem Netz erfolgen? +CHARGER_FORECAST_THRESHOLD=20 + +# Trockenlauf-Modus: Der Ladevorgang wird nicht gestartet (Standard: false) +# CHARGER_DRY_RUN=true + +# Zugangsdaten für InfluxDB +INFLUX_HOST=influxdb.example.com +INFLUX_SCHEMA=https +INFLUX_PORT=443 +INFLUX_ADMIN_TOKEN=my-super-secret-admin-token +INFLUX_TOKEN_WRITE=${INFLUX_ADMIN_TOKEN} +INFLUX_TOKEN_READ=${INFLUX_ADMIN_TOKEN} +INFLUX_ORG=my-org +INFLUX_PASSWORD=my-password +INFLUX_USERNAME=my-user + +# InfluxDB bucket und measurements +INFLUX_BUCKET=my-bucket +INFLUX_MEASUREMENT_PRICES=my-prices +INFLUX_MEASUREMENT_FORECAST=my-forecast + +# Zeitzone +TZ=Europe/Berlin +``` diff --git a/komponenten/senec-collector/index.md b/komponenten/senec-collector/index.md new file mode 100644 index 0000000..ffaba20 --- /dev/null +++ b/komponenten/senec-collector/index.md @@ -0,0 +1,21 @@ +--- +title: SENEC-Collector +layout: page +parent: Komponenten +nav_order: 2 +--- + +Der **SENEC-Collector** ist eine Komponente, die Daten von einem SENEC-Stromspeicher ausliest und in eine InfluxDB schreibt. + +Grundsätzlich sind zwei verschiedene Betriebsmodi (Adapter) möglich: + +- **Lokal:** Direkter Zugriff auf den SENEC-Stromspeicher über dessen lokale IP-Adresse. Die Daten werden über die lala.cgi-Schnittstelle ausgelesen. Möglich ist das für den V2.1 und V3, nicht aber beim Home 4 (dieser hat diese Schnittstelle nicht). Ein Auslesen der Messwerte ist in einem kurzen Intervall möglich, vorgegeben sind 5 Sekunden. + +- **Cloud:** Der SENEC-Collector liest die Daten aus der SENEC-Cloud aus und verwendet dazu die Schnittstelle, die von SENEC für die App bereitgestellt wird, d.h. es sind die SENEC-Zugangsdaten anzugeben (E-Mail und Passwort). Möglich ist das auch für den Home 4. Das Auslesen der Messwerte ist nur einem einem längeren Intervall erlaubt, das vom Gerät abhängt. Beim Home 4 ist eine Abfrage im 1m-Takt möglich, beim V2.1 und V3 im 5-Minuten-Takt. + +Beim Home 4 ist es also nicht möglich, den SENEC-Collector im lokalen Modus zu betreiben. Dort ist nur der Cloud-Modus möglich. + +Beim V2.1 und V3 ist es möglich, sich für einen der beiden Adapter frei zu entscheiden. Dies eröffnet die Möglichkeit, SOLECTRUS rein in der Cloud zu betreiben, also ohne einen Raspberry o.ä. im lokalen Netzwerk. Diesem Vorteil steht der Nachteil gegenüber, dass die Daten nicht so häufig aktualisiert werden (einmal alle 5min, statt alle 5s). + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/senec-collector](https://github.com/solectrus/senec-collector) diff --git a/komponenten/senec-collector/konfiguration.md b/komponenten/senec-collector/konfiguration.md new file mode 100644 index 0000000..66cb44d --- /dev/null +++ b/komponenten/senec-collector/konfiguration.md @@ -0,0 +1,107 @@ +--- +title: Konfiguration +layout: page +parent: SENEC-Collector +--- + +Der SENEC-Collector wird in das Gesamt-Setup von SOLECTRUS integriert, d.h. die bestehenden Dateien `compose.yaml` und `.env` müssen erweitert werden. Hier nur die relevanten Teile: + +Erforderlich ist eine Schreibberechtigung auf InfluxDB, um dorthin Messwerte schreiben zu können. + +## compose.yaml + +```yaml +services: + senec-collector: + image: ghcr.io/solectrus/senec-collector:latest + environment: + - TZ + - SENEC_ADAPTER + - SENEC_HOST + - SENEC_SCHEMA + - SENEC_INTERVAL + - SENEC_LANGUAGE + - SENEC_USERNAME + - SENEC_PASSWORD + - INFLUX_HOST + - INFLUX_SCHEMA + - INFLUX_PORT + - INFLUX_TOKEN=${INFLUX_TOKEN_WRITE} + - INFLUX_ORG + - INFLUX_BUCKET + - INFLUX_MEASUREMENT=${SENEC_INFLUX_MEASUREMENT} + restart: unless-stopped + logging: + options: + max-size: 10m + max-file: '3' + depends_on: + influxdb: + condition: service_healthy + links: + - influxdb + labels: + - com.centurylinklabs.watchtower.scope=solectrus + + influxdb: + # ... + + watchtower: + # ... +``` + +## .env + +```properties +# Welcher Adapter soll verwendet werden? +# Werte: local, cloud (Standard: local) +SENEC_ADAPTER=local + +# Die IP-Adresse oder der Hostname Ihres SENEC-Geräts +# Wird nur bei Verwendung des lokalen Adapters genutzt +SENEC_HOST=192.168.178.12 + +# Das zu verwendende Potokoll +# Werte: http, https (Standard: https) +# Wird nur bei Verwendung des lokalen Adapters genutzt +SENEC_SCHEMA=https + +# Die Sprache, die für Status-Texte verwendet werden soll. +# Werte: de, en, it (Standard: de) +# Wird nur bei Verwendung des lokalen Adapters genutzt +SENEC_LANGUAGE=de + +# Anmeldedaten für mein-senec.de +# Wird nur bei Verwendung des Cloud-Adapters genutzt +SENEC_USERNAME=me@example.com +SENEC_PASSWORD=my-senec-password + +# Die System-ID des SENEC-Geräts +# Wird nur bei Verwendung des Cloud-Adapters genutzt +# Kann leer bleiben, wenn es nur ein System gibt. Der Collector ermittelt +# dann die verfügbaren IDs, listet sie im Protokoll auf und verwendet die erste. +SENEC_SYSTEM_ID=123456 + +# Das Intervall in Sekunden für die Häufigkeit der Datenabfrage +# Minimum für den lokalen Adapter ist 5 Sekunden. +# Minimum für den Cloud-Adapter ist 30 Sekunden. +SENEC_INTERVAL=5 + +# Speicherort ("Measurement") für InfluxDB +SENEC_INFLUX_MEASUREMENT=SENEC + +# Optional: Deaktivieren bestimmter Messwerte, die nicht an InfluxDB gesendet werden sollen. +# Dies ist nützlich, wenn einzelne Daten (z.B. Wallbox) aus einer anderen Quelle entnommen werden sollen. +# Komma-getrennte Liste von Feldern, keine Leerzeichen. Beispiel: +# SENEC_IGNORE=wallbox_charge_power,grid_power_minus + +# Zugangsdaten für InfluxDB +INFLUX_HOST=influxdb.example.com +INFLUX_SCHEMA=https +INFLUX_PORT=443 +INFLUX_TOKEN=my-super-secret-write-token +INFLUX_ORG=solectrus + +# Der Name des Buckets in InfluxDB +INFLUX_BUCKET=my-solectrus-bucket +``` diff --git a/komponenten/shelly-collector/index.md b/komponenten/shelly-collector/index.md new file mode 100644 index 0000000..fddb093 --- /dev/null +++ b/komponenten/shelly-collector/index.md @@ -0,0 +1,33 @@ +--- +title: Shelly-Collector +layout: page +parent: Komponenten +nav_order: 4 +--- + +Der **Shelly-Collector** sammelt den Stromverbrauch eines Shelly-Gerätes ein und schreibt diese in die INfluxDB. + +Unterstützt werden Shelly-Geräte der Generation 2, wie diese: + +- Shelly Pro 3EM +- Shelly Plus Plug S + +In Arbeit ist außerdem die Unterstützung für Shelly der Generation 1, wie diese: + +- Shelly EM +- Shelly 3EM +- Shelly Plug S + +Der Collector schreibt die folgenden Messwerte in das angegebene Measurement der InfluxDB: + +- `power` (Stromverbrauch, in Watt) +- `power_a` (Stromverbrauch Phase A, in Watt, sofern vorhanden) +- `power_b` (Stromverbrauch Phase A, in Watt, sofern vorhanden) +- `power_c` (Stromverbrauch Phase A, in Watt, sofern vorhanden) +- `temp` (Temperatur, in °C, sofern vorhanden) +- `response_duration` (Dauer der Antwort, in ms) + +Hat man mehrere Shelly-Geräte, so ist für jedes Gerät ein eigener Collector einzurichten. + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/shelly-collector](https://github.com/solectrus/shelly-collector) diff --git a/komponenten/shelly-collector/konfiguration.md b/komponenten/shelly-collector/konfiguration.md new file mode 100644 index 0000000..76598c5 --- /dev/null +++ b/komponenten/shelly-collector/konfiguration.md @@ -0,0 +1,93 @@ +--- +title: Konfiguration +layout: page +parent: Shelly-Collector +--- + +Der Shelly-Collector wird in das Gesamt-Setup von SOLECTRUS integriert, d.h. die bestehenden Dateien `compose.yaml` und `.env` müssen erweitert werden. Hier nur die relevanten Teile: + +Erforderlich ist eine Schreibberechtigung auf InfluxDB, um dorthin Messwerte schreiben zu können. + +SOLECTRUS wird über Umgebungsvariablen konfiguriert. Diese stehen in der Datei `.env` im gleichen Verzeichnis wie die `compose.yml`. Jeder Container hat seine eigenen Variablen, mache Variablen werden von verschiedenen Containern benutzt. + +Es ist zu beachten, dass die Umgebungsvariablen nicht nur in der `.env` definiert werden, sondern auch in der `compose.yml` aufgeführt werden (als Auflistung im Abschnitt `environment` des Services `shelly-collector`). Andernfalls sind sie für den Collector nicht erreichbar. + +Nach einer Bearbeitung von `.env` oder `compose.yml` müssen die Container neu erstellt werden, um die Änderungen zu übernehmen. Dies geschieht mit dem Befehl `docker compose up -d` (bei älteren Docker-Versionen `docker-compose up -d`, also mit Bindestrich). + +## Zugriff auf InfluxDB + +## compose.yaml + +```yaml +services: + shelly-collector: + image: ghcr.io/solectrus/shelly-collector:latest + environment: + - TZ + - SHELLY_HOST + - SHELLY_INTERVAL + - INFLUX_HOST + - INFLUX_SCHEMA + - INFLUX_PORT + - INFLUX_TOKEN=${INFLUX_TOKEN_WRITE} + - INFLUX_ORG + - INFLUX_BUCKET + - INFLUX_MEASUREMENT=${SHELLY_INFLUX_MEASUREMENT} + logging: + options: + max-size: 10m + max-file: '3' + restart: unless-stopped + depends_on: + influxdb: + condition: service_healthy + links: + - influxdb + labels: + - com.centurylinklabs.watchtower.scope=solectrus + + influxdb: + # ... + + watchtower: + # ... +``` + +## .env + +```properties +# Hostname des Shelly. Dies ist üblicherweise die IP-Adresse, kann aber auch eine +# lokale Domain sein. Darf **kein** `http://` oder `https://` enthalten! +SHELLY_HOST=shelly + +- `SHELLY_INTERVAL` (standardmäßig `5`) + +# Wie oft soll der aktuelle Messwert abgerufen werden? Der Standardwert von `5` ist ein guter Kompromiss, von dem nur in begründeten Fällen abgewichen werden sollte. +SHELLY_INTERVAL=5 + +# Name des Measurements in InfluxDB, das die Messwerte aufnehmen soll +SHELLY_INFLUX_MEASUREMENT=heatpump + +#### Zugangsdaten für InfluxDB + +# Hostname des InfluxDB-Servers. Im Normalfall, wenn InfluxDB im gleichen Docker-Netzwerk läuft, ist das der Name des Containers (z.B. `influxdb`). Es kann aber auch ein externer InfluxDB-Server sein, z.B. `influxdb.example.com`. +INFLUX_HOST=influxdb + +# Schema für die Verbindung zu InfluxDB. Bei Verwendung einer externen InfluxDB, +# die über TLS abgesichert ist, muss dieser Wert auf `https` gesetzt werden. +# (standardmäßig `http`) +INFLUX_SCHEMA=https + + # Port für die Verbindung zu InfluxDB. Bei Verwendung einer externen InfluxDB könnte eine Anpassung erforderlich sein, z.B. auf `443`. + # (standardmäßig `8086`) +INFLUX_PORT=8086 + +# Token für den Zugriff auf InfluxDB. Dieser Token muss in InfluxDB erstellt werden und die Berechtigung haben, Daten in den angegebenen Bucket zu **schreiben**. +INFLUX_TOKEN=my-super-secret-write-token + +# Organisation in InfluxDB, in der die Messwerte gespeichert werden sollen +INFLUX_ORG=solectrus + +# Bucket in InfluxDB, in der die Messwerte gespeichert werden sollen +INFLUX_BUCKET=my-solectrus-bucket +``` diff --git a/komponenten/tibber-collector/index.md b/komponenten/tibber-collector/index.md new file mode 100644 index 0000000..4780044 --- /dev/null +++ b/komponenten/tibber-collector/index.md @@ -0,0 +1,9 @@ +--- +title: Tibber-Collector +layout: page +parent: Komponenten +nav_order: 9 +--- + +Quelltext im GitHub-Repository: \ +[github.com/solectrus/tibber-collector](https://github.com/solectrus/tibber-collector) diff --git a/komponenten/tibber-collector/konfiguration.md b/komponenten/tibber-collector/konfiguration.md new file mode 100644 index 0000000..7b8fb26 --- /dev/null +++ b/komponenten/tibber-collector/konfiguration.md @@ -0,0 +1,7 @@ +--- +title: Konfiguration +layout: page +parent: Tibber-Collector +--- + +todo diff --git a/support.md b/support.md new file mode 100644 index 0000000..e34ea29 --- /dev/null +++ b/support.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Support +nav_order: 5 +--- + +# Wo bekomme ich Unterstützung? + +Nicht immer funktioniert alles so, wie es soll. Wenn es bei der Installation oder dem Betrieb von SOLECTRUS irgendwo hakt, gibt es verschiedene Anlaufstellen: + +Bei technischen Problemen oder Fehlerreports lege bitte ein **Issue** an: \ +[https://github.com/solectrus/solectrus/issues](https://github.com/solectrus/solectrus/issues) + +Für alles andere, z.B. Fragen zur Installation, Verbesserungsvorschläge, Ideen, Lob und Kritik steht der **Diskussionsbereich** zur Verfügung: \ +[https://github.com/solectrus/solectrus/discussions](https://github.com/solectrus/solectrus/discussions) + +Mit der Suchfunktion in GitHub kannst du auch nach bereits bestehenden Problemen oder Diskussionen suchen. Vielleicht wurde dein Problem schon einmal gelöst. + +{: .note } + +Bitte nutze bei Fragen oder Problemen wirklich die oben genannten Kanäle und schreibe **nicht** eine E-Mail. So können auch andere von deinen Fragen und den Antworten profitieren.