iobroker.poolcontrol 1.3.11 → 1.3.13

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
@@ -188,6 +188,53 @@ New features are added regularly – please refer to the changelog.
188
188
  ---
189
189
 
190
190
  ## Changelog
191
+ ### 1.3.13 (2026-05-08)
192
+ - (copilot) Adapter requires node.js >= 22 now
193
+ - Fixed invalid `common.installedFrom` entry in `io-package.json`
194
+ - Added German and English function overview documentation
195
+
196
+ ### 1.3.12 (2026-05-02)
197
+
198
+ **Solar Insights – Calculation fix & structure improvement**
199
+
200
+ - Fixed incorrect thermal power and energy calculation
201
+ - Previously used collector – pool temperature → caused unrealistic values
202
+ - Switched to correct physical calculation: return – flow (water delta)
203
+ - Thermal power is now only calculated when:
204
+ - valid flow is available
205
+ - delta T > 0
206
+ - Prevents unrealistic values (e.g. hundreds of kW or >100 kWh daily gain)
207
+ - Stabilized daily gain and peak power calculation
208
+ - No accumulation with invalid or missing data
209
+ - Improved sensor logic:
210
+ - introduced `flow` and `water_delta`
211
+ - clear separation between flow and temperature delta
212
+ - Increased transparency:
213
+ - new output: `thermal_delta_source = return_flow_delta`
214
+ - HTML and JSON outputs extended
215
+ - Added new i18n key:
216
+ - `solar_insights_label_thermal_delta_source`
217
+
218
+ **Photovoltaic Insights – Runtime & stability fix**
219
+
220
+ - Fixed incorrect runtime calculation
221
+ - Root cause: runtime was only calculated on state changes
222
+ - Added internal periodic recalculation (every 60 seconds during PV runtime)
223
+ - Runtime is now accumulated continuously and correctly
224
+ - Logic unchanged:
225
+ - only real PV surplus runtime is counted (`pv_surplus_active && photovoltaicHelper`)
226
+ - no afterrun included
227
+ - Improved calculation:
228
+ - runtime is now independent from pump power availability
229
+ - energy is only calculated with valid pump power
230
+ - Increased stability:
231
+ - improved start detection (`starts_today`)
232
+ - more reliable time delta handling
233
+ - Added daily reset:
234
+ - all daily values reset at midnight
235
+ - runtime, energy, savings, starts and active state cleared
236
+ - internal helper states reset
237
+
191
238
  ### 1.3.11 (2026-05-02)
192
239
 
193
240
  - (DasBo) New: pH evaluation module (`chemistry.ph`)
@@ -257,21 +304,6 @@ Fix: PV Circulation Logic
257
304
  - Fix: Added missing `debug.last_update` update on successful calculation
258
305
  - Improvement: General stability and plausibility improvements in solar insights and logbook processing
259
306
 
260
- ### 1.3.7 (2026-04-23)
261
-
262
- Bugfixes
263
- - solarInsightsHelper: fixed detection of standard solar runtime, replaced non-existing solar.active with solar.request_active, improved reliability of solar_ran_today for normal solar setups
264
- - photovoltaicHelper: round surplus value in status text (avoid long decimal numbers), switched afterrun timer to adapter.setTimeout / clearTimeout
265
-
266
- ### 1.3.6 (2026-04-21)
267
-
268
- frostHelper
269
- - Fixed incorrect pump shutdown when other helpers (e.g. photovoltaicHelper) are active
270
- - frostHelper now only disables the pump if it previously activated it itself
271
- - improved internal ownership logic for safer multi-helper interaction
272
- - corrected frost speech state handling (no longer based on current pump state)
273
- - switched timer to adapter.setInterval / adapter.clearInterval for better stability and ioBroker compliance
274
-
275
307
  ## Support
