iobroker.goodwe-sems 0.1.16 → 0.1.18
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 +11 -0
- package/README.md +11 -0
- package/io-package.json +27 -27
- package/lib/semsApi.js +43 -3
- package/package.json +1 -1
package/README.de.md
CHANGED
|
@@ -151,6 +151,17 @@ Pull Requests willkommen, insbesondere um zusätzliche, vom Portal gelieferte Fe
|
|
|
151
151
|
-->
|
|
152
152
|
### **WORK IN PROGRESS**
|
|
153
153
|
|
|
154
|
+
### 0.1.18 (2026-07-19)
|
|
155
|
+
|
|
156
|
+
- (Stefan Bühler) Fix: Der SEMS+-Login wurde trotz des Host-Fixes in 0.1.17 weiterhin mit `code=C0602 "account_login_abnormal"` abgelehnt, weil sich der Adapter als iOS-App ausgab (`User-Agent: PVMaster/...`, Token-`client: "ios"`) - der aufgerufene Endpunkt (`eu-semsplus.goodwe.com`) wird laut echtem Browser-Mitschnitt aber ausschließlich vom SEMS+-*Web*-Client genutzt, der `client: "semsPlusWeb"`, einen Browser-User-Agent sowie `Origin`/`Referer`-Header sendet. Der Login-Call baut jetzt eine eigene, passende Header-Identität nur für diesen einen Aufruf; alle anderen (klassischen/Legacy-)Endpunkte nutzen unverändert weiterhin die etablierte iOS-Identität
|
|
157
|
+
- (Stefan Bühler) 1 verschärfter Regressionstest, der die Client-Identität und Header des Login-Calls prüft
|
|
158
|
+
|
|
159
|
+
### 0.1.17 (2026-07-19)
|
|
160
|
+
|
|
161
|
+
- (Stefan Bühler) Fix: Der SEMS+-Login schlug für manche Konten fehl (`code=C0602 "account_login_abnormal"`), weil der Adapter den globalen Endpunkt (`semsplus.goodwe.com`) statt des EU-regionalen (`eu-semsplus.goodwe.com`) aufrief. Bestätigt durch einen echten Browser-HAR-Mitschnitt: derselbe Request-Body und Passwort-Hash war gegen den regionalen Host erfolgreich. Bewusst **ohne** Host-Fallback-Schleife umgesetzt - mehrere Login-Versuche mit denselben Zugangsdaten gegen verschiedene Hosts sehen für das Backend wie Credential-Stuffing aus und riskieren eine echte Kontosperre
|
|
162
|
+
- (Stefan Bühler) Der Login-Request sendet jetzt zusätzlich den `x-signature`-Header (exakt wie im echten Browser-Traffic), und ein echtes SEMS+-Session-Token wird von der in 0.1.16 eingeführten Gateway-API jetzt korrekt akzeptiert - zuvor bekam der Gateway-Fallback nur ein aus dem Legacy-CrossLogin abgeleitetes Token, das vom Gateway mit demselben C0602-Fehler abgelehnt wurde, da es keine echte SEMS+-Session ist
|
|
163
|
+
- (Stefan Bühler) 1 aktualisierter Regressionstest, der die exakte Login-URL und das Vorhandensein des Signatur-Headers beim Login prüft
|
|
164
|
+
|
|
154
165
|
### 0.1.16 (2026-07-19)
|
|
155
166
|
|
|
156
167
|
- (Stefan Bühler) Großer Fund: Manche Konten, deren SEMS+-Login abgelehnt wird und die auf die Legacy-CrossLogin-API zurückfallen, landen gar nicht auf dem klassischen `semsportal.com`-artigen Backend - sie bekommen eine Session für eine komplett andere, moderne Microservice-API ("SEMS+-Gateway", `eu-gateway.semsportal.com`). Das erklärt, warum `GetMonitorDetailByPowerstationId` unter keinem der in 0.1.14/0.1.15 versuchten Pfade (`v1`/`v2`/`v3`) je funktionieren konnte. Bestätigt durch einen echten Browser-HAR-Mitschnitt (`eu-semsplus.goodwe.com`), der die tatsächlich genutzten Endpunkte zeigt (`sems-plant/api/stations/...`, `sems-plant/api/equipments/<sn>/telemetry` usw.)
|
package/README.md
CHANGED
|
@@ -151,6 +151,17 @@ Pull requests are welcome, especially to add further fields delivered by the por
|
|
|
151
151
|
-->
|
|
152
152
|
### **WORK IN PROGRESS**
|
|
153
153
|
|
|
154
|
+
### 0.1.18 (2026-07-19)
|
|
155
|
+
|
|
156
|
+
- (Stefan Bühler) fix: SEMS+ login still got rejected with `code=C0602 "account_login_abnormal"` even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (`User-Agent: PVMaster/...`, token `client: "ios"`) - but the called endpoint (`eu-semsplus.goodwe.com`) is, per the real browser capture, only ever used by the SEMS+ *web* client, sending `client: "semsPlusWeb"`, a browser User-Agent, and `Origin`/`Referer` headers. The login call now builds its own matching header identity for just that one request; every other (classic/legacy) endpoint keeps using the established iOS identity, unchanged
|
|
157
|
+
- (Stefan Bühler) 1 tightened regression test verifying the login call's client identity and headers
|
|
158
|
+
|
|
159
|
+
### 0.1.17 (2026-07-19)
|
|
160
|
+
|
|
161
|
+
- (Stefan Bühler) fix: SEMS+ login failed for some accounts (`code=C0602 "account_login_abnormal"`) because the adapter called the global endpoint (`semsplus.goodwe.com`) instead of the EU-regional one (`eu-semsplus.goodwe.com`). Confirmed via a real browser HAR capture: the identical request body and password hash succeeded against the regional host. Deliberately implemented **without** a host-fallback loop - repeatedly retrying the same credentials against multiple hosts looks like credential stuffing to the backend and risks a real account lockout
|
|
162
|
+
- (Stefan Bühler) the login request now also sends the `x-signature` header (matching real browser traffic exactly), and a genuine SEMS+ session token is now correctly accepted by the gateway API introduced in 0.1.16 - previously, the gateway fallback only ever received a Legacy-CrossLogin-derived token, which the gateway rejected with the same C0602 error since it isn't a real SEMS+ session
|
|
163
|
+
- (Stefan Bühler) 1 updated regression test verifying the exact login URL and the presence of the login-time signature header
|
|
164
|
+
|
|
154
165
|
### 0.1.16 (2026-07-19)
|
|
155
166
|
|
|
156
167
|
- (Stefan Bühler) major finding: some accounts whose SEMS+ login is rejected and fall back to the legacy CrossLogin API do not end up on the classic `semsportal.com`-style backend at all - they get a session for a completely different, modern microservice API ("SEMS+ gateway", `eu-gateway.semsportal.com`), which explains why `GetMonitorDetailByPowerstationId` could never succeed under any of the `v1`/`v2`/`v3` paths tried in 0.1.14/0.1.15. Confirmed via a real account's browser HAR capture (`eu-semsplus.goodwe.com`) showing the actual endpoints in use (`sems-plant/api/stations/...`, `sems-plant/api/equipments/<sn>/telemetry`, etc.)
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "goodwe-sems",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.18",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.1.18": {
|
|
7
|
+
"de": "Fix: SEMS+-Login blieb trotz korrektem Host (0.1.17) weiter mit code=C0602 abgelehnt, weil der Adapter sich als iOS-App ausgab (User-Agent 'PVMaster', Token-Client 'ios') - obwohl der aufgerufene Endpunkt (eu-semsplus.goodwe.com) laut Browser-Mitschnitt nur vom SEMS+-Web-Client mit client:'semsPlusWeb', Browser-User-Agent sowie Origin/Referer-Headern genutzt wird. Der Login-Call sendet jetzt eine eigene, passende Header-Identität nur für diesen einen Aufruf; alle anderen Endpunkte bleiben unverändert bei der iOS-Identität.",
|
|
8
|
+
"en": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
9
|
+
"ru": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
10
|
+
"pt": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
11
|
+
"nl": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
12
|
+
"fr": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
13
|
+
"it": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
14
|
+
"es": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
15
|
+
"pl": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
16
|
+
"zh-cn": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before.",
|
|
17
|
+
"uk": "Fix: SEMS+ login still got rejected with code=C0602 even after the host fix in 0.1.17, because the adapter identified itself as the iOS app (User-Agent 'PVMaster', token client 'ios') - even though the called endpoint (eu-semsplus.goodwe.com) is, per the real browser capture, only ever used by the SEMS+ web client with client:'semsPlusWeb', a browser User-Agent, and Origin/Referer headers. The login call now sends its own, matching header identity for just that one request; every other endpoint keeps using the iOS identity as before."
|
|
18
|
+
},
|
|
19
|
+
"0.1.17": {
|
|
20
|
+
"de": "Fix: Der SEMS+-Login schlug für manche Konten fehl (code=C0602 'account_login_abnormal'), weil der Adapter den globalen Endpunkt (semsplus.goodwe.com) statt des EU-regionalen (eu-semsplus.goodwe.com) nutzte - bestätigt durch einen echten Browser-Mitschnitt mit identischem Request/Passwort-Hash, der gegen den regionalen Host erfolgreich war. Bewusst OHNE Host-Fallback-Schleife umgesetzt: mehrere Login-Versuche mit denselben Zugangsdaten gegen verschiedene Hosts sehen wie Credential-Stuffing aus und könnten zu einer Kontosperre führen.",
|
|
21
|
+
"en": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
22
|
+
"ru": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
23
|
+
"pt": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
24
|
+
"nl": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
25
|
+
"fr": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
26
|
+
"it": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
27
|
+
"es": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
28
|
+
"pl": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
29
|
+
"zh-cn": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout.",
|
|
30
|
+
"uk": "Fix: SEMS+ login failed for some accounts (code=C0602 'account_login_abnormal') because the adapter used the global endpoint (semsplus.goodwe.com) instead of the EU-regional one (eu-semsplus.goodwe.com) - confirmed via a real browser capture with the identical request/password hash succeeding against the regional host. Deliberately implemented WITHOUT a host-fallback loop: retrying the same credentials against multiple hosts looks like credential stuffing and risks a real account lockout."
|
|
31
|
+
},
|
|
6
32
|
"0.1.16": {
|
|
7
33
|
"de": "Großer Fund: Konten, deren SEMS+-Login abgelehnt wird und die auf die Legacy-CrossLogin-API zurückfallen, landen teils auf einem komplett anderen, modernen SEMS+-Gateway-Backend (eu-gateway.semsportal.com) statt dem klassischen semsportal.com - das erklärt, warum v1/v2/v3 GetMonitorDetailByPowerstationId dort NIE funktionieren konnten. Der Adapter spricht jetzt zusätzlich dieses Gateway-Backend (eigene Endpunkte, eigenes Antwortformat, inkl. der zur Authentifizierung nötigen Request-Signatur) und nutzt es automatisch als letzten Fallback, wenn alle klassischen Pfade fehlschlagen.",
|
|
8
34
|
"en": "Major finding: accounts whose SEMS+ login is rejected and fall back to the legacy CrossLogin API sometimes end up on a completely different, modern SEMS+ gateway backend (eu-gateway.semsportal.com) instead of the classic semsportal.com one - explaining why v1/v2/v3 GetMonitorDetailByPowerstationId could never work there. The adapter now also speaks this gateway backend (its own endpoints, response format, and required request signature) and automatically uses it as a last-resort fallback when all classic paths fail.",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "kolejne poprawki: usunieto wpis news dla 0.1.10 (nigdy nie opublikowano na npm), dodano needs: check-and-lint do zadania adapter-tests, @types/node ustalono na ^22, poprawiono schematy w .vscode/settings.json, dodano automerge dependabot",
|
|
68
94
|
"uk": "подальші виправлення: видалено запис news для 0.1.10 (ніколи не публікувався на npm), додано needs: check-and-lint для adapter-tests, @types/node зафіксовано на ^22, виправлено схеми в .vscode/settings.json, додано automerge для dependabot",
|
|
69
95
|
"zh-cn": "进一步修复:移除 0.1.10 的 news 条目(从未发布到 npm),为 adapter-tests 任务添加 needs: check-and-lint,将 @types/node 固定为 ^22,修复 .vscode/settings.json 中的 schema 匹配,添加 dependabot 自动合并"
|
|
70
|
-
},
|
|
71
|
-
"0.1.11": {
|
|
72
|
-
"en": "fix broken CI: remove Node.js 20.x from the adapter-tests matrix - it is incompatible with engines.node >=22 (introduced in 0.1.10) under the official action's engine-strict npm ci, which crashed that matrix job and cancelled all others",
|
|
73
|
-
"de": "defekte CI behoben: Node.js 20.x aus der adapter-tests-Matrix entfernt - inkompatibel mit engines.node >=22 (seit 0.1.10) unter dem engine-strict npm ci der offiziellen Action, wodurch dieser Matrix-Job abstürzte und alle anderen abgebrochen wurden",
|
|
74
|
-
"ru": "исправлен неработающий CI: Node.js 20.x удалён из матрицы adapter-tests - несовместим с engines.node >=22 (введено в 0.1.10)",
|
|
75
|
-
"pt": "corrigido o CI quebrado: Node.js 20.x removido da matriz adapter-tests - incompatível com engines.node >=22 (introduzido em 0.1.10)",
|
|
76
|
-
"nl": "defecte CI opgelost: Node.js 20.x verwijderd uit de adapter-tests-matrix - incompatibel met engines.node >=22 (geïntroduceerd in 0.1.10)",
|
|
77
|
-
"fr": "correction du CI cassé : Node.js 20.x retiré de la matrice adapter-tests - incompatible avec engines.node >=22 (introduit en 0.1.10)",
|
|
78
|
-
"it": "risolto il CI non funzionante: rimosso Node.js 20.x dalla matrice adapter-tests - incompatibile con engines.node >=22 (introdotto in 0.1.10)",
|
|
79
|
-
"es": "se corrigió el CI roto: se eliminó Node.js 20.x de la matriz adapter-tests - incompatible con engines.node >=22 (introducido en 0.1.10)",
|
|
80
|
-
"pl": "naprawiono uszkodzone CI: usunięto Node.js 20.x z macierzy adapter-tests - niekompatybilne z engines.node >=22 (wprowadzone w 0.1.10)",
|
|
81
|
-
"uk": "виправлено зламаний CI: видалено Node.js 20.x з матриці adapter-tests - несумісний з engines.node >=22 (введено в 0.1.10)",
|
|
82
|
-
"zh-cn": "修复损坏的 CI:从 adapter-tests 矩阵中移除 Node.js 20.x - 与 engines.node >=22(0.1.10 中引入)不兼容"
|
|
83
|
-
},
|
|
84
|
-
"0.1.9": {
|
|
85
|
-
"en": "address stricter ioBroker.repositories PR check: move encryptedNative/protectedNative to io-package.json root, update deps (adapter-core, testing, adapter-dev, admin, js-controller), rewrite CI workflow (check-and-lint/adapter-tests/deploy jobs, concurrency, full OS+Node matrix), use adapter-managed timers, node:crypto, fix jsonConfig responsive sizes + i18n key, translate README to English (required), add CHANGELOG_OLD.md",
|
|
86
|
-
"de": "strengere ioBroker.repositories-PR-Prüfung behoben: encryptedNative/protectedNative auf io-package.json-Root verschoben, Abhängigkeiten aktualisiert (adapter-core, testing, adapter-dev, admin, js-controller), CI-Workflow neu geschrieben (check-and-lint/adapter-tests/deploy Jobs, Concurrency, volle OS+Node-Matrix), adapter-verwaltete Timer, node:crypto, jsonConfig Responsive-Größen + i18n-Key behoben, README auf Englisch übersetzt (Pflicht), CHANGELOG_OLD.md ergänzt",
|
|
87
|
-
"ru": "устранены более строгие проверки PR ioBroker.repositories: encryptedNative/protectedNative перемещены в корень io-package.json, обновлены зависимости, переписан CI, README переведён на английский (обязательно)",
|
|
88
|
-
"pt": "corrigidas verificações mais rigorosas do PR do ioBroker.repositories: encryptedNative/protectedNative movidos para a raiz do io-package.json, dependências atualizadas, CI reescrito, README traduzido para inglês (obrigatório)",
|
|
89
|
-
"nl": "strengere ioBroker.repositories-PR-controles opgelost: encryptedNative/protectedNative naar de root van io-package.json verplaatst, dependencies bijgewerkt, CI herschreven, README naar het Engels vertaald (verplicht)",
|
|
90
|
-
"fr": "correction des vérifications plus strictes du PR ioBroker.repositories : encryptedNative/protectedNative déplacés à la racine de io-package.json, dépendances mises à jour, CI réécrit, README traduit en anglais (obligatoire)",
|
|
91
|
-
"it": "risolti controlli più severi del PR ioBroker.repositories: encryptedNative/protectedNative spostati alla radice di io-package.json, dipendenze aggiornate, CI riscritta, README tradotto in inglese (obbligatorio)",
|
|
92
|
-
"es": "se resolvieron comprobaciones más estrictas del PR de ioBroker.repositories: encryptedNative/protectedNative movidos a la raíz de io-package.json, dependencias actualizadas, CI reescrita, README traducido al inglés (obligatorio)",
|
|
93
|
-
"pl": "rozwiązano bardziej rygorystyczne kontrole PR ioBroker.repositories: encryptedNative/protectedNative przeniesiono do katalogu głównego io-package.json, zaktualizowano zależności, przepisano CI, README przetłumaczono na angielski (wymagane)",
|
|
94
|
-
"uk": "усунено суворіші перевірки PR ioBroker.repositories: encryptedNative/protectedNative перенесено в корінь io-package.json, оновлено залежності, переписано CI, README перекладено англійською (обов'язково)",
|
|
95
|
-
"zh-cn": "解决更严格的 ioBroker.repositories PR 检查:将 encryptedNative/protectedNative 移至 io-package.json 根目录,更新依赖项,重写 CI,将 README 翻译为英文(必需)"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/lib/semsApi.js
CHANGED
|
@@ -29,8 +29,15 @@ const { SemsAuthError, SemsRateLimitError, SemsNetworkError, SemsProtocolError }
|
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
// "New" SEMS+ login, in use since ~2024. Needs an MD5(password) hash,
|
|
32
|
-
// base64-encoded, plus a few boilerplate flags.
|
|
33
|
-
|
|
32
|
+
// base64-encoded, plus a few boilerplate flags. Uses the EU-regional host
|
|
33
|
+
// (not the global "semsplus.goodwe.com" one) - confirmed via a real
|
|
34
|
+
// account's browser HAR capture that the global host rejects valid
|
|
35
|
+
// credentials with "C0602 account_login_abnormal" while the identical
|
|
36
|
+
// request against the regional host succeeds (code 00000). Deliberately
|
|
37
|
+
// NOT tried against multiple hosts/variants: repeatedly hitting a login
|
|
38
|
+
// endpoint with the same credentials from different hosts looks like
|
|
39
|
+
// credential-stuffing and risks a real account lockout.
|
|
40
|
+
const NEW_LOGIN_URL = "https://eu-semsplus.goodwe.com/web/sems/sems-user/api/v1/auth/cross-login";
|
|
34
41
|
// Legacy login, kept as a fallback for accounts / regions where the new
|
|
35
42
|
// endpoint is unavailable or rejects the credentials.
|
|
36
43
|
const LEGACY_LOGIN_URL = "https://www.semsportal.com/api/v3/Common/CrossLogin";
|
|
@@ -91,6 +98,16 @@ const DEFAULT_CLIENT_TOKEN = JSON.stringify({
|
|
|
91
98
|
language: "en",
|
|
92
99
|
});
|
|
93
100
|
|
|
101
|
+
// The SEMS+ login endpoint is web-only (eu-semsplus.goodwe.com) and, unlike
|
|
102
|
+
// the classic/legacy endpoints, is only ever called by the SEMS+ *web* app -
|
|
103
|
+
// there is no mobile-app equivalent. Sending it the iOS identity above
|
|
104
|
+
// (wrong client, non-browser User-Agent, no Origin/Referer) is a plausible
|
|
105
|
+
// explanation for the persistent "C0602 account_login_abnormal" rejections:
|
|
106
|
+
// confirmed real browser traffic for this exact endpoint always used a
|
|
107
|
+
// browser User-Agent and client:"semsPlusWeb".
|
|
108
|
+
const SEMS_PLUS_WEB_USER_AGENT =
|
|
109
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36";
|
|
110
|
+
|
|
94
111
|
/**
|
|
95
112
|
* Thin wrapper around fetch() with a hard timeout and JSON handling.
|
|
96
113
|
*
|
|
@@ -263,12 +280,35 @@ class SemsApi {
|
|
|
263
280
|
isChinese: false,
|
|
264
281
|
isLocal: false,
|
|
265
282
|
});
|
|
283
|
+
// Dedicated headers matching the real semsPlusWeb browser client
|
|
284
|
+
// exactly (see SEMS_PLUS_WEB_USER_AGENT comment above) - NOT the
|
|
285
|
+
// iOS-app identity _defaultHeaders()/_authHeaders() use for the
|
|
286
|
+
// classic/legacy endpoints. Includes an x-signature header even on
|
|
287
|
+
// the login call itself (with empty uid/token, since no session
|
|
288
|
+
// exists yet), matching observed real traffic exactly.
|
|
289
|
+
const tokenPayload = {
|
|
290
|
+
uid: "",
|
|
291
|
+
timestamp: 0,
|
|
292
|
+
token: "",
|
|
293
|
+
client: GATEWAY_CLIENT,
|
|
294
|
+
version: "",
|
|
295
|
+
language: "en",
|
|
296
|
+
};
|
|
297
|
+
const headers = {
|
|
298
|
+
"Content-Type": "application/json",
|
|
299
|
+
Accept: "application/json, text/plain, */*",
|
|
300
|
+
"User-Agent": SEMS_PLUS_WEB_USER_AGENT,
|
|
301
|
+
Origin: "https://eu-semsplus.goodwe.com",
|
|
302
|
+
Referer: "https://eu-semsplus.goodwe.com/",
|
|
303
|
+
token: JSON.stringify(tokenPayload),
|
|
304
|
+
"x-signature": this._gatewaySignature("", ""),
|
|
305
|
+
};
|
|
266
306
|
|
|
267
307
|
const { json } = await httpPostJson(
|
|
268
308
|
NEW_LOGIN_URL,
|
|
269
309
|
{
|
|
270
310
|
method: "POST",
|
|
271
|
-
headers
|
|
311
|
+
headers,
|
|
272
312
|
body,
|
|
273
313
|
timeoutMs: this.requestTimeoutMs,
|
|
274
314
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.goodwe-sems",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "ioBroker adapter to read GoodWe inverter data from the SEMS Portal cloud API (for installations without local/LAN access to the inverter).",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "bueste",
|