iobroker.poolcontrol 1.3.34 → 1.4.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.
package/README.md CHANGED
@@ -283,6 +283,21 @@ New features are added regularly – please refer to the changelog.
283
283
  ---
284
284
 
285
285
  ## Changelog
286
+ ### 1.4.0 (2026-06-29)
287
+
288
+ - Added a reset button for pump learning to quickly clear learned values after a pump replacement or incorrect learning while keeping user settings intact.
289
+ - Made the daily circulation factor writable and persistent. The adapter configuration is now only used as the initial value, allowing adjustments directly via states (e.g. VIS or HomePanel).
290
+ - Added an optional temperature-dependent circulation factor that automatically increases the required daily circulation based on a selectable temperature sensor and configurable threshold.
291
+ - Extended the existing time control with an optional interval mode. Each time window can now operate either continuously or in configurable intervals without introducing a new pump mode.
292
+ - Added new diagnostic states and multilingual status messages to improve transparency and troubleshooting for the new circulation and time control features.
293
+
294
+ ### 1.3.35 (2026-06-29)
295
+
296
+ - Fixed an inconsistency in the daily circulation calculation.
297
+ - `circulation.daily_remaining` is now recalculated together with `circulation.daily_required`.
298
+ - Changing the pool size or minimum daily circulation now produces consistent values immediately after adapter restart.
299
+ - The remaining daily circulation is no longer blocked by zero flow or a stopped pump.
300
+
286
301
  ### 1.3.34 (2026-06-27)
287
302
 
288
303
  - **Major stability improvement:** Completely redesigned the internal chemistry history (pH, ORP and TDS) to prevent unbounded JSON state growth. This significantly reduces the risk of oversized `states.jsonl` files and potential js-controller startup failures.
@@ -306,16 +321,6 @@ New features are added regularly – please refer to the changelog.
306
321
  - Added detailed diagnostic states under `circulation.plausibility` for troubleshooting and analysis.
307
322
  - Improved diagnostics for circulation calculations without changing existing pump, PV or solar control logic.
308
323
 
309
- ### 1.3.31 (2026-06-07)
310
-
311
- - Fixed automatic circulation top-up logic when temperature sensors are missing. Automatic top-up is now only blocked by collector/pool temperature comparison when solar control is active and both temperatures are valid.
312
-
313
- ### 1.3.30 (2026-06-05)
314
-
315
- - Updated release tooling to the required minimum version.
316
- - Cleaned up outdated Admin i18n keys.
317
- - Replaced native timers in AI weather helpers with ioBroker adapter timers.
318
-
319
324
  ## Archived Release History
320
325
 
321
326
  For older releases and archived version history see:
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "Das KI-System (aiHelper & aiForecastHelper) ruft Wetterdaten von Open-Meteo über HTTPS ab. Es verwendet die Geokoordinaten aus der ioBroker-Systemkonfiguration (system.config › Breitengrad/Längengrad). Es werden keine Daten gespeichert oder an Dritte übermittelt. Ohne gültige Geokoordinaten kann das KI-System keine Prognosen erstellen.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "Der PoolControl-Adapter arbeitet standardmäßig vollständig lokal. Derzeit greifen nur die KI-Funktionen über verschlüsseltes HTTPS auf Wetterdaten von Open-Meteo zu. Es werden ausschließlich die im ioBroker hinterlegten Geokoordinaten (Breitengrad und Längengrad) übermittelt. Es werden keine darüber hinausgehenden Daten gespeichert oder an Dritte weitergegeben. Zukünftige optionale Internetdienste können hinzugefügt werden, sie werden jedoch immer deutlich gekennzeichnet sein.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Diese Warnwerte werden als Anfangswerte verwendet, wenn die Datenpunkte zum ersten Mal erstellt werden. Spätere Änderungen sollten über „solar.warn_active“, „solar.warn_temp“ und „solar.warn_speech“ oder Ihre Visualisierung vorgenommen werden.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Dieser Wert ist nur der Initialwert für general.min_circulation_per_day. Er wird bei der ersten Einrichtung oder bei leerem bzw. ungültigem State übernommen. Der wirksame Wert ist der beschreibbare State general.min_circulation_per_day und kann später per VIS oder HomePanel geändert werden.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Dieser Wert wird als anfänglicher Saisonstatus verwendet, wenn der Datenpunkt zum ersten Mal erstellt wird. Spätere Änderungen sollten über „status.season_active“ oder Ihre Visualisierung vorgenommen werden.",
139
140
  "Threshold for PV surplus (W)": "Schwelle für PV-Überschuss (W)",
140
141
  "Thursday": "Donnerstag",
@@ -83,6 +83,7 @@
83
83
  "Note: The AI features are completely optional and can be disabled at any time via the 'ai.enabled' datapoint. Weather features (e.g. weather hints, pool tips, forecast for tomorrow) can also be individually enabled or disabled via 'ai.weather.switches.*'. The adapter uses the Open-Meteo service to generate weather data. For this, the geo-coordinates stored in ioBroker (latitude and longitude from system.config) are required.": "Note: The AI features are completely optional and can be disabled at any time via the 'ai.enabled' datapoint. Weather features (e.g. weather hints, pool tips, forecast for tomorrow) can also be individually enabled or disabled via 'ai.weather.switches.*'. The adapter uses the Open-Meteo service to generate weather data. For this, the geo-coordinates stored in ioBroker (latitude and longitude from system.config) are required.",
84
84
  "Note: The warning resets automatically once the temperature drops 10% below the configured threshold.": "Note: The warning resets automatically once the temperature drops 10% below the configured threshold.",
85
85
  "Note: These settings are mainly used as initial values when PoolControl is set up for the first time. Later operation should be done via the PoolControl datapoints or your visualization. Existing runtime datapoints are not overwritten on adapter restart.": "Note: These settings are mainly used as initial values when PoolControl is set up for the first time. Later operation should be done via the PoolControl datapoints or your visualization. Existing runtime datapoints are not overwritten on adapter restart.",
86
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.",
86
87
  "Object ID Auxiliary pump 1": "Object ID Auxiliary pump 1",