276
308
  - [ioBroker Forum](https://forum.iobroker.net/)
277
309
  - [GitHub Issues](https://github.com/DasBo1975/ioBroker.poolcontrol/issues)
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "poolcontrol",
4
- "version": "1.3.11",
4
+ "version": "1.3.13",
5
5
  "news": {
6
+ "1.3.13": {
7
+ "en": "Added German and English function overview documentation. Fixed invalid common.installedFrom entry in io-package.json.",
8
+ "de": "Deutsche und englische Funktionsübersicht ergänzt. Ungültigen common.installedFrom-Eintrag in der io-package.json korrigiert.",
9
+ "ru": "Добавлена ​​обзорная документация по функциям на немецком и английском языках. Исправлена ​​неверная запись common.installedFrom в io-package.json.",
10
+ "pt": "Adicionada documentação de visão geral das funções em alemão e inglês. Corrigida entrada common.installedFrom inválida em io-package.json.",
11
+ "nl": "Duitse en Engelse functieoverzichtdocumentatie toegevoegd. Ongeldige common.installedFrom-vermelding in io-package.json opgelost.",
12
+ "fr": "Ajout d'une documentation de présentation des fonctions en allemand et en anglais. Correction de l'entrée common.installedFrom invalide dans io-package.json.",
13
+ "it": "Aggiunta la documentazione panoramica delle funzioni in tedesco e inglese. Risolto il problema con la voce common.installedFrom non valida in io-package.json.",
14
+ "es": "Se agregó documentación de descripción general de funciones en alemán e inglés. Se corrigió la entrada common.installedFrom no válida en io-package.json.",
15
+ "pl": "Dodano dokumentację przeglądu funkcji w języku niemieckim i angielskim. Naprawiono nieprawidłowy wpis common.installedFrom w io-package.json.",
16
+ "uk": "Додано документацію щодо огляду функцій німецькою та англійською мовами. Виправлено недійсний запис common.installedFrom у io-package.json.",
17
+ "zh-cn": "添加了德语和英语功能概述文档。修复了 io-package.json 中无效的 common.installedFrom 条目。"
18
+ },
19
+ "1.3.12": {
20
+ "en": "Solar Insights calculation fixed and photovoltaic runtime tracking stabilized",
21
+ "de": "Solar Insights Berechnung korrigiert und Photovoltaik-Laufzeit stabilisiert",
22
+ "ru": "Исправлен расчет Solar Insights и стабилизировано отслеживание времени работы фотоэлектрических систем.",
23
+ "pt": "Cálculo do Solar Insights corrigido e rastreamento de tempo de execução fotovoltaico estabilizado",
24
+ "nl": "Solar Insights-berekening vast en tracking van fotovoltaïsche looptijd gestabiliseerd",
25
+ "fr": "Calcul de Solar Insights corrigé et suivi de la durée de fonctionnement photovoltaïque stabilisé",
26
+ "it": "Calcolo Solar Insights fisso e monitoraggio dell'autonomia fotovoltaica stabilizzato",
27
+ "es": "Cálculo de Solar Insights fijo y seguimiento del tiempo de funcionamiento fotovoltaico estabilizado",
28
+ "pl": "Naprawiono obliczenia Solar Insights i ustabilizowano śledzenie czasu działania fotowoltaiki",
29
+ "uk": "Виправлено розрахунок Solar Insights і стабілізовано відстеження часу роботи фотоелектричної системи",
30
+ "zh-cn": "Solar Insights 计算固定,光伏运行时间跟踪稳定"
31
+ },
6
32
  "1.3.11": {
7
33
  "en": "New: Added pH evaluation module (chemistry.ph) with manual and external input, validation, measurement location handling and recommendations. New: Added TDS evaluation module (chemistry.tds) with trend analysis (24h, 7d, 30d), reference tracking and summary outputs (text/JSON/HTML). Fix: Resolved solar speech toggle issue between standard and extended mode. solarExtendedHelper no longer overwrites speech.solar_active in standard mode.",
8
34
  "de": "Neu: pH-Auswertungsmodul (chemistry.ph) mit manueller und externer Eingabe, Validierung, Messort-Berücksichtigung und Handlungsempfehlungen. Neu: TDS-Auswertungsmodul (chemistry.tds) mit Trendanalyse (24h, 7 Tage, 30 Tage), Referenzwert-Verfolgung und Zusammenfassungen (Text/JSON/HTML). Fix: Problem mit Solar-Sprachausgabe zwischen Standard- und Extended-Modus behoben. Der solarExtendedHelper überschreibt speech.solar_active im Standard-Modus nicht mehr.",
@@ -41,32 +67,6 @@
41
67
  "pl": "Napraw duplikację dziennika słonecznego i nieprawidłowe wpisy, popraw stabilność dziennika i obsługę tekstu pogodowego; napraw obliczenia czasu działania Solar Insights i aktualizację znacznika czasu debugowania.",
42
68
  "uk": "Виправте дублювання сонячного журналу та недійсні записи, покращте стабільність журналу та обробку тексту погоди; виправити розрахунок часу виконання solar insights і налагодити оновлення часових позначок.",
43
69
  "zh-cn": "修复太阳能日志重复和无效条目,提高日志稳定性和天气文本处理;修复 Solar Insights 运行时计算和调试时间戳更新。"
44
- },
45
- "1.3.7": {
46
- "en": "Fix solarInsights detection for standard solar (use solar.request_active instead of non-existing solar.active). photovoltaicHelper improvements: rounded surplus value in status text and switched afterrun timer to adapter.setTimeout/clearTimeout.",
47
- "de": "Fix der solarInsights-Erkennung für Standard-Solar (Verwendung von solar.request_active statt nicht vorhandenem solar.active). Verbesserungen im photovoltaicHelper: Rundung des Überschusswerts im Status-Text und Umstellung des Afterrun-Timers auf adapter.setTimeout/clearTimeout.",
48
- "ru": "Исправлено обнаружение SolarInsights для стандартной солнечной энергии (используйте Solar.request_active вместо несуществующего Solar.active). Улучшения photovoltaicHelper: округленное лишнее значение в тексте состояния и переключение таймера послезапуска на адаптер.setTimeout/clearTimeout.",
49
- "pt": "Corrija a detecção do solarInsights para energia solar padrão (use solar.request_active em vez de solar.active inexistente). Melhorias no photovoltaicHelper: valor excedente arredondado no texto de status e temporizador pós-execução alterado para adaptador.setTimeout/clearTimeout.",
50
- "nl": "Fix solarInsights-detectie voor standaard zonne-energie (gebruik solar.request_active in plaats van niet-bestaande solar.active). photovoltaicHelper-verbeteringen: afgeronde meerwaarde in statustekst en geschakelde nalooptimer naar adapter.setTimeout/clearTimeout.",
51
- "fr": "Correction de la détection solarInsights pour l'énergie solaire standard (utilisez solar.request_active au lieu de solar.active inexistant). Améliorations de photovoltaicHelper : valeur excédentaire arrondie dans le texte d'état et minuterie de post-exécution commutée sur adapter.setTimeout/clearTimeout.",
52
- "it": "Correggere il rilevamento di solarInsights per l'energia solare standard (utilizzare solar.request_active anziché solar.active inesistente). Miglioramenti di fotovoltaicoHelper: valore surplus arrotondato nel testo di stato e timer di postesecuzione commutato su Adapter.setTimeout/clearTimeout.",
53
- "es": "Se corrigió la detección de solarInsights para energía solar estándar (use solar.request_active en lugar de solar.active no existente). Mejoras en photovoltaicHelper: valor excedente redondeado en el texto de estado y temporizador de posejecución cambiado a adaptor.setTimeout/clearTimeout.",
54
- "pl": "Napraw wykrywanie solarInsights dla standardowej energii słonecznej (użyj solar.request_active zamiast nieistniejącego solar.active). Udoskonalenia programu photovoltaicHelper: zaokrąglona wartość nadwyżki w tekście statusu i przełączona licznik czasu afterrun na adapter.setTimeout/clearTimeout.",
55
- "uk": "Виправте виявлення solarInsights для стандартної сонячної енергії (використовуйте solar.request_active замість неіснуючого solar.active). Покращення photovoltaicHelper: округлене надлишкове значення в тексті стану та переключений таймер післязапуску на adapter.setTimeout/clearTimeout.",
56
- "zh-cn": "修复标准太阳能的 SolarInsights 检测(使用 Solar.request_active 而不是不存在的 Solar.active)。 PVHelper 改进:对状态文本中的剩余值进行四舍五入,并将 Afterrun 计时器切换为 adapter.setTimeout/clearTimeout。"
57
- },
58
- "1.3.6": {
59
- "en": "Fix for frostHelper: prevents incorrect pump shutdown when other helpers (e.g. photovoltaic) are active. Frost protection now only disables the pump if it previously activated it itself. Improved speech state logic for frost indication. Switched frostHelper timer to adapter.setInterval for better stability and ioBroker compliance.",
60
- "de": "Fix für frostHelper: verhindert falsches Abschalten der Pumpe, wenn andere Helper (z. B. Photovoltaik) aktiv sind. Frostschutz schaltet die Pumpe jetzt nur noch aus, wenn er sie zuvor selbst aktiviert hat. Sprach-State für Frostanzeige korrigiert. Timer im frostHelper auf adapter.setInterval umgestellt für bessere Stabilität und ioBroker-Konformität.",
61
- "ru": "Исправление FrostHelper: предотвращает некорректное выключение насоса, когда активны другие помощники (например, фотоэлектрические). Защита от замерзания теперь отключает насос только в том случае, если он ранее активировал его сам. Улучшена логика речевого состояния для индикации замерзания. Таймер FrostHelper переключен на адаптер.setInterval для большей стабильности и соответствия требованиям ioBroker.",
62
- "pt": "Correção parafrostHelper: evita o desligamento incorreto da bomba quando outros auxiliares (por exemplo, fotovoltaicos) estão ativos. A proteção contra congelamento agora só desativa a bomba se ela mesma a tiver ativado anteriormente. Lógica de estado de fala aprimorada para indicação de congelamento. Mudou o temporizadorfrostHelper para adaptador.setInterval para melhor estabilidade e conformidade com ioBroker.",
63
- "nl": "Oplossing voor FrostHelper: voorkomt onjuiste pompuitschakeling wanneer andere helpers (bijv. fotovoltaïsche energie) actief zijn. De vorstbeveiliging schakelt de pomp nu alleen uit als deze deze eerder zelf heeft geactiveerd. Verbeterde spraakstatuslogica voor vorstindicatie. FrostHelper-timer omgeschakeld naar adapter.setInterval voor betere stabiliteit en ioBroker-compliance.",
64
- "fr": "Correctif pour frostHelper : empêche un arrêt incorrect de la pompe lorsque d'autres assistants (par exemple photovoltaïques) sont actifs. La protection antigel désactive désormais la pompe uniquement si elle l'a activée elle-même auparavant. Logique d’état vocale améliorée pour l’indication de gel. La minuterie FrostHelper a été remplacée par adapter.setInterval pour une meilleure stabilité et une meilleure conformité à ioBroker.",
65
- "it": "Correzione per FrostHelper: impedisce lo spegnimento errato della pompa quando altri helper (ad esempio fotovoltaico) sono attivi. La protezione antigelo ora disabilita la pompa solo se precedentemente l'aveva attivata da sola. Logica dello stato vocale migliorata per l'indicazione del gelo. Cambiato il timer FrostHelper su Adapter.setInterval per una migliore stabilità e conformità con ioBroker.",
66
- "es": "Solución para frostHelper: evita el apagado incorrecto de la bomba cuando otros ayudantes (por ejemplo, fotovoltaicos) están activos. La protección contra heladas ahora solo desactiva la bomba si previamente la activó ella misma. Lógica de estado de voz mejorada para indicación de escarcha. Se cambió el temporizador frostHelper a adaptor.setInterval para una mejor estabilidad y cumplimiento de ioBroker.",
67
- "pl": "Poprawka dla FrostHelper: zapobiega nieprawidłowemu wyłączeniu pompy, gdy aktywne są inne pomoce (np. fotowoltaiczne). Ochrona przed zamarzaniem wyłącza teraz pompę tylko wtedy, gdy wcześniej sama ją uruchomiła. Ulepszona logika stanu mowy dla sygnalizacji mrozu. Zmieniono licznik czasu FrostHelper na adapter.setInterval, aby zapewnić lepszą stabilność i zgodność z ioBrokerem.",
68
- "uk": "Виправлення для frostHelper: запобігає неправильному вимкненню насоса, коли інші помічники (наприклад, фотоелектричні) активні. Захист від замерзання тепер вимикає насос лише в тому випадку, якщо він раніше сам його активував. Покращена логіка стану мови для індикації морозу. Перемкнуто таймер frostHelper на adapter.setInterval для кращої стабільності та відповідності ioBroker.",
69
- "zh-cn": "修复霜助手:防止当其他助手(例如光伏)处于活动状态时错误地关闭泵。现在,防冻保护只会在泵之前自行激活的情况下禁用泵。改进了霜冻指示的语音状态逻辑。将frostHelper计时器切换为adapter.setInterval以获得更好的稳定性和ioBroker合规性。"
70
70
  }
71
71
  },
72
72
  "titleLang": {
@@ -133,8 +133,7 @@
133
133
  {
134
134
  "admin": ">=7.6.20"
135
135
  }
136
- ],
137
- "installedFrom": "file:///opt/iobroker/ioBroker.poolcontrol"
136
+ ]
138
137
  },
