iobroker.poolcontrol 1.3.29 → 1.3.30
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 +6 -6
- package/admin/i18n/de/translations.json +0 -1
- package/admin/i18n/es/translations.json +0 -1
- package/admin/i18n/fr/translations.json +0 -1
- package/admin/i18n/it/translations.json +0 -1
- package/admin/i18n/nl/translations.json +0 -1
- package/admin/i18n/pl/translations.json +0 -1
- package/admin/i18n/pt/translations.json +0 -1
- package/admin/i18n/ru/translations.json +0 -1
- package/admin/i18n/uk/translations.json +0 -1
- package/admin/i18n/zh-cn/translations.json +0 -1
- package/io-package.json +14 -14
- package/lib/helpers/aiForecastHelper.js +6 -4
- package/lib/helpers/aiHelper.js +6 -4
- package/lib/helpers/poolInsightsHelper.js +130 -23
- package/lib/stateDefinitions/poolInsightsStates.js +19 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -271,6 +271,12 @@ New features are added regularly – please refer to the changelog.
|
|
|
271
271
|
---
|
|
272
272
|
|
|
273
273
|
## Changelog
|
|
274
|
+
### 1.3.30 (2026-06-05)
|
|
275
|
+
|
|
276
|
+
- Updated release tooling to the required minimum version.
|
|
277
|
+
- Cleaned up outdated Admin i18n keys.
|
|
278
|
+
- Replaced native timers in AI weather helpers with ioBroker adapter timers.
|
|
279
|
+
|
|
274
280
|
### 1.3.29 (2026-06-04)
|
|
275
281
|
|
|
276
282
|
- Added Pool Insights V1 with observations, status evaluation and runtime i18n support.
|
|
@@ -301,12 +307,6 @@ New features are added regularly – please refer to the changelog.
|
|
|
301
307
|
- Internal cleanup and small structural improvements
|
|
302
308
|
- Further preparation for cleaner review and repository checks
|
|
303
309
|
|
|
304
|
-
### 1.3.25 (2026-05-26)
|
|
305
|
-
|
|
306
|
-
- Updated README structure and feature overview
|
|
307
|
-
- Synchronized German and English function overviews
|
|
308
|
-
- Updated repository maintenance dependencies
|
|
309
|
-
|
|
310
310
|
## Archived Release History
|
|
311
311
|
|
|
312
312
|
For older releases and archived version history see:
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "Logischer Kontrollstatus (wahr/falsch)",
|
|
66
66
|
"Mail": "E-Mail",
|
|
67
67
|
"Male": "Männlich",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "Viele automatische Funktionen (z. B. Solarsteuerung, Photovoltaikmodus, KI-Wetterlogik und Diagnosefunktionen) funktionieren nur, wenn die Poolsaison aktiv ist. Der Saisonstatus kann jederzeit über den Datenpunkt „status.season_active“ oder in der Instanzkonfiguration geändert werden.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "Viele automatische Funktionen (z. B. Solarsteuerung, Photovoltaikmodus, KI-Wetterlogik und Diagnosefunktionen) funktionieren nur, wenn die Poolsaison aktiv ist. Der Saisonstatus kann jederzeit über den Datenpunkt „status.season_active“ oder Ihre Visualisierung geändert werden. Die Instanzkonfiguration liefert nur den Anfangswert, wenn der Datenpunkt zum ersten Mal erstellt wird.",
|
|
70
69
|
"Max Power (Watt)": "Maximale Leistung (Watt)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Maximale Pooltemperatur (°C – Sicherheitsabschaltung)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "Estado de control lógico (verdadero/falso)",
|
|
66
66
|
"Mail": "Correo",
|
|
67
67
|
"Male": "Masculino",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "Muchas funciones automáticas (por ejemplo, control solar, modo fotovoltaico, lógica meteorológica AI y funciones de diagnóstico) solo funcionan cuando la temporada de piscina está activa. El estado de la temporada se puede cambiar en cualquier momento a través del punto de datos 'status.season_active' o en la configuración de la instancia.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "Muchas funciones automáticas (por ejemplo, control solar, modo fotovoltaico, lógica meteorológica AI y funciones de diagnóstico) solo funcionan cuando la temporada de piscina está activa. El estado de la temporada se puede cambiar en cualquier momento a través del punto de datos 'status.season_active' o su visualización. La configuración de la instancia solo proporciona el valor inicial cuando el punto de datos se crea por primera vez.",
|
|
70
69
|
"Max Power (Watt)": "Potencia máxima (vatios)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Temperatura máxima de la piscina (°C – Límite de seguridad)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "État de contrôle logique (vrai/faux)",
|
|
66
66
|
"Mail": "Mail",
|
|
67
67
|
"Male": "Mâle",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "De nombreuses fonctionnalités automatiques (par exemple le contrôle solaire, le mode photovoltaïque, la logique météorologique AI et les fonctions de diagnostic) ne fonctionnent que lorsque la saison de la piscine est active. Le statut de la saison peut être modifié à tout moment via le point de données 'status.season_active' ou dans la configuration de l'instance.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "De nombreuses fonctionnalités automatiques (par exemple le contrôle solaire, le mode photovoltaïque, la logique météorologique AI et les fonctions de diagnostic) ne fonctionnent que lorsque la saison de la piscine est active. Le statut de la saison peut être modifié à tout moment via le point de données « status.season_active » ou votre visualisation. La configuration de l'instance fournit uniquement la valeur initiale lorsque le point de données est créé pour la première fois.",
|
|
70
69
|
"Max Power (Watt)": "Puissance maximale (Watts)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Température maximale de la piscine (°C – Coupure de sécurité)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "Stato del controllo logico (vero/falso)",
|
|
66
66
|
"Mail": "Posta",
|
|
67
67
|
"Male": "Maschio",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "Molte funzionalità automatiche (ad esempio controllo solare, modalità fotovoltaica, logica meteorologica AI e funzioni diagnostiche) funzionano solo quando la stagione della piscina è attiva. Lo stato della stagione può essere modificato in qualsiasi momento tramite il datapoint 'status.season_active' o nella configurazione dell'istanza.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "Molte funzionalità automatiche (ad esempio controllo solare, modalità fotovoltaica, logica meteorologica AI e funzioni diagnostiche) funzionano solo quando la stagione della piscina è attiva. Lo stato della stagione può essere modificato in qualsiasi momento tramite il datapoint 'status.season_active' o la tua visualizzazione. La configurazione dell'istanza fornisce il valore iniziale solo quando il datapoint viene creato per la prima volta.",
|
|
70
69
|
"Max Power (Watt)": "Potenza massima (Watt)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Temperatura massima della piscina (°C – Interruzione di sicurezza)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "Logische controlestatus (waar / onwaar)",
|
|
66
66
|
"Mail": "Mail",
|
|
67
67
|
"Male": "Mannelijk",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "Veel automatische functies (bijv. zonneregeling, fotovoltaïsche modus, AI-weerlogica en diagnosefuncties) werken alleen als het zwembadseizoen actief is. De seizoensstatus kan op elk moment worden gewijzigd via het datapunt 'status.season_active' of in de instanceconfiguratie.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "Veel automatische functies (bijv. zonneregeling, fotovoltaïsche modus, AI-weerlogica en diagnosefuncties) werken alleen als het zwembadseizoen actief is. De seizoensstatus kan op elk moment worden gewijzigd via het datapunt 'status.season_active' of uw visualisatie. De instanceconfiguratie levert alleen de initiële waarde wanneer het datapunt voor de eerste keer wordt aangemaakt.",
|
|
70
69
|
"Max Power (Watt)": "Maximaal vermogen (Watt)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Maximale zwembadtemperatuur (°C – veiligheidsuitschakeling)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "Stan kontroli logicznej (prawda / fałsz)",
|
|
66
66
|
"Mail": "Poczta",
|
|
67
67
|
"Male": "Mężczyzna",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "Wiele funkcji automatycznych (np. sterowanie solarne, tryb fotowoltaiczny, logika pogodowa AI i funkcje diagnostyczne) działa tylko wtedy, gdy trwa sezon basenowy. Status sezonu można zmienić w dowolnym momencie poprzez punkt danych „status.season_active” lub w konfiguracji instancji.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "Wiele funkcji automatycznych (np. sterowanie solarne, tryb fotowoltaiczny, logika pogodowa AI i funkcje diagnostyczne) działa tylko wtedy, gdy trwa sezon basenowy. Status sezonu można zmienić w dowolnym momencie za pomocą punktu danych „status.season_active” lub za pomocą wizualizacji. Konfiguracja instancji zapewnia wartość początkową tylko wtedy, gdy punkt danych jest tworzony po raz pierwszy.",
|
|
70
69
|
"Max Power (Watt)": "Maksymalna moc (W)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Maksymalna temperatura basenu (°C – wyłącznik bezpieczeństwa)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "Estado de controle lógico (verdadeiro/falso)",
|
|
66
66
|
"Mail": "Correspondência",
|
|
67
67
|
"Male": "Macho",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "Muitos recursos automáticos (por exemplo, controle solar, modo fotovoltaico, lógica meteorológica de IA e funções de diagnóstico) só funcionam quando a temporada de piscinas está ativa. O status da temporada pode ser alterado a qualquer momento por meio do ponto de dados 'status.season_active' ou na configuração da instância.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "Muitos recursos automáticos (por exemplo, controle solar, modo fotovoltaico, lógica meteorológica de IA e funções de diagnóstico) só funcionam quando a temporada de piscinas está ativa. O status da temporada pode ser alterado a qualquer momento por meio do ponto de dados 'status.season_active' ou de sua visualização. A configuração da instância fornece o valor inicial apenas quando o ponto de dados é criado pela primeira vez.",
|
|
70
69
|
"Max Power (Watt)": "Potência máxima (Watts)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Temperatura Máxima da Piscina (°C – Corte de Segurança)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "Состояние логического управления (истина/ложь)",
|
|
66
66
|
"Mail": "Почта",
|
|
67
67
|
"Male": "Мужской",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "Многие автоматические функции (например, управление солнечной энергией, фотоэлектрический режим, логика погоды AI и функции диагностики) работают только во время сезона бассейнов. Статус сезона можно изменить в любое время с помощью точки данных status. Season_active или в конфигурации экземпляра.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "Многие автоматические функции (например, управление солнечной энергией, фотоэлектрический режим, логика погоды AI и функции диагностики) работают только во время сезона бассейнов. Статус сезона можно изменить в любое время с помощью точки данных status. Season_active или вашей визуализации. Конфигурация экземпляра предоставляет начальное значение только при первом создании точки данных.",
|
|
70
69
|
"Max Power (Watt)": "Максимальная мощность (Ватт)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Максимальная температура бассейна (°C – безопасное отключение)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "Логічний контрольний стан (істина/хибність)",
|
|
66
66
|
"Mail": "Пошта",
|
|
67
67
|
"Male": "Чоловік",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "Багато автоматичних функцій (наприклад, сонячний контроль, фотоелектричний режим, логіка погоди штучного інтелекту та функції діагностики) працюють лише під час сезону басейну. Статус сезону можна будь-коли змінити за допомогою точки даних status.season_active або в конфігурації екземпляра.",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "Багато автоматичних функцій (наприклад, сонячний контроль, фотоелектричний режим, логіка погоди штучного інтелекту та функції діагностики) працюють лише під час сезону басейну. Статус сезону можна будь-коли змінити за допомогою точки даних status.season_active або вашої візуалізації. Конфігурація екземпляра надає лише початкове значення, коли точка даних створюється вперше.",
|
|
70
69
|
"Max Power (Watt)": "Максимальна потужність (ват)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "Максимальна температура басейну (°C – безпечне обмеження)",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"Logical Control State (true / false)": "逻辑控制状态(真/假)",
|
|
66
66
|
"Mail": "邮件",
|
|
67
67
|
"Male": "男性",
|
|
68
|
-
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or in the instance configuration.": "许多自动功能(例如太阳能控制、光伏模式、人工智能天气逻辑和诊断功能)仅在泳池季节活跃时运行。季节状态可以随时通过“status.season_active”数据点或在实例配置中更改。",
|
|
69
68
|
"Many automatic features (e.g. solar control, photovoltaic mode, AI weather logic and diagnostic functions) only operate when the pool season is active. The season status can be changed at any time via the 'status.season_active' datapoint or your visualization. The instance configuration only provides the initial value when the datapoint is created for the first time.": "许多自动功能(例如太阳能控制、光伏模式、人工智能天气逻辑和诊断功能)仅在泳池季节活跃时运行。季节状态可以随时通过“status.season_active”数据点或可视化更改。实例配置仅在第一次创建数据点时提供初始值。",
|
|
70
69
|
"Max Power (Watt)": "最大功率(瓦)",
|
|
71
70
|
"Maximum Pool Temperature (°C – Safety Cutoff)": "最高水池温度(°C – 安全截止值)",
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "poolcontrol",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.30",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.3.30": {
|
|
7
|
+
"en": "Updated release tooling to the required minimum version. Cleaned up outdated Admin i18n keys. Replaced native timers in AI weather helpers with ioBroker adapter timers.",
|
|
8
|
+
"de": "Release-Werkzeuge auf die erforderliche Mindestversion aktualisiert. Veraltete Admin-i18n-Schlüssel bereinigt. Native Timer in den KI-Wetter-Helpern durch ioBroker-Adapter-Timer ersetzt.",
|
|
9
|
+
"ru": "Обновлены инструменты выпуска до необходимой минимальной версии. Очищены устаревшие ключи администратора i18n. Заменены встроенные таймеры в помощниках погоды AI на таймеры адаптера ioBroker.",
|
|
10
|
+
"pt": "Ferramentas de lançamento atualizadas para a versão mínima exigida. Limpeza de chaves Admin i18n desatualizadas. Temporizadores nativos substituídos em ajudantes meteorológicos de IA por temporizadores adaptadores ioBroker.",
|
|
11
|
+
"nl": "Releasetooling bijgewerkt naar de vereiste minimumversie. Verouderde Admin i18n-sleutels opgeschoond. Native timers in AI-weerhelpers vervangen door ioBroker-adaptertimers.",
|
|
12
|
+
"fr": "Outils de version mis à jour vers la version minimale requise. Nettoyage des clés Admin i18n obsolètes. Remplacement des minuteries natives dans les assistants météo AI par des minuteries d'adaptateur ioBroker.",
|
|
13
|
+
"it": "Strumenti di rilascio aggiornati alla versione minima richiesta. Ripulite le chiavi Admin i18n obsolete. Sostituiti i timer nativi negli assistenti meteorologici AI con i timer dell'adattatore ioBroker.",
|
|
14
|
+
"es": "Herramientas de lanzamiento actualizadas a la versión mínima requerida. Se limpiaron las claves de Admin i18n obsoletas. Se reemplazaron los temporizadores nativos en los asistentes meteorológicos de IA con temporizadores del adaptador ioBroker.",
|
|
15
|
+
"pl": "Zaktualizowano narzędzia wydania do wymaganej wersji minimalnej. Wyczyszczono nieaktualne klucze administratora i18n. Zastąpiono natywne liczniki czasu w pomocnikach pogodowych AI zegarami adaptera ioBroker.",
|
|
16
|
+
"uk": "Оновлено інструмент випуску до необхідної мінімальної версії. Очищено застарілі ключі адміністратора i18n. Вбудовані таймери в помічниках погоди штучного інтелекту замінено на таймери адаптера ioBroker.",
|
|
17
|
+
"zh-cn": "将发布工具更新为所需的最低版本。清理了过时的 Admin i18n 密钥。将 AI 天气助手中的本机计时器替换为 ioBroker 适配器计时器。"
|
|
18
|
+
},
|
|
6
19
|
"1.3.29": {
|
|
7
20
|
"en": "Added Pool Insights V1 with observations, status evaluation and runtime i18n support. Improved Pool Insights text generation and removed dependency on external summary blocks. Fixed missing initialization of season and solar warning runtime states from adapter configuration. Added admin UI notes explaining initial values versus runtime datapoint control.",
|
|
8
21
|
"de": "Pool Insights V1 mit Beobachtungen, Statusbewertung und Runtime-i18n hinzugefügt. Pool-Insights-Texte verbessert und die Abhängigkeit von externen Summary-Blöcken entfernt. Fehlende Initialisierung der Saison- und Solarwarnungs-States aus der Adapterkonfiguration behoben. Hinweise in der Admin-Oberfläche ergänzt, die den Unterschied zwischen Initialwerten und Runtime-Datenpunkten erläutern.",
|
|
@@ -54,19 +67,6 @@
|
|
|
54
67
|
"pl": "Przerobiono kilka ostrzeżeń i uwag z oficjalnych kontroli ioBroker. Różne drobne ulepszenia i wewnętrzne porządki.",
|
|
55
68
|
"uk": "Перероблено кілька попереджень і приміток до огляду з офіційних перевірок ioBroker. Різні невеликі покращення та внутрішні очищення.",
|
|
56
69
|
"zh-cn": "重新设计了官方 ioBroker 检查中的几条警告和审查说明。各种小的改进和内部清理。"
|
|
57
|
-
},
|
|
58
|
-
"1.3.25": {
|
|
59
|
-
"en": "Updated documentation and repository maintenance: improved README structure, synchronized function overviews and updated development dependencies",
|
|
60
|
-
"de": "Dokumentation und Repository-Wartung aktualisiert: README-Struktur verbessert, Funktionsübersichten synchronisiert und Entwicklungsabhängigkeiten aktualisiert",
|
|
61
|
-
"ru": "Обновленная документация и обслуживание репозитория: улучшенная структура README, синхронизированные обзоры функций и обновленные зависимости разработки.",
|
|
62
|
-
"pt": "Documentação atualizada e manutenção de repositório: estrutura README aprimorada, visões gerais de funções sincronizadas e dependências de desenvolvimento atualizadas",
|
|
63
|
-
"nl": "Bijgewerkte documentatie en repository-onderhoud: verbeterde README-structuur, gesynchroniseerde functieoverzichten en bijgewerkte ontwikkelingsafhankelijkheden",
|
|
64
|
-
"fr": "Documentation mise à jour et maintenance du référentiel : structure README améliorée, aperçus des fonctions synchronisés et dépendances de développement mises à jour",
|
|
65
|
-
"it": "Documentazione aggiornata e manutenzione del repository: struttura README migliorata, panoramiche delle funzioni sincronizzate e dipendenze di sviluppo aggiornate",
|
|
66
|
-
"es": "Documentación actualizada y mantenimiento del repositorio: estructura README mejorada, descripciones generales de funciones sincronizadas y dependencias de desarrollo actualizadas",
|
|
67
|
-
"pl": "Zaktualizowana dokumentacja i konserwacja repozytorium: ulepszona struktura README, zsynchronizowane przeglądy funkcji i zaktualizowane zależności programistyczne",
|
|
68
|
-
"uk": "Оновлена документація та обслуговування репозиторію: покращена структура README, синхронізовані огляди функцій та оновлені залежності розробки",
|
|
69
|
-
"zh-cn": "更新的文档和存储库维护:改进的自述文件结构、同步的功能概述和更新的开发依赖项"
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
"titleLang": {
|
|
@@ -41,7 +41,9 @@ const aiForecastHelper = {
|
|
|
41
41
|
// ----------------------------------------------------------
|
|
42
42
|
// NEU: Delay, damit ioBroker alle States laden kann
|
|
43
43
|
// ----------------------------------------------------------
|
|
44
|
-
await new Promise(
|
|
44
|
+
await new Promise(resolve => {
|
|
45
|
+
this.adapter.setTimeout(resolve, 1500);
|
|
46
|
+
});
|
|
45
47
|
|
|
46
48
|
// ----------------------------------------------------------
|
|
47
49
|
// NEU: Sofortige Ausführung beim Adapterstart (wenn aktiviert)
|
|
@@ -64,7 +66,7 @@ const aiForecastHelper = {
|
|
|
64
66
|
*/
|
|
65
67
|
cleanup() {
|
|
66
68
|
if (this.timer) {
|
|
67
|
-
clearInterval(this.timer);
|
|
69
|
+
this.adapter.clearInterval(this.timer);
|
|
68
70
|
this.timer = null;
|
|
69
71
|
}
|
|
70
72
|
this.adapter && this.adapter.log.debug('[aiForecastHelper] cleanup finished');
|
|
@@ -113,7 +115,7 @@ const aiForecastHelper = {
|
|
|
113
115
|
async _refreshTimer() {
|
|
114
116
|
// alten Timer stoppen
|
|
115
117
|
if (this.timer) {
|
|
116
|
-
clearInterval(this.timer);
|
|
118
|
+
this.adapter.clearInterval(this.timer);
|
|
117
119
|
this.timer = null;
|
|
118
120
|
}
|
|
119
121
|
|
|
@@ -132,7 +134,7 @@ const aiForecastHelper = {
|
|
|
132
134
|
);
|
|
133
135
|
|
|
134
136
|
// minütlicher Check
|
|
135
|
-
this.timer = setInterval(async () => {
|
|
137
|
+
this.timer = this.adapter.setInterval(async () => {
|
|
136
138
|
const now = new Date();
|
|
137
139
|
if (now.getHours() === time.hour && now.getMinutes() === time.minute) {
|
|
138
140
|
try {
|
package/lib/helpers/aiHelper.js
CHANGED
|
@@ -123,7 +123,9 @@ const aiHelper = {
|
|
|
123
123
|
// ----------------------------------------------------------
|
|
124
124
|
// NEU: Delay, damit ioBroker alle States laden kann
|
|
125
125
|
// ----------------------------------------------------------
|
|
126
|
-
await new Promise(
|
|
126
|
+
await new Promise(resolve => {
|
|
127
|
+
this.adapter.setTimeout(resolve, 1500);
|
|
128
|
+
});
|
|
127
129
|
|
|
128
130
|
// NEU: Wenn Uhrzeit heute noch in der Zukunft liegt → sofort ausführen
|
|
129
131
|
try {
|
|
@@ -183,7 +185,7 @@ const aiHelper = {
|
|
|
183
185
|
*/
|
|
184
186
|
_clearTimers() {
|
|
185
187
|
for (const t of this.timers) {
|
|
186
|
-
clearInterval(t);
|
|
188
|
+
this.adapter.clearInterval(t);
|
|
187
189
|
}
|
|
188
190
|
this.timers = [];
|
|
189
191
|
},
|
|
@@ -257,7 +259,7 @@ const aiHelper = {
|
|
|
257
259
|
//--------------------------------------------------------
|
|
258
260
|
this.adapter.log.debug('[aiHelper] setting hourly weather update timer');
|
|
259
261
|
|
|
260
|
-
const hourlyTimer = setInterval(
|
|
262
|
+
const hourlyTimer = this.adapter.setInterval(
|
|
261
263
|
async () => {
|
|
262
264
|
try {
|
|
263
265
|
const geo = await this._loadGeoLocation();
|
|
@@ -303,7 +305,7 @@ const aiHelper = {
|
|
|
303
305
|
*/
|
|
304
306
|
_createDailyTimer(timeObj, callback) {
|
|
305
307
|
const { hour, minute } = timeObj;
|
|
306
|
-
const timer = setInterval(async () => {
|
|
308
|
+
const timer = this.adapter.setInterval(async () => {
|
|
307
309
|
const now = new Date();
|
|
308
310
|
|
|
309
311
|
// --- FIX: Nachholen nur in den ersten 3 Minuten nach Adapterstart ---
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { I18n } = require('@iobroker/adapter-core');
|
|
4
4
|
|
|
5
5
|
const POOL_INSIGHTS_PREFIX = 'analytics.insights.pool';
|
|
6
|
-
const
|
|
6
|
+
const DEFAULT_DAILY_ANALYSIS_TIME = '20:00';
|
|
7
7
|
const SPEECH_COOLDOWN_MS = 6 * 60 * 60 * 1000;
|
|
8
8
|
|
|
9
9
|
const poolInsightsHelper = {
|
|
@@ -15,6 +15,7 @@ const poolInsightsHelper = {
|
|
|
15
15
|
this.adapter = adapter;
|
|
16
16
|
|
|
17
17
|
this.adapter.subscribeStates(`${POOL_INSIGHTS_PREFIX}.enabled`);
|
|
18
|
+
this.adapter.subscribeStates(`${POOL_INSIGHTS_PREFIX}.schedule_time`);
|
|
18
19
|
this.adapter.subscribeStates(`${POOL_INSIGHTS_PREFIX}.manual_trigger`);
|
|
19
20
|
this.adapter.subscribeStates(`${POOL_INSIGHTS_PREFIX}.send_to_speech_queue`);
|
|
20
21
|
|
|
@@ -32,7 +33,7 @@ const poolInsightsHelper = {
|
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
if (id.endsWith(`${POOL_INSIGHTS_PREFIX}.enabled`)) {
|
|
36
|
+
if (id.endsWith(`${POOL_INSIGHTS_PREFIX}.enabled`) || id.endsWith(`${POOL_INSIGHTS_PREFIX}.schedule_time`)) {
|
|
36
37
|
void this._refreshSchedule();
|
|
37
38
|
}
|
|
38
39
|
},
|
|
@@ -66,9 +67,11 @@ const poolInsightsHelper = {
|
|
|
66
67
|
this.dailyTimer = null;
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
const scheduleTime = await this._readString(`${POOL_INSIGHTS_PREFIX}.schedule_time`);
|
|
71
|
+
const { hours, minutes } = this._parseScheduleTime(scheduleTime);
|
|
69
72
|
const now = new Date();
|
|
70
73
|
const next = new Date(now);
|
|
71
|
-
next.setHours(
|
|
74
|
+
next.setHours(hours, minutes, 0, 0);
|
|
72
75
|
if (next <= now) {
|
|
73
76
|
next.setDate(next.getDate() + 1);
|
|
74
77
|
}
|
|
@@ -84,6 +87,24 @@ const poolInsightsHelper = {
|
|
|
84
87
|
this.adapter.log.debug(`[poolInsightsHelper] Daily analysis scheduled for ${next.toISOString()}`);
|
|
85
88
|
},
|
|
86
89
|
|
|
90
|
+
_parseScheduleTime(value) {
|
|
91
|
+
const match = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(value);
|
|
92
|
+
if (match) {
|
|
93
|
+
return {
|
|
94
|
+
hours: Number(match[1]),
|
|
95
|
+
minutes: Number(match[2]),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.adapter.log.debug(
|
|
100
|
+
`[poolInsightsHelper] Invalid schedule_time ${value}, using fallback ${DEFAULT_DAILY_ANALYSIS_TIME}`,
|
|
101
|
+
);
|
|
102
|
+
return {
|
|
103
|
+
hours: 20,
|
|
104
|
+
minutes: 0,
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
|
|
87
108
|
async _runAnalysis(reason, allowSpeech) {
|
|
88
109
|
if (this.running) {
|
|
89
110
|
this.adapter.log.debug('[poolInsightsHelper] Analysis already running - skipped');
|
|
@@ -177,11 +198,19 @@ const poolInsightsHelper = {
|
|
|
177
198
|
|
|
178
199
|
if (tempDelta <= 0.2) {
|
|
179
200
|
level = this._raiseLevel(level, 'info');
|
|
180
|
-
recommendations.push(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
recommendations.push(
|
|
202
|
+
this._createRecommendation(
|
|
203
|
+
'temperature',
|
|
204
|
+
'info',
|
|
205
|
+
'low_temperature_change',
|
|
206
|
+
0.7,
|
|
207
|
+
this._translate('pool_insights_recommendation_temperature_low_change'),
|
|
208
|
+
['temperature.surface.min_today', 'temperature.surface.max_today'],
|
|
209
|
+
{
|
|
210
|
+
temperature_delta_c: rounded,
|
|
211
|
+
},
|
|
212
|
+
),
|
|
213
|
+
);
|
|
185
214
|
}
|
|
186
215
|
}
|
|
187
216
|
|
|
@@ -208,11 +237,19 @@ const poolInsightsHelper = {
|
|
|
208
237
|
|
|
209
238
|
if (snapshot.pump.startCountToday > 12) {
|
|
210
239
|
level = this._raiseLevel(level, 'info');
|
|
211
|
-
recommendations.push(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
240
|
+
recommendations.push(
|
|
241
|
+
this._createRecommendation(
|
|
242
|
+
'pump',
|
|
243
|
+
'info',
|
|
244
|
+
'many_pump_starts',
|
|
245
|
+
0.8,
|
|
246
|
+
this._translate('pool_insights_recommendation_many_pump_starts'),
|
|
247
|
+
['runtime.start_count_today'],
|
|
248
|
+
{
|
|
249
|
+
starts_today: snapshot.pump.startCountToday,
|
|
250
|
+
},
|
|
251
|
+
),
|
|
252
|
+
);
|
|
216
253
|
}
|
|
217
254
|
}
|
|
218
255
|
|
|
@@ -223,11 +260,19 @@ const poolInsightsHelper = {
|
|
|
223
260
|
level: 'warning',
|
|
224
261
|
text: this._translate('pool_insights_observation_pump_error'),
|
|
225
262
|
});
|
|
226
|
-
recommendations.push(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
263
|
+
recommendations.push(
|
|
264
|
+
this._createRecommendation(
|
|
265
|
+
'pump',
|
|
266
|
+
'warning',
|
|
267
|
+
'pump_error_active',
|
|
268
|
+
1,
|
|
269
|
+
this._translate('pool_insights_recommendation_pump_error'),
|
|
270
|
+
['pump.error'],
|
|
271
|
+
{
|
|
272
|
+
pump_error: true,
|
|
273
|
+
},
|
|
274
|
+
),
|
|
275
|
+
);
|
|
231
276
|
}
|
|
232
277
|
|
|
233
278
|
this._appendSolarObservations(snapshot.solar, observations);
|
|
@@ -235,11 +280,19 @@ const poolInsightsHelper = {
|
|
|
235
280
|
|
|
236
281
|
if (snapshot.photovoltaic.startsToday !== null && snapshot.photovoltaic.startsToday > 10) {
|
|
237
282
|
level = this._raiseLevel(level, 'info');
|
|
238
|
-
recommendations.push(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
283
|
+
recommendations.push(
|
|
284
|
+
this._createRecommendation(
|
|
285
|
+
'photovoltaic',
|
|
286
|
+
'info',
|
|
287
|
+
'many_pv_starts',
|
|
288
|
+
0.8,
|
|
289
|
+
this._translate('pool_insights_recommendation_many_pv_starts'),
|
|
290
|
+
['analytics.insights.photovoltaic.results.starts_today'],
|
|
291
|
+
{
|
|
292
|
+
pv_starts_today: snapshot.photovoltaic.startsToday,
|
|
293
|
+
},
|
|
294
|
+
),
|
|
295
|
+
);
|
|
243
296
|
}
|
|
244
297
|
|
|
245
298
|
this._appendConsumptionObservations(snapshot.consumption, observations);
|
|
@@ -570,6 +623,60 @@ const poolInsightsHelper = {
|
|
|
570
623
|
await this.adapter.setStateChangedAsync(id, { val, ack });
|
|
571
624
|
},
|
|
572
625
|
|
|
626
|
+
_createRecommendation(area, level, reason, confidence, text, sourceStates = [], evidence = {}) {
|
|
627
|
+
return {
|
|
628
|
+
area: String(area || ''),
|
|
629
|
+
level: String(level || ''),
|
|
630
|
+
reason: String(reason || ''),
|
|
631
|
+
confidence: this._clampConfidence(confidence),
|
|
632
|
+
text: String(text || ''),
|
|
633
|
+
source_states: Array.isArray(sourceStates)
|
|
634
|
+
? sourceStates.filter(value => value !== undefined).map(value => String(value))
|
|
635
|
+
: [],
|
|
636
|
+
evidence: this._cleanEvidence(evidence),
|
|
637
|
+
};
|
|
638
|
+
},
|
|
639
|
+
|
|
640
|
+
_clampConfidence(value) {
|
|
641
|
+
const confidence = Number(value);
|
|
642
|
+
if (!Number.isFinite(confidence)) {
|
|
643
|
+
return 0;
|
|
644
|
+
}
|
|
645
|
+
return Math.min(1, Math.max(0, confidence));
|
|
646
|
+
},
|
|
647
|
+
|
|
648
|
+
_cleanEvidence(evidence) {
|
|
649
|
+
if (!evidence || typeof evidence !== 'object' || Array.isArray(evidence)) {
|
|
650
|
+
return {};
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
return this._cleanObject(evidence);
|
|
654
|
+
},
|
|
655
|
+
|
|
656
|
+
_cleanObject(object) {
|
|
657
|
+
const cleaned = {};
|
|
658
|
+
for (const [key, value] of Object.entries(object)) {
|
|
659
|
+
const cleanedValue = this._cleanValue(value);
|
|
660
|
+
if (cleanedValue !== undefined) {
|
|
661
|
+
cleaned[key] = cleanedValue;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return cleaned;
|
|
665
|
+
},
|
|
666
|
+
|
|
667
|
+
_cleanValue(value) {
|
|
668
|
+
if (value === undefined) {
|
|
669
|
+
return undefined;
|
|
670
|
+
}
|
|
671
|
+
if (Array.isArray(value)) {
|
|
672
|
+
return value.map(entry => this._cleanValue(entry)).filter(entry => entry !== undefined);
|
|
673
|
+
}
|
|
674
|
+
if (value !== null && typeof value === 'object') {
|
|
675
|
+
return this._cleanObject(value);
|
|
676
|
+
}
|
|
677
|
+
return value;
|
|
678
|
+
},
|
|
679
|
+
|
|
573
680
|
_formatRuntime(seconds) {
|
|
574
681
|
const totalMinutes = Math.max(0, Math.round(seconds / 60));
|
|
575
682
|
const hours = Math.floor(totalMinutes / 60);
|
|
@@ -84,6 +84,25 @@ async function createPoolInsightsStates(adapter) {
|
|
|
84
84
|
persist: true,
|
|
85
85
|
},
|
|
86
86
|
},
|
|
87
|
+
{
|
|
88
|
+
id: 'analytics.insights.pool.schedule_time',
|
|
89
|
+
common: {
|
|
90
|
+
name: {
|
|
91
|
+
en: 'Daily pool insights analysis time',
|
|
92
|
+
de: 'Uhrzeit der täglichen Pool-Insights-Analyse',
|
|
93
|
+
},
|
|
94
|
+
desc: {
|
|
95
|
+
en: 'Time for the daily automatic pool insights analysis in HH:mm format.',
|
|
96
|
+
de: 'Uhrzeit für die tägliche automatische Pool-Insights-Analyse im Format HH:mm.',
|
|
97
|
+
},
|
|
98
|
+
type: 'string',
|
|
99
|
+
role: 'text',
|
|
100
|
+
read: true,
|
|
101
|
+
write: true,
|
|
102
|
+
def: '20:00',
|
|
103
|
+
persist: true,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
87
106
|
{
|
|
88
107
|
id: 'analytics.insights.pool.manual_trigger',
|
|
89
108
|
common: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.poolcontrol",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.30",
|
|
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",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@iobroker/adapter-core": "^3.3.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@alcalzone/release-script": "^5.2.
|
|
27
|
+
"@alcalzone/release-script": "^5.2.1",
|
|
28
28
|
"@alcalzone/release-script-plugin-iobroker": "^5.2.0",
|
|
29
29
|
"@alcalzone/release-script-plugin-license": "^5.2.0",
|
|
30
30
|
"@alcalzone/release-script-plugin-manual-review": "^5.2.0",
|