@impact0815/node-red-contrib-home-connect 0.0.0-stage → 0.2.0

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.
Files changed (52) hide show
  1. package/BUILD-INFO.json +23 -0
  2. package/CHANGELOG.md +52 -0
  3. package/LICENSE +21 -0
  4. package/NOTICE +19 -0
  5. package/README.de.md +326 -0
  6. package/README.md +325 -2
  7. package/SECURITY.md +47 -0
  8. package/docs/API-COVERAGE.md +59 -0
  9. package/docs/ARCHITECTURE.md +95 -0
  10. package/docs/DASHBOARD.de.md +121 -0
  11. package/docs/DASHBOARD.md +121 -0
  12. package/docs/FIRST-PUSH.md +42 -0
  13. package/docs/LOCAL-LAN.de.md +150 -0
  14. package/docs/LOCAL-LAN.md +150 -0
  15. package/docs/MESSAGE-API.md +111 -0
  16. package/docs/RELEASE.md +78 -0
  17. package/docs/TROUBLESHOOTING.de.md +230 -0
  18. package/docs/TROUBLESHOOTING.md +230 -0
  19. package/docs/images/README.md +10 -0
  20. package/docs/images/dashboard-details-en.png +0 -0
  21. package/docs/images/dashboard-overview-en.png +0 -0
  22. package/docs/official-api-contract.json +418 -0
  23. package/examples/01-first-steps-device-list.json +148 -0
  24. package/examples/02-events.json +165 -0
  25. package/examples/03-safe-read-write.json +155 -0
  26. package/examples/04-local-read-only.json +214 -0
  27. package/examples/dashboard-dishwasher-washer-oven.json +628 -0
  28. package/examples/dashboard-screenshot-simulated.json +405 -0
  29. package/examples/demo-home-connect-flowfuse-1.34.1-scriptless.json +390 -0
  30. package/lib/client.js +600 -0
  31. package/lib/constants.js +66 -0
  32. package/lib/dashboard-i18n.js +255 -0
  33. package/lib/device-label.js +39 -0
  34. package/lib/errors.js +51 -0
  35. package/lib/health.js +525 -0
  36. package/lib/local-client.js +1014 -0
  37. package/lib/local-crypto.js +122 -0
  38. package/lib/local-diagnostics.js +115 -0
  39. package/lib/local-profile.js +706 -0
  40. package/lib/local-trace.js +103 -0
  41. package/lib/oauth.js +23 -0
  42. package/lib/rate-limiter.js +186 -0
  43. package/lib/simulator.js +290 -0
  44. package/lib/sse.js +58 -0
  45. package/lib/validation.js +194 -0
  46. package/lib/websocket-transport.js +374 -0
  47. package/nodes/home-connect.html +795 -0
  48. package/nodes/home-connect.js +699 -0
  49. package/nodes/locales/de/home-connect.html +19 -0
  50. package/nodes/locales/de/home-connect.json +10 -0
  51. package/nodes/locales/en-US/home-connect.json +10 -0
  52. package/package.json +71 -4
