iobroker.poolcontrol 0.8.1 → 0.9.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.
@@ -0,0 +1,392 @@
1
+ 'use strict';
2
+ /* eslint-disable jsdoc/require-param-description */
3
+ /* eslint-disable jsdoc/require-returns-description */
4
+
5
+ /**
6
+ * aiChemistryHelpHelper
7
+ * --------------------------------------------------------------
8
+ * KI-Chemie-Hilfe für PoolControl (rein informativ).
9
+ *
10
+ * Nutzt die States aus aiChemistryHelpStates.js:
11
+ * ai.chemistry_help.issue
12
+ * ai.chemistry_help.help_text
13
+ * ai.chemistry_help.last_issue_time
14
+ *
15
+ * Prinzip:
16
+ * - User wählt ein beobachtetes Problem (issue)
17
+ * - Helper schreibt einen erklärenden Text (help_text)
18
+ *
19
+ * WICHTIG:
20
+ * - Keine Dosierungen
21
+ * - Keine Produktempfehlungen
22
+ * - Keine Steuerung / Automatik
23
+ * - Keine Sprachausgabe (speech.queue bleibt unberührt)
24
+ *
25
+ * Inhalte:
26
+ * - Allgemeine Ursachen
27
+ * - Wichtige Zusammenhänge (pH ↔ Chlor ↔ Filterung)
28
+ * - Übliche Lösungsrichtungen (schrittweise, messen, zirkulieren)
29
+ */
30
+
31
+ const aiChemistryHelpHelper = {
32
+ adapter: null,
33
+
34
+ /**
35
+ * Initialisiert den Helper.
36
+ *
37
+ * @param {import('iobroker').Adapter} adapter
38
+ */
39
+ async init(adapter) {
40
+ this.adapter = adapter;
41
+ this.adapter.log.info('[aiChemistryHelpHelper] Initialisierung gestartet');
42
+
43
+ // NEU: auf Auswahländerungen reagieren
44
+ this.adapter.subscribeStates('ai.chemistry_help.issue');
45
+
46
+ // NEU: beim Start aktuellen Auswahlwert übernehmen (wenn vorhanden)
47
+ try {
48
+ const st = await this.adapter.getStateAsync('ai.chemistry_help.issue');
49
+ if (st && st.val !== null && st.val !== undefined) {
50
+ await this._processIssue(String(st.val));
51
+ }
52
+ } catch (e) {
53
+ this.adapter.log.debug(`[aiChemistryHelpHelper] Init: Konnte issue nicht lesen: ${e.message}`);
54
+ }
55
+
56
+ this.adapter.log.info('[aiChemistryHelpHelper] Initialisierung abgeschlossen');
57
+ },
58
+
59
+ /**
60
+ * Aufräumen beim Adapter-Stop.
61
+ */
62
+ cleanup() {
63
+ // aktuell keine Timer / Intervalle
64
+ this.adapter && this.adapter.log.debug('[aiChemistryHelpHelper] Cleanup abgeschlossen');
65
+ },
66
+
67
+ /**
68
+ * Reagiert auf State-Änderungen.
69
+ *
70
+ * @param {string} id
71
+ * @param {ioBroker.State | null} state
72
+ */
73
+ async handleStateChange(id, state) {
74
+ if (!this.adapter) {
75
+ return;
76
+ }
77
+ if (!state) {
78
+ return;
79
+ }
80
+
81
+ // Eigene Rückschreibungen ignorieren (Loop-Schutz)
82
+ if (
83
+ state.ack === true &&
84
+ (id.endsWith('.ai.chemistry_help.help_text') || id.endsWith('.ai.chemistry_help.last_issue_time'))
85
+ ) {
86
+ return;
87
+ }
88
+
89
+ // Nur unser relevanter Datenpunkt
90
+ if (!id.includes('.ai.chemistry_help.issue')) {
91
+ return;
92
+ }
93
+
94
+ let issue = 'none';
95
+
96
+ // Enum-Auswahl: Index → String auflösen
97
+ if (typeof state.val === 'number') {
98
+ try {
99
+ const obj = await this.adapter.getObjectAsync(id);
100
+ if (obj?.common?.states) {
101
+ issue = obj.common.states[state.val] || 'none';
102
+ }
103
+ } catch (e) {
104
+ this.adapter.log.debug(`[aiChemistryHelpHelper] Konnte Enum-Text nicht auflösen: ${e.message}`);
105
+ }
106
+ } else {
107
+ issue = String(state.val || 'none');
108
+ }
109
+ this.adapter.log.debug(`[aiChemistryHelpHelper] Auswahl geändert: ${issue}`);
110
+
111
+ await this._processIssue(issue);
112
+ },
113
+
114
+ // ---------------------------------------------------------------------
115
+ // Core
116
+ // ---------------------------------------------------------------------
117
+
118
+ /**
119
+ * Schreibt Text + Timestamp für das gewählte Problem.
120
+ *
121
+ * @param {string} issue
122
+ */
123
+ async _processIssue(issue) {
124
+ const normalized = (issue || 'none').trim();
125
+
126
+ // "none" oder leer → Text leeren
127
+ if (!normalized || normalized === 'none') {
128
+ await this._setStateIfChanged('ai.chemistry_help.help_text', '');
129
+ await this._setStateIfChanged('ai.chemistry_help.last_issue_time', Date.now());
130
+ return;
131
+ }
132
+
133
+ const text = this._getHelpText(normalized);
134
+
135
+ await this.adapter.setStateAsync('ai.chemistry_help.help_text', {
136
+ val: text,
137
+ ack: true,
138
+ });
139
+ await this.adapter.setStateAsync('ai.chemistry_help.last_issue_time', {
140
+ val: Date.now(),
141
+ ack: true,
142
+ });
143
+ },
144
+
145
+ /**
146
+ * Liefert den finalen Hilfetext (Deutsch) für ein Problem.
147
+ *
148
+ * @param {string} issue
149
+ * @returns {string}
150
+ */
151
+ _getHelpText(issue) {
152
+ const commonFooter =
153
+ '\n\nWichtig:\n' +
154
+ '• Immer schrittweise vorgehen: erst messen → klein korrigieren → umwälzen lassen → erneut messen.\n' +
155
+ '• Angaben auf dem Produkt beachten (Konzentration/Beckenvolumen unterscheiden sich).\n' +
156
+ '• Wenn du unsicher bist: lieber langsamer korrigieren als „mit Gewalt“.\n';
157
+
158
+ const map = {
159
+ // ----------------------------------------------------------
160
+ // pH
161
+ // ----------------------------------------------------------
162
+ ph_low:
163
+ `Problem: pH-Wert ist zu niedrig (Wasser ist „zu sauer“).\n\n` +
164
+ `Was das bedeutet:\n` +
165
+ `Ein zu niedriger pH-Wert kann Material (Metalle/Einbauteile) stärker angreifen und Badereizungen begünstigen. Außerdem kann die Wasserbalance insgesamt instabil werden.\n\n` +
166
+ `Häufige Ursachen:\n` +
167
+ `• Viel Regen-/Frischwasser (kann das Wasser „ansäuern“)\n` +
168
+ `• Niedrige Alkalinität (Puffer fehlt → pH fällt schneller)\n` +
169
+ `• Häufige Korrekturen/Backwash/Wasserwechsel\n\n` +
170
+ `Übliche Lösungsrichtung:\n` +
171
+ `• pH mit einem „pH-Plus“/pH-Heber schrittweise anheben.\n` +
172
+ `• Wenn der pH ständig wieder fällt: Totalalkalinität/„Puffer“ mit prüfen, weil sonst jede pH-Korrektur nur kurz hält.\n${
173
+ commonFooter
174
+ }`,
175
+
176
+ ph_high:
177
+ `Problem: pH-Wert ist zu hoch (Wasser ist „zu basisch“).\n\n` +
178
+ `Was das bedeutet:\n` +
179
+ `Bei zu hohem pH-Wert arbeitet Chlor/Desinfektion oft schlechter, und es kann leichter zu Trübungen/Ausfällungen kommen (z. B. Kalk). Außerdem können Augen/Haut gereizt sein.\n\n` +
180
+ `Häufige Ursachen:\n` +
181
+ `• Starkes „Ausgasen“/viel Sprudel (CO₂ entweicht → pH steigt)\n` +
182
+ `• Hartes Wasser / hohe Alkalinität\n` +
183
+ `• Manche Becken/Materialien können anfangs pH nach oben ziehen\n\n` +
184
+ `Übliche Lösungsrichtung:\n` +
185
+ `• pH mit „pH-Minus“/pH-Senker in kleinen Schritten senken.\n` +
186
+ `• Bei wiederkehrend hohem pH: Alkalinität/Wasserhärte mit betrachten, weil das die Stabilität stark beeinflusst.\n${
187
+ commonFooter
188
+ }`,
189
+
190
+ // ----------------------------------------------------------
191
+ // Chlor
192
+ // ----------------------------------------------------------
193
+ chlor_low:
194
+ `Problem: Chlorwert ist zu niedrig.\n\n` +
195
+ `Was das bedeutet:\n` +
196
+ `Zu wenig wirksames Chlor kann dazu führen, dass sich Keime/Algen leichter vermehren. Häufig sieht man dann zuerst „müdes“ Wasser: weniger klar, mehr Geruch, schneller Belag.\n\n` +
197
+ `Häufige Ursachen:\n` +
198
+ `• Viel Sonne/UV (Chlor wird schneller abgebaut)\n` +
199
+ `• Hohe Badebelastung (Schweiß/Organik „verbraucht“ Chlor)\n` +
200
+ `• pH-Wert ungünstig (Chlor wirkt schlechter)\n\n` +
201
+ `Übliche Lösungsrichtung:\n` +
202
+ `• Desinfektion wieder in einen normalen Bereich bringen und parallel pH kontrollieren.\n` +
203
+ `• Wenn Chlor dauerhaft „wegbricht“: Ursachen wie organische Belastung/Filterzustand/Umwälzung mit prüfen.\n${
204
+ commonFooter
205
+ }`,
206
+
207
+ chlor_high:
208
+ `Problem: Chlorwert ist zu hoch.\n\n` +
209
+ `Was das bedeutet:\n` +
210
+ `Zu hoher Chlorwert kann Augen/Haut reizen, starken Geruch verursachen und Material/Abdeckungen stärker belasten. In diesem Zustand ist „mehr Chemie“ fast nie die richtige Richtung.\n\n` +
211
+ `Häufige Ursachen:\n` +
212
+ `• Zu viel nachdosiert / Schockbehandlung zu hoch\n` +
213
+ `• Zu wenig Abbau (Abdeckung drauf + wenig Sonne)\n\n` +
214
+ `Übliche Lösungsrichtung:\n` +
215
+ `• Keine weitere Chlorzugabe.\n` +
216
+ `• Zeit wirken lassen (Sonne/UV baut Chlor ab) und gut umwälzen.\n` +
217
+ `• Erst wenn Chlor wieder im normalen Bereich ist, weitere Korrekturen (z. B. pH) sinnvoll bewerten.\n${
218
+ commonFooter
219
+ }`,
220
+
221
+ chlor_no_effect:
222
+ `Problem: „Chlor steigt trotz Zugabe nicht“.\n\n` +
223
+ `Was das bedeutet:\n` +
224
+ `Das passiert häufig, wenn das Wasser eine hohe „Chlornachfrage“ hat: Das zugegebene Chlor wird sofort verbraucht, bevor ein stabiler freier Chlorwert messbar bleibt.\n\n` +
225
+ `Häufige Ursachen:\n` +
226
+ `• Hohe organische Belastung (Schmutz, Biofilm, starke Nutzung)\n` +
227
+ `• Beginnender/unsichtbarer Algenbefall\n` +
228
+ `• Stark falscher pH-Wert (Wirkung eingeschränkt)\n\n` +
229
+ `Übliche Lösungsrichtung:\n` +
230
+ `• Erst Grundwerte prüfen (pH, Filter/Umwälzung, Sichtprüfung auf Beläge).\n` +
231
+ `• Wasser „sauber bekommen“ (Filter reinigen/rückspülen, Becken bürsten), damit Chlor nicht nur „verbraucht“ wird.\n` +
232
+ `• Wenn dauerhaft keine Wirkung messbar ist, liegt oft ein „oxidativer Bedarf“ vor (Chlor wird sofort gebunden/abgebaut) – dann hilft nur konsequent Ursachen reduzieren und danach erneut messen.\n${
233
+ commonFooter
234
+ }`,
235
+
236
+ chlor_smell:
237
+ `Problem: Starker „Chlorgeruch“ trotz Messwert.\n\n` +
238
+ `Was das bedeutet:\n` +
239
+ `Der typische „Hallenbad-Geruch“ kommt oft nicht von „zu viel gutem Chlor“, sondern von gebundenen Chlorverbindungen (Chloramine). Diese entstehen, wenn Chlor sich mit Stickstoff-/Organik aus Schweiß/Urinfrachten verbindet.\n\n` +
240
+ `Häufige Ursachen:\n` +
241
+ `• Hohe Badebelastung / organische Einträge\n` +
242
+ `• Zu wenig Frischwasser/Abbau/Filterpflege\n` +
243
+ `• Schlechte Lüftung (bei Indoor-Pools) verstärkt die Wahrnehmung\n\n` +
244
+ `Übliche Lösungsrichtung:\n` +
245
+ `• Ziel ist, gebundene Belastung zu reduzieren: gute Umwälzung/Filtration, Beckenreinigung, ggf. Frischwasseranteil.\n` +
246
+ `• Parallel pH prüfen, weil falscher pH die Desinfektion zusätzlich verschlechtert.\n${commonFooter}`,
247
+
248
+ // ----------------------------------------------------------
249
+ // Wasserbild / Optik
250
+ // ----------------------------------------------------------
251
+ water_green:
252
+ `Problem: Wasser ist grün.\n\n` +
253
+ `Was das bedeutet:\n` +
254
+ `Grünes Wasser ist sehr häufig ein Hinweis auf Algenwachstum (oft ausgelöst durch zu wenig wirksames Chlor und/oder schlechte Umwälzung).\n\n` +
255
+ `Häufige Ursachen:\n` +
256
+ `• Freies Chlor zu niedrig oder „verbraucht“\n` +
257
+ `• pH zu hoch → Chlor wirkt deutlich schlechter\n` +
258
+ `• Filter/Umwälzung unzureichend oder Filter verschmutzt\n` +
259
+ `• Hohe Temperatur + Sonne (Algenwachstum wird begünstigt)\n\n` +
260
+ `Übliche Lösungsrichtung:\n` +
261
+ `• Wasserwerte prüfen (insb. pH und Chlor) und Umwälzung/Filterzustand verbessern.\n` +
262
+ `• Becken gründlich bürsten/absaugen, damit Beläge nicht „überleben“.\n` +
263
+ `• Danach geduldig filtern lassen, bis das Wasser wieder klar wird.\n${commonFooter}`,
264
+
265
+ water_cloudy:
266
+ `Problem: Wasser ist trüb / grau / milchig.\n\n` +
267
+ `Was das bedeutet:\n` +
268
+ `Trübes Wasser entsteht oft durch feine Schwebstoffe oder chemische Ungleichgewichte (z. B. pH/Alkalinität/Kalk), die der Filter nicht gut „packt“.\n\n` +
269
+ `Häufige Ursachen:\n` +
270
+ `• Filter verschmutzt/zu kurze Filterlaufzeit\n` +
271
+ `• pH/Alkalinität außerhalb des stabilen Bereichs\n` +
272
+ `• Hohe Wasserhärte (Kalk) – besonders in Kombination mit hohem pH\n` +
273
+ `• Zu wenig Desinfektion → biologische Trübung möglich\n\n` +
274
+ `Übliche Lösungsrichtung:\n` +
275
+ `• Filterzustand prüfen (Reinigung/Rückspülen) und ausreichend umwälzen.\n` +
276
+ `• Grundwerte pH/Chlor prüfen und stabilisieren.\n` +
277
+ `• Wenn die Trübung „mineralisch“ wirkt (milchig/weiß): Wasserhärte/Balance mit betrachten.\n${
278
+ commonFooter
279
+ }`,
280
+
281
+ algae_visible:
282
+ `Problem: Algen an Wänden oder Boden sichtbar.\n\n` +
283
+ `Was das bedeutet:\n` +
284
+ `Sichtbare Algen sind ein klares Zeichen, dass die Desinfektion/Umwälzung nicht ausreichend war oder lokal tote Zonen entstehen (Ecken/Leitungen).\n\n` +
285
+ `Häufige Ursachen:\n` +
286
+ `• Chlor zu niedrig oder „verbraucht“\n` +
287
+ `• pH zu hoch (Chlor wirkt schlechter)\n` +
288
+ `• Zu wenig Bürsten/Beckenpflege, schlechte Zirkulation\n\n` +
289
+ `Übliche Lösungsrichtung:\n` +
290
+ `• Mechanik zuerst: konsequent bürsten/absaugen, Filterpflege.\n` +
291
+ `• Werte (pH/Chlor) danach stabilisieren und Umwälzung verbessern.\n` +
292
+ `• Ziel ist, Algen nicht nur „chemisch“, sondern auch mechanisch zu entfernen.\n${commonFooter}`,
293
+
294
+ foam_on_surface:
295
+ `Problem: Schaumbildung auf der Wasseroberfläche.\n\n` +
296
+ `Was das bedeutet:\n` +
297
+ `Schaum entsteht oft durch Tenside/Organik (Sonnencreme, Körperpflege, Reinigungsreste), manche Algenmittel/Polymere oder auch Luft im System. Es ist meist kein „Chlor-Problem“, sondern ein „Stoffe-im-Wasser“-Problem.\n\n` +
298
+ `Häufige Ursachen:\n` +
299
+ `• Viele Lotionen/Öle im Wasser, hohe organische Belastung\n` +
300
+ `• Bestimmte algenhemmende Mittel können Schaum begünstigen\n` +
301
+ `• Luft zieht ins System (kleine Undichtigkeiten) → Schaum wirkt stärker\n\n` +
302
+ `Übliche Lösungsrichtung:\n` +
303
+ `• Oberfläche abschöpfen, Filter sauber halten, organische Einträge reduzieren.\n` +
304
+ `• pH/Chlor im Blick behalten (stabile Werte helfen, Organik schneller abzubauen).\n` +
305
+ `• Wenn Schaum dauerhaft bleibt: Quelle (Produkte/Einträge/Technik) systematisch eingrenzen.\n${
306
+ commonFooter
307
+ }`,
308
+
309
+ // ----------------------------------------------------------
310
+ // Badegefühl / Stabilität
311
+ // ----------------------------------------------------------
312
+ skin_eye_irritation:
313
+ `Problem: Haut- oder Augenreizungen beim Baden.\n\n` +
314
+ `Was das bedeutet:\n` +
315
+ `Reizungen können verschiedene Ursachen haben: zu hoher oder sehr niedriger pH, zu hohe Desinfektionskonzentration, oder gebundene Chlorverbindungen (Chloramine) bei organischer Belastung.\n\n` +
316
+ `Häufige Ursachen:\n` +
317
+ `• pH außerhalb des Wohlfühlbereichs\n` +
318
+ `• Chlor deutlich zu hoch\n` +
319
+ `• „Chlorgeruch“/Chloramine durch starke organische Einträge\n\n` +
320
+ `Übliche Lösungsrichtung:\n` +
321
+ `• Zuerst messen (pH & Chlor) und Werte wieder in einen normalen Bereich bringen.\n` +
322
+ `• Becken/Filter sauber halten, damit organische Belastung nicht in „gebundene“ Formen kippt.\n` +
323
+ `• Bei starken Beschwerden: Baden pausieren, bis Wasserwerte stabil sind.\n${commonFooter}`,
324
+
325
+ values_unstable:
326
+ `Problem: Wasserwerte sind häufig instabil (kippen schnell).\n\n` +
327
+ `Was das bedeutet:\n` +
328
+ `Wenn pH/Chlor ständig stark schwanken, fehlt oft „Stabilität“ im Wasser: Puffer (Alkalinität) zu niedrig/zu hoch, wechselnde Belastung, oder die Umwälzung/Filtration ist nicht konstant genug.\n\n` +
329
+ `Häufige Ursachen:\n` +
330
+ `• Totalalkalinität zu niedrig → pH springt/kippt schnell\n` +
331
+ `• Viele kleine Korrekturen ohne ausreichende Umwälzzeit\n` +
332
+ `• Filterzustand schlecht / zu kurze Filterzeiten\n` +
333
+ `• Starke externe Einflüsse (Regen, Hitze, hohe Nutzung)\n\n` +
334
+ `Übliche Lösungsrichtung:\n` +
335
+ `• Einmal „Basis“ stabil bekommen (Puffer/Filter/Regelmäßigkeit), dann erst fein korrigieren.\n` +
336
+ `• Korrigieren immer in kleinen Schritten und mit Zeit zum Durchmischen.\n${commonFooter}`,
337
+
338
+ unknown_problem:
339
+ `Problem: Unklar, was genau los ist.\n\n` +
340
+ `Vorgehen (minimal & sinnvoll):\n` +
341
+ `1) Sichtcheck: Grün? Trüb? Beläge? Schaum?\n` +
342
+ `2) Zwei Messwerte reichen für den Start: pH + freies Chlor.\n` +
343
+ `3) Technik prüfen: Läuft die Umwälzung? Filter sauber? Rückspülen nötig?\n\n` +
344
+ `Typische Faustregel:\n` +
345
+ `• Optik-Probleme (grün/trüb) sind sehr oft eine Kombination aus Desinfektion + pH + Filterung.\n` +
346
+ `• „Geruch/Reizung“ ist oft nicht „zu viel Chlor“, sondern „falsch gebunden/organisch belastet“.\n${
347
+ commonFooter
348
+ }`,
349
+ };
350
+
351
+ if (map[issue]) {
352
+ return map[issue];
353
+ }
354
+
355
+ // Fallback
356
+ return (
357
+ `Hinweis: Dieses Problem ist (noch) nicht bekannt.\n\n` +
358
+ `Bitte wähle einen der vorhandenen Punkte aus oder nutze „Problem unklar / nicht eindeutig“.\n${
359
+ commonFooter
360
+ }`
361
+ );
362
+ },
363
+
364
+ // ---------------------------------------------------------------------
365
+ // Helpers
366
+ // ---------------------------------------------------------------------
367
+
368
+ /**
369
+ * Setzt einen State nur dann, wenn sich der Wert wirklich ändert.
370
+ * Verhindert unnötige State-Writes und mögliche Loop-Effekte.
371
+ *
372
+ * @param {string} id
373
+ * @param {string|number|boolean} value
374
+ */
375
+ async _setStateIfChanged(id, value) {
376
+ try {
377
+ const current = await this.adapter.getStateAsync(id);
378
+ const curVal = current ? current.val : undefined;
379
+
380
+ // String/Number/Bool robust vergleichen
381
+ if (String(curVal ?? '') === String(value ?? '')) {
382
+ return;
383
+ }
384
+
385
+ await this.adapter.setStateAsync(id, { val: value, ack: true });
386
+ } catch (e) {
387
+ this.adapter.log.debug(`[aiChemistryHelpHelper] _setStateIfChanged Fehler (${id}): ${e.message}`);
388
+ }
389
+ },
390
+ };
391
+
392
+ module.exports = aiChemistryHelpHelper;