iobroker.poolcontrol 0.8.0 → 0.8.2
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.md +23 -0
- package/io-package.json +27 -27
- package/lib/helpers/aiChemistryHelpHelper.js +392 -0
- package/lib/helpers/aiForecastHelper.js +5 -0
- package/lib/helpers/aiHelper.js +16 -4
- package/lib/stateDefinitions/aiChemistryHelpStates.js +122 -0
- package/main.js +12 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -93,6 +93,17 @@ Er ermöglicht die Automatisierung von Pumpen-, Temperatur- und Solarsteuerung s
|
|
|
93
93
|
- Separate Schalter unter `ai.weather.switches.*` zum Aktivieren/Deaktivieren einzelner Prognosefunktionen
|
|
94
94
|
- Ergebnisse werden unter `ai.weather.outputs.forecast_text` gespeichert
|
|
95
95
|
|
|
96
|
+
- **Chemie-Hilfe (aiChemistryHelpHelper, ab v0.8.x)**
|
|
97
|
+
- Interaktive, rein informative KI-Hilfe zur Wasserchemie
|
|
98
|
+
- Auswahl typischer Poolprobleme über ein Auswahlfeld (z. B. pH zu hoch/niedrig, Chlor wirkt nicht, Wasser grün/trüb)
|
|
99
|
+
- Ausgabe verständlicher Ursachen- und Lösungsbeschreibungen als Text
|
|
100
|
+
- Keine automatische Dosierung
|
|
101
|
+
- Keine Produktempfehlungen
|
|
102
|
+
- Keine Steuerung von Geräten
|
|
103
|
+
- Keine Sprachausgabe (rein visuelle Information)
|
|
104
|
+
- Ziel: Ursachen verstehen und strukturiert vorgehen (messen → korrigieren → filtern → erneut messen)
|
|
105
|
+
- Datenpunkte unter `ai.chemistry_help.*`
|
|
106
|
+
|
|
96
107
|
|
|
97
108
|
- **Info-System (seit v0.7.x)**
|
|
98
109
|
- Informationssystem des Adapters
|
|
@@ -165,6 +176,18 @@ Neue Funktionen werden regelmäßig ergänzt – bitte den Changelog beachten.
|
|
|
165
176
|
## Changelog
|
|
166
177
|
### **WORK IN PROGRESS**
|
|
167
178
|
|
|
179
|
+
## v0.8.2 (2025-12-25)
|
|
180
|
+
- Neues KI-Modul **Chemie-Hilfe** (`aiChemistryHelpHelper`)
|
|
181
|
+
- Rein informatives Hilfesystem zur Poolwasserchemie
|
|
182
|
+
- Auswahl typischer Poolprobleme (z. B. pH zu hoch/niedrig, Chlor wirkt nicht, Wasser grün/trüb)
|
|
183
|
+
- Verständliche Ursachen- und Lösungshinweise als Textausgabe
|
|
184
|
+
- Keine automatische Dosierung
|
|
185
|
+
- Keine Produktempfehlungen
|
|
186
|
+
- Keine Geräte- oder Pumpensteuerung
|
|
187
|
+
- Keine Sprachausgabe (rein visuelle Information)
|
|
188
|
+
- Neue Datenpunkte unter `ai.chemistry_help.*`
|
|
189
|
+
|
|
190
|
+
|
|
168
191
|
## v0.8.0 (2025-12-08)
|
|
169
192
|
- Module: Wetterhinweise (Open-Meteo), Pooltipps, Tageszusammenfassung, Wochenendbericht
|
|
170
193
|
- Automatische Textausgaben mit optionaler Sprachausgabe
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "poolcontrol",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.2",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.8.2": {
|
|
7
|
+
"en": "New AI chemistry help module. Provides an interactive, purely informational help system for common pool water issues (e.g. pH too high/low, chlorine ineffective, green or cloudy water). Generates understandable explanations and solution directions without automatic dosing, product recommendations, device control or speech output.",
|
|
8
|
+
"de": "Neues KI-Chemie-Hilfesystem. Bietet eine interaktive, rein informative Unterstützung bei typischen Poolwasserproblemen (z. B. pH zu hoch/niedrig, Chlor wirkt nicht, grünes oder trübes Wasser). Erzeugt verständliche Ursachen- und Lösungshinweise ohne automatische Dosierung, Produktempfehlungen, Gerätesteuerung oder Sprachausgabe.",
|
|
9
|
+
"ru": "Новый модуль помощи по химии бассейна на основе ИИ. Интерактивная, исключительно информационная система поддержки для типичных проблем воды (например, высокий/низкий pH, неэффективный хлор, зелёная или мутная вода). Без автоматического дозирования, рекомендаций продуктов, управления устройствами или голосового вывода.",
|
|
10
|
+
"pt": "Novo módulo de ajuda química com IA. Sistema interativo e puramente informativo para problemas comuns da água da piscina (por exemplo, pH alto/baixo, cloro ineficaz, água verde ou turva). Sem dosagem automática, recomendações de produtos, controlo de dispositivos ou saída de voz.",
|
|
11
|
+
"nl": "Nieuw AI-chemiehulpmodule. Biedt een interactieve, puur informatieve hulp voor veelvoorkomende zwembadwaterproblemen (bijv. pH te hoog/laag, chloor werkt niet, groen of troebel water). Geen automatische dosering, productaanbevelingen, apparaatbesturing of spraakuitvoer.",
|
|
12
|
+
"fr": "Nouveau module d’aide chimique basé sur l’IA. Système interactif et purement informatif pour les problèmes courants de l’eau de piscine (pH trop élevé/bas, chlore inefficace, eau verte ou trouble). Sans dosage automatique, recommandations de produits, contrôle d’appareils ni sortie vocale.",
|
|
13
|
+
"it": "Nuovo modulo di aiuto chimico basato su IA. Sistema interattivo e puramente informativo per i problemi comuni dell’acqua della piscina (ad es. pH troppo alto/basso, cloro inefficace, acqua verde o torbida). Nessun dosaggio automatico, consigli sui prodotti, controllo dei dispositivi o output vocale.",
|
|
14
|
+
"es": "Nuevo módulo de ayuda química con IA. Sistema interactivo y puramente informativo para problemas comunes del agua de la piscina (p. ej., pH alto/bajo, cloro ineficaz, agua verde o turbia). Sin dosificación automática, recomendaciones de productos, control de dispositivos ni salida por voz.",
|
|
15
|
+
"pl": "Nowy moduł pomocy chemicznej oparty na AI. Interaktywny, wyłącznie informacyjny system wsparcia dla typowych problemów wody basenowej (np. zbyt wysokie/niskie pH, nieskuteczny chlor, zielona lub mętna woda). Bez automatycznego dozowania, rekomendacji produktów, sterowania urządzeniami ani komunikatów głosowych.",
|
|
16
|
+
"uk": "Новий модуль допомоги з хімії басейну на основі ШІ. Інтерактивна, виключно інформаційна система підтримки для типових проблем води (наприклад, високий/низький pH, неефективний хлор, зелена або каламутна вода). Без автоматичного дозування, рекомендацій продуктів, керування пристроями чи голосового виводу.",
|
|
17
|
+
"zh-cn": "新增 AI 水质化学帮助模块。为常见的泳池水问题(如 pH 过高/过低、氯无效、绿水或浑浊水)提供交互式、纯信息性的帮助说明。不包含自动投加、产品推荐、设备控制或语音输出。"
|
|
18
|
+
},
|
|
19
|
+
"0.8.1": {
|
|
20
|
+
"en": "Fix: AI messages were executed multiple times (e.g. 3x in Telegram). The timer system in aiHelper has been reworked: late executions now only run during the first 3 minutes after adapter start. All AI weather modules now trigger exactly once per day again. Stability improvements in the daily timers.",
|
|
21
|
+
"de": "Fix: KI-Meldungen wurden mehrfach ausgeführt (z.B. 3× in Telegram). Das Timer-System im aiHelper wurde überarbeitet: Nachholausführungen laufen jetzt nur noch in den ersten 3 Minuten nach Adapterstart. Alle AI-Wettermodule werden wieder exakt einmal pro Tag ausgelöst. Stabilitätsverbesserungen bei den täglichen Timern.",
|
|
22
|
+
"ru": "Исправление: сообщения ИИ выполнялись несколько раз (например, 3× в Telegram). Таймерная система в aiHelper была переработана: пропущенные задачи выполняются только в первые 3 минуты после запуска адаптера. Все модули погоды ИИ снова выполняются строго один раз в день.",
|
|
23
|
+
"pt": "Correção: mensagens de IA eram executadas várias vezes (ex.: 3× no Telegram). O sistema de temporizadores do aiHelper foi reestruturado: execuções atrasadas agora ocorrem apenas nos primeiros 3 minutos após iniciar o adaptador. Todos os módulos de clima da IA voltam a ser executados exatamente uma vez por dia.",
|
|
24
|
+
"nl": "Fix: AI-berichten werden meerdere keren uitgevoerd (bijv. 3× in Telegram). Het timersysteem in aiHelper is herwerkt: inhaaluitvoeringen draaien nu alleen in de eerste 3 minuten na adapterstart. Alle AI-weermodules worden weer precies één keer per dag uitgevoerd.",
|
|
25
|
+
"fr": "Correctif : les messages IA étaient exécutés plusieurs fois (ex. 3× dans Telegram). Le système de minuteries dans aiHelper a été revu : les exécutions différées ne s'exécutent plus que pendant les 3 premières minutes après le démarrage. Tous les modules météo IA se déclenchent à nouveau exactement une fois par jour.",
|
|
26
|
+
"it": "Fix: i messaggi dell'IA venivano eseguiti più volte (es. 3× su Telegram). Il sistema di timer dell'aiHelper è stato rivisto: le esecuzioni recuperate ora avvengono solo nei primi 3 minuti dopo l'avvio dell'adattatore. Tutti i moduli meteo IA ora si attivano nuovamente una sola volta al giorno.",
|
|
27
|
+
"es": "Corrección: los mensajes de IA se ejecutaban varias veces (p. ej., 3× en Telegram). Se ha rediseñado el sistema de temporizadores en aiHelper: las ejecuciones atrasadas ahora solo ocurren en los primeros 3 minutos tras iniciar el adaptador. Todos los módulos meteorológicos de IA vuelven a ejecutarse una sola vez al día.",
|
|
28
|
+
"pl": "Poprawka: komunikaty AI były wykonywane wielokrotnie (np. 3× w Telegramie). System timerów w aiHelper został przebudowany: zaległe wykonania działają teraz tylko w pierwszych 3 minutach po uruchomieniu adaptera. Wszystkie moduły pogodowe AI znów uruchamiają się dokładnie raz dziennie.",
|
|
29
|
+
"uk": "Виправлення: повідомлення ШІ виконувалися кілька разів (наприклад, 3× у Telegram). Систему таймерів в aiHelper перероблено: запізнілі виконання відбуваються лише в перші 3 хвилини після запуску. Усі погодні модулі ШІ знову працюють рівно один раз на добу.",
|
|
30
|
+
"zh-cn": "修复:AI 消息会被多次执行(例如在 Telegram 中出现 3 次)。已重构 aiHelper 中的计时器系统:补偿执行现在仅在适配器启动后的前 3 分钟内运行。所有 AI 天气模块现在每天只会执行一次。"
|
|
31
|
+
},
|
|
6
32
|
"0.8.0": {
|
|
7
33
|
"en": "New: Introduction of the AI Forecast System (aiForecastHelper). The adapter now creates a daily weather forecast for tomorrow, including temperature range, weather description, rain probability, wind analysis, and pool recommendations. New switches, schedules and outputs were added under ai.weather.*. First execution runs automatically at adapter start. Admin interface updated with important AI information.",
|
|
8
34
|
"de": "Neu: Einführung des KI-Vorhersagesystems (aiForecastHelper). Der Adapter erstellt nun täglich eine Wettervorhersage für morgen – inklusive Temperaturspanne, Wetterbeschreibung, Regenwahrscheinlichkeit, Windanalyse und Pool-Empfehlungen. Neue Schalter, Zeitpläne und Ausgaben unter ai.weather.* hinzugefügt. Erste Ausführung erfolgt automatisch beim Adapterstart. Admin-Oberfläche um wichtige KI-Hinweise erweitert.",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "Poprawka inicjalizacji czujnika ciśnienia: adapter poprawnie rozpoznaje teraz skonfigurowany identyfikator czujnika w pumpHelper4. Ulepszono również obsługę brakujących lub nieprawidłowych wartości.",
|
|
68
94
|
"uk": "Виправлення ініціалізації датчика тиску: адаптер тепер правильно розпізнає налаштований ID датчика в pumpHelper4. Покращено обробку відсутніх або некоректних значень.",
|
|
69
95
|
"zh-cn": "修复压力传感器初始化:适配器现在可以正确识别 pumpHelper4 中配置的传感器 ID,并改进了对缺失或无效数值的处理。"
|
|
70
|
-
},
|
|
71
|
-
"0.7.0": {
|
|
72
|
-
"en": "Added full pressure sensor integration (pump.pressure.*), including trend detection, self-learning min/max values, diagnostic output and configurable normal pressure range. No automatic control logic – purely informative.",
|
|
73
|
-
"de": "Vollständige Drucksensor-Integration (pump.pressure.*) hinzugefügt, inklusive Trenderkennung, selbstlernenden Min-/Max-Werten, Diagnoseausgabe und einstellbarem Normaldruckbereich. Keine automatische Logik – rein informativ.",
|
|
74
|
-
"ru": "Добавлена полная интеграция датчика давления (pump.pressure.*), включая определение тренда, самообучающиеся минимальные/максимальные значения, диагностический вывод и настраиваемый диапазон нормального давления. Без автоматической логики – только информация.",
|
|
75
|
-
"pt": "Adicionada integração completa do sensor de pressão (pump.pressure.*), incluindo detecção de tendência, valores mínimos/máximos autoaprendidos, saída de diagnóstico e faixa de pressão normal configurável. Sem lógica automática – apenas informativo.",
|
|
76
|
-
"nl": "Volledige druksensorintegratie (pump.pressure.*) toegevoegd, inclusief trenddetectie, zelflerende min/max-waarden, diagnostische uitvoer en instelbaar normaaldrukbereik. Geen automatische logica – puur informatief.",
|
|
77
|
-
"fr": "Intégration complète du capteur de pression (pump.pressure.*) ajoutée, comprenant la détection de tendance, des valeurs min/max auto-apprises, une sortie de diagnostic et une plage de pression normale configurable. Aucune logique automatique – uniquement informatif.",
|
|
78
|
-
"it": "Aggiunta integrazione completa del sensore di pressione (pump.pressure.*), con rilevamento delle tendenze, valori min/max autoapprendenti, output diagnostico e intervallo di pressione normale configurabile. Nessuna logica automatica – solo informativo.",
|
|
79
|
-
"es": "Se añadió la integración completa del sensor de presión (pump.pressure.*), incluyendo detección de tendencia, valores mínimos/máximos autoaprendidos, salida de diagnóstico y rango de presión normal configurable. Sin lógica automática – solo informativo.",
|
|
80
|
-
"pl": "Dodano pełną integrację czujnika ciśnienia (pump.pressure.*), w tym wykrywanie trendów, samo uczące się wartości min/max, dane diagnostyczne oraz konfigurowalny zakres ciśnienia normalnego. Bez automatycznej logiki – wyłącznie informacyjne.",
|
|
81
|
-
"uk": "Додано повну інтеграцію датчика тиску (pump.pressure.*), включаючи визначення трендів, самонавчальні мін/макс значення, діагностичний вихід та налаштовуваний діапазон нормального тиску. Без автоматичної логіки – лише інформаційно.",
|
|
82
|
-
"zh-cn": "新增完整压力传感器集成 (pump.pressure.*),包括趋势检测、自学习最小/最大值、诊断输出以及可配置的正常压力范围。无自动控制逻辑,仅提供信息。"
|
|
83
|
-
},
|
|
84
|
-
"0.6.5": {
|
|
85
|
-
"en": "Fix for weekly, monthly and yearly reset in consumptionHelper",
|
|
86
|
-
"de": "Fix für Wochen-, Monats- und Jahres-Reset im ConsumptionHelper",
|
|
87
|
-
"ru": "Исправление еженедельного, ежемесячного и ежегодного сброса в consumptionHelper",
|
|
88
|
-
"pt": "Correção para redefinição semanal, mensal e anual no consumptionHelper",
|
|
89
|
-
"nl": "Fix voor wekelijkse, maandelijkse en jaarlijkse reset in consumptionHelper",
|
|
90
|
-
"fr": "Correctif pour la réinitialisation hebdomadaire, mensuelle et annuelle dans consumptionHelper",
|
|
91
|
-
"it": "Correzione per il reset settimanale, mensile e annuale in consumptionHelper",
|
|
92
|
-
"es": "Corrección para el reinicio semanal, mensual y anual en consumptionHelper",
|
|
93
|
-
"pl": "Poprawka cotygodniowego, comiesięcznego i corocznego resetu w consumptionHelper",
|
|
94
|
-
"uk": "Виправлення щотижневого, щомісячного та щорічного скидання в consumptionHelper",
|
|
95
|
-
"zh-cn": "修复 consumptionHelper 中每周、每月和每年重置的问题"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -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;
|
|
@@ -38,6 +38,11 @@ const aiForecastHelper = {
|
|
|
38
38
|
|
|
39
39
|
await this._refreshTimer();
|
|
40
40
|
|
|
41
|
+
// ----------------------------------------------------------
|
|
42
|
+
// NEU: Delay, damit ioBroker alle States laden kann
|
|
43
|
+
// ----------------------------------------------------------
|
|
44
|
+
await new Promise(res => setTimeout(res, 1500));
|
|
45
|
+
|
|
41
46
|
// ----------------------------------------------------------
|
|
42
47
|
// NEU: Sofortige Ausführung beim Adapterstart (wenn aktiviert)
|
|
43
48
|
// ----------------------------------------------------------
|
package/lib/helpers/aiHelper.js
CHANGED
|
@@ -47,6 +47,8 @@ const aiHelper = {
|
|
|
47
47
|
_lastScheduleValues: {}, // NEU: merkt sich letzte Zeitwerte
|
|
48
48
|
_debugMode: false,
|
|
49
49
|
|
|
50
|
+
_adapterStartedAt: Date.now(), // FIX: Zeitpunkt des Adapterstarts
|
|
51
|
+
|
|
50
52
|
// Anti-Spam-Level (merkt sich letzte Warnungen)
|
|
51
53
|
_lastPoolTipCode: null,
|
|
52
54
|
_lastPoolTipWindLevel: null,
|
|
@@ -120,6 +122,11 @@ const aiHelper = {
|
|
|
120
122
|
// Timer neu aufbauen
|
|
121
123
|
await this._refreshTimers();
|
|
122
124
|
|
|
125
|
+
// ----------------------------------------------------------
|
|
126
|
+
// NEU: Delay, damit ioBroker alle States laden kann
|
|
127
|
+
// ----------------------------------------------------------
|
|
128
|
+
await new Promise(res => setTimeout(res, 1500));
|
|
129
|
+
|
|
123
130
|
// NEU: Wenn Uhrzeit heute noch in der Zukunft liegt → sofort ausführen
|
|
124
131
|
try {
|
|
125
132
|
const now = new Date();
|
|
@@ -303,15 +310,20 @@ const aiHelper = {
|
|
|
303
310
|
const timer = setInterval(async () => {
|
|
304
311
|
const now = new Date();
|
|
305
312
|
|
|
306
|
-
// ---
|
|
313
|
+
// --- FIX: Nachholen nur in den ersten 3 Minuten nach Adapterstart ---
|
|
307
314
|
const diffMinutes = now.getHours() * 60 + now.getMinutes() - (hour * 60 + minute);
|
|
308
315
|
|
|
309
|
-
|
|
316
|
+
const adapterUptimeMs = Date.now() - this._adapterStartedAt;
|
|
317
|
+
const withinStartupWindow = adapterUptimeMs <= 3 * 60 * 1000; // 3 Minuten
|
|
318
|
+
|
|
319
|
+
if (withinStartupWindow && diffMinutes > 0 && diffMinutes <= 2) {
|
|
310
320
|
try {
|
|
311
321
|
await callback();
|
|
312
|
-
this.adapter.log.
|
|
322
|
+
this.adapter.log.info(
|
|
323
|
+
'[aiHelper] Nachholung ausgeführt (innerhalb der ersten 3 Minuten nach Start)',
|
|
324
|
+
);
|
|
313
325
|
} catch (err) {
|
|
314
|
-
this.adapter.log.warn(`[aiHelper] Fehler bei
|
|
326
|
+
this.adapter.log.warn(`[aiHelper] Fehler bei Nachholung: ${err.message}`);
|
|
315
327
|
}
|
|
316
328
|
}
|
|
317
329
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* aiChemistryHelpStates.js
|
|
5
|
+
* ----------------------------------------------------------
|
|
6
|
+
* Legt die States für die KI-Chemie-Hilfe an.
|
|
7
|
+
*
|
|
8
|
+
* Zweck:
|
|
9
|
+
* - Manuelle Auswahl eines beobachteten Pool-Problems
|
|
10
|
+
* - Ausgabe eines erklärenden Hilfetextes (ohne Dosierung)
|
|
11
|
+
*
|
|
12
|
+
* Struktur:
|
|
13
|
+
* ai.chemistry_help.*
|
|
14
|
+
*
|
|
15
|
+
* Hinweis:
|
|
16
|
+
* - Reine Informationsfunktion
|
|
17
|
+
* - Keine Steuerung, keine Automatik, keine Sprachausgabe
|
|
18
|
+
* ----------------------------------------------------------
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Erstellt alle States für die AI-Chemie-Hilfe.
|
|
23
|
+
*
|
|
24
|
+
* @param {import('iobroker').Adapter} adapter - ioBroker Adapterinstanz
|
|
25
|
+
*/
|
|
26
|
+
async function createAiChemistryHelpStates(adapter) {
|
|
27
|
+
adapter.log.debug('[aiChemistryHelpStates] Initialisierung gestartet');
|
|
28
|
+
|
|
29
|
+
// ----------------------------------------------------------
|
|
30
|
+
// Channel: ai.chemistry_help
|
|
31
|
+
// ----------------------------------------------------------
|
|
32
|
+
await adapter.setObjectNotExistsAsync('ai.chemistry_help', {
|
|
33
|
+
type: 'channel',
|
|
34
|
+
common: {
|
|
35
|
+
name: 'Chemie-Hilfe (Erklärungen & Ursachen)',
|
|
36
|
+
},
|
|
37
|
+
native: {},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// ----------------------------------------------------------
|
|
41
|
+
// Auswahl des Problems (manuell)
|
|
42
|
+
// ----------------------------------------------------------
|
|
43
|
+
await adapter.setObjectNotExistsAsync('ai.chemistry_help.issue', {
|
|
44
|
+
type: 'state',
|
|
45
|
+
common: {
|
|
46
|
+
name: 'Chemie-Hilfe: Problem auswählen',
|
|
47
|
+
desc: 'Manuelle Auswahl eines beobachteten Pool-Problems zur Anzeige allgemeiner Erklärungen.',
|
|
48
|
+
type: 'string',
|
|
49
|
+
role: 'value',
|
|
50
|
+
read: true,
|
|
51
|
+
write: true,
|
|
52
|
+
def: 'none',
|
|
53
|
+
states: {
|
|
54
|
+
none: 'Kein Problem ausgewählt',
|
|
55
|
+
|
|
56
|
+
// pH-Wert
|
|
57
|
+
ph_low: 'pH-Wert ist zu niedrig',
|
|
58
|
+
ph_high: 'pH-Wert ist zu hoch',
|
|
59
|
+
|
|
60
|
+
// Chlor / Desinfektion
|
|
61
|
+
chlor_low: 'Chlorwert ist zu niedrig',
|
|
62
|
+
chlor_high: 'Chlorwert ist zu hoch',
|
|
63
|
+
chlor_no_effect: 'Chlor steigt trotz Zugabe nicht',
|
|
64
|
+
chlor_smell: 'Starker Chlorgeruch trotz Messwert',
|
|
65
|
+
|
|
66
|
+
// Wasserbild / Optik
|
|
67
|
+
water_green: 'Wasser ist grün',
|
|
68
|
+
water_cloudy: 'Wasser ist trüb / grau / milchig',
|
|
69
|
+
algae_visible: 'Algen an Wänden oder Boden sichtbar',
|
|
70
|
+
foam_on_surface: 'Schaumbildung auf der Wasseroberfläche',
|
|
71
|
+
|
|
72
|
+
// Badegefühl / Stabilität
|
|
73
|
+
skin_eye_irritation: 'Haut- oder Augenreizungen beim Baden',
|
|
74
|
+
values_unstable: 'Wasserwerte sind häufig instabil',
|
|
75
|
+
|
|
76
|
+
// Unsicherheit
|
|
77
|
+
unknown_problem: 'Problem unklar / nicht eindeutig',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
native: {},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// ----------------------------------------------------------
|
|
84
|
+
// Erklärungstext (wird später vom Helper gefüllt)
|
|
85
|
+
// ----------------------------------------------------------
|
|
86
|
+
await adapter.setObjectNotExistsAsync('ai.chemistry_help.help_text', {
|
|
87
|
+
type: 'state',
|
|
88
|
+
common: {
|
|
89
|
+
name: 'Chemie-Hilfe: Erklärung',
|
|
90
|
+
desc: 'Erklärender Text zu Ursachen und allgemeinen Lösungsansätzen (keine Dosierung, keine Steuerung).',
|
|
91
|
+
type: 'string',
|
|
92
|
+
role: 'text',
|
|
93
|
+
read: true,
|
|
94
|
+
write: false,
|
|
95
|
+
def: '',
|
|
96
|
+
},
|
|
97
|
+
native: {},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// ----------------------------------------------------------
|
|
101
|
+
// Zeitpunkt der letzten Auswahl
|
|
102
|
+
// ----------------------------------------------------------
|
|
103
|
+
await adapter.setObjectNotExistsAsync('ai.chemistry_help.last_issue_time', {
|
|
104
|
+
type: 'state',
|
|
105
|
+
common: {
|
|
106
|
+
name: 'Chemie-Hilfe: Letzte Auswahl',
|
|
107
|
+
desc: 'Zeitpunkt der letzten Auswahl eines Chemie-Hilfe-Problems.',
|
|
108
|
+
type: 'number',
|
|
109
|
+
role: 'value.time',
|
|
110
|
+
read: true,
|
|
111
|
+
write: false,
|
|
112
|
+
def: 0,
|
|
113
|
+
},
|
|
114
|
+
native: {},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
adapter.log.debug('[aiChemistryHelpStates] Initialisierung abgeschlossen');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = {
|
|
121
|
+
createAiChemistryHelpStates,
|
|
122
|
+
};
|
package/main.js
CHANGED
|
@@ -23,6 +23,7 @@ const statusHelper = require('./lib/helpers/statusHelper');
|
|
|
23
23
|
const photovoltaicHelper = require('./lib/helpers/photovoltaicHelper');
|
|
24
24
|
const aiHelper = require('./lib/helpers/aiHelper');
|
|
25
25
|
const aiForecastHelper = require('./lib/helpers/aiForecastHelper');
|
|
26
|
+
const aiChemistryHelpHelper = require('./lib/helpers/aiChemistryHelpHelper');
|
|
26
27
|
const controlHelper = require('./lib/helpers/controlHelper');
|
|
27
28
|
const controlHelper2 = require('./lib/helpers/controlHelper2');
|
|
28
29
|
const debugLogHelper = require('./lib/helpers/debugLogHelper');
|
|
@@ -47,6 +48,7 @@ const { createControlStates } = require('./lib/stateDefinitions/controlStates');
|
|
|
47
48
|
const { createDebugLogStates } = require('./lib/stateDefinitions/debugLogStates');
|
|
48
49
|
const { createInfoStates } = require('./lib/stateDefinitions/infoStates');
|
|
49
50
|
const { createAiStates } = require('./lib/stateDefinitions/aiStates'); // NEU: KI-States
|
|
51
|
+
const { createAiChemistryHelpStates } = require('./lib/stateDefinitions/aiChemistryHelpStates'); // NEU: KI-Chemie-Hilfe
|
|
50
52
|
|
|
51
53
|
class Poolcontrol extends utils.Adapter {
|
|
52
54
|
constructor(options) {
|
|
@@ -115,6 +117,7 @@ class Poolcontrol extends utils.Adapter {
|
|
|
115
117
|
|
|
116
118
|
// --- AI States ---
|
|
117
119
|
await createAiStates(this); // NEU: KI-States anlegen
|
|
120
|
+
await createAiChemistryHelpStates(this); // NEU: KI-Chemie-Hilfe-States
|
|
118
121
|
|
|
119
122
|
// --- Migration Helper zuletzt starten ---
|
|
120
123
|
await migrationHelper.init(this);
|
|
@@ -136,6 +139,7 @@ class Poolcontrol extends utils.Adapter {
|
|
|
136
139
|
photovoltaicHelper.init(this);
|
|
137
140
|
aiHelper.init(this);
|
|
138
141
|
aiForecastHelper.init(this);
|
|
142
|
+
aiChemistryHelpHelper.init(this);
|
|
139
143
|
frostHelper.init(this);
|
|
140
144
|
statusHelper.init(this);
|
|
141
145
|
infoHelper.init(this);
|
|
@@ -201,6 +205,9 @@ class Poolcontrol extends utils.Adapter {
|
|
|
201
205
|
if (aiForecastHelper.cleanup) {
|
|
202
206
|
aiForecastHelper.cleanup();
|
|
203
207
|
}
|
|
208
|
+
if (aiChemistryHelpHelper.cleanup) {
|
|
209
|
+
aiChemistryHelpHelper.cleanup();
|
|
210
|
+
}
|
|
204
211
|
if (infoHelper.cleanup) {
|
|
205
212
|
infoHelper.cleanup();
|
|
206
213
|
}
|
|
@@ -283,6 +290,11 @@ class Poolcontrol extends utils.Adapter {
|
|
|
283
290
|
} catch (e) {
|
|
284
291
|
this.log.warn(`[main] Fehler in aiForecastHelper.handleStateChange: ${e.message}`);
|
|
285
292
|
}
|
|
293
|
+
try {
|
|
294
|
+
aiChemistryHelpHelper.handleStateChange(id, state);
|
|
295
|
+
} catch (e) {
|
|
296
|
+
this.log.warn(`[main] Fehler in aiChemistryHelpHelper.handleStateChange: ${e.message}`);
|
|
297
|
+
}
|
|
286
298
|
try {
|
|
287
299
|
statusHelper.handleStateChange(id, state);
|
|
288
300
|
} catch (e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.poolcontrol",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Steuerung & Automatisierung für den Pool (Pumpe, Heizung, Ventile, Sensoren).",
|
|
5
5
|
"author": "DasBo1975 <dasbo1975@outlook.de>",
|
|
6
6
|
"homepage": "https://github.com/DasBo1975/ioBroker.poolcontrol",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "https://github.com/DasBo1975/ioBroker.poolcontrol.git"
|
|
18
|
+
"url": "git+https://github.com/DasBo1975/ioBroker.poolcontrol.git"
|
|
19
19
|
},
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">= 20"
|