139
138
  "native": {},
140
139
  "objects": [],
@@ -5,6 +5,7 @@ const { I18n } = require('@iobroker/adapter-core');
5
5
  const photovoltaicInsightsHelper = {
6
6
  adapter: null,
7
7
  checkTimer: null,
8
+ resetTimer: null,
8
9
  lastResultTimestamp: null,
9
10
  lastPvRuntimeActive: false,
10
11
 
@@ -12,6 +13,7 @@ const photovoltaicInsightsHelper = {
12
13
  this.adapter = adapter;
13
14
 
14
15
  void this._subscribeStates();
16
+ this._scheduleDailyReset();
15
17
  this._scheduleCheck(0);
16
18
 
17
19
  this.adapter.log.debug(
@@ -31,6 +33,79 @@ const photovoltaicInsightsHelper = {
31
33
  this._scheduleCheck(200);
32
34
  },
33
35
 
36
+ _scheduleDailyReset() {
37
+ if (this.resetTimer) {
38
+ this.adapter.clearTimeout(this.resetTimer);
39
+ this.resetTimer = null;
40
+ }
41
+
42
+ const now = new Date();
43
+ const next = new Date(now);
44
+ next.setDate(now.getDate() + 1);
45
+ next.setHours(0, 0, 5, 0);
46
+
47
+ const delay = Math.max(1000, next.getTime() - now.getTime());
48
+
49
+ this.resetTimer = this.adapter.setTimeout(async () => {
50
+ try {
51
+ await this.adapter.setStateChangedAsync('analytics.insights.photovoltaic.results.active_today', {
52
+ val: false,
53
+ ack: true,
54
+ });
55
+
56
+ await this.adapter.setStateChangedAsync('analytics.insights.photovoltaic.results.runtime_today_min', {
57
+ val: 0,
58
+ ack: true,
59
+ });
60
+
61
+ await this.adapter.setStateChangedAsync(
62
+ 'analytics.insights.photovoltaic.results.energy_used_today_kwh',
63
+ {
64
+ val: 0,
65
+ ack: true,
66
+ },
67
+ );
68
+
69
+ await this.adapter.setStateChangedAsync('analytics.insights.photovoltaic.results.savings_today_eur', {
70
+ val: 0,
71
+ ack: true,
72
+ });
73
+
74
+ await this.adapter.setStateChangedAsync('analytics.insights.photovoltaic.results.starts_today', {
75
+ val: 0,
76
+ ack: true,
77
+ });
78
+
79
+ this.lastResultTimestamp = null;
80
+ this.lastPvRuntimeActive = false;
81
+
82
+ await this.adapter.setStateChangedAsync('analytics.insights.photovoltaic.debug.last_update', {
83
+ val: new Date().toISOString(),
84
+ ack: true,
85
+ });
86
+
87
+ await this.adapter.setStateChangedAsync(
88
+ 'analytics.insights.photovoltaic.debug.last_recalculation_reason',
89
+ {
90
+ val: I18n.translate('photovoltaic_insights_debug_reason_daily_reset'),
91
+ ack: true,
92
+ },
93
+ );
94
+
95
+ await this.adapter.setStateChangedAsync('analytics.insights.photovoltaic.debug.debug_text', {
96
+ val: I18n.translate('photovoltaic_insights_debug_text_daily_reset'),
97
+ ack: true,
98
+ });
99
+
100
+ this.adapter.log.debug('[photovoltaicInsightsHelper] Daily reset executed');
101
+ } catch (err) {
102
+ this.adapter.log.warn(`[photovoltaicInsightsHelper] Daily reset failed: ${err.message}`);
103
+ }
104
+
105
+ this._scheduleDailyReset();
106
+ }, delay);
107
+ },
108
+
34
109
  _scheduleCheck(delayMs = 0) {
35
110
  if (this.checkTimer) {
36
111
  this.adapter.clearTimeout(this.checkTimer);
@@ -142,26 +217,36 @@ const photovoltaicInsightsHelper = {
142
217
 
143
218
  if (pvRuntimeActive && !this.lastPvRuntimeActive) {
144
219
  startsToday += 1;
145
- this.lastResultTimestamp = now;
146
220
  }
147
221
 
148
- if (pvRuntimeActive && this.lastResultTimestamp && Number.isFinite(pumpPowerW) && pumpPowerW > 0) {
222
+ if (pvRuntimeActive && this.lastResultTimestamp) {
149
223
  const deltaHours = (now - this.lastResultTimestamp) / 3600000;
150
224
 
151
225
  if (deltaHours > 0 && deltaHours <= 0.5) {
152
- const energyDeltaKwh = (pumpPowerW * deltaHours) / 1000;
153
-
154
226
  runtimeTodayMin = Number((runtimeTodayMin + deltaHours * 60).toFixed(2));
155
- energyUsedTodayKwh = Number((energyUsedTodayKwh + energyDeltaKwh).toFixed(4));
156
227
 
157
- if (Number.isFinite(electricityPriceEurKwh) && electricityPriceEurKwh > 0) {
158
- savingsTodayEur = Number((savingsTodayEur + energyDeltaKwh * electricityPriceEurKwh).toFixed(2));
228
+ if (Number.isFinite(pumpPowerW) && pumpPowerW > 0) {
229
+ const energyDeltaKwh = (pumpPowerW * deltaHours) / 1000;
230
+
231
+ energyUsedTodayKwh = Number((energyUsedTodayKwh + energyDeltaKwh).toFixed(4));
232
+
233
+ if (Number.isFinite(electricityPriceEurKwh) && electricityPriceEurKwh > 0) {
234
+ savingsTodayEur = Number(
235
+ (savingsTodayEur + energyDeltaKwh * electricityPriceEurKwh).toFixed(4),
236
+ );
237
+ }
159
238
  }
160
239
  }
161
240
  }
162
241
 
163
242
  if (pvRuntimeActive) {
164
243
  this.lastResultTimestamp = now;
244
+
245
+ // FIX:
246
+ // Während echter PV-Überschusslaufzeit regelmäßig weiterrechnen,
247
+ // auch wenn keine neuen State-Events eintreffen.
248
+ // Nachlauf ohne PV-Überschuss wird dadurch bewusst nicht gezählt.
249
+ this._scheduleCheck(60 * 1000);
165
250
  } else {
166
251
  this.lastResultTimestamp = null;
167
252
  }
@@ -300,6 +385,11 @@ const photovoltaicInsightsHelper = {
300
385
  this.adapter.clearTimeout(this.checkTimer);
301
386
  this.checkTimer = null;
302
387
  }
388
+
389
+ if (this.resetTimer) {
390
+ this.adapter.clearTimeout(this.resetTimer);
391
+ this.resetTimer = null;
392
+ }
303
393
  },
304
394
  };
305
395
 
@@ -229,6 +229,8 @@ const solarInsightsHelper = {
229
229
  const collectorTemp = await this._readNumber('temperature.collector.current');
230
230
  const surfaceTemp = await this._readNumber('temperature.surface.current');
231
231
  const groundTemp = await this._readNumber('temperature.ground.current');
232
+ const flowTemp = await this._readNumber('temperature.flow.current'); // FIX: Vorlauf für echte Wärmeberechnung
233
+ const returnTemp = await this._readNumber('temperature.return.current'); // FIX: Rücklauf für echte Wärmeberechnung
232
234
  const outsideTemp = await this._readNumber('temperature.outside.current');
233
235
  const currentFlowLh = await this._readNumber('pump.live.flow_current_lh');
234
236
  const pumpCurrentPowerW = await this._readNumber('pump.live.current_power_w');
@@ -261,7 +263,10 @@ const solarInsightsHelper = {
261
263
  availableSensors.push('ground');
262
264
  }
263
265
  if (flowAvailable) {
264
- availableSensors.push('calculated_flow');
266
+ availableSensors.push('flow');
267
+ }
268
+ if (flowTempAvailable && returnAvailable) {
269
+ availableSensors.push('water_delta');
265
270
  }
266
271
  if (returnAvailable) {
267
272
  availableSensors.push('return');
@@ -283,7 +288,10 @@ const solarInsightsHelper = {
283
288
  usedSensors.push('ground');
284
289
  }
285
290
  if (flowUsed) {
286
- usedSensors.push('calculated_flow');
291
+ usedSensors.push('flow');
292
+ }
293
+ if (flowTempAvailable && returnAvailable) {
294
+ usedSensors.push('water_delta');
287
295
  }
288
296
  if (returnUsed) {
289
297
  usedSensors.push('return');
@@ -317,15 +325,20 @@ const solarInsightsHelper = {
317
325
  }
318
326
 
319
327
  let deltaTUsed = null;
320
- if (Number.isFinite(collectorTemp) && Number.isFinite(poolReferenceTemp)) {
321
- deltaTUsed = Number((collectorTemp - poolReferenceTemp).toFixed(2));
328
+
329
+ // FIX:
330
+ // Für thermische Leistung und Tagesertrag darf nicht Kollektor - Pool verwendet werden.
331
+ // Das überschätzt massiv, weil die Kollektortemperatur keine echte Wasser-Ausgangstemperatur ist.
332
+ // Für Energie/COP wird nur die echte Wasserdifferenz Rücklauf - Vorlauf verwendet.
333
+ if (Number.isFinite(returnTemp) && Number.isFinite(flowTemp)) {
334
+ deltaTUsed = Number((returnTemp - flowTemp).toFixed(2));
322
335
  }
323
336
 
324
337
  // --- Block 3: Thermische Leistung berechnen ---
325
338
  let thermalPowerW = null;
326
339
  let thermalPowerKW = null;
327
340
 
328
- if (Number.isFinite(deltaTUsed) && Number.isFinite(currentFlowLh) && currentFlowLh > 0) {
341
+ if (Number.isFinite(deltaTUsed) && deltaTUsed > 0 && Number.isFinite(currentFlowLh) && currentFlowLh > 0) {
329
342
  thermalPowerW = Number((currentFlowLh * deltaTUsed * 1.16).toFixed(2));
330
343
  thermalPowerKW = Number((thermalPowerW / 1000).toFixed(3));
331
344
  }
@@ -425,6 +438,7 @@ const solarInsightsHelper = {
425
438
  solar_effective_now: solarEffectiveNow,
426
439
  pool_reference_source: poolReferenceSource,
427
440
  flow_source: flowSource,
441
+ thermal_delta_source: 'return_flow_delta',
428
442
  weather_correction_active: weatherCorrectionActive,
429
443
  confidence_percent: confidencePercent,
430
444
  used_sensors: usedSensors,
@@ -456,6 +470,7 @@ const solarInsightsHelper = {
456
470
  `<b>${I18n.translate('solar_insights_label_solar_effective_now')}:</b> ${solarEffectiveNow}<br>`,
457
471
  `<b>${I18n.translate('solar_insights_label_pool_reference_source')}:</b> ${poolReferenceSource}<br>`,
458
472
  `<b>${I18n.translate('solar_insights_label_flow_source')}:</b> ${flowSource}<br>`,
473
+ `<b>${I18n.translate('solar_insights_label_thermal_delta_source')}:</b> return_flow_delta<br>`,
459
474
  `<b>${I18n.translate('solar_insights_label_weather_correction_active')}:</b> ${weatherCorrectionActive}<br>`,
460
475
  `<b>${I18n.translate('solar_insights_label_confidence')}:</b> ${confidencePercent} %<br>`,
461
476
  `<b>${I18n.translate('solar_insights_label_used_sensors')}:</b> ${usedSensors.join(', ') || I18n.translate('solar_insights_value_none')}<br>`,
@@ -545,6 +560,7 @@ const solarInsightsHelper = {
545
560
  available: availableSensors,
546
561
  used: usedSensors,
547
562
  mode: 'estimated_daily_gain',
563
+ thermal_delta_source: 'return_flow_delta',
548
564
  block: 7,
549
565
  }),
550
566
  ack: true,
package/lib/i18n/de.json CHANGED
@@ -109,6 +109,7 @@
109
109
  "solar_insights_label_solar_effective_now": "Solar aktuell wirksam",
110
110
  "solar_insights_label_pool_reference_source": "Pool-Referenzquelle",
111
111
  "solar_insights_label_flow_source": "Durchflussquelle",
112
+ "solar_insights_label_thermal_delta_source": "Quelle Wärme-Delta",
112
113
  "solar_insights_label_weather_correction_active": "Wetterkorrektur aktiv",
113
114
  "solar_insights_label_confidence": "Vertrauen",
114
115
  "solar_insights_label_used_sensors": "Verwendete Sensoren",
@@ -185,6 +186,8 @@
185
186
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Kein aktiver PV-Überschussbetrieb",
186
187
  "photovoltaic_insights_debug_text_pv_runtime_active": "PV-Überschuss ist aktiv und der Photovoltaik-Helper besitzt aktuell die Pumpe.",
187
188
  "photovoltaic_insights_debug_text_no_pv_runtime": "Aktuell wird keine PV-Laufzeit gezählt, weil entweder kein PV-Überschuss aktiv ist oder der Photovoltaik-Helper die Pumpe nicht besitzt.",
189
+ "photovoltaic_insights_debug_reason_daily_reset": "Täglicher Reset",
190
+ "photovoltaic_insights_debug_text_daily_reset": "Die täglichen Photovoltaik-Insights-Werte wurden zurückgesetzt.",
188
191
 
189
192
  "pH source state configured.": "pH-Quell-Datenpunkt konfiguriert.",
190
193
  "pH source state could not be subscribed.": "pH-Quell-Datenpunkt konnte nicht abonniert werden.",
package/lib/i18n/en.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Solar effective now",
182
182
  "solar_insights_label_pool_reference_source": "Pool reference source",
183
183
  "solar_insights_label_flow_source": "Flow source",
184
+ "solar_insights_label_thermal_delta_source": "Thermal delta source",
184
185
  "solar_insights_label_weather_correction_active": "Weather correction active",
185
186
  "solar_insights_label_confidence": "Confidence",
186
187
  "solar_insights_label_used_sensors": "Used sensors",
@@ -257,7 +258,8 @@
257
258
  "photovoltaic_insights_debug_reason_no_pv_runtime": "No active PV surplus operation",
258
259
  "photovoltaic_insights_debug_text_pv_runtime_active": "PV surplus is active and the photovoltaic helper currently owns the pump.",
259
260
  "photovoltaic_insights_debug_text_no_pv_runtime": "No PV runtime is currently counted because either no PV surplus is active or the photovoltaic helper does not own the pump.",
260
-
261
+ "photovoltaic_insights_debug_reason_daily_reset": "Daily reset",
262
+ "photovoltaic_insights_debug_text_daily_reset": "Photovoltaic insights daily values have been reset.",
261
263
  "pH source state configured.": "pH source state configured.",
262
264
  "pH source state could not be subscribed.": "pH source state could not be subscribed.",
263
265
  "No pH source state configured.": "No pH source state configured.",
package/lib/i18n/es.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Solar activo actualmente",
182
182
  "solar_insights_label_pool_reference_source": "Fuente de referencia del pool",
183
183
  "solar_insights_label_flow_source": "Fuente de caudal",
184
+ "solar_insights_label_thermal_delta_source": "Fuente delta térmica",
184
185
  "solar_insights_label_weather_correction_active": "Corrección meteorológica activa",
185
186
  "solar_insights_label_confidence": "Confianza",
186
187
  "solar_insights_label_used_sensors": "Sensores utilizados",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Sin operación activa con excedente FV",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "El excedente FV está activo y el helper fotovoltaico posee actualmente la bomba.",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "Actualmente no se cuenta ningún tiempo de funcionamiento FV porque no hay excedente FV activo o el helper fotovoltaico no posee la bomba.",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "Reinicio diario",
261
+ "photovoltaic_insights_debug_text_daily_reset": "Los valores diarios de los insights fotovoltaicos han sido restablecidos.",
259
262
 
260
263
  "pH source state configured.": "Estado de origen de pH configurado.",
261
264
  "pH source state could not be subscribed.": "No se pudo suscribir el estado de origen de pH.",
package/lib/i18n/fr.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Solaire actif actuellement",
182
182
  "solar_insights_label_pool_reference_source": "Source de référence du pool",
183
183
  "solar_insights_label_flow_source": "Source de débit",
184
+ "solar_insights_label_thermal_delta_source": "Source du delta thermique",
184
185
  "solar_insights_label_weather_correction_active": "Correction météo active",
185
186
  "solar_insights_label_confidence": "Confiance",
186
187
  "solar_insights_label_used_sensors": "Capteurs utilisés",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Aucun fonctionnement actif sur surplus PV",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "Le surplus PV est actif et le helper photovoltaïque possède actuellement la pompe.",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "Aucun temps de fonctionnement PV n’est actuellement comptabilisé, car aucun surplus PV n’est actif ou le helper photovoltaïque ne possède pas la pompe.",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "Réinitialisation quotidienne",
261
+ "photovoltaic_insights_debug_text_daily_reset": "Les valeurs quotidiennes des insights photovoltaïques ont été réinitialisées.",
259
262
 
260
263
  "pH source state configured.": "État source pH configuré.",
261
264
  "pH source state could not be subscribed.": "Impossible de s'abonner à l'état source pH.",
package/lib/i18n/it.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Solare attivo attualmente",
182
182
  "solar_insights_label_pool_reference_source": "Fonte di riferimento della piscina",
183
183
  "solar_insights_label_flow_source": "Fonte di flusso",
184
+ "solar_insights_label_thermal_delta_source": "Fonte delta termico",
184
185
  "solar_insights_label_weather_correction_active": "Correzione meteo attiva",
185
186
  "solar_insights_label_confidence": "Affidabilità",
186
187
  "solar_insights_label_used_sensors": "Sensori utilizzati",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Nessun funzionamento attivo con surplus FV",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "Il surplus FV è attivo e l'helper fotovoltaico possiede attualmente la pompa.",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "Attualmente non viene conteggiato alcun tempo di funzionamento FV perché non c'è surplus FV attivo oppure l'helper fotovoltaico non possiede la pompa.",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "Reset giornaliero",
261
+ "photovoltaic_insights_debug_text_daily_reset": "I valori giornalieri degli insight fotovoltaici sono stati azzerati.",
259
262
 
260
263
  "pH source state configured.": "Stato sorgente pH configurato.",
261
264
  "pH source state could not be subscribed.": "Impossibile sottoscrivere lo stato sorgente pH.",
package/lib/i18n/nl.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Zonne-energie momenteel actief",
182
182
  "solar_insights_label_pool_reference_source": "Zwembadreferentiebron",
183
183
  "solar_insights_label_flow_source": "Debietbron",
184
+ "solar_insights_label_thermal_delta_source": "Bron thermisch verschil",
184
185
  "solar_insights_label_weather_correction_active": "Weercorrectie actief",
185
186
  "solar_insights_label_confidence": "Betrouwbaarheid",
186
187
  "solar_insights_label_used_sensors": "Gebruikte sensoren",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Geen actief PV-overschotbedrijf",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "PV-overschot is actief en de photovoltaic helper bezit momenteel de pomp.",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "Er wordt momenteel geen PV-looptijd geteld omdat er geen PV-overschot actief is of omdat de photovoltaic helper de pomp niet bezit.",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "Dagelijkse reset",
261
+ "photovoltaic_insights_debug_text_daily_reset": "De dagelijkse fotovoltaïsche inzichten zijn gereset.",
259
262
 
260
263
  "pH source state configured.": "pH-bronstatus geconfigureerd.",
261
264
  "pH source state could not be subscribed.": "Kon niet abonneren op de pH-bronstatus.",
package/lib/i18n/pl.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Solary aktywne teraz",
182
182
  "solar_insights_label_pool_reference_source": "Źródło odniesienia basenu",
183
183
  "solar_insights_label_flow_source": "Źródło przepływu",
184
+ "solar_insights_label_thermal_delta_source": "Źródło różnicy temperatur",
184
185
  "solar_insights_label_weather_correction_active": "Korekcja pogodowa aktywna",
185
186
  "solar_insights_label_confidence": "Wiarygodność",
186
187
  "solar_insights_label_used_sensors": "Użyte czujniki",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Brak aktywnej pracy z nadwyżki PV",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "Nadwyżka PV jest aktywna, a helper fotowoltaiczny aktualnie posiada pompę.",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "Obecnie nie jest zliczany czas pracy PV, ponieważ nie ma aktywnej nadwyżki PV albo helper fotowoltaiczny nie posiada pompy.",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "Reset dzienny",
261
+ "photovoltaic_insights_debug_text_daily_reset": "Dzienne dane fotowoltaiczne zostały zresetowane.",
259
262
 
260
263
  "pH source state configured.": "Skonfigurowano stan źródła pH.",
261
264
  "pH source state could not be subscribed.": "Nie można zasubskrybować stanu źródła pH.",
package/lib/i18n/pt.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Solar ativo no momento",
182
182
  "solar_insights_label_pool_reference_source": "Fonte de referência da piscina",
183
183
  "solar_insights_label_flow_source": "Fonte de fluxo",
184
+ "solar_insights_label_thermal_delta_source": "Fonte delta térmico",
184
185
  "solar_insights_label_weather_correction_active": "Correção meteorológica ativa",
185
186
  "solar_insights_label_confidence": "Confiabilidade",
186
187
  "solar_insights_label_used_sensors": "Sensores utilizados",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Nenhuma operação ativa com excedente FV",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "O excedente FV está ativo e o helper fotovoltaico possui atualmente a bomba.",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "Atualmente nenhum tempo de funcionamento FV é contado porque não há excedente FV ativo ou o helper fotovoltaico não possui a bomba.",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "Reinício diário",
261
+ "photovoltaic_insights_debug_text_daily_reset": "Os valores diários de análise fotovoltaica foram redefinidos.",
259
262
 
260
263
  "pH source state configured.": "Estado de origem de pH configurado.",
261
264
  "pH source state could not be subscribed.": "Não foi possível subscrever o estado de origem de pH.",
package/lib/i18n/ru.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Солнечная система сейчас активна",
182
182
  "solar_insights_label_pool_reference_source": "Источник опорного значения бассейна",
183
183
  "solar_insights_label_flow_source": "Источник потока",
184
+ "solar_insights_label_thermal_delta_source": "Источник тепловой разницы",
184
185
  "solar_insights_label_weather_correction_active": "Погодная коррекция активна",
185
186
  "solar_insights_label_confidence": "Надёжность",
186
187
  "solar_insights_label_used_sensors": "Используемые датчики",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Нет активной работы от излишка PV",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "Излишек PV активен, и photovoltaic helper сейчас владеет насосом.",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "Время работы PV сейчас не учитывается, потому что либо нет активного излишка PV, либо photovoltaic helper не владеет насосом.",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "Ежедневный сброс",
261
+ "photovoltaic_insights_debug_text_daily_reset": "Дневные значения фотогальванических данных были сброшены.",
259
262
 
260
263
  "pH source state configured.": "Состояние источника pH настроено.",
261
264
  "pH source state could not be subscribed.": "Не удалось подписаться на состояние источника pH.",
package/lib/i18n/uk.json CHANGED
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "Сонячна система зараз активна",
182
182
  "solar_insights_label_pool_reference_source": "Джерело опорного значення басейну",
183
183
  "solar_insights_label_flow_source": "Джерело потоку",
184
+ "solar_insights_label_thermal_delta_source": "Джерело теплової різниці",
184
185
  "solar_insights_label_weather_correction_active": "Погодні коригування активні",
185
186
  "solar_insights_label_confidence": "Надійність",
186
187
  "solar_insights_label_used_sensors": "Використані датчики",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "Немає активної роботи від надлишку PV",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "Надлишок PV активний, і photovoltaic helper наразі володіє насосом.",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "Наразі час роботи PV не підраховується, оскільки або немає активного надлишку PV, або photovoltaic helper не володіє насосом.",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "Щоденне скидання",
261
+ "photovoltaic_insights_debug_text_daily_reset": "Щоденні дані фотогальванічної аналітики були скинуті.",
259
262
 
260
263
  "pH source state configured.": "Стан джерела pH налаштовано.",
261
264
  "pH source state could not be subscribed.": "Не вдалося підписатися на стан джерела pH.",
@@ -181,6 +181,7 @@
181
181
  "solar_insights_label_solar_effective_now": "当前太阳能有效",
182
182
  "solar_insights_label_pool_reference_source": "泳池参考来源",
183
183
  "solar_insights_label_flow_source": "流量来源",
184
+ "solar_insights_label_thermal_delta_source": "热量差来源",
184
185
  "solar_insights_label_weather_correction_active": "天气修正已启用",
185
186
  "solar_insights_label_confidence": "可信度",
186
187
  "solar_insights_label_used_sensors": "使用的传感器",
@@ -256,6 +257,8 @@
256
257
  "photovoltaic_insights_debug_reason_no_pv_runtime": "没有活跃的光伏余电运行",
257
258
  "photovoltaic_insights_debug_text_pv_runtime_active": "光伏余电处于激活状态,并且 photovoltaic helper 当前拥有泵。",
258
259
  "photovoltaic_insights_debug_text_no_pv_runtime": "当前未统计光伏运行时间,因为没有活跃的光伏余电,或者 photovoltaic helper 未拥有泵。",
260
+ "photovoltaic_insights_debug_reason_daily_reset": "每日重置",
261
+ "photovoltaic_insights_debug_text_daily_reset": "光伏分析的每日数据已重置。",
259
262
 
260
263
  "pH source state configured.": "已配置 pH 源状态。",
261
264
  "pH source state could not be subscribed.": "无法订阅 pH 源状态。",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.poolcontrol",
3
- "version": "1.3.11",
3
+ "version": "1.3.13",
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",
@@ -18,7 +18,7 @@
18
18
  "url": "git+https://github.com/DasBo1975/ioBroker.poolcontrol.git"
19
19
  },
20
20
  "engines": {
21
- "node": ">= 20"
21
+ "node": ">= 22"
22
22
  },
23
23
  "dependencies": {
24
24
  "@iobroker/adapter-core": "^3.3.2"