iobroker.goodwe-sems 0.1.8 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.de.md ADDED
@@ -0,0 +1,224 @@
1
+ ![Logo](admin/goodwe-sems.png)
2
+
3
+ *[Read this in English](README.md)*
4
+
5
+ # ioBroker.goodwe-sems
6
+
7
+ [![NPM version](https://img.shields.io/npm/v/iobroker.goodwe-sems.svg)](https://www.npmjs.com/package/iobroker.goodwe-sems)
8
+ [![Downloads](https://img.shields.io/npm/dm/iobroker.goodwe-sems.svg)](https://www.npmjs.com/package/iobroker.goodwe-sems)
9
+ ![Test and Release](https://github.com/bueste/ioBroker.goodwe-sems/actions/workflows/test-and-release.yml/badge.svg)
10
+ [![Donate](https://img.shields.io/badge/Spenden-PayPal-00457C?style=flat&logo=paypal&logoColor=white)](https://www.paypal.com/ncp/payment/TT6MTBLXX9L9U)
11
+
12
+ Liest Wechselrichter-, Batterie- und Energiefluss-Daten aus dem **GoodWe SEMS Portal (Cloud)** – für Anlagen, die (z. B. weil kein LAN-Zugriff auf den Wechselrichter besteht) **nicht** mit dem lokalen [ioBroker.goodwe](https://github.com/FossyTom/ioBroker.goodwe)-Adapter (Modbus/UDP, Port 8899) abgefragt werden können.
13
+
14
+ Login erfolgt mit dem **ganz normalen SEMS-Portal-Konto** (dasselbe wie unter semsportal.com / in der SEMS-App). Ein GoodWe-"Organization"/OpenAPI-Konto wird **nicht** benötigt.
15
+
16
+ ## Inhaltsverzeichnis
17
+
18
+ - [Warum dieser Adapter?](#warum-dieser-adapter)
19
+ - [API-Herkunft und Grenzen (bitte lesen)](#api-herkunft-und-grenzen-bitte-lesen)
20
+ - [Installation](#installation)
21
+ - [Konfiguration](#konfiguration)
22
+ - [Objekt-/State-Struktur](#objekt-state-struktur)
23
+ - [Fehlerbehandlung, Backoff und Rate-Limits](#fehlerbehandlung-backoff-und-rate-limits)
24
+ - [Pushover-Benachrichtigungen](#pushover-benachrichtigungen)
25
+ - [Sicherheit & Datenschutz](#sicherheit--datenschutz)
26
+ - [Entwicklung](#entwicklung)
27
+ - [Changelog](#changelog)
28
+ - [Lizenz](#lizenz)
29
+
30
+ ## Warum dieser Adapter?
31
+
32
+ GoodWe ET/EH/BH/BT-Wechselrichter lassen sich normalerweise lokal per Modbus/UDP auslesen (siehe [ioBroker.goodwe](https://github.com/FossyTom/ioBroker.goodwe)). Steht kein LAN-Zugriff auf den Wechselrichter zur Verfügung (z. B. weil nur ein WLAN/LTE-Stick mit dem SEMS-Portal verbunden ist und das Zielnetz nicht erreichbar ist), bleibt nur der Umweg über die Cloud: das **SEMS Portal** (semsportal.com), über das die Anlage ohnehin schon überwacht wird.
33
+
34
+ ## API-Herkunft und Grenzen (bitte lesen)
35
+
36
+ GoodWe bietet offiziell drei APIs an (siehe [GoodWe API Technical Document](https://community.goodwe.com/solution/API)):
37
+
38
+ - **OpenAPI** – nur für SEMS-*Organization*-Konten, erfordert Freischaltung durch GoodWe.
39
+ - **Real-time Data Monitoring API** – für Drittanbieter, erfordert Lizenzvertrag + Geräte-Whitelist.
40
+ - **Batch Remote Control Interface** – Kafka-basiert, nur Fernsteuerung.
41
+
42
+ Für ein **normales** SEMS-Portal-Konto (wie es die meisten Privatanwender haben) ist keine davon zugänglich. Dieser Adapter spricht stattdessen dieselbe **undokumentierte HTTPS-API**, die auch die offizielle SEMS-App/Webseite verwendet (Login via `CrossLogin`/`SEMS+ cross-login`, Datenabfrage via `GetMonitorDetailByPowerstationId`). Diese Endpunkte wurden nicht von GoodWe für Drittnutzung freigegeben oder dokumentiert; die Implementierung basiert auf eigener Analyse sowie den quelloffenen Referenzprojekten:
43
+
44
+ - [pygoodwe](https://github.com/yaleman/pygoodwe) (MIT)
45
+ - [goodwe-sems-home-assistant](https://github.com/TimSoethout/goodwe-sems-home-assistant)
46
+ - [openHAB SEMSPortal-Binding](https://www.openhab.org/addons/bindings/semsportal/)
47
+
48
+ **Konsequenzen:**
49
+
50
+ - GoodWe kann die API jederzeit ohne Vorankündigung ändern - der Adapter kann dadurch (temporär) ausfallen.
51
+ - Es gibt **kein dokumentiertes Echtzeit-/Push-Verfahren** (Websocket/SignalR) für Drittanbieter. Ein `msgSocketAdr`-Feld taucht in älteren Login-Antworten auf, wird aber von keinem der oben genannten Referenzprojekte tatsächlich genutzt - es wäre reines Reverse-Engineering ohne belastbare Dokumentation und ein deutlich höheres Risiko (Kontosperrung, instabile Verbindung). Dieser Adapter pollt daher bewusst per HTTPS in konfigurierbarem Intervall (Default 5 Minuten) statt eine ungetestete Websocket-Verbindung vorzutäuschen.
52
+ - Es wurde ein **Rate-Limit-Code (`GY0429`)** beobachtet (u. a. in der Home-Assistant-Integration dokumentiert). Der Adapter erkennt diesen Code und pausiert automatisch (Default 5 Minuten Cool-down), statt das Konto durch wiederholte Anfragen zu gefährden.
53
+ - Nutzung erfolgt auf eigenes Risiko, siehe [LICENSE](LICENSE) (MIT, ohne Gewährleistung).
54
+
55
+ ## Installation
56
+
57
+ Solange der Adapter noch nicht im offiziellen ioBroker-Repository gelistet ist:
58
+
59
+ ```
60
+ cd /opt/iobroker
61
+ npm install https://github.com/bueste/ioBroker.goodwe-sems/tarball/main
62
+ iobroker add goodwe-sems
63
+ ```
64
+
65
+ ## Konfiguration
66
+
67
+ | Feld | Beschreibung |
68
+ |---|---|
69
+ | SEMS-Konto / Passwort | Dieselben Zugangsdaten wie auf semsportal.com. Passwort wird von ioBroker verschlüsselt gespeichert. |
70
+ | Anlagen-ID (optional) | Leer lassen für automatische Erkennung (`GetPowerStationIdByOwner`). Bei mehreren Anlagen pro Konto: ID manuell aus der Portal-URL übernehmen (`.../powerstation/powerstatussnmin/<ID>`). |
71
+ | Poll-Intervall | Default 300 s. Der Adapter erzwingt ein Minimum von 60 s, unabhängig von der Konfiguration. |
72
+ | Pushover | Siehe [Pushover-Benachrichtigungen](#pushover-benachrichtigungen). |
73
+
74
+ ## Objekt-/State-Struktur
75
+
76
+ ```
77
+ goodwe-sems.0.info.connection SEMS Portal erreichbar (bool)
78
+ goodwe-sems.0.info.lastSuccess Zeitstempel letzter erfolgreicher Poll
79
+ goodwe-sems.0.info.lastError Letzte Fehlermeldung
80
+ goodwe-sems.0.info.consecutiveErrors Anzahl aufeinanderfolgender Fehlversuche
81
+ goodwe-sems.0.info.rateLimited SEMS Portal limitiert aktuell (bool)
82
+ goodwe-sems.0.info.activePollInterval Aktuell wirksames Intervall inkl. Backoff (s)
83
+ goodwe-sems.0.info.rawResponse Rohe JSON-Antwort (nur wenn Debug-Option aktiv)
84
+
85
+ goodwe-sems.0.Station.Name / .Capacity / .Address / .Latitude / .Longitude / .PortalTimestamp / .Status / .StationId
86
+ goodwe-sems.0.KPI.CurrentPower / .TodayGeneration / .MonthGeneration / .TotalGeneration / .TodayIncome / .TotalIncome / .Currency
87
+ goodwe-sems.0.PowerFlow.PV / .Load / .Grid / .Battery / .LoadStatus / .GridStatus / .PvStatus / .BatteryStatus
88
+ goodwe-sems.0.Battery.SOC / .Status
89
+ goodwe-sems.0.EVCharger.* (nur wenn vom Portal gemeldet)
90
+
91
+ goodwe-sems.0.Inverters.<Seriennummer>.Name / .Model / .Status / .WarningCode
92
+ goodwe-sems.0.Inverters.<Seriennummer>.CurrentPower / .TodayGeneration / .TotalGeneration / .Temperature
93
+ goodwe-sems.0.Inverters.<Seriennummer>.PV1..4.Voltage / .Current
94
+ goodwe-sems.0.Inverters.<Seriennummer>.AC_L1..3.Voltage / .Current / .Frequency
95
+ goodwe-sems.0.Inverters.<Seriennummer>.Battery.SOC / .Voltage / .Current
96
+ ```
97
+
98
+ Bei zwei Wechselrichtern (wie in der ursprünglichen Anforderung) entstehen automatisch zwei `Inverters.<SN>.*`-Zweige - die Anzahl ist nicht fest codiert, sondern richtet sich nach dem, was das Portal für das jeweilige Konto zurückliefert.
99
+
100
+ Felder, die das Portal liefert, aber dieser Adapter (noch) nicht kennt, gehen nicht verloren: Mit aktivierter Debug-Option landet die komplette Rohantwort in `info.rawResponse` (JSON), sodass sie inspiziert und bei Bedarf per PR ergänzt werden können.
101
+
102
+ ## Fehlerbehandlung, Backoff und Rate-Limits
103
+
104
+ - Jeder Poll-Zyklus ist vollständig try/catch-abgesichert; ein einzelner Fehler kann die Polling-Schleife nicht dauerhaft stoppen.
105
+ - Fehlerklassen (`SemsAuthError`, `SemsRateLimitError`, `SemsNetworkError`, `SemsProtocolError`) steuern das Verhalten gezielt:
106
+ - **Rate-Limit (`GY0429`)** → sofortige Pause (Default 300 s), `info.rateLimited = true`.
107
+ - **Login-Fehler** → exponentielles Backoff (bis 1 h Deckel), damit falsche Zugangsdaten das Konto nicht zusätzlich belasten.
108
+ - **Netzwerk-/Protokollfehler** → moderates Backoff.
109
+ - Nach konfigurierbar vielen aufeinanderfolgenden Fehlversuchen (Default 3) gilt die Anlage als "offline" und es wird - falls aktiviert - eine Pushover-Meldung ausgelöst.
110
+ - Alles wird zusätzlich strukturiert ins ioBroker-Log geschrieben (`error`/`warn`/`debug` je nach Schweregrad).
111
+
112
+ ## Pushover-Benachrichtigungen
113
+
114
+ Konfigurierbar in drei Modi:
115
+
116
+ 1. **Über eine bestehende `ioBroker.pushover`-Instanz** (`sendTo`) - empfohlen, keine doppelte Zugangsdatenverwaltung.
117
+ 2. **Direkt über die Pushover-API** (eigener User-Key + API-/App-Token, verschlüsselt gespeichert) - funktioniert auch ohne separate Pushover-Instanz.
118
+ 3. **Beides gleichzeitig.**
119
+
120
+ Ausgelöst wird bei: SEMS-Login-Fehler, SEMS-Rate-Limit, länger andauerndem Ausfall, unerwartetem Adapterfehler - jeweils einzeln aktivierbar. Eine interne Sperrfrist (Default 1 h pro Kategorie) verhindert Spam bei andauernden Störungen.
121
+
122
+ ## Sicherheit & Datenschutz
123
+
124
+ - SEMS-Passwort und Pushover-API-Token sind in `io-package.json` als `encryptedNative`/`protectedNative` markiert und werden von ioBroker verschlüsselt abgelegt, nicht im Klartext geloggt (Kontoname wird in Log-Meldungen maskiert, z. B. `st***@gmail.com`).
125
+ - Der Adapter führt **ausschließlich lesende** Zugriffe aus (`GetMonitorDetailByPowerstationId`, `GetPowerStationIdByOwner`). Es gibt bewusst **keine** Fernsteuerungs-/Schreibfunktion (`SaveRemoteControlInverter`) - das wäre ein deutlich größeres Sicherheits- und Haftungsrisiko und war nicht Teil der Anforderung.
126
+ - Keine Drittanbieter-Abhängigkeiten für den HTTP-Zugriff: Es wird das in Node.js ≥18 eingebaute `fetch` verwendet statt einer zusätzlichen HTTP-Bibliothek - kleinere Angriffsfläche, weniger Supply-Chain-Risiko.
127
+ - Alle Netzwerkfehler werden typisiert abgefangen; es werden keine ungeprüften Daten aus der API-Antwort ausgeführt (`eval`, `Function`, o. ä. werden nirgends verwendet).
128
+
129
+ ## Entwicklung
130
+
131
+ ```
132
+ npm install
133
+ npm run lint
134
+ npm test # Unit-Tests (lib/mapping.js, lib/semsApi.js, lib/notify.js) + Package-Konsistenz-Check
135
+ ```
136
+
137
+ Empfehlung vor jedem Release zusätzlich lokal:
138
+
139
+ ```
140
+ npx @iobroker/adapter-checker@latest .
141
+ ```
142
+
143
+ Pull Requests willkommen, insbesondere um zusätzliche, vom Portal gelieferte Felder zu ergänzen (siehe `info.rawResponse` mit aktivierter Debug-Option) oder Übersetzungen zu verbessern.
144
+
145
+ ## Changelog
146
+
147
+ ### **WORK IN PROGRESS**
148
+
149
+ ### 0.1.8 (2026-07-19)
150
+
151
+ ioBroker-Adapter-Check-Befunde behoben:
152
+
153
+ - (Stefan Bühler) **[E254]** News-Einträge für 0.1.1/0.1.2 entfernt - diese Tags wurden zwar gepusht, aber der zugehörige npm-Publish-Job schlug damals fehl (fehlendes NPM_TOKEN bzw. zu alte npm-CLI für OIDC), die Versionen existieren nie auf npm
154
+ - (Stefan Bühler) **[W132]** dadurch automatisch unter dem 7-Einträge-Limit des Repository-Builders für `common.news`
155
+ - (Stefan Bühler) **[W184]** veraltetes `common.title` entfernt (durch `common.titleLang` ersetzt) und veraltetes/ignoriertes `common.main` entfernt (Entry-Point kommt aus `package.json`)
156
+ - (Stefan Bühler) **[W034]** `@iobroker/adapter-core` von ^3.1.6 auf ^3.2.2 angehoben (installiert 3.4.3)
157
+ - (Stefan Bühler) **[W173]/[W174]/[E999]/[W401]**: `password` ist bereits korrekt in `encryptedNative`/`protectedNative` gelistet (per Tarball-Inspektion verifiziert) - diese Meldungen sowie der globale Axios-404-Fehler beim Abruf von `sources-dist-latest.json` sind Nebenwirkungen davon, dass der Adapter noch nicht im offiziellen ioBroker-Repository gelistet ist; sollten nach der Aufnahme verschwinden
158
+
159
+ ### 0.1.7 (2026-07-19)
160
+
161
+ - (Stefan Bühler) Branding: Platzhalter-Icon durch das offizielle GoodWe-Logo ersetzt (mit Genehmigung von GoodWe verwendet)
162
+
163
+ ### 0.1.6 (2026-07-18)
164
+
165
+ - (Stefan Bühler) Dev-Toolchain aktualisiert: mocha 11, sinon 22, @alcalzone/release-script 5, @iobroker/eslint-config 2; verbleibende transitive CVEs (adm-zip, diff, esbuild, serialize-javascript) per npm-`overrides` erzwungen behoben - `npm audit`: 0 Schwachstellen (auch inkl. Dev-Dependencies)
166
+
167
+ Sicherheits-/Qualitätsaudit (Security-Tester, Maintainer-Review, Fuzzing der Mapping-Schicht):
168
+
169
+ - (Stefan Bühler) **Security:** Wechselrichter-Seriennummern aus der (nicht vertrauenswürdigen) Portal-Antwort werden bereinigt, bevor sie Teil von ioBroker-Objekt-IDs werden (verhindert kaputte/unerwartet verschachtelte Objektbäume durch Sonderzeichen wie `.` `*` `]`)
170
+ - (Stefan Bühler) **Security:** die vom Login-Server gelieferte API-Basis-URL wird validiert - nur HTTPS auf GoodWe-eigenen Domains (`*.semsportal.com`, `*.goodwe.com`), sonst Fallback auf die bekannte Regional-URL. Eine manipulierte Login-Antwort kann das Session-Token damit nicht mehr an fremde Hosts umleiten
171
+ - (Stefan Bühler) **Fix:** `null`/defekte Einträge im `inverter[]`-Array des Portals ließen den kompletten Poll-Zyklus abstürzen - werden jetzt übersprungen, gesunde Wechselrichter derselben Antwort werden weiter verarbeitet
172
+ - (Stefan Bühler) **Fix:** Zahlen in Exponentialschreibweise (`"1e5"`) wurden falsch geparst (ergab 15 statt 100000)
173
+ - (Stefan Bühler) **Fix:** offensichtlich ungültige Portal-Zeitstempel (`99/99/9999 …`) erzeugten durch JS-Date-Rollover absurde Epochen-Werte - werden jetzt verworfen
174
+ - (Stefan Bühler) **Fix:** automatische Anlagen-Erkennung filtert Einträge ohne verwertbare ID (verhinderte sonst dauerhafte Fehlzyklen)
175
+ - (Stefan Bühler) **Robustheit:** keine State-Writes mehr nach Adapter-Unload; `adapterError`-Dedupe wird nach Erholung ebenfalls zurückgesetzt
176
+ - (Stefan Bühler) 14 neue Regressionstests (42 Unit-Tests gesamt); `npm audit`: 0 Schwachstellen in Produktions-Dependencies (verbleibende betreffen ausschließlich Dev-Toolchain)
177
+
178
+ ### 0.1.5 (2026-07-18)
179
+
180
+ - (Stefan Bühler) fix: PayPal-Spendenlink im README korrigiert (Button-Link statt Donate-Link)
181
+
182
+ ### 0.1.4 (2026-07-18)
183
+
184
+ - (Stefan Bühler) docs: PayPal-Spendenlink im README ergänzt
185
+
186
+ ### 0.1.3 (2026-07-18)
187
+
188
+ - (Stefan Bühler) CI: OIDC Trusted Publishing repariert - Node 22 Runner bringt npm 10.9.x mit, was unter der für Trusted Publishing benötigten Version (>=11.5.1) liegt. Release-Job aktualisiert npm jetzt explizit vor `npm publish`.
189
+
190
+ ### 0.1.2 (2026-07-18)
191
+
192
+ - (Stefan Bühler) CI: npm-Publish von langlebigem `NPM_TOKEN` auf OIDC Trusted Publishing umgestellt (kein Secret mehr im Repo nötig)
193
+
194
+ ### 0.1.1 (2026-07-18)
195
+
196
+ - (Stefan Bühler) fix `repository.url` field format in package.json (removed npm-publish normalization warning)
197
+
198
+ ### 0.1.0 (2026-07-18)
199
+
200
+ - (Stefan Bühler) initial release: SEMS-Portal-Login (SEMS+ mit Legacy-Fallback), automatische Anlagen-Erkennung, vollständiges Monitoring (Station/KPI/PowerFlow/Battery/EV-Charger/pro Wechselrichter), Rate-Limit-Handling, Backoff, Pushover-Alarmierung, Admin6-JSON-Config, i18n (11 Sprachen), Unit-Tests.
201
+
202
+ ## Lizenz
203
+
204
+ MIT License
205
+
206
+ Copyright (c) 2026 Stefan Bühler
207
+
208
+ Permission is hereby granted, free of charge, to any person obtaining a copy
209
+ of this software and associated documentation files (the "Software"), to deal
210
+ in the Software without restriction, including without limitation the rights
211
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
212
+ copies of the Software, and to permit persons to whom the Software is
213
+ furnished to do so, subject to the following conditions:
214
+
215
+ The above copyright notice and this permission notice shall be included in all
216
+ copies or substantial portions of the Software.
217
+
218
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
219
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
220
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
221
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
222
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
223
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
224
+ SOFTWARE.