87
88
  "Object ID Auxiliary pump 2": "Object ID Auxiliary pump 2",
88
89
  "Object ID Auxiliary pump 3": "Object ID Auxiliary pump 3",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "El sistema de inteligencia artificial (aiHelper y aiForecastHelper) recupera datos meteorológicos de Open-Meteo a través de HTTPS. Utiliza las coordenadas geográficas de la configuración del sistema ioBroker (system.config › latitud/longitud). No se almacenan ni se transmiten datos a terceros. Sin coordenadas geográficas válidas, el sistema de IA no puede generar pronósticos.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "El adaptador PoolControl funciona de forma completamente local de forma predeterminada. Actualmente, solo las funciones de IA acceden a los datos meteorológicos de Open-Meteo a través de HTTPS cifrado. Sólo se transmiten las coordenadas geográficas almacenadas en ioBroker (latitud y longitud). No se almacenan ni envían datos adicionales a terceros. Se podrán añadir futuros servicios opcionales de internet, pero siempre estarán claramente marcados.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Estos valores de advertencia se utilizan como valores iniciales cuando los puntos de datos se crean por primera vez. Los cambios posteriores deben realizarse a través de 'solar.warn_active', 'solar.warn_temp' y 'solar.warn_speech' o su visualización.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Este valor es solo el valor inicial para general.min_circulation_per_day. Se copia durante la primera configuración o cuando el estado está vacío o no es válido. El valor efectivo es el estado escribible general.min_circulation_per_day y puede modificarse posteriormente mediante VIS o HomePanel.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Este valor se utiliza como estado inicial de la temporada cuando se crea el punto de datos por primera vez. Los cambios posteriores deben realizarse a través de 'status.season_active' o su visualización.",
139
140
  "Threshold for PV surplus (W)": "Umbral de excedente fotovoltaico (W)",
140
141
  "Thursday": "Jueves",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "Le système d'IA (aiHelper & aiForecastHelper) récupère les données météorologiques d'Open-Meteo via HTTPS. Il utilise les coordonnées géographiques de la configuration du système ioBroker (system.config › latitude/longitude). Aucune donnée n'est stockée ou transmise à des tiers. Sans coordonnées géographiques valides, le système d’IA ne peut pas générer de prévisions.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "L'adaptateur PoolControl fonctionne entièrement localement par défaut. Actuellement, seules les fonctionnalités d’IA accèdent aux données météorologiques d’Open-Meteo via HTTPS crypté. Seules les coordonnées géographiques stockées dans ioBroker (latitude et longitude) sont transmises. Aucune donnée supplémentaire n'est stockée ou transmise à des tiers. De futurs services Internet optionnels pourront être ajoutés, mais ils seront toujours clairement indiqués.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Ces valeurs d'avertissement sont utilisées comme valeurs initiales lorsque les points de données sont créés pour la première fois. Les modifications ultérieures doivent être apportées via 'solar.warn_active', 'solar.warn_temp' et 'solar.warn_speech' ou votre visualisation.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Cette valeur est uniquement la valeur initiale pour general.min_circulation_per_day. Elle est copiée lors de la première configuration ou lorsque l’état est vide ou invalide. La valeur effective est l’état modifiable general.min_circulation_per_day et peut ensuite être modifiée via VIS ou HomePanel.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Cette valeur est utilisée comme état initial de la saison lorsque le point de données est créé pour la première fois. Les modifications ultérieures doivent être apportées via « status.season_active » ou votre visualisation.",
139
140
  "Threshold for PV surplus (W)": "Seuil de surplus PV (W)",
140
141
  "Thursday": "Jeudi",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "Il sistema AI (aiHelper e aiForecastHelper) recupera i dati meteorologici da Open-Meteo tramite HTTPS. Utilizza le coordinate geografiche dalla configurazione del sistema ioBroker (system.config › latitudine/longitudine). Nessun dato viene memorizzato o trasmesso a terzi. Senza coordinate geografiche valide, il sistema AI non può generare previsioni.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "Per impostazione predefinita, l'adattatore PoolControl funziona completamente localmente. Attualmente, solo le funzionalità AI accedono ai dati meteorologici da Open-Meteo tramite HTTPS crittografato. Vengono trasmesse solo le coordinate geografiche memorizzate in ioBroker (latitudine e longitudine). Nessun dato aggiuntivo viene memorizzato o inviato a terzi. Potranno essere aggiunti futuri servizi internet opzionali, ma saranno sempre chiaramente segnalati.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Questi valori di avviso vengono utilizzati come valori iniziali quando i datapoint vengono creati per la prima volta. Le modifiche successive dovranno essere apportate tramite 'solar.warn_active', 'solar.warn_temp' e 'solar.warn_speech' o tramite la visualizzazione.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Questo valore è solo il valore iniziale per general.min_circulation_per_day. Viene copiato durante la prima configurazione o quando lo stato è vuoto o non valido. Il valore effettivo è lo stato scrivibile general.min_circulation_per_day e può essere modificato successivamente tramite VIS o HomePanel.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Questo valore viene utilizzato come stato stagionale iniziale quando il datapoint viene creato per la prima volta. Le modifiche successive dovrebbero essere apportate tramite \"status.season_active\" o la tua visualizzazione.",
139
140
  "Threshold for PV surplus (W)": "Soglia per surplus FV (W)",
140
141
  "Thursday": "Giovedì",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "Het AI-systeem (aiHelper & aiForecastHelper) haalt weergegevens op van Open-Meteo via HTTPS. Het gebruikt de geocoördinaten van de ioBroker-systeemconfiguratie (system.config ›breedtegraad/lengtegraad). Er worden geen gegevens opgeslagen of doorgegeven aan derden. Zonder geldige geocoördinaten kan het AI-systeem geen voorspellingen genereren.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "De PoolControl adapter werkt standaard volledig lokaal. Momenteel heeft alleen de AI-functie toegang tot weergegevens van Open-Meteo via gecodeerde HTTPS. Alleen de geocoördinaten die zijn opgeslagen in ioBroker (breedtegraad en lengtegraad) worden verzonden. Er worden geen aanvullende gegevens opgeslagen of verzonden naar derden. In de toekomst kunnen optionele internetdiensten worden toegevoegd, maar deze zullen altijd duidelijk worden gemarkeerd.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Deze waarschuwingswaarden worden gebruikt als initiële waarden wanneer de datapunten voor de eerste keer worden aangemaakt. Latere wijzigingen moeten worden aangebracht via 'solar.warn_active', 'solar.warn_temp' en 'solar.warn_speech' of uw visualisatie.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Deze waarde is alleen de beginwaarde voor general.min_circulation_per_day. Hij wordt overgenomen bij de eerste installatie of wanneer de status leeg of ongeldig is. De effectieve waarde is de schrijfbare status general.min_circulation_per_day en kan later via VIS of HomePanel worden gewijzigd.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Deze waarde wordt gebruikt als de initiële seizoenstatus wanneer het datapunt voor de eerste keer wordt aangemaakt. Latere wijzigingen dienen via 'status.season_active' of uw visualisatie te worden doorgevoerd.",
139
140
  "Threshold for PV surplus (W)": "Drempel voor PV-overschot (W)",
140
141
  "Thursday": "Donderdag",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "System AI (aiHelper i aiForecastHelper) pobiera dane pogodowe z Open-Meteo za pośrednictwem protokołu HTTPS. Wykorzystuje współrzędne geograficzne z konfiguracji systemu ioBroker (system.config › latitude/longitude). Żadne dane nie są przechowywane ani przekazywane osobom trzecim. Bez prawidłowych współrzędnych geograficznych system AI nie może generować prognoz.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "Adapter PoolControl domyślnie działa całkowicie lokalnie. Obecnie tylko sztuczna inteligencja umożliwia dostęp do danych pogodowych z Open-Meteo za pośrednictwem szyfrowanego protokołu HTTPS. Przesyłane są tylko współrzędne geograficzne zapisane w ioBroker (szerokość i długość geograficzna). Żadne dodatkowe dane nie są przechowywane ani przesyłane osobom trzecim. W przyszłości mogą zostać dodane opcjonalne usługi internetowe, ale zawsze będą one wyraźnie oznaczone.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Te wartości ostrzegawcze są używane jako wartości początkowe podczas tworzenia punktów danych po raz pierwszy. Późniejszych zmian należy dokonać poprzez 'solar.warn_active', 'solar.warn_temp' i 'solar.warn_speech' lub poprzez swoją wizualizację.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Ta wartość jest tylko wartością początkową dla general.min_circulation_per_day. Jest kopiowana podczas pierwszej konfiguracji albo gdy stan jest pusty lub nieprawidłowy. Wartością efektywną jest zapisywalny stan general.min_circulation_per_day, który można później zmieniać przez VIS lub HomePanel.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Ta wartość jest używana jako początkowy stan sezonu, gdy punkt danych jest tworzony po raz pierwszy. Późniejszych zmian należy dokonać poprzez 'status.season_active' lub swoją wizualizację.",
139
140
  "Threshold for PV surplus (W)": "Próg nadwyżki PV (W)",
140
141
  "Thursday": "Czwartek",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "O sistema AI (aiHelper e aiForecastHelper) recupera dados meteorológicos do Open-Meteo via HTTPS. Ele usa as coordenadas geográficas da configuração do sistema ioBroker (system.config › latitude/longitude). Nenhum dado é armazenado ou transmitido a terceiros. Sem coordenadas geográficas válidas, o sistema de IA não pode gerar previsões.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "O adaptador PoolControl funciona completamente localmente por padrão. Atualmente, apenas os recursos de IA acessam dados meteorológicos do Open-Meteo via HTTPS criptografado. Apenas as coordenadas geográficas armazenadas no ioBroker (latitude e longitude) são transmitidas. Nenhum dado adicional é armazenado ou enviado a terceiros. Futuros serviços opcionais de Internet poderão ser adicionados, mas estarão sempre claramente marcados.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Esses valores de aviso são usados ​​como valores iniciais quando os pontos de dados são criados pela primeira vez. Alterações posteriores devem ser feitas por meio de 'solar.warn_active', 'solar.warn_temp' e 'solar.warn_speech' ou de sua visualização.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Este valor é apenas o valor inicial para general.min_circulation_per_day. É copiado na primeira configuração ou quando o estado está vazio ou inválido. O valor efetivo é o estado gravável general.min_circulation_per_day e pode ser alterado posteriormente via VIS ou HomePanel.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Este valor é usado como o status inicial da temporada quando o ponto de dados é criado pela primeira vez. Alterações posteriores devem ser feitas através de 'status.season_active' ou de sua visualização.",
139
140
  "Threshold for PV surplus (W)": "Limite para excedente fotovoltaico (W)",
140
141
  "Thursday": "Quinta-feira",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "Система искусственного интеллекта (aiHelper и aiForecastHelper) получает данные о погоде из Open-Meteo через HTTPS. Он использует географические координаты из конфигурации системы ioBroker (system.config › широта/долгота). Никакие данные не сохраняются и не передаются третьим лицам. Без действительных географических координат система ИИ не может генерировать прогнозы.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "Адаптер PoolControl по умолчанию работает полностью локально. В настоящее время только функции искусственного интеллекта получают доступ к данным о погоде из Open-Meteo через зашифрованный HTTPS. Передаются только географические координаты, хранящиеся в ioBroker (широта и долгота). Никакие дополнительные данные не сохраняются и не передаются третьим лицам. В будущем могут быть добавлены дополнительные интернет-услуги, но они всегда будут четко обозначены.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Эти значения предупреждения используются в качестве начальных значений при первом создании точек данных. Позже изменения следует внести с помощью «solar.warn_active», «solar.warn_temp» и «solar.warn_speech» или вашей визуализации.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Это значение является только начальным значением для general.min_circulation_per_day. Оно копируется при первой настройке или если состояние пустое либо недействительное. Действующее значение хранится в доступном для записи состоянии general.min_circulation_per_day и позже может изменяться через VIS или HomePanel.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Это значение используется в качестве начального статуса сезона при первом создании точки данных. Более поздние изменения следует внести через «status. Season_active» или вашу визуализацию.",