@@ -0,0 +1,111 @@
1
+ # Message API
2
+
3
+ All functional nodes preserve unrelated incoming properties. Output 2 contains a structured error in `msg.payload`. Confirmation values are removed from success and error output.
4
+
5
+ ## Normalized health envelope
6
+
7
+ Every functional output includes:
8
+
9
+ ```js
10
+ msg.health = 'ok'; // ok | running | info | warning | action_required | offline | error
11
+ msg.warnings = [{
12
+ source: 'status', // status | event | connection | api | oauth
13
+ code: 'HC_...', // stable integration code
14
+ severity: 'warning', // info | warning | error | critical
15
+ text: { de: '...', en: '...' },
16
+ transient: false
17
+ }];
18
+ msg.homeConnect.health = msg.health;
19
+ msg.homeConnect.warnings = msg.warnings;
20
+ msg.homeConnect.healthSchema = 'home-connect-health/v1';
21
+ msg.homeConnect.healthAt = '...';
22
+ ```
23
+
24
+ Snapshots and discovery entries also carry `payload.health`, `payload.warnings`, `payload.healthSchema`, and `payload.healthAt`. Raw API status and event values are retained. Transient notices are deduplicated and expire; disconnected/offline state remains until a later connection or snapshot confirms recovery. Errors are assessed for that error output and do not poison later successful messages.
25
+
26
+ ## discover
27
+
28
+ ```js
29
+ msg.haId = '...'; // single mode
30
+ msg.force = true; // bypass five-minute capability cache
31
+ ```
32
+
33
+ No real appliance ID, name, program or capability is built into the package. The editor's **Load devices** button and discovery output use the appliances returned by the connected account or protected local profiles. For local connections, Host/IP and the optional Auto/AES/TLS choice exist only in `home-connect-config`; Read and Events nodes store only a selected appliance/profile ID.
34
+
35
+ Documented appliance fields such as `name`, `brand`, `type`, `vib` and `connected` remain available under `appliance`. Firmware version/history/update is not part of the public API and has no message operation.
36
+
37
+ ## read
38
+
39
+ ```js
40
+ msg.haId = '...';
41
+ msg.operation = 'snapshot';
42
+ msg.key = '...'; // resource key, map ID or cleaning-summary counter
43
+ msg.subKey = '...'; // detected object, room or zone ID
44
+ ```
45
+
46
+ Operations:
47
+
48
+ - `snapshot`, `capabilities`, `appliances`, `appliance`
49
+ - `status`, `status-item`, `settings`, `setting`
50
+ - `all-programs`, `programs`, `program`
51
+ - `active-program`, `active-options`, `active-option`
52
+ - `selected-program`, `selected-options`, `selected-option`
53
+ - `commands`, `images`, `image`
54
+ - `maps`, `map`, `map-occupancy-grid`, `map-layout`, `map-cleaning-status`
55
+ - `map-detected-objects`, `map-detected-object`, `map-rooms`, `map-room`, `map-zones`, `map-zone`
56
+ - `map-robot-position`, `map-config-restrictions`, `map-cleaning-summaries`, `map-cleaning-summary`
57
+
58
+ `image` returns:
59
+
60
+ ```js
61
+ msg.payload = {
62
+ contentType: 'image/jpeg',
63
+ data: Buffer.from(/* JPEG bytes */)
64
+ };
65
+ ```
66
+
67
+ The operation may select only a predefined resource; it cannot provide a URL or HTTP method. Local connections support appliance/snapshot/status/settings/program reads derived from `/ro/*` values. Cloud-only image/map operations return `LOCAL_READ_UNSUPPORTED` locally.
68
+
69
+ ## events
70
+
71
+ An input message with `msg.haId` restarts the stream for that appliance. Use `*` for all configured appliances. The cloud client reconnects SSE with bounded exponential backoff and sends `Last-Event-ID` when supplied. The local client maintains per-appliance WebSockets and emits `STATUS`. Both emit synthetic `CONNECTED` and `DISCONNECTED` lifecycle events. Local event envelopes include `connection.local: true` and `connection.readOnly: true`.
72
+
73
+ ## write
74
+
75
+ A request can be supplied in `msg.payload`; top-level `msg.haId`, `msg.action`, `msg.program`, `msg.key`, `msg.value` and `msg.options` take precedence.
76
+
77
+ ### Start a program
78
+
79
+ ```js
80
+ msg.payload = {
81
+ action: 'start-program',
82
+ haId: '...',
83
+ program: 'Cooking.Oven.Program.HeatingMode.HotAir',
84
+ options: [{ key: 'Cooking.Oven.Option.SetpointTemperature', value: 180 }],
85
+ confirm: 'CONFIRM'
86
+ };
87
+ ```
88
+
89
+ ### Other actions
90
+
91
+ ```js
92
+ msg.payload = { action: 'stop-program', haId: '...', confirm: 'CONFIRM' };
93
+ msg.payload = { action: 'select-program', haId: '...', program: '...', options: [], confirm: 'CONFIRM' };
94
+ msg.payload = { action: 'set-setting', haId: '...', key: 'BSH.Common.Setting.PowerState', value: 'BSH.Common.EnumType.PowerState.Standby', confirm: 'CONFIRM' };
95
+ msg.payload = { action: 'command', haId: '...', key: 'BSH.Common.Command.PauseProgram', value: true, confirm: 'CONFIRM' };
96
+ msg.payload = { action: 'set-active-option', haId: '...', key: 'BSH.Common.Option.Duration', value: 600, confirm: 'CONFIRM' };
97
+ msg.payload = { action: 'set-selected-option', haId: '...', key: '...', value: '...', confirm: 'CONFIRM' };
98
+ ```
99
+
100
+ Options may also be an object shorthand:
101
+
102
+ ```js
103
+ msg.options = {
104
+ 'Cooking.Oven.Option.SetpointTemperature': 180,
105
+ 'BSH.Common.Option.Duration': { value: 1800, unit: 'seconds' }
106
+ };
107
+ ```
108
+
109
+ Arbitrary methods, paths, body envelopes and bulk writes are intentionally unsupported. The confirmation token is stored in Node-RED credentials rather than in the flow JSON.
110
+
111
+ Local configurations reject every write with `LOCAL_READ_ONLY` before capability validation or network I/O. This cannot be overridden by `msg`, editor fields, or `allowWrite`.
@@ -0,0 +1,78 @@
1
+ # Release procedure for 0.2.0
2
+
3
+ The feature set is frozen at build `hc-0.2.0-final`. Do not add features after this point; only release-blocking corrections are allowed, followed by the complete validation sequence.
4
+
5
+ ## Required release inputs
6
+
7
+ - `docs/images/dashboard-overview-en.png`
8
+ - `docs/images/dashboard-details-en.png`
9
+ - `examples/demo-home-connect-flowfuse-1.34.1-scriptless.json`
10
+
11
+ The screenshots must come from the isolated simulated Demo and must be visually reviewed for browser/account context, hostnames, addresses, real appliance IDs, tokens, QR codes, profiles, unrelated tabs, and notifications.
12
+
13
+ ## Final local checks
14
+
15
+ ```bash
16
+ npm ci --ignore-scripts
17
+ npm run release:check
18
+ npm run validate
19
+ npm pack --json
20
+ sha256sum node-red-contrib-home-connect-0.2.0.tgz
21
+ ```
22
+
23
+ Inspect the exact package payload:
24
+
25
+ ```bash
26
+ tar -tzf node-red-contrib-home-connect-0.2.0.tgz | sort
27
+ npm publish --dry-run ./node-red-contrib-home-connect-0.2.0.tgz --access public
28
+ ```
29
+
30
+ ## First GitHub publication
31
+
32
+ Create `impact0815/node-red-contrib-home-connect` as an empty public repository, without generated README, license, or `.gitignore`, then run:
33
+
34
+ ```bash
35
+ git init -b main
36
+ git add .
37
+ git status --short
38
+ git commit -m "Release node-red-contrib-home-connect 0.2.0"
39
+ git remote add origin https://github.com/impact0815/node-red-contrib-home-connect.git
40
+ git push -u origin main
41
+ ```
42
+
43
+ After GitHub Actions CI succeeds on `main`:
44
+
45
+ ```bash
46
+ git tag -a v0.2.0 -m "node-red-contrib-home-connect 0.2.0"
47
+ git push origin v0.2.0
48
+ gh release create v0.2.0 \
49
+ ./node-red-contrib-home-connect-0.2.0.tgz \
50
+ ./SHA256SUMS.txt \
51
+ --title "node-red-contrib-home-connect 0.2.0" \
52
+ --notes-file RELEASE_NOTES.md
53
+ ```
54
+
55
+ ## npm publication
56
+
57
+ Confirm the account and package name before publishing:
58
+
59
+ ```bash
60
+ npm whoami
61
+ npm view node-red-contrib-home-connect versions --json
62
+ npm publish ./node-red-contrib-home-connect-0.2.0.tgz --access public
63
+ npm view node-red-contrib-home-connect@0.2.0 version dist.integrity dist.tarball
64
+ ```
65
+
66
+ If the unscoped npm name is not controlled by the publisher, stop. Do not silently rename or publish under a different scope; update package metadata, documentation, lockfile, and release plan as one reviewed change.
67
+
68
+ ## Post-publication smoke test
69
+
70
+ ```bash
71
+ TMPDIR="$(mktemp -d)"
72
+ cd "$TMPDIR"
73
+ npm init -y
74
+ npm install node-red-contrib-home-connect@0.2.0
75
+ node -p "require('node-red-contrib-home-connect/BUILD-INFO.json')"
76
+ ```
77
+
78
+ The build ID must be `hc-0.2.0-final`.
@@ -0,0 +1,230 @@
1
+ # Home Connect: Troubleshooting und FAQ
2
+
3
+ Zurück zur [deutschen README](../README.de.md).
4
+
5
+ Diese Anleitung beginnt beim sichtbaren Symptom. Zugangsdaten, Hostnamen, Geräte-IDs und OAuth-Codes gehören nie in Fehlerberichte.
6
+
7
+ ## 1. Vorprüfung in zwei Minuten
8
+
9
+ 1. Läuft wirklich der erwartete Build?
10
+ ```bash
11
+ cd ~/.node-red
12
+ node -p "require('./node_modules/node-red-contrib-home-connect/BUILD-INFO.json')"
13
+ ```
14
+ Erwartet: Version `0.2.0`, Build `hc-0.2.0-final`, `pkce: false`.
15
+ 2. Ist die richtige Connection ausgewählt und eindeutig benannt?
16
+ 3. Wurde nach der letzten Änderung **Fertig → Deploy** ausgeführt?
17
+ 4. Sind Redirect URI im Developer Portal und in Node-RED exakt gleich?
18
+ 5. Ist die Node-RED-Adresse vom verwendeten Browser erreichbar?
19
+ 6. Wurde OAuth bis zur Seite **Home Connect authorized** abgeschlossen?
20
+ 7. Enthalten die Scopes mindestens `IdentifyAppliance` und die benötigten gerätespezifischen Rechte?
21
+
22
+ ## 2. Autorisieren ist deaktiviert
23
+
24
+ Das ist Absicht: Die Config-Node prüft, ob genau diese gespeicherte Konfiguration bereits in der laufenden Node-RED-Runtime existiert.
25
+
26
+ - **Neue/änderte Verbindung:** Fertig klicken, deployen, Verbindung erneut öffnen.
27
+ - **Integrierter Simulator:** OAuth ist nicht erforderlich.
28
+ - **Weiterhin deaktiviert:** Node-RED vollständig neu starten und Browser hart neu laden. Prüfen, ob eine zweite/alte Paketinstallation existiert.
29
+
30
+ ## 3. `CONFIG_NOT_FOUND`
31
+
32
+ **Bedeutung:** Die URL enthält die ID einer Config-Node, welche die laufende Runtime nicht kennt.
33
+
34
+ Typische Ursachen:
35
+
36
+ - Beispiel- oder Simulator-Config wurde referenziert.
37
+ - Verbindung wurde zwar im Editor angelegt, aber nicht deployt.
38
+ - Alter Browser-Tab enthält eine Autorisierungs-URL einer gelöschten Config.
39
+ - Nach Paket-/Flow-Wechsel läuft noch eine andere Runtime-Instanz.
40
+
41
+ **Behebung:**
42
+
43
+ 1. Alten Auth-Tab schließen.
44
+ 2. Im verwendeten Home-Connect-Node die richtige Connection wählen.
45
+ 3. Connection eindeutig benennen.
46
+ 4. Fertig → Deploy.
47
+ 5. Connection erneut öffnen.
48
+ 6. Autorisierung über den dortigen Knopf neu starten.
49
+
50
+ ## 4. Falsche oder irreführende Verbindungsbezeichnung
51
+
52
+ Technisch steuert das Feld **Umgebung** den API-Host, nicht der Name. Ein Name wie `Simulator` bei Umgebung `Production` erhöht aber das Fehlerrisiko. Die Oberfläche zeigt deshalb eine Warnung. Name korrigieren, speichern und deployen.
53
+
54
+ ## 5. Redirect URI: exakter Vergleich
55
+
56
+ Folgende Teile müssen identisch sein:
57
+
58
+ | Teil | Häufiger Fehler |
59
+ |---|---|
60
+ | Protokoll | `http` im Portal, `https` in Node-RED |
61
+ | Host | DNS-Name im Portal, IP-Adresse in Node-RED |
62
+ | Port | Port fehlt auf einer Seite |
63
+ | Pfad | Tippfehler in `/home-connect/oauth/callback` |
64
+ | Ende | zusätzlicher Slash `/callback/` |
65
+ | Groß-/Kleinschreibung | abweichende Zeichen im Pfad |
66
+
67
+ Am sichersten die vollständige URI aus einem Feld kopieren und im anderen einfügen.
68
+
69
+ ## 6. Nach Login: localhost, `ERR_EMPTY_RESPONSE`, Verbindung fehlgeschlagen
70
+
71
+ `localhost` zeigt aus Sicht des Browsers auf das Browser-Gerät. Läuft Node-RED auf NAS, Server, Raspberry Pi, Home Assistant, ioBroker oder in einem anderen Rechner/Container, erreicht der Browser dort nicht Node-RED.
72
+
73
+ 1. Einen vom Browser erreichbaren Hostnamen oder eine erreichbare IP-Adresse für Node-RED wählen.
74
+ 2. Callback-Pfad anhängen: `/home-connect/oauth/callback`.
75
+ 3. URI im Developer Portal ändern.
76
+ 4. Dieselbe URI in Node-RED eintragen.
77
+ 5. Fertig → Deploy.
78
+ 6. OAuth neu starten.
79
+
80
+ ## 7. `unauthorized_client` / `client or redirection URI not authorized`
81
+
82
+ Prüfreihenfolge:
83
+
84
+ 1. Wurde Client ID aus der richtigen Developer-Portal-Application kopiert?
85
+ 2. Stimmt die Redirect URI Zeichen für Zeichen?
86
+ 3. Verwendet die Application den Authorization Code Grant?
87
+ 4. Ist PKCE in dieser Application deaktiviert?
88
+ 5. Läuft der Build `hc-0.2.0-final`?
89
+ 6. Wurde nach jeder Änderung eine neue Autorisierung gestartet?
90
+
91
+ Wurde das Client Secret sichtbar, nicht weiter testen: Secret regenerieren, in Node-RED ersetzen, deployen und neu autorisieren.
92
+
93
+ ## 8. Nach Update läuft alter Code
94
+
95
+ Ein Flow-Deploy lädt keinen neuen Node.js-Runtime-Code. Zusätzlich zur npm-Version BUILD-INFO prüfen, um doppelte Installationen zu erkennen.
96
+
97
+ ```bash
98
+ cd ~/.node-red
99
+ npm uninstall node-red-contrib-home-connect
100
+ rm -rf node_modules/node-red-contrib-home-connect
101
+ npm install --force /absoluter/pfad/node-red-contrib-home-connect-0.2.0.tgz
102
+ node -p "require('./node_modules/node-red-contrib-home-connect/BUILD-INFO.json')"
103
+ ```
104
+
105
+ Danach Node-RED/Container vollständig neu starten, Browser hart neu laden und OAuth neu beginnen. Authorization Codes und State-Links sind kurzlebig/einmalig und dürfen nicht wiederverwendet werden.
106
+
107
+ ## 9. `No refresh token is stored. Complete OAuth authorization first.`
108
+
109
+ Der Refresh Token wird erst beim erfolgreichen Callback gespeichert.
110
+
111
+ - Autorisierung aus der deployten Connection starten.
112
+ - Login und Zustimmung abschließen.
113
+ - Auf **Home Connect authorized** warten.
114
+ - Erst dann Test/Discover/Read/Events ausführen.
115
+
116
+ Bleibt der Fehler, den Fehler auf der Callback-Seite notieren, aber keine Codes/Tokens veröffentlichen.
117
+
118
+ ## 10. `insufficient_scope`
119
+
120
+ Der Token darf die angeforderte Ressource nicht lesen oder steuern.
121
+
122
+ 1. `IdentifyAppliance` beibehalten.
123
+ 2. Passenden gerätespezifischen Scope ergänzen, etwa `Dishwasher-Monitor`, `Washer-Monitor` oder `Oven-Monitor`.
124
+ 3. Für Aktionen zusätzlich nur benötigtes `*-Control` und/oder `*-Settings` ergänzen.
125
+ 4. Fertig → Deploy.
126
+ 5. Neu autorisieren; ein alter Refresh Token erhält nicht automatisch neue Rechte.
127
+
128
+ Der allgemeine Scope `Monitor` kann je nach Application/Konto unzureichend sein.
129
+
130
+ ## 11. Events zeigt dauerhaft `reconnecting`
131
+
132
+ `reconnecting` ist ein Folgezustand, nicht die eigentliche Ursache. Den zweiten Ausgang des Events-Nodes mit Debug verbinden.
133
+
134
+ Häufig:
135
+
136
+ - kein Refresh Token
137
+ - fehlender Monitor-Scope
138
+ - abgelaufene/entzogene Autorisierung
139
+ - Netzwerk-/Proxy-Unterbrechung des SSE-Streams
140
+ - zu viele parallele Event-Streams
141
+
142
+ Zuerst Geräteliste/Test reparieren, dann einen einzigen Events-Node mit Appliance ID `*` verwenden.
143
+
144
+ ## 12. Erfolgsbild
145
+
146
+ Die Einrichtung ist abgeschlossen, wenn:
147
+
148
+ 1. die Browserseite **Home Connect authorized** anzeigt,
149
+ 2. Test ohne Fehler eine Geräteanzahl meldet,
150
+ 3. **Geräte laden** die Auswahl befüllt,
151
+ 4. der Events-Node nach Verbindung Events ausgibt statt dauerhaft zu reconnecten.
152
+
153
+ ## 13. Sicheres Fehlerreporting
154
+
155
+ Erlaubt:
156
+
157
+ - Paketversion und Build-ID
158
+ - Node.js- und Node-RED-Version
159
+ - Umgebungstyp (Production/Simulator), ohne privaten Hostnamen
160
+ - Fehlercode und bereinigte Fehlermeldung
161
+ - Schritte zur Reproduktion mit Simulator
162
+
163
+ Nicht veröffentlichen:
164
+
165
+ - Client ID oder Client Secret
166
+ - Access-/Refresh-Token
167
+ - Authorization Code oder OAuth-State
168
+ - echte Redirect-URI/Hostname/IP
169
+ - echte `haId`, Serien-/Gerätenummern
170
+ - vollständige Events oder Debug-Ausgaben mit persönlichen Daten
171
+
172
+
173
+ ## 14. Health- und Warning-Codes verstehen
174
+
175
+ Jede funktionale Ausgabe enthält das Schema `home-connect-health/v1`:
176
+
177
+ - `ok`: keine aktuelle Auffälligkeit
178
+ - `running`: Programm läuft
179
+ - `info`: nützlicher, nicht dringender Hinweis
180
+ - `warning`: Einschränkung oder pausierter/abbrechender Zustand
181
+ - `action_required`: Eingriff oder neue Autorisierung erforderlich
182
+ - `offline`: Gerät, Event-Stream oder Netzwerk nicht erreichbar
183
+ - `error`: Geräte-/API-Fehler
184
+
185
+ `warnings` ist dedupliziert. Jeder Eintrag enthält mindestens `source`, `code`, `severity`, `text.de`, `text.en` und `transient`. Kurzlebige Hinweise besitzen zusätzlich Zeitfelder und verschwinden nach Ablauf. Statusbedingungen bleiben nur so lange bestehen, wie der aktuelle Status sie bestätigt.
186
+
187
+ Wichtige Codes:
188
+
189
+ | Code | Bedeutung | Maßnahme |
190
+ |---|---|---|
191
+ | `HC_OPERATION_ACTION_REQUIRED` | Gerät fordert lokalen Eingriff | Gerätedisplay/Tür/Vorräte prüfen |
192
+ | `HC_STREAM_DISCONNECTED` | SSE-Verbindung getrennt | Reconnect abwarten; bei Dauerfehler Ausgang 2 prüfen |
193
+ | `HC_OAUTH_INSUFFICIENT_SCOPE` | Token hat zu wenige Rechte | Scope korrigieren, deployen, neu autorisieren |
194
+ | `HC_OAUTH_AUTHORIZATION_EXPIRED` | Autorisierung fehlt/abgelaufen/widerrufen | neu autorisieren |
195
+ | `HC_API_RATE_LIMITED` | HTTP 429/API-Limit | Polling reduzieren, `retryAfter` beachten |
196
+ | `HC_NETWORK_ERROR` | Netzwerk/Timeout | DNS, Proxy, TLS und Erreichbarkeit prüfen |
197
+
198
+ Der Events-Node erzeugt zusätzlich synthetische `CONNECTED`-/`DISCONNECTED`-Lebenszyklusereignisse für den tatsächlichen SSE-Stream. Sie enthalten keine Zugangsdaten.
199
+
200
+ ## 15. HTTP 429 / `1000 calls in 1 day`
201
+
202
+ Der lokale Limiter verhindert standardmäßig, dass dieses Paket mehr als 900 API-Versuche in einem rollierenden 24-Stunden-Fenster sendet. In der Verbindung werden der aktuelle Verbrauch und eine eventuelle Sperrzeit angezeigt. Bei ausgeschöpftem Budget erscheint `LOCAL_RATE_LIMITED`; `retryAfter` und `resetAt` geben die verbleibende Wartezeit an.
203
+
204
+ Wenn Home Connect bereits HTTP 429 mit einer Meldung wie `remaining period of 75502 seconds` zurückgegeben hat, übernimmt das Paket diese Sperrzeit und sendet bis dahin keine weiteren API-Aufrufe. Der Zustand bleibt über Deploys und Neustarts erhalten. Nicht wiederholt auf **Test** oder Inject-Nodes klicken. Polling deutlich reduzieren, nach Möglichkeit einen All-Appliance-Event-Stream verwenden und Snapshots nicht alle 15 Sekunden abrufen. Andere Rechner oder Programme mit derselben Developer-Portal-Application separat prüfen, da sie nicht vom lokalen Zähler erfasst werden.
205
+
206
+ ## 16. Firmwareversion oder Firmwareupdate fehlt
207
+
208
+ Das ist kein Konfigurationsfehler. Die öffentlich dokumentierte Home-Connect-API stellt Firmwareversion, Firmwarehistorie und Firmwareupdate nicht bereit. Das Paket verwendet keine undokumentierten Endpunkte und bietet absichtlich keinen Firmware-Button. Sichtbar sind nur dokumentierte Geräteinformationen wie Name, Marke, Typ, `vib`/E-Nummer und Verbindungsstatus, sofern geliefert. Firmware ausschließlich über offizielle Hersteller-/Home-Connect-Kanäle prüfen.
209
+
210
+ ## 17. Lokale LAN-Profile und Verbindungsfehler
211
+
212
+ Bei lokalen Konfigurationen sind OAuth-, Autorisierungs-, Refresh-Token- und Cloud-Tagesbudget-Bereiche absichtlich ausgeblendet. Erfolgreich ist die Einrichtung, wenn **Verbindung testen** in jeder Gerätekarte eine lokale Read-only-Verbindung meldet und Discover/Read/Events `local: true` sowie `readOnly: true` liefern.
213
+
214
+ In dieser Reihenfolge prüfen:
215
+
216
+ 1. Prüfen, ob der Profilordner im Node-RED-Host/-Container wirklich unter dem eingetragenen Pfad gemountet und für das Servicekonto lesbar ist. Dann ausdrücklich **Profile suchen / Geräte erkennen** anklicken.
217
+ 2. Geräte-JSON, `DeviceDescription.xml` und `FeatureMapping.xml` desselben Profile-Downloader-Exports zusammenlassen. `LOCAL_PROFILE_FILES_INCOMPLETE` nennt die fehlende Datei; `LOCAL_PROFILE_ORPHAN_COMPANION` weist auf unpassende Ordner/Dateinamen hin.
218
+ 3. Bei einer doppelten Profil-ID nennt der Scanner die betroffenen Dateien. Keine Zuordnung raten: doppelten/alten Export entfernen und erneut suchen.
219
+ 4. Nach erfolgreicher Suche muss zum Beispiel **3 Geräteprofile gefunden** erscheinen. Für jedes vollständige Profil gibt es genau eine Karte. Fehlt eine Karte, die Hinweise direkt unter dem Suchergebnis lesen.
220
+ 5. In jeder Karte Host/IP eintragen. Fehlende, formal falsche oder öffentliche IPs werden rot markiert. Hostnamen werden beim Test serverseitig aufgelöst. Nur private/link-lokale Ziele sind erlaubt; Loopback und öffentliche Ziele werden mit `LOCAL_HOST_NOT_PRIVATE` abgewiesen. Ein Einzeltest verwendet sofort die aktuellen Felder genau dieser Karte, benötigt noch kein Fertig/Deploy und wird nicht von leeren Nachbarkarten blockiert.
221
+ 6. **Verbindungsart: Auto (empfohlen)** beibehalten. Eine ausdrückliche Profilangabe AES/TLS/PSK hat Vorrang; IV-Anwesenheit ist nur der Fallback. `LOCAL_PROFILE_IV_MISSING` bei AES-Override bedeutet, dass das Original-IV fehlt.
222
+ 7. Pro Karte **Verbindung testen** anklicken und die sieben Stufen lesen. `LOCAL_NETWORK_ERROR`/Timeout stoppt bei **IP erreichbar**. `EHOSTUNREACH` ist ein fehlender Netzwerkpfad und kein Protokollfehler: Gerät aus/Standby, IP, WLAN, VLAN-Routing und Firewall prüfen. `LOCAL_TLS_PSK_UNAVAILABLE`/`LOCAL_TRANSPORT_UNSUPPORTED` stoppt bei **Transport erkannt**. `LOCAL_WEBSOCKET_UPGRADE_FAILED` bedeutet: TCP beziehungsweise TLS war erfolgreich, aber das Gerät lehnte den Upgrade auf `/homeconnect` ab. Der Test liest nur lokale Ressourcen.
223
+ 8. Erst wenn alle Karten gültig sind: **Fertig → Deployen**. Dabei wird `localDeviceMappings` nochmals gespeichert und nach Deploy wiederhergestellt. Host/IP nie in Read-/Events-Nodes eintragen; dort die verständliche Bezeichnung wählen, während intern die volle ID erhalten bleibt.
224
+ 9. `LOCAL_CRYPTO_AUTH_FAILED`, `LOCAL_PROFILE_KEY_REJECTED` oder `LOCAL_PROFILE_AUTHENTICATION_FAILED` bedeutet falsches/unvollständiges Profil; PSK/IV weder bearbeiten noch raten. `LOCAL_PROTOCOL_REJECTED` ist davon getrennt und nennt Ressource, Aktion, ausgehandelte Version und Gerätecode. Einzelne nicht unterstützte `/ro/*`-Pfade sind zulässig, sobald ein anderer Read oder ein Geräte-`NOTIFY` Werte geliefert hat. Werden alle fünf Pfade abgelehnt, enthält `rejectedResources` die komplette Folge. `/ci/services` muss Version 1 ohne leeres `data`-Array verwenden.
225
+ 10. Werden nur numerische UIDs angezeigt, die XML-Dateien desselben Downloads wiederherstellen und neu suchen.
226
+ 11. Manuelles Profil-JSON ist nur der optionale Bereich **Erweitert**. Bei gesetztem Ordner ist es deaktiviert/ignoriert. Bei Bedarf mit der Schaltfläche aus erkannten Profilen und Zuordnungen erzeugen statt selbst schreiben.
227
+ 12. Für reale Firmwareabweichungen unter **Erweitert** den sicheren Protokoll-Mitschnitt kurz aktivieren. Ohne Pfad erscheint nur der begrenzte, bereinigte Speicherpuffer beim Test; ein absoluter Pfad schreibt unter POSIX JSONL mit `0600`. Unter Windows den Mitschnittpfad per NTFS-ACL auf das Node-RED-Dienstkonto beschränken, weil POSIX-Rechte dort nicht zuverlässig sind. PSK, IV, Schlüssel, Nonces sowie Geräte-/Netzwerkkennungen werden entfernt. Vor Weitergabe trotzdem prüfen, danach ausschalten und Datei löschen.
228
+ 13. `LOCAL_HEARTBEAT_TIMEOUT` oder `LOCAL_DISCONNECTED` nach zunächst erfolgreicher Verbindung deutet auf Strom/Standby, WLAN-Roaming, VLAN/Firewall oder Paketverlust. Die Runtime baut Transport, Kryptozustand, `sID`, `msgID`, Services und Read-Session mit Backoff vollständig neu auf.
229
+
230
+ `LOCAL_READ_ONLY` ist kein Verbindungsfehler, sondern die erfolgreiche lokale Schreibsperre. Für abgesicherte Schreibzugriffe eine separate Cloud-Konfiguration verwenden. Siehe [Lokale LAN-Verbindung](LOCAL-LAN.de.md).
@@ -0,0 +1,230 @@
1
+ # Home Connect troubleshooting and FAQ
2
+
3
+ Back to the [English README](../README.md).
4
+
5
+ Start with the visible symptom. Never include credentials, hostnames, appliance IDs, or OAuth codes in a bug report.
6
+
7
+ ## 1. Two-minute preflight check
8
+
9
+ 1. Is the expected build installed?
10
+ ```bash
11
+ cd ~/.node-red
12
+ node -p "require('./node_modules/node-red-contrib-home-connect/BUILD-INFO.json')"
13
+ ```
14
+ Expect version `0.2.0`, build `hc-0.2.0-final`, and `pkce: false`.
15
+ 2. Is the correct connection selected and clearly named?
16
+ 3. Did you click **Done → Deploy** after the latest change?
17
+ 4. Are the Redirect URIs in the Developer Portal and Node-RED exactly identical?
18
+ 5. Can the browser reach the configured Node-RED address?
19
+ 6. Did OAuth finish on the **Home Connect authorized** page?
20
+ 7. Do scopes include `IdentifyAppliance` and the required appliance-specific permissions?
21
+
22
+ ## 2. Authorize is disabled
23
+
24
+ This is intentional: the configuration node checks whether this exact saved configuration exists in the running Node-RED runtime.
25
+
26
+ - **New or changed connection:** click Done, deploy, and reopen the connection.
27
+ - **Built-in simulator:** OAuth is not required.
28
+ - **Still disabled:** restart Node-RED completely and hard-reload the browser. Check for an old or duplicate package installation.
29
+
30
+ ## 3. `CONFIG_NOT_FOUND`
31
+
32
+ **Meaning:** the URL contains the ID of a configuration node that the running runtime does not know.
33
+
34
+ Typical causes:
35
+
36
+ - an example or simulator configuration was referenced;
37
+ - the connection was created in the editor but not deployed;
38
+ - an old browser tab contains an authorization URL for a deleted configuration;
39
+ - another runtime instance is still active after a package or flow change.
40
+
41
+ **Fix:**
42
+
43
+ 1. Close the old authorization tab.
44
+ 2. Select the correct connection in the Home Connect node.
45
+ 3. Give it an unambiguous name.
46
+ 4. Click Done → Deploy.
47
+ 5. Reopen the connection.
48
+ 6. Start a new authorization from that connection.
49
+
50
+ ## 4. Misleading connection name
51
+
52
+ The **Environment** field controls the API host; the name does not. A name such as `Simulator` with the Production environment is still risky. The editor now warns about this combination. Rename, save, and deploy it.
53
+
54
+ ## 5. Exact Redirect URI comparison
55
+
56
+ These parts must match:
57
+
58
+ | Part | Common mistake |
59
+ |---|---|
60
+ | Protocol | `http` in the portal, `https` in Node-RED |
61
+ | Host | DNS name in one place, IP address in the other |
62
+ | Port | port omitted in one place |
63
+ | Path | typo in `/home-connect/oauth/callback` |
64
+ | Ending | extra slash `/callback/` |
65
+ | Case | different characters in the path |
66
+
67
+ Copy the complete URI from one field to the other instead of retyping it.
68
+
69
+ ## 6. After sign-in: localhost, `ERR_EMPTY_RESPONSE`, connection failed
70
+
71
+ From the browser's perspective, `localhost` is the browser's own computer. If Node-RED runs on a NAS, server, Raspberry Pi, Home Assistant, ioBroker, or another computer/container, the browser cannot reach Node-RED there via localhost.
72
+
73
+ 1. Choose a Node-RED hostname or IP address reachable from the browser.
74
+ 2. Append `/home-connect/oauth/callback`.
75
+ 3. Change the URI in the Developer Portal.
76
+ 4. Enter the identical URI in Node-RED.
77
+ 5. Click Done → Deploy.
78
+ 6. Start OAuth again.
79
+
80
+ ## 7. `unauthorized_client` / `client or redirection URI not authorized`
81
+
82
+ Check in this order:
83
+
84
+ 1. Was the Client ID copied from the correct Developer Portal Application?
85
+ 2. Does the Redirect URI match character for character?
86
+ 3. Does the Application use the Authorization Code Grant?
87
+ 4. Is PKCE disabled for that Application?
88
+ 5. Is build `hc-0.2.0-final` running?
89
+ 6. Did you start a new authorization after each change?
90
+
91
+ If the Client Secret was exposed, stop troubleshooting with that value: regenerate it, replace it in Node-RED, deploy, and authorize again.
92
+
93
+ ## 8. Old code still runs after an update
94
+
95
+ A flow deploy does not reload Node.js runtime code. Use BUILD-INFO in addition to the npm version when checking for duplicate installs.
96
+
97
+ ```bash
98
+ cd ~/.node-red
99
+ npm uninstall node-red-contrib-home-connect
100
+ rm -rf node_modules/node-red-contrib-home-connect
101
+ npm install --force /absolute/path/node-red-contrib-home-connect-0.2.0.tgz
102
+ node -p "require('./node_modules/node-red-contrib-home-connect/BUILD-INFO.json')"
103
+ ```
104
+
105
+ Then restart Node-RED or the container completely, hard-reload the browser, and begin OAuth again. Authorization codes and state links are short-lived and single-use.
106
+
107
+ ## 9. `No refresh token is stored. Complete OAuth authorization first.`
108
+
109
+ The refresh token is saved only after a successful callback.
110
+
111
+ - Start authorization from the deployed connection.
112
+ - Complete sign-in and consent.
113
+ - Wait for **Home Connect authorized**.
114
+ - Only then use Test, Discover, Read, or Events.
115
+
116
+ If it still fails, record the callback's error code but never publish codes or tokens.
117
+
118
+ ## 10. `insufficient_scope`
119
+
120
+ The token may not access the requested resource.
121
+
122
+ 1. Keep `IdentifyAppliance`.
123
+ 2. Add the relevant appliance-specific scope, such as `Dishwasher-Monitor`, `Washer-Monitor`, or `Oven-Monitor`.
124
+ 3. Add only the required `*-Control` and/or `*-Settings` for actions.
125
+ 4. Click Done → Deploy.
126
+ 5. Authorize again; an existing refresh token does not gain new permissions automatically.
127
+
128
+ The generic `Monitor` scope can be insufficient for some Applications/accounts.
129
+
130
+ ## 11. Events stays on `reconnecting`
131
+
132
+ `reconnecting` is a consequence, not the root cause. Connect the Events node's second output to Debug.
133
+
134
+ Common causes:
135
+
136
+ - no refresh token;
137
+ - missing monitor scope;
138
+ - expired or revoked authorization;
139
+ - network/proxy interruption of the SSE stream;
140
+ - too many parallel event streams.
141
+
142
+ Repair Test/appliance discovery first, then prefer one Events node with appliance ID `*`.
143
+
144
+ ## 12. Successful end state
145
+
146
+ Setup is complete when:
147
+
148
+ 1. the browser page displays **Home Connect authorized**;
149
+ 2. Test reports an appliance count without an error;
150
+ 3. **Load appliances** populates the selector;
151
+ 4. the Events node emits events instead of reconnecting indefinitely.
152
+
153
+ ## 13. Safe bug reports
154
+
155
+ Safe to include:
156
+
157
+ - package version and build ID;
158
+ - Node.js and Node-RED versions;
159
+ - environment type (Production/Simulator), without a private hostname;
160
+ - error code and sanitized message;
161
+ - simulator-based reproduction steps.
162
+
163
+ Never include:
164
+
165
+ - Client ID or Client Secret;
166
+ - access or refresh tokens;
167
+ - authorization code or OAuth state;
168
+ - real Redirect URI, hostname, or IP address;
169
+ - real `haId`, serial number, or appliance number;
170
+ - complete events or debug output containing personal data.
171
+
172
+
173
+ ## 14. Understanding health and warning codes
174
+
175
+ Every functional output uses schema `home-connect-health/v1`:
176
+
177
+ - `ok`: no current concern
178
+ - `running`: a program is running
179
+ - `info`: useful, non-urgent notice
180
+ - `warning`: restriction or paused/aborting state
181
+ - `action_required`: local intervention or renewed authorization required
182
+ - `offline`: appliance, event stream, or network unavailable
183
+ - `error`: appliance/API error
184
+
185
+ `warnings` is deduplicated. Every entry contains at least `source`, `code`, `severity`, `text.de`, `text.en`, and `transient`. Short-lived notices also include timing fields and disappear after expiry. Status conditions remain only while the current status confirms them.
186
+
187
+ Important codes:
188
+
189
+ | Code | Meaning | Action |
190
+ |---|---|---|
191
+ | `HC_OPERATION_ACTION_REQUIRED` | appliance requests local intervention | inspect appliance display, door, and supplies |
192
+ | `HC_STREAM_DISCONNECTED` | SSE connection disconnected | wait for reconnect; inspect output 2 if persistent |
193
+ | `HC_OAUTH_INSUFFICIENT_SCOPE` | token has insufficient rights | correct scope, deploy, authorize again |
194
+ | `HC_OAUTH_AUTHORIZATION_EXPIRED` | authorization missing/expired/revoked | authorize again |
195
+ | `HC_API_RATE_LIMITED` | HTTP 429/API limit | reduce polling and observe `retryAfter` |
196
+ | `HC_NETWORK_ERROR` | network/timeout | check DNS, proxy, TLS, and reachability |
197
+
198
+ The Events node also emits synthetic `CONNECTED`/`DISCONNECTED` lifecycle events for the actual SSE stream. They contain no credentials.
199
+
200
+ ## 15. HTTP 429 / `1000 calls in 1 day`
201
+
202
+ By default, the local limiter prevents this package from sending more than 900 API attempts in a rolling 24-hour window. The connection editor displays current usage and any active block. When the budget is exhausted, output 2 receives `LOCAL_RATE_LIMITED`; `retryAfter` and `resetAt` state the remaining wait.
203
+
204
+ If Home Connect has already returned HTTP 429 with text such as `remaining period of 75502 seconds`, the package adopts that block period and sends no further API calls until it expires. The state survives deploys and restarts. Do not repeatedly click **Test** or Inject nodes. Reduce polling substantially, prefer one all-appliance event stream, and do not request snapshots every 15 seconds. Check other computers or programs using the same Developer Portal Application because their calls are outside the local counter.
205
+
206
+ ## 16. Firmware version or update is missing
207
+
208
+ This is not a configuration error. The publicly documented Home Connect API does not provide firmware version, firmware history, or firmware update. The package does not use undocumented endpoints and intentionally provides no firmware button. It displays only documented appliance information such as name, brand, type, `vib`/E-number, and connection state when supplied. Check firmware only through official manufacturer/Home Connect channels.
209
+
210
+ ## 17. Local LAN profiles and connection failures
211
+
212
+ For local configurations, OAuth, authorization, refresh-token, and cloud daily-budget sections are intentionally hidden. Setup succeeds when **Test connection** in every device card reports a local read-only connection and Discover/Read/Events return `local: true` and `readOnly: true`.
213
+
214
+ Check in this order:
215
+
216
+ 1. Confirm the profile folder is mounted at the entered path inside the Node-RED host/container and readable by its service account. Then explicitly click **Scan profiles / Detect devices**.
217
+ 2. Keep appliance JSON, `DeviceDescription.xml`, and `FeatureMapping.xml` from the same Profile Downloader export together. `LOCAL_PROFILE_FILES_INCOMPLETE` names a missing file; `LOCAL_PROFILE_ORPHAN_COMPANION` indicates mismatched folders/names.
218
+ 3. A duplicate profile ID lists the affected files. Do not guess an assignment: remove the duplicate/old export and scan again.
219
+ 4. A successful scan says, for example, **3 device profiles found**, with one card per complete profile. If a card is absent, read the issues directly below the result.
220
+ 5. Enter Host/IP in every card. Missing, malformed, or public IPs are marked. Hostnames are resolved server-side during testing. Only private/link-local targets are accepted; loopback/public targets return `LOCAL_HOST_NOT_PRIVATE`. An individual card test uses that card's current fields immediately; it does not require Done/Deploy and is not blocked by empty sibling cards.
221
+ 6. Leave **Connection type: Auto (recommended)**. An explicit AES/TLS/PSK profile declaration wins; IV presence is only the fallback. `LOCAL_PROFILE_IV_MISSING` with an AES override means the original IV is absent.
222
+ 7. Click **Test connection** and read its seven stages. `LOCAL_NETWORK_ERROR`/timeout stops at **IP reachable**. `EHOSTUNREACH` means no network path and is not a protocol failure: check power/standby, IP, Wi-Fi, VLAN routing, and firewall. `LOCAL_TLS_PSK_UNAVAILABLE`/`LOCAL_TRANSPORT_UNSUPPORTED` stops at **Transport detected**. `LOCAL_WEBSOCKET_UPGRADE_FAILED` means TCP or TLS succeeded but the appliance rejected the upgrade on `/homeconnect`. The test reads local resources only.
223
+ 8. After all cards are valid, click **Done → Deploy**. `localDeviceMappings` is saved again on Done and restored after deploy. Never copy Host/IP into Read/Events; select the descriptive label while the full ID remains internal.
224
+ 9. `LOCAL_CRYPTO_AUTH_FAILED`, `LOCAL_PROFILE_KEY_REJECTED`, or `LOCAL_PROFILE_AUTHENTICATION_FAILED` points to the wrong/incomplete profile; re-download it and never edit/guess PSK/IV. `LOCAL_PROTOCOL_REJECTED` is separate and identifies resource, action, negotiated version, and device code. An unsupported `/ro/*` path is tolerated once another read or appliance `NOTIFY` delivered data. If all five paths are rejected, `rejectedResources` contains the complete sequence. `/ci/services` must be version 1 without an empty `data` array.
225
+ 10. If only numeric UIDs appear, restore the XML files from the same download and scan again.
226
+ 11. Manual profile JSON is only the optional **Advanced** fallback. It is disabled/ignored while a folder is set. Generate it from detected profiles and assignments instead of writing it manually.
227
+ 12. For real firmware differences, briefly enable the safe protocol trace under **Advanced**. With no path, the bounded sanitized memory trace is shown only after the test; an absolute path writes JSONL mode `0600` on POSIX. On Windows, restrict the trace path to the Node-RED service account with an NTFS ACL because POSIX mode bits are not reliable there. PSK, IV, keys, nonces, and appliance/network identifiers are removed. Inspect before sharing, then disable tracing and delete the file.
228
+ 13. `LOCAL_HEARTBEAT_TIMEOUT` or `LOCAL_DISCONNECTED` after an initially successful connection points to power/standby, Wi-Fi roaming, VLAN/firewall, or packet loss. The runtime rebuilds transport, crypto state, `sID`, `msgID`, services, and read session with backoff.
229
+
230
+ `LOCAL_READ_ONLY` is not a connectivity failure. It proves the local write barrier worked. Use a separate cloud configuration for guarded writes. See [Local LAN connection](LOCAL-LAN.md).
@@ -0,0 +1,10 @@
1
+ # Documentation screenshots
2
+
3
+ The final 0.2.0 release includes two user-provided, visually reviewed English PNG captures from the isolated simulated Demo:
4
+
5
+ - `dashboard-overview-en.png` — English **Demo Overview** with three simulated summary cards; 2048 × 511; SHA-256 `fda4af394e65bb2cc48eafec152ae04eabe422d4c18a19a5a2152c7e13dce222`
6
+ - `dashboard-details-en.png` — English details view with three simulated appliance cards; 2048 × 1063; SHA-256 `35f260f5ef49a8e8afb60c0ef19fb57961e966dbf44ce3f7039879e681a2dff9`
7
+
8
+ Visual and OCR-assisted privacy review confirmed that both captures show only English Demo content. Every card is marked `SIMULATED`; visible identifiers are synthetic `Demo`/`DEMO-*` values. The frames contain no browser profile or chrome, account name, email address, hostname, IP address, OAuth material, credential, token, QR code, local profile data, real appliance identifier, unrelated tab/window, or private notification.
9
+
10
+ Do not substitute screenshots from a real installation. `npm run release:check` verifies the exact reviewed SHA-256 hashes as well as PNG structure, minimum dimensions, and sensitive-looking metadata.