139
140
  "Threshold for PV surplus (W)": "Порог для избытка фотоэлектрической энергии (Вт)",
140
141
  "Thursday": "Четверг",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "Система AI (aiHelper & aiForecastHelper) отримує дані про погоду з Open-Meteo через HTTPS. Він використовує геокоординати з конфігурації системи ioBroker (system.config › широта/довгота). Жодні дані не зберігаються та не передаються третім особам. Без дійсних геокоординат система ШІ не може створювати прогнози.",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "Адаптер PoolControl за замовчуванням працює повністю локально. Наразі тільки функції ШІ отримують доступ до даних про погоду з Open-Meteo через зашифрований HTTPS. Передаються лише геокоординати, збережені в ioBroker (широта та довгота). Ніякі додаткові дані не зберігаються та не надсилаються третім особам. Майбутні додаткові інтернет-послуги можуть бути додані, але вони завжди будуть чітко позначені.",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "Ці значення попередження використовуються як початкові значення, коли точки даних створюються вперше. Зміни слід вносити пізніше за допомогою 'solar.warn_active', 'solar.warn_temp' і 'solar.warn_speech' або вашої візуалізації.",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "Це значення є лише початковим значенням для general.min_circulation_per_day. Воно копіюється під час першого налаштування або якщо стан порожній чи недійсний. Дієве значення зберігається у доступному для запису стані general.min_circulation_per_day і згодом може змінюватися через VIS або HomePanel.",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "Це значення використовується як початковий статус сезону, коли точка даних створюється вперше. Пізніші зміни слід вносити через 'status.season_active' або вашу візуалізацію.",
139
140
  "Threshold for PV surplus (W)": "Поріг для надлишку PV (Вт)",
140
141
  "Thursday": "четвер",
@@ -135,6 +135,7 @@
135
135
  "The AI system (aiHelper & aiForecastHelper) retrieves weather data from Open-Meteo via HTTPS. It uses the geo-coordinates from the ioBroker system configuration (system.config › latitude/longitude). No data is stored or transmitted to third parties. Without valid geo-coordinates, the AI system cannot generate forecasts.": "AI 系统(aiHelper 和 aiForecastHelper)通过 HTTPS 从 Open-Meteo 检索天气数据。它使用 ioBroker 系统配置(system.config › 纬度/经度)中的地理坐标。不会存储任何数据或将其传输给第三方。如果没有有效的地理坐标,人工智能系统就无法生成预测。",
136
136
  "The PoolControl adapter works completely locally by default. Currently, only the AI features access weather data from Open-Meteo via encrypted HTTPS. Only the geo-coordinates stored in ioBroker (latitude and longitude) are transmitted. No additional data is stored or sent to third parties. Future optional internet services may be added, but they will always be clearly marked.": "默认情况下,PoolControl 适配器完全在本地工作。目前,只有 AI 功能可以通过加密的 HTTPS 访问 Open-Meteo 的天气数据。仅传输存储在 ioBroker 中的地理坐标(纬度和经度)。不会存储任何额外数据或将其发送给第三方。未来可能会添加可选的互联网服务,但它们将始终被明确标记。",
137
137
  "These warning values are used as initial values when the datapoints are created for the first time. Later changes should be made via 'solar.warn_active', 'solar.warn_temp' and 'solar.warn_speech' or your visualization.": "首次创建数据点时,这些警告值将用作初始值。稍后的更改应通过“solar.warn_active”、“solar.warn_temp”和“solar.warn_speech”或您的可视化进行。",
138
+ "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.": "此值仅是 general.min_circulation_per_day 的初始值。首次设置时,或当状态为空或无效时,会复制该值。实际生效值是可写状态 general.min_circulation_per_day,之后可通过 VIS 或 HomePanel 修改。",
138
139
  "This value is used as the initial season status when the datapoint is created for the first time. Later changes should be made via 'status.season_active' or your visualization.": "当第一次创建数据点时,该值用作初始季节状态。稍后的更改应通过“status.season_active”或您的可视化进行。",
139
140
  "Threshold for PV surplus (W)": "光伏剩余阈值(W)",
140
141
  "Thursday": "周四",
@@ -67,6 +67,16 @@
67
67
  "lg": 3,
68
68
  "xl": 3
69
69
  },
70
+ "min_circulation_hint": {
71
+ "type": "staticText",
72
+ "text": "This value is only the initial value for general.min_circulation_per_day. It is copied during first setup or when the state is empty or invalid. The effective value is the writable state general.min_circulation_per_day and can later be changed via VIS or HomePanel.",
73
+ "newLine": true,
74
+ "xs": 12,
75
+ "sm": 12,
76
+ "md": 12,
77
+ "lg": 12,
78
+ "xl": 12
79
+ },
70
80
  "general_season_header": {
71
81
  "type": "header",
72
82
  "text": "Season Settings",
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "poolcontrol",
4
- "version": "1.3.34",
4
+ "version": "1.4.0",
5
5
  "news": {
6
+ "1.4.0": {
7
+ "en": "Added pump learning reset button with multilingual status messages, made the daily circulation factor writable and persistent with instant recalculation, introduced temperature-dependent automatic circulation factor adjustment, and extended time control with optional interval operation including diagnostic status messages.",
8
+ "de": "Reset-Button für das Pumpen-Learning mit mehrsprachigen Statusmeldungen hinzugefügt, täglichen Umwälzfaktor beschreibbar und persistent gemacht inklusive sofortiger Neuberechnung, temperaturabhängige automatische Anpassung des Umwälzfaktors ergänzt sowie die Zeitsteuerung um einen optionalen Intervallbetrieb mit Diagnosestatus erweitert.",
9
+ "ru": "Добавлена ​​кнопка сброса обучения насоса с многоязычными сообщениями о состоянии, сделан дневной коэффициент циркуляции доступным для записи и постоянным с мгновенным перерасчетом, введена автоматическая регулировка коэффициента циркуляции в зависимости от температуры и расширенное управление временем с опциональной интервальной работой, включая диагностические сообщения о состоянии.",
10
+ "pt": "Adicionado botão de reinicialização de aprendizado da bomba com mensagens de status multilíngues, tornou o fator de circulação diário gravável e persistente com recálculo instantâneo, introduziu ajuste automático do fator de circulação dependente da temperatura e controle de tempo estendido com operação em intervalo opcional, incluindo mensagens de status de diagnóstico.",
11
+ "nl": "Pomplerende resetknop toegevoegd met meertalige statusberichten, de dagelijkse circulatiefactor beschrijfbaar en persistent gemaakt met onmiddellijke herberekening, temperatuurafhankelijke automatische aanpassing van de circulatiefactor geïntroduceerd en uitgebreide tijdcontrole met optionele intervalbediening inclusief diagnostische statusberichten.",
12
+ "fr": "Ajout d'un bouton de réinitialisation de l'apprentissage de la pompe avec messages d'état multilingues, rendu le facteur de circulation quotidien inscriptible et persistant avec un recalcul instantané, introduction d'un réglage automatique du facteur de circulation en fonction de la température et contrôle de temps étendu avec fonctionnement par intervalles en option, y compris des messages d'état de diagnostic.",
13
+ "it": "Aggiunto pulsante di ripristino dell'apprendimento della pompa con messaggi di stato multilingue, reso il fattore di circolazione giornaliero scrivibile e persistente con ricalcolo istantaneo, introdotta la regolazione automatica del fattore di circolazione dipendente dalla temperatura e controllo del tempo esteso con funzionamento a intervalli opzionale inclusi messaggi di stato diagnostici.",
14
+ "es": "Se agregó un botón de reinicio de aprendizaje de la bomba con mensajes de estado multilingües, se hizo que el factor de circulación diario sea escribible y persistente con recálculo instantáneo, se introdujo el ajuste automático del factor de circulación dependiente de la temperatura y se extendió el control de tiempo con operación de intervalo opcional que incluye mensajes de estado de diagnóstico.",
15
+ "pl": "Dodano przycisk resetowania uczenia pompy z wielojęzycznymi komunikatami o stanie, umożliwiono zapis i trwałość dziennego współczynnika cyrkulacji dzięki natychmiastowemu przeliczeniu, wprowadzono automatyczną regulację współczynnika cyrkulacji zależną od temperatury oraz rozszerzoną kontrolę czasu z opcjonalną pracą interwałową, w tym komunikatami diagnostycznymi o stanie.",
16
+ "uk": "Додано кнопку скидання навчання насоса з багатомовними повідомленнями про стан, зробив щоденний коефіцієнт циркуляції записуваним і постійним із миттєвим перерахунком, запровадив автоматичне регулювання коефіцієнта циркуляції залежно від температури та розширений контроль часу з додатковим інтервалом роботи, включаючи діагностичні повідомлення про стан.",
17
+ "zh-cn": "添加了具有多语言状态消息的泵学习重置按钮,使每日循环系数可写并通过即时重新计算保持不变,引入了与温度相关的自动循环系数调整,以及具有可选间隔操作(包括诊断状态消息)的延长时间控制。"
18
+ },
19
+ "1.3.35": {
20
+ "en": "Fixed daily circulation remaining calculation after changing pool size or minimum daily circulation.",
21
+ "de": "Korrigiert die Berechnung der verbleibenden täglichen Umwälzung nach Änderung von Poolgröße oder Mindestumwälzung.",
22
+ "ru": "Исправлен расчет остатка дневного тиража после изменения размера пула или минимального дневного тиража.",
23
+ "pt": "Corrigido o cálculo restante da circulação diária após alterar o tamanho da piscina ou a circulação diária mínima.",
24
+ "nl": "Vaste berekening van de resterende dagelijkse circulatie na wijziging van de zwembadgrootte of minimale dagelijkse circulatie.",
25
+ "fr": "Calcul de la circulation quotidienne restante fixe après avoir modifié la taille de la piscine ou la circulation quotidienne minimale.",
26
+ "it": "Risolto il problema con il calcolo della circolazione giornaliera rimanente dopo aver modificato le dimensioni della piscina o la circolazione giornaliera minima.",
27
+ "es": "Se corrigió el cálculo de la circulación diaria restante después de cambiar el tamaño de la piscina o la circulación diaria mínima.",
28
+ "pl": "Naprawiono obliczanie pozostałego dziennego obiegu po zmianie wielkości basenu lub minimalnego dziennego obiegu.",
29
+ "uk": "Виправлено розрахунок залишку денного тиражу після зміни розміру пулу або мінімального добового тиражу.",
30
+ "zh-cn": "修复了更改矿池大小或最低每日流通量后每日流通量剩余计算的问题。"
31
+ },
6
32
  "1.3.34": {
7
33
  "en": "Improved chemistry history architecture with protected short-term and daily history, prevented oversized JSON states, added safeguards against state database growth, enhanced solar logbook/debug log protection, and updated adapter-core dependency.",
8
34
  "de": "Chemie-Historie grundlegend verbessert: geschützte Kurzzeit- und Tageshistorie eingeführt, übergroße JSON-States verhindert, Schutz vor unkontrolliertem Wachstum der State-Datenbank ergänzt, Solar-Logbuch und Debug-Log zusätzlich abgesichert sowie adapter-core-Abhängigkeit aktualisiert.",
@@ -41,32 +67,6 @@
41
67
  "pl": "Dodano diagnostykę wiarygodności obiegu. Nowe kontrole wykrywają nieprawdopodobną moc pompy, natężenie przepływu i codzienne skoki cyrkulacji. Dodano szczegółowe stany diagnostyczne w obszarze cyrkulacja.wiarygodność, aby uprościć rozwiązywanie problemów i analizę obliczeń cyrkulacji.",
42
68
  "uk": "Додана діагностика вірогідності циркуляції. Нові перевірки виявляють неправдоподібну потужність насоса, швидкість потоку та щоденні стрибки циркуляції. Додано детальні діагностичні стани під циркуляцією. Правдоподібність для спрощення пошуку несправностей і аналізу розрахунків циркуляції.",
43
69
  "zh-cn": "添加了循环合理性诊断。新的检查可以检测到难以置信的泵功率、流量和每日循环跳跃。在循环下添加了详细的诊断状态。合理性以简化循环计算的故障排除和分析。"
44
- },
45
- "1.3.31": {
46
- "en": "Fixed automatic circulation top-up logic when temperature sensors are missing. Automatic top-up is now only blocked by collector/pool temperature comparison when solar control is active and both temperatures are valid.",
47
- "de": "Fehler in der automatischen Nachpump-Logik bei fehlenden Temperatursensoren behoben. Das automatische Nachpumpen wird jetzt nur noch durch den Kollektor-/Pooltemperaturvergleich blockiert, wenn die Solarsteuerung aktiv ist und beide Temperaturwerte gültig vorliegen.",
48
- "ru": "Исправлена ​​логика автоматического пополнения циркуляции при отсутствии датчиков температуры. Автоматическое пополнение теперь блокируется только при сравнении температур коллектора и бассейна, когда активно управление солнечной батареей и обе температуры действительны.",
49
- "pt": "Lógica de recarga automática de circulação corrigida quando faltam sensores de temperatura. O reabastecimento automático agora só é bloqueado pela comparação da temperatura do coletor/piscina quando o controle solar está ativo e ambas as temperaturas são válidas.",
50
- "nl": "Probleem opgelost met het automatisch bijvullen van de circulatie wanneer temperatuursensoren ontbreken. Het automatisch bijvullen wordt nu alleen geblokkeerd door de vergelijking van de collector-/zwembadtemperatuur als de zonneregeling actief is en beide temperaturen geldig zijn.",
51
- "fr": "Correction de la logique de recharge automatique de la circulation lorsque les capteurs de température sont manquants. L'appoint automatique n'est désormais bloqué par la comparaison des températures capteur/piscine que lorsque le contrôle solaire est actif et que les deux températures sont valables.",
52
- "it": "Risolta la logica di rabbocco della circolazione automatica in caso di mancanza dei sensori di temperatura. Il rabbocco automatico ora è bloccato solo dal confronto della temperatura collettore/piscina quando il controllo solare è attivo ed entrambe le temperature sono valide.",
53
- "es": "Se corrigió la lógica de recarga de circulación automática cuando faltaban sensores de temperatura. La recarga automática ahora solo se bloquea mediante la comparación de temperatura del colector/piscina cuando el control solar está activo y ambas temperaturas son válidas.",
54
- "pl": "Naprawiono logikę automatycznego uzupełniania cyrkulacji w przypadku braku czujników temperatury. Automatyczne uzupełnianie jest teraz blokowane tylko przez porównanie temperatur kolektora/basenu, gdy aktywna jest kontrola solarna i obie temperatury są prawidłowe.",
55
- "uk": "Виправлена ​​логіка автоматичного доповнення циркуляції, коли датчики температури відсутні. Автоматичне поповнення тепер блокується лише шляхом порівняння температури колектора/басейну, коли активовано сонячне керування та обидві температури дійсні.",
56
- "zh-cn": "修复了缺少温度传感器时的自动循环充值逻辑。现在,仅当太阳能控制处于活动状态并且两个温度都有效时,自动充值才会被收集器/池温度比较阻止。"
57
- },
58
- "1.3.30": {
59
- "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.",
60
- "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.",
61
- "ru": "Обновлены инструменты выпуска до необходимой минимальной версии. Очищены устаревшие ключи администратора i18n. Заменены встроенные таймеры в помощниках погоды AI на таймеры адаптера ioBroker.",
62
- "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.",
63
- "nl": "Releasetooling bijgewerkt naar de vereiste minimumversie. Verouderde Admin i18n-sleutels opgeschoond. Native timers in AI-weerhelpers vervangen door ioBroker-adaptertimers.",
64
- "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.",
65
- "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.",
66
- "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.",
67
- "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.",
68
- "uk": "Оновлено інструмент випуску до необхідної мінімальної версії. Очищено застарілі ключі адміністратора i18n. Вбудовані таймери в помічниках погоди штучного інтелекту замінено на таймери адаптера ioBroker.",
69
- "zh-cn": "将发布工具更新为所需的最低版本。清理了过时的 Admin i18n 密钥。将 AI 天气助手中的本机计时器替换为 ioBroker 适配器计时器。"
70
70
  }
71
71
  },
72
72
  "titleLang": {
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const { I18n } = require('@iobroker/adapter-core');
4
+
3
5
  /**
4
6
  * pumpHelper3.js
5
7
  * ----------------------------------------------------------
@@ -50,6 +52,7 @@ const pumpHelper3 = {
50
52
  this.adapter.subscribeStates('pump.pump_switch');
51
53
  this.adapter.subscribeStates('pump.live.current_power_w');
52
54
  this.adapter.subscribeStates('pump.live.flow_current_lh');
55
+ this.adapter.subscribeStates('pump.learning.reset');
53
56
 
54
57
  this.adapter.log.info('[pumpHelper3] Successfully initialized');
55
58
  },
@@ -66,6 +69,12 @@ const pumpHelper3 = {
66
69
  }
67
70
 
68
71
  try {
72
+ if (id.endsWith('pump.learning.reset') && state.ack === false && state.val === true) {
73
+ await this._resetLearningValues();
74
+ await this.adapter.setStateAsync('pump.learning.reset', { val: false, ack: true });
75
+ return;
76
+ }
77
+
69
78
  if (id.endsWith('pump.pump_switch')) {
70
79
  const isOn = state.val === true;
71
80
  if (isOn) {
@@ -246,15 +255,50 @@ const pumpHelper3 = {
246
255
  const tolerance = Number(toleranceState?.val) || 15;
247
256
 
248
257
  if (absPower <= tolerance && absFlow <= tolerance) {
249
- return 'Pumpe läuft im Normalbereich';
258
+ return I18n.translate('Pump is running within the normal range');
250
259
  }
251
260
  if (devPower < -tolerance || devFlow < -tolerance) {
252
- return 'Pumpe läuft unterhalb des Normalbereichs (möglicher Filterdruck)';
261
+ return I18n.translate('Pump is running below the normal range');
253
262
  }
254
263
  if (devPower > tolerance || devFlow > tolerance) {
255
- return 'Pumpe läuft oberhalb des Normalbereichs (möglicher Luftstau)';
264
+ return I18n.translate('Pump is running above the normal range');
256
265
  }
257
- return 'Pumpe außerhalb des bekannten Bereichs';
266
+ return I18n.translate('Pump is outside the known range');
267
+ },
268
+
269
+ async _resetLearningValues() {
270
+ const statesToReset = [
271
+ 'pump.learning.learned_avg_flow_lh',
272
+ 'pump.learning.learned_avg_power_w',
273
+ 'pump.learning.learning_cycles_total',
274
+ 'pump.learning.normal_range_flow_low',
275
+ 'pump.learning.normal_range_flow_high',
276
+ 'pump.learning.normal_range_power_low',
277
+ 'pump.learning.normal_range_power_high',
278
+ 'pump.learning.deviation_flow_percent',
279
+ 'pump.learning.deviation_power_percent',
280
+ ];
281
+
282
+ for (const id of statesToReset) {
283
+ await this.adapter.setStateAsync(id, { val: 0, ack: true });
284
+ }
285
+
286
+ const resetText = I18n.translate('Pump learning values reset');
287
+
288
+ await this.adapter.setStateAsync('pump.learning.status_text', {
289
+ val: resetText,
290
+ ack: true,
291
+ });
292
+
293
+ this.currentSessionValues.power = [];
294
+ this.currentSessionValues.flow = [];
295
+ this._lastLearningStatus = '';
296
+ this._lastDevPower = 0;
297
+ this._lastDevFlow = 0;
298
+ this._lastDevWrite = 0;
299
+ this._lastLearningWrite = 0;
300
+
301
+ this.adapter.log.info('[pumpHelper3] Pump learning values reset.');
258
302
  },
259
303
 
260
304
  /**
@@ -50,6 +50,10 @@ const runtimeHelper = {
50
50
 
51
51
  // Pumpenschalter überwachen
52
52
  this.adapter.subscribeStates('pump.pump_switch');
53
+ this.adapter.subscribeStates('general.min_circulation_per_day');
54
+ this.adapter.subscribeStates('control.circulation.temperature_factor.*');
55
+ this.adapter.subscribeStates('temperature.*_temp_active');
56
+ this.adapter.subscribeStates('temperature.*.current');
53
57
 
54
58
  // >>> NEU: Alte Werte aus States laden
55
59
  this._restoreFromStates()
@@ -113,6 +117,16 @@ const runtimeHelper = {
113
117
  return;
114
118
  }
115
119
 
120
+ const updatesCirculationTarget =
121
+ id.endsWith('general.min_circulation_per_day') ||
122
+ /control\.circulation\.temperature_factor\.(enabled|sensor|threshold_c|add_factor)$/.test(id) ||
123
+ /^.+\.temperature\.(surface|ground|flow|return|collector|outside)(_temp_active|\.current)$/.test(id);
124
+
125
+ if (updatesCirculationTarget) {
126
+ await this._updateCirculationTargets();
127
+ return;
128
+ }
129
+
116
130
  // FIX: Robuste Start-/Stop-Logik für pump.pump_switch
117
131
  if (id.endsWith('pump.pump_switch')) {
118
132
  if (state.val) {
@@ -227,23 +241,12 @@ const runtimeHelper = {
227
241
  await this.adapter.setStateAsync('runtime.start_count_today', { val: this.startCountToday, ack: true });
228
242
 
229
243
  // Poolparameter laden (vor Durchflussprüfung!)
230
- const poolSize = (await this.adapter.getStateAsync('general.pool_size'))?.val || 0;
231
- const minCirc = (await this.adapter.getStateAsync('general.min_circulation_per_day'))?.val || 1;
232
-
233
- // daily_required immer direkt setzen – auch ohne Durchfluss
234
- const dailyRequired = Math.round(poolSize * minCirc);
235
- if (dailyRequired > 0) {
236
- await this.adapter.setStateAsync('circulation.daily_required', { val: dailyRequired, ack: true });
237
- }
244
+ const { dailyRequired, oldTotal, remainingFromCurrentTotal } = await this._updateCirculationTargets();
238
245
 
239
246
  // Umwälzmenge berechnen
240
247
  // Reeller Durchflusswert aus pump.live.flow_current_lh
241
248
  const liveFlowLh = Number((await this.adapter.getStateAsync('pump.live.flow_current_lh'))?.val || 0);
242
249
 
243
- // Bestehende Werte für Total/Remaining laden
244
- const oldTotal = Number((await this.adapter.getStateAsync('circulation.daily_total'))?.val || 0);
245
- const oldRemaining = Number((await this.adapter.getStateAsync('circulation.daily_remaining'))?.val || 0);
246
-
247
250
  if (liveFlowLh <= 0) {
248
251
  await this._updateCirculationPlausibility({
249
252
  dailyTotal: oldTotal,
@@ -279,7 +282,7 @@ const runtimeHelper = {
279
282
  );
280
283
  } else {
281
284
  this.adapter.log.debug(
282
- `[runtimeHelper] No valid live data – keeping existing values (Total=${oldTotal}, Required=${dailyRequired}, Remaining=${oldRemaining})`,
285
+ `[runtimeHelper] No valid live data – keeping existing total (Total=${oldTotal}, Required=${dailyRequired}, Remaining=${remainingFromCurrentTotal})`,
283
286
  );
284
287
  }
285
288
  } catch (err) {
@@ -287,6 +290,112 @@ const runtimeHelper = {
287
290
  }
288
291
  },
289
292
 
293
+ _normalizeMinCirculation(value) {
294
+ const num = Number(value);
295
+ return Number.isFinite(num) && num >= 0.5 && num <= 3 ? num : null;
296
+ },
297
+
298
+ async _readMinCirculation() {
299
+ const configured = this._normalizeMinCirculation(this.adapter.config.min_circulation_per_day) ?? 1;
300
+ const state = await this.adapter.getStateAsync('general.min_circulation_per_day');
301
+ const current = this._normalizeMinCirculation(state?.val);
302
+
303
+ if (current !== null) {
304
+ return current;
305
+ }
306
+
307
+ await this.adapter.setStateAsync('general.min_circulation_per_day', { val: configured, ack: true });
308
+ return configured;
309
+ },
310
+
311
+ async _updateCirculationTargets() {
312
+ const poolSize = Number((await this.adapter.getStateAsync('general.pool_size'))?.val || 0);
313
+ const minCirc = await this._readMinCirculation();
314
+ const { effectiveFactor } = await this._calculateEffectiveMinCirculation(minCirc);
315
+ const dailyRequired = Math.round(poolSize * effectiveFactor);
316
+ const oldTotal = Number((await this.adapter.getStateAsync('circulation.daily_total'))?.val || 0);
317
+ const remainingFromCurrentTotal = Math.max(dailyRequired - oldTotal, 0);
318
+
319
+ await this.adapter.setStateAsync('circulation.daily_required', { val: dailyRequired, ack: true });
320
+ await this.adapter.setStateAsync('circulation.daily_remaining', {
321
+ val: remainingFromCurrentTotal,
322
+ ack: true,
323
+ });
324
+
325
+ return { dailyRequired, oldTotal, remainingFromCurrentTotal };
326
+ },
327
+
328
+ async _calculateEffectiveMinCirculation(baseFactor) {
329
+ const prefix = 'control.circulation.temperature_factor';
330
+ const writeResult = async (effectiveFactor, active, reason) => {
331
+ await this.adapter.setStateAsync('general.min_circulation_effective_per_day', {
332
+ val: effectiveFactor,
333
+ ack: true,
334
+ });
335
+ await this.adapter.setStateAsync('general.min_circulation_effective_reason', { val: reason, ack: true });
336
+ await this.adapter.setStateAsync(`${prefix}.active`, { val: active, ack: true });
337
+ await this.adapter.setStateAsync(`${prefix}.status`, { val: reason, ack: true });
338
+ return { effectiveFactor, active, reason };
339
+ };
340
+
341
+ const enabled = (await this.adapter.getStateAsync(`${prefix}.enabled`))?.val;
342
+ if (enabled !== true) {
343
+ return writeResult(baseFactor, false, enabled === false ? 'disabled' : 'invalid_config');
344
+ }
345
+
346
+ const validSensors = ['surface', 'ground', 'flow', 'return', 'collector', 'outside'];
347
+ const sensor = (await this.adapter.getStateAsync(`${prefix}.sensor`))?.val;
348
+ if (typeof sensor !== 'string' || !validSensors.includes(sensor)) {
349
+ return writeResult(baseFactor, false, 'invalid_sensor');
350
+ }
351
+
352
+ const thresholdRaw = (await this.adapter.getStateAsync(`${prefix}.threshold_c`))?.val;
353
+ const addFactorRaw = (await this.adapter.getStateAsync(`${prefix}.add_factor`))?.val;
354
+ const threshold = Number(thresholdRaw);
355
+ const addFactor = Number(addFactorRaw);
356
+ if (
357
+ thresholdRaw === null ||
358
+ thresholdRaw === undefined ||
359
+ thresholdRaw === '' ||
360
+ !Number.isFinite(threshold) ||
361
+ threshold < -20 ||
362
+ threshold > 60 ||
363
+ addFactorRaw === null ||
364
+ addFactorRaw === undefined ||
365
+ addFactorRaw === '' ||
366
+ !Number.isFinite(addFactor) ||
367
+ addFactor < 0 ||
368
+ addFactor > 2.5
369
+ ) {
370
+ return writeResult(baseFactor, false, 'invalid_config');
371
+ }
372
+
373
+ const sensorActive = (await this.adapter.getStateAsync(`temperature.${sensor}_temp_active`))?.val;
374
+ if (sensorActive !== true) {
375
+ return writeResult(baseFactor, false, 'sensor_inactive');
376
+ }
377
+
378
+ const temperatureRaw = (await this.adapter.getStateAsync(`temperature.${sensor}.current`))?.val;
379
+ const temperature = Number(temperatureRaw);
380
+ if (
381
+ temperatureRaw === null ||
382
+ temperatureRaw === undefined ||
383
+ temperatureRaw === '' ||
384
+ !Number.isFinite(temperature)
385
+ ) {
386
+ return writeResult(baseFactor, false, 'temperature_missing');
387
+ }
388
+
389
+ if (temperature < threshold) {
390
+ return writeResult(baseFactor, false, 'base');
391
+ }
392
+
393
+ const uncappedFactor = baseFactor + addFactor;
394
+ const effectiveFactor = Math.min(uncappedFactor, 3);
395
+ const reason = uncappedFactor > 3 ? 'temperature_factor_capped' : 'temperature_factor_active';
396
+ return writeResult(effectiveFactor, true, reason);
397
+ },
398
+
290
399
  async _updateCirculationPlausibility({
291
400
  dailyTotal,
292
401
  oldTotal,
@@ -535,10 +644,7 @@ const runtimeHelper = {
535
644
  await this.adapter.setStateAsync('circulation.daily_total', { val: 0, ack: true });
536
645
 
537
646
  // daily_required neu berechnen (optional, falls sich Poolgröße geändert hat)
538
- const poolSize = (await this.adapter.getStateAsync('general.pool_size'))?.val || 0;
539
- const minCirc = (await this.adapter.getStateAsync('general.min_circulation_per_day'))?.val || 1;
540
- const dailyRequired = Math.round(poolSize * minCirc);
541
- await this.adapter.setStateAsync('circulation.daily_required', { val: dailyRequired, ack: true });
647
+ const { dailyRequired } = await this._updateCirculationTargets();
542
648
 
543
649
  // 👉 daily_remaining neue berechnen auf Grundlage von daily_required
544
650
  await this.adapter.setStateAsync('circulation.daily_remaining', { val: dailyRequired, ack: true });