iobroker.poolcontrol 1.3.6 → 1.3.9
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 +17 -14
- package/io-package.json +27 -40
- package/lib/helpers/photovoltaicHelper.js +9 -7
- package/lib/helpers/solarInsightsHelper.js +32 -9
- package/lib/helpers/solarLogbookHelper.js +70 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -188,6 +188,23 @@ New features are added regularly – please refer to the changelog.
|
|
|
188
188
|
---
|
|
189
189
|
|
|
190
190
|
## Changelog
|
|
191
|
+
### 1.3.9 (2026-04-24)
|
|
192
|
+
|
|
193
|
+
- Fix: solarLogbookHelper no longer creates duplicate or unnecessary log entries (improved filtering & throttling logic)
|
|
194
|
+
- Fix: Removed obsolete "no runtime today" entries once solar has actually run
|
|
195
|
+
- Fix: Improved handling of weather summary text to avoid broken or cut-off sentences
|
|
196
|
+
- Fix: solarLogbookHelper now updates `last_entry_time` only when a real log entry is written
|
|
197
|
+
- Fix: solarInsightsHelper runtime calculation improved (no incorrect time accumulation on state changes)
|
|
198
|
+
- Fix: solarInsightsHelper now correctly tracks previous solar state for more accurate active time calculation
|
|
199
|
+
- Fix: Added missing `debug.last_update` update on successful calculation
|
|
200
|
+
- Improvement: General stability and plausibility improvements in solar insights and logbook processing
|
|
201
|
+
|
|
202
|
+
### 1.3.7 (2026-04-23)
|
|
203
|
+
|
|
204
|
+
Bugfixes
|
|
205
|
+
- 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
|
|
206
|
+
- photovoltaicHelper: round surplus value in status text (avoid long decimal numbers), switched afterrun timer to adapter.setTimeout / clearTimeout
|
|
207
|
+
|
|
191
208
|
### 1.3.6 (2026-04-21)
|
|
192
209
|
|
|
193
210
|
frostHelper
|
|
@@ -207,20 +224,6 @@ frostHelper
|
|
|
207
224
|
- Fixed critical i18n issue in solarInsightsHelper and solarLogbookHelper that could lead to instability or crashes
|
|
208
225
|
- Switched translation handling to I18n.translate() for stable and consistent i18n behavior
|
|
209
226
|
|
|
210
|
-
### 1.3.3 (2026-04-18)
|
|
211
|
-
|
|
212
|
-
- Added solar COP calculation to evaluate system efficiency
|
|
213
|
-
- Added solar logbook helper with easy-to-read daily summaries for better user understanding
|
|
214
|
-
|
|
215
|
-
### 1.3.2 (2026-04-17)
|
|
216
|
-
|
|
217
|
-
- Fix: Solar Extended no longer interferes with controlHelper or timeHelper (prevents unwanted pump shutdown)
|
|
218
|
-
- Fix: Solar Extended no longer interferes with standard solar mode
|
|
219
|
-
- Fix: Improved handling of external actuator (clean ON/OFF behavior depending on Solar Extended state)
|
|
220
|
-
- Improvement: Added stable delta hysteresis (delta_on / delta_off) to prevent switching fluctuations
|
|
221
|
-
- Improvement: Replaced global timers with adapter timers in solarExtendedHelper
|
|
222
|
-
- Cleanup: Removed duplicate reading of request_active state
|
|
223
|
-
|
|
224
227
|
## Support
|
|
225
228
|
- [ioBroker Forum](https://forum.iobroker.net/)
|
|
226
229
|
- [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.
|
|
4
|
+
"version": "1.3.9",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.3.9": {
|
|
7
|
+
"en": "Fix solar logbook duplication and invalid entries, improve log stability and weather text handling; fix solar insights runtime calculation and debug timestamp update.",
|
|
8
|
+
"de": "Behebung von doppelten und ungültigen Solar-Logbuch-Einträgen, Verbesserung der Log-Stabilität und Wettertext-Verarbeitung; Korrektur der Laufzeitberechnung im Solar-Insights-Bereich sowie Aktualisierung des Debug-Zeitstempels.",
|
|
9
|
+
"ru": "Исправьте дублирование журнала солнечной энергии и неверные записи, улучшите стабильность журнала и обработку текста о погоде; исправить расчет времени выполнения Solar Insights и обновить временную метку отладки.",
|
|
10
|
+
"pt": "Corrija a duplicação do diário de bordo solar e entradas inválidas, melhore a estabilidade do registro e o manuseio de textos meteorológicos; corrigir o cálculo do tempo de execução do Solar Insights e depurar a atualização do carimbo de data/hora.",
|
|
11
|
+
"nl": "Herstel het dupliceren van zonnelogboeken en ongeldige vermeldingen, verbeter de logstabiliteit en de verwerking van weerteksten; runtimeberekening van zonne-inzichten repareren en tijdstempelupdate debuggen.",
|
|
12
|
+
"fr": "Corrigez la duplication du journal solaire et les entrées invalides, améliorez la stabilité du journal et la gestion des textes météorologiques ; correction du calcul d'exécution des informations solaires et de la mise à jour de l'horodatage de débogage.",
|
|
13
|
+
"it": "Correggere la duplicazione del registro solare e le voci non valide, migliorare la stabilità del registro e la gestione del testo meteorologico; correggere il calcolo del runtime di Solar Insights e l'aggiornamento del timestamp di debug.",
|
|
14
|
+
"es": "Corrija la duplicación del libro de registro solar y las entradas no válidas, mejore la estabilidad del registro y el manejo de textos meteorológicos; corrige el cálculo del tiempo de ejecución de Solar Insights y la actualización de la marca de tiempo de depuración.",
|
|
15
|
+
"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.",
|
|
16
|
+
"uk": "Виправте дублювання сонячного журналу та недійсні записи, покращте стабільність журналу та обробку тексту погоди; виправити розрахунок часу виконання solar insights і налагодити оновлення часових позначок.",
|
|
17
|
+
"zh-cn": "修复太阳能日志重复和无效条目,提高日志稳定性和天气文本处理;修复 Solar Insights 运行时计算和调试时间戳更新。"
|
|
18
|
+
},
|
|
19
|
+
"1.3.7": {
|
|
20
|
+
"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.",
|
|
21
|
+
"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.",
|
|
22
|
+
"ru": "Исправлено обнаружение SolarInsights для стандартной солнечной энергии (используйте Solar.request_active вместо несуществующего Solar.active). Улучшения photovoltaicHelper: округленное лишнее значение в тексте состояния и переключение таймера послезапуска на адаптер.setTimeout/clearTimeout.",
|
|
23
|
+
"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.",
|
|
24
|
+
"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.",
|
|
25
|
+
"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.",
|
|
26
|
+
"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.",
|
|
27
|
+
"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.",
|
|
28
|
+
"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.",
|
|
29
|
+
"uk": "Виправте виявлення solarInsights для стандартної сонячної енергії (використовуйте solar.request_active замість неіснуючого solar.active). Покращення photovoltaicHelper: округлене надлишкове значення в тексті стану та переключений таймер післязапуску на adapter.setTimeout/clearTimeout.",
|
|
30
|
+
"zh-cn": "修复标准太阳能的 SolarInsights 检测(使用 Solar.request_active 而不是不存在的 Solar.active)。 PVHelper 改进:对状态文本中的剩余值进行四舍五入,并将 Afterrun 计时器切换为 adapter.setTimeout/clearTimeout。"
|
|
31
|
+
},
|
|
6
32
|
"1.3.6": {
|
|
7
33
|
"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.",
|
|
8
34
|
"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.",
|
|
@@ -28,45 +54,6 @@
|
|
|
28
54
|
"pl": "Naprawiono krytyczny problem i18n w programach solarInsightsHelper i solarLogbookHelper, który mógł prowadzić do niestabilności lub awarii. Przełączono obsługę tłumaczeń na I18n.translate(), aby zapewnić stabilne działanie.",
|
|
29
55
|
"uk": "Виправлено критичну проблему i18n у solarInsightsHelper і solarLogbookHelper, яка могла призвести до нестабільності або збоїв. Перемкнуто обробку перекладу на I18n.translate(), щоб забезпечити стабільну роботу.",
|
|
30
56
|
"zh-cn": "修复了 SolarInsightsHelper 和 SolarLogbookHelper 中可能导致不稳定或崩溃的关键 i18n 问题。将翻译处理切换为 I18n.translate() 以确保稳定运行。"
|
|
31
|
-
},
|
|
32
|
-
"1.3.4": {
|
|
33
|
-
"en": "Fixed critical i18n issue in solarInsightsHelper and solarLogbookHelper that could lead to instability or crashes. Switched translation handling to I18n.translate() to ensure stable operation.",
|
|
34
|
-
"de": "Kritischer i18n-Fehler in solarInsightsHelper und solarLogbookHelper behoben, der zu Instabilität oder Abstürzen führen konnte. Übersetzungen wurden auf I18n.translate() umgestellt, um einen stabilen Betrieb sicherzustellen.",
|
|
35
|
-
"ru": "Исправлена критическая проблема i18n в SolarInsightsHelper и SolarLogbookHelper, которая могла привести к нестабильности или сбоям. Обработку перевода переключили на I18n.translate() для обеспечения стабильной работы.",
|
|
36
|
-
"pt": "Foi corrigido um problema crítico do i18n no solarInsightsHelper e no solarLogbookHelper que poderia causar instabilidade ou travamentos. Manipulação de tradução alterada para I18n.translate() para garantir uma operação estável.",
|
|
37
|
-
"nl": "Een kritiek i18n-probleem in solarInsightsHelper en solarLogbookHelper opgelost dat tot instabiliteit of crashes kon leiden. De verwerking van de vertalingen is gewijzigd naar I18n.translate() om een stabiele werking te garanderen.",
|
|
38
|
-
"fr": "Correction d'un problème i18n critique dans solarInsightsHelper et solarLogbookHelper qui pouvait entraîner une instabilité ou des plantages. Gestion de la traduction commutée vers I18n.translate() pour garantir un fonctionnement stable.",
|
|
39
|
-
"it": "Risolto un problema critico i18n in solarInsightsHelper e solarLogbookHelper che poteva portare a instabilità o arresti anomali. Modificata la gestione della traduzione su I18n.translate() per garantire un funzionamento stabile.",
|
|
40
|
-
"es": "Se solucionó un problema crítico de i18n en solarInsightsHelper y solarLogbookHelper que podía provocar inestabilidad o fallas. Se cambió el manejo de traducción a I18n.translate() para garantizar un funcionamiento estable.",
|
|
41
|
-
"pl": "Naprawiono krytyczny problem i18n w programach solarInsightsHelper i solarLogbookHelper, który mógł prowadzić do niestabilności lub awarii. Przełączono obsługę tłumaczeń na I18n.translate(), aby zapewnić stabilne działanie.",
|
|
42
|
-
"uk": "Виправлено критичну проблему i18n у solarInsightsHelper і solarLogbookHelper, яка могла призвести до нестабільності або збоїв. Перемкнуто обробку перекладу на I18n.translate(), щоб забезпечити стабільну роботу.",
|
|
43
|
-
"zh-cn": "修复了 SolarInsightsHelper 和 SolarLogbookHelper 中可能导致不稳定或崩溃的关键 i18n 问题。将翻译处理切换为 I18n.translate() 以确保稳定运行。"
|
|
44
|
-
},
|
|
45
|
-
"1.3.3": {
|
|
46
|
-
"en": "Added solar COP calculation and solar logbook helper with human-readable daily entries based on solar insights.",
|
|
47
|
-
"de": "Solar-COP-Berechnung sowie Solar-Logbuch-Helper mit verständlichen Tages-Einträgen basierend auf Solar-Insights hinzugefügt.",
|
|
48
|
-
"ru": "Добавлен расчет солнечного КПД и помощник в журнале солнечной энергии с удобочитаемыми ежедневными записями на основе данных о солнечной энергии.",
|
|
49
|
-
"pt": "Adicionado cálculo de COP solar e auxiliar de diário de bordo solar com entradas diárias legíveis por humanos com base em insights solares.",
|
|
50
|
-
"nl": "Zonne-COP-berekening en zonne-logboekhulp toegevoegd met voor mensen leesbare dagelijkse gegevens op basis van zonne-inzichten.",
|
|
51
|
-
"fr": "Ajout du calcul du COP solaire et d'un assistant de journal de bord solaire avec des entrées quotidiennes lisibles par l'homme basées sur des informations solaires.",
|
|
52
|
-
"it": "Aggiunto il calcolo del COP solare e l'assistente del registro solare con voci giornaliere leggibili dall'uomo basate su informazioni solari.",
|
|
53
|
-
"es": "Se agregó un cálculo de COP solar y un asistente de registro solar con entradas diarias legibles por humanos basadas en conocimientos solares.",
|
|
54
|
-
"pl": "Dodano obliczenia COP energii słonecznej i pomocnika dziennika słonecznego z czytelnymi dla człowieka codziennymi wpisami opartymi na spostrzeżeniach dotyczących energii słonecznej.",
|
|
55
|
-
"uk": "Додано розрахунок COP сонячної енергії та помічник сонячного журналу із зрозумілими для людини щоденними записами на основі даних про сонячну енергію.",
|
|
56
|
-
"zh-cn": "添加了太阳能 COP 计算和太阳能日志助手,其中包含基于太阳能洞察的人类可读的每日条目。"
|
|
57
|
-
},
|
|
58
|
-
"1.3.2": {
|
|
59
|
-
"en": "Fixed Solar Extended conflicts with controlHelper/timeHelper and standard solar mode, improved external actuator handling, added stable delta hysteresis, and aligned timer handling with adapter timers.",
|
|
60
|
-
"de": "Solar-Extended-Konflikte mit controlHelper/timeHelper und dem Standard-Solarmodus behoben, externe Aktorsteuerung verbessert, stabile Delta-Hysterese ergänzt und Timer auf Adapter-Timer umgestellt.",
|
|
61
|
-
"ru": "Исправлены конфликты Solar Extended с controlHelper/timeHelper и стандартным солнечным режимом, улучшено управление внешним приводом, добавлен стабильный дельта-гистерезис и согласована обработка таймера с таймерами адаптера.",
|
|
62
|
-
"pt": "Corrigidos conflitos Solar Extended com controlHelper/timeHelper e modo solar padrão, manuseio aprimorado do atuador externo, histerese delta estável adicionada e manuseio de temporizador alinhado com temporizadores adaptadores.",
|
|
63
|
-
"nl": "Vaste Solar Extended-conflicten met controlHelper/timeHelper en standaard zonnemodus, verbeterde afhandeling van externe actuatoren, toegevoegde stabiele delta-hysteresis en afgestemde timerafhandeling met adaptertimers.",
|
|
64
|
-
"fr": "Correction des conflits solaires étendus avec controlHelper/timeHelper et le mode solaire standard, gestion améliorée des actionneurs externes, ajout d'une hystérésis delta stable et gestion des minuteries alignées avec les minuteries de l'adaptateur.",
|
|
65
|
-
"it": "Risolti i conflitti Solar Extended con controlHelper/timeHelper e la modalità solare standard, migliore gestione dell'attuatore esterno, aggiunta isteresi delta stabile e gestione del timer allineata con i timer dell'adattatore.",
|
|
66
|
-
"es": "Se corrigieron los conflictos de Solar Extended con controlHelper/timeHelper y el modo solar estándar, manejo mejorado del actuador externo, histéresis delta estable agregada y manejo del temporizador alineado con temporizadores adaptadores.",
|
|
67
|
-
"pl": "Naprawiono konflikty Solar Extended z ControlHelper/timeHelper i standardowym trybem solarnym, ulepszono obsługę zewnętrznego siłownika, dodano stabilną histerezę delta i dostosowano obsługę timera z timerami adaptera.",
|
|
68
|
-
"uk": "Виправлено конфлікти Solar Extended з controlHelper/timeHelper і стандартним сонячним режимом, покращено обробку зовнішнього приводу, додано стабільний дельта-гістерезис і узгоджено обробку таймера з таймерами адаптера.",
|
|
69
|
-
"zh-cn": "修复了 Solar Extended 与 controlHelper/timeHelper 和标准太阳能模式的冲突,改进了外部执行器处理,添加了稳定的增量迟滞,以及与适配器计时器对齐的计时器处理。"
|
|
70
57
|
}
|
|
71
58
|
},
|
|
72
59
|
"titleLang": {
|
|
@@ -130,14 +130,16 @@ const photovoltaicHelper = {
|
|
|
130
130
|
|
|
131
131
|
// Überschussberechnung
|
|
132
132
|
const surplus = Math.max(0, gen - house);
|
|
133
|
+
// FIX: Nur für die Textausgabe auf ganze Watt runden
|
|
134
|
+
const surplusDisplay = Math.round(surplus);
|
|
133
135
|
|
|
134
136
|
// **NEU:** Einschaltlogik = Pumpenleistung + Sicherheitsaufschlag
|
|
135
137
|
const requiredPower = pumpMax + threshold;
|
|
136
138
|
const surplusActive = surplus >= requiredPower && seasonActive;
|
|
137
139
|
|
|
138
140
|
const txt = surplusActive
|
|
139
|
-
? `Überschuss aktiv (${
|
|
140
|
-
: `Kein Überschuss (${
|
|
141
|
+
? `Überschuss aktiv (${surplusDisplay} W ≥ ${pumpMax}+${threshold} W)`
|
|
142
|
+
: `Kein Überschuss (${surplusDisplay} W < ${pumpMax}+${threshold} W)`;
|
|
141
143
|
|
|
142
144
|
// FIX: Bestehende Ergebnisstates zuerst lesen, damit last_update nur bei echter Ergebnisänderung gesetzt wird
|
|
143
145
|
const currentSurplus = Number((await this.adapter.getStateAsync('photovoltaic.power_surplus_w'))?.val ?? 0);
|
|
@@ -242,7 +244,7 @@ const photovoltaicHelper = {
|
|
|
242
244
|
// FIX: Wenn während eines laufenden Nachlaufs wieder Überschuss kommt,
|
|
243
245
|
// muss der Nachlauf-Timer immer beendet werden
|
|
244
246
|
if (this.afterrunTimer) {
|
|
245
|
-
clearTimeout(this.afterrunTimer);
|
|
247
|
+
this.adapter.clearTimeout(this.afterrunTimer);
|
|
246
248
|
this.afterrunTimer = null;
|
|
247
249
|
}
|
|
248
250
|
this._pvPumpHoldUntil = 0;
|
|
@@ -259,7 +261,7 @@ const photovoltaicHelper = {
|
|
|
259
261
|
async _maybeStopPump(immediate, afterrunMin, tag) {
|
|
260
262
|
if (await this._isControlHelperPriorityActive()) {
|
|
261
263
|
if (this.afterrunTimer) {
|
|
262
|
-
clearTimeout(this.afterrunTimer);
|
|
264
|
+
this.adapter.clearTimeout(this.afterrunTimer);
|
|
263
265
|
this.afterrunTimer = null;
|
|
264
266
|
}
|
|
265
267
|
this._pvPumpHoldUntil = 0;
|
|
@@ -273,7 +275,7 @@ const photovoltaicHelper = {
|
|
|
273
275
|
if (immediate || !afterrunMin || afterrunMin <= 0) {
|
|
274
276
|
// FIX: Laufenden Nachlauf-Timer bei Sofort-Aus immer sauber beenden
|
|
275
277
|
if (this.afterrunTimer) {
|
|
276
|
-
clearTimeout(this.afterrunTimer);
|
|
278
|
+
this.adapter.clearTimeout(this.afterrunTimer);
|
|
277
279
|
this.afterrunTimer = null;
|
|
278
280
|
}
|
|
279
281
|
this._pvPumpHoldUntil = 0;
|
|
@@ -297,7 +299,7 @@ const photovoltaicHelper = {
|
|
|
297
299
|
}
|
|
298
300
|
|
|
299
301
|
this._pvPumpHoldUntil = Date.now() + holdMs;
|
|
300
|
-
this.afterrunTimer = setTimeout(async () => {
|
|
302
|
+
this.afterrunTimer = this.adapter.setTimeout(async () => {
|
|
301
303
|
// FIX: Timer-Handle direkt freigeben, damit der Zustand sauber ist
|
|
302
304
|
this.afterrunTimer = null;
|
|
303
305
|
this._pvPumpHoldUntil = 0;
|
|
@@ -364,7 +366,7 @@ const photovoltaicHelper = {
|
|
|
364
366
|
|
|
365
367
|
cleanup() {
|
|
366
368
|
if (this.afterrunTimer) {
|
|
367
|
-
clearTimeout(this.afterrunTimer);
|
|
369
|
+
this.adapter.clearTimeout(this.afterrunTimer);
|
|
368
370
|
this.afterrunTimer = null;
|
|
369
371
|
}
|
|
370
372
|
this._pvPumpHoldUntil = 0;
|
|
@@ -15,6 +15,7 @@ const solarInsightsHelper = {
|
|
|
15
15
|
checkTimer: null,
|
|
16
16
|
resetTimer: null,
|
|
17
17
|
lastCheckTimestamp: null,
|
|
18
|
+
lastSolarLogicActive: false,
|
|
18
19
|
|
|
19
20
|
init(adapter) {
|
|
20
21
|
this.adapter = adapter;
|
|
@@ -35,8 +36,11 @@ const solarInsightsHelper = {
|
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
// Tages-Latch
|
|
39
|
-
if (
|
|
39
|
+
// FIX: Tages-Latch auch bei vollständigen ioBroker IDs sicher setzen
|
|
40
|
+
if (
|
|
41
|
+
(this._matchesStateId(id, 'solar.request_active') || this._matchesStateId(id, 'solar.extended.active')) &&
|
|
42
|
+
state.val === true
|
|
43
|
+
) {
|
|
40
44
|
void this.adapter.setStateChangedAsync('analytics.insights.solar.results.solar_ran_today', {
|
|
41
45
|
val: true,
|
|
42
46
|
ack: true,
|
|
@@ -99,6 +103,7 @@ const solarInsightsHelper = {
|
|
|
99
103
|
});
|
|
100
104
|
|
|
101
105
|
this.lastCheckTimestamp = null;
|
|
106
|
+
this.lastSolarLogicActive = false;
|
|
102
107
|
|
|
103
108
|
await this.adapter.setStateChangedAsync('analytics.insights.solar.debug.last_update', {
|
|
104
109
|
val: new Date().toISOString(),
|
|
@@ -144,7 +149,7 @@ const solarInsightsHelper = {
|
|
|
144
149
|
'pump.live.current_power_w',
|
|
145
150
|
'temperature.delta.surface_ground',
|
|
146
151
|
|
|
147
|
-
'solar.
|
|
152
|
+
'solar.request_active',
|
|
148
153
|
'solar.extended.active',
|
|
149
154
|
'solar.control_mode',
|
|
150
155
|
|
|
@@ -178,14 +183,20 @@ const solarInsightsHelper = {
|
|
|
178
183
|
'pump.live.current_power_w',
|
|
179
184
|
'temperature.delta.surface_ground',
|
|
180
185
|
|
|
181
|
-
'solar.
|
|
186
|
+
'solar.request_active',
|
|
182
187
|
'solar.extended.active',
|
|
183
188
|
'solar.control_mode',
|
|
184
189
|
|
|
185
190
|
'ai.weather.outputs.daily_summary',
|
|
186
191
|
];
|
|
187
192
|
|
|
188
|
-
|
|
193
|
+
// FIX: Also support full ioBroker IDs like "poolcontrol.0.solar.request_active"
|
|
194
|
+
return ids.some(relevantId => id === relevantId || id.endsWith(`.${relevantId}`));
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
_matchesStateId(id, stateId) {
|
|
198
|
+
// FIX: Also support full ioBroker IDs like "poolcontrol.0.solar.request_active"
|
|
199
|
+
return id === stateId || id.endsWith(`.${stateId}`);
|
|
189
200
|
},
|
|
190
201
|
|
|
191
202
|
async _checkSolarInsights() {
|
|
@@ -284,7 +295,7 @@ const solarInsightsHelper = {
|
|
|
284
295
|
usedSensors.push('weather');
|
|
285
296
|
}
|
|
286
297
|
|
|
287
|
-
const solarStandardActive = await this._readBoolean('solar.
|
|
298
|
+
const solarStandardActive = await this._readBoolean('solar.request_active');
|
|
288
299
|
const solarExtendedActive = await this._readBoolean('solar.extended.active');
|
|
289
300
|
const oldSolarRanToday = await this._readBoolean('analytics.insights.solar.results.solar_ran_today');
|
|
290
301
|
|
|
@@ -353,13 +364,18 @@ const solarInsightsHelper = {
|
|
|
353
364
|
peakPowerTodayW = 0;
|
|
354
365
|
}
|
|
355
366
|
|
|
356
|
-
if (this.lastCheckTimestamp &&
|
|
367
|
+
if (this.lastCheckTimestamp && (this.lastSolarLogicActive || solarLogicActive)) {
|
|
357
368
|
const deltaHours = (nowTs - this.lastCheckTimestamp) / 3600000;
|
|
358
369
|
|
|
359
|
-
//
|
|
370
|
+
// FIX: Count active solar minutes based on solar runtime, not only on positive thermal gain.
|
|
371
|
+
// The interval is counted if solar was active at the previous or current check.
|
|
360
372
|
if (deltaHours > 0 && deltaHours <= 0.5) {
|
|
361
|
-
estimatedGainTodayWh = Number((estimatedGainTodayWh + thermalPowerW * deltaHours).toFixed(2));
|
|
362
373
|
activeMinutesToday = Number((activeMinutesToday + deltaHours * 60).toFixed(2));
|
|
374
|
+
|
|
375
|
+
// FIX: Energy gain is only accumulated when a positive thermal power can be calculated
|
|
376
|
+
if (solarEffectiveNow && Number.isFinite(thermalPowerW) && thermalPowerW > 0) {
|
|
377
|
+
estimatedGainTodayWh = Number((estimatedGainTodayWh + thermalPowerW * deltaHours).toFixed(2));
|
|
378
|
+
}
|
|
363
379
|
}
|
|
364
380
|
}
|
|
365
381
|
|
|
@@ -681,7 +697,14 @@ const solarInsightsHelper = {
|
|
|
681
697
|
ack: true,
|
|
682
698
|
});
|
|
683
699
|
|
|
700
|
+
await this.adapter.setStateChangedAsync('analytics.insights.solar.debug.last_update', {
|
|
701
|
+
val: new Date().toISOString(),
|
|
702
|
+
ack: true,
|
|
703
|
+
});
|
|
704
|
+
|
|
684
705
|
this.lastCheckTimestamp = nowTs;
|
|
706
|
+
this.lastSolarLogicActive = solarLogicActive;
|
|
707
|
+
|
|
685
708
|
this.adapter.log.debug('[solarInsightsHelper] Block 7 updated successfully');
|
|
686
709
|
} catch (err) {
|
|
687
710
|
this.adapter.log.warn(`[solarInsightsHelper] Error in check: ${err.message}`);
|
|
@@ -224,10 +224,6 @@ const solarLogbookHelper = {
|
|
|
224
224
|
|
|
225
225
|
const currentEntry = await this._readString('analytics.insights.solar.logbook.current_entry');
|
|
226
226
|
|
|
227
|
-
if (currentEntry === entry.text) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
227
|
const now = new Date();
|
|
232
228
|
const nowIso = now.toISOString();
|
|
233
229
|
const timeLabel = this._formatTime(now);
|
|
@@ -241,13 +237,31 @@ const solarLogbookHelper = {
|
|
|
241
237
|
};
|
|
242
238
|
|
|
243
239
|
const dayLogJsonRaw = await this._readString('analytics.insights.solar.logbook.day_log_json');
|
|
244
|
-
|
|
240
|
+
let dayLog = this._safeParseArray(dayLogJsonRaw);
|
|
241
|
+
|
|
242
|
+
// FIX: Remove obsolete "no runtime today" entries once solar has actually run today.
|
|
243
|
+
// The current_entry remains live, but the readable day log should not keep a misleading
|
|
244
|
+
// "Solar did not run today" entry after solar runtime was detected.
|
|
245
|
+
if (entry.type !== 'no_runtime_today') {
|
|
246
|
+
dayLog = dayLog.filter(item => item && item.type !== 'no_runtime_today');
|
|
247
|
+
}
|
|
245
248
|
|
|
246
|
-
dayLog.
|
|
249
|
+
const lastLogItem = dayLog.length > 0 ? dayLog[dayLog.length - 1] : null;
|
|
250
|
+
const shouldAppendLogEntry = this._shouldAppendLogEntry(lastLogItem, entry, now);
|
|
247
251
|
|
|
248
|
-
|
|
252
|
+
// FIX: current_entry is the live readable status and may change often.
|
|
253
|
+
// day_log_json/day_log_text are readable day history and should only receive meaningful entries.
|
|
254
|
+
if (currentEntry === entry.text && !shouldAppendLogEntry) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
249
257
|
|
|
250
|
-
|
|
258
|
+
let trimmedLog = dayLog.slice(-100);
|
|
259
|
+
|
|
260
|
+
if (shouldAppendLogEntry) {
|
|
261
|
+
trimmedLog = [...dayLog, newLogItem].slice(-100);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const dayLogText = this._buildDayLogText(trimmedLog);
|
|
251
265
|
|
|
252
266
|
await this.adapter.setStateChangedAsync('analytics.insights.solar.logbook.current_entry', {
|
|
253
267
|
val: entry.text,
|
|
@@ -269,8 +283,10 @@ const solarLogbookHelper = {
|
|
|
269
283
|
ack: true,
|
|
270
284
|
});
|
|
271
285
|
|
|
286
|
+
const lastEntryTime = await this._readString('analytics.insights.solar.logbook.last_entry_time');
|
|
287
|
+
|
|
272
288
|
await this.adapter.setStateChangedAsync('analytics.insights.solar.logbook.last_entry_time', {
|
|
273
|
-
val: nowIso,
|
|
289
|
+
val: shouldAppendLogEntry ? nowIso : lastEntryTime,
|
|
274
290
|
ack: true,
|
|
275
291
|
});
|
|
276
292
|
|
|
@@ -472,18 +488,61 @@ const solarLogbookHelper = {
|
|
|
472
488
|
};
|
|
473
489
|
},
|
|
474
490
|
|
|
491
|
+
// ================================
|
|
492
|
+
// FIX: Logbook Filter & Throttling
|
|
493
|
+
// ================================
|
|
494
|
+
|
|
495
|
+
_shouldAppendLogEntry(lastLogItem, entry, now) {
|
|
496
|
+
if (!lastLogItem) {
|
|
497
|
+
return true;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (!entry || !entry.type) {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Statuswechsel IMMER loggen
|
|
505
|
+
if (lastLogItem.type !== entry.type) {
|
|
506
|
+
return true;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const lastTimestamp = Date.parse(lastLogItem.ts);
|
|
510
|
+
|
|
511
|
+
if (!Number.isFinite(lastTimestamp)) {
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// max alle 15 Minuten neuen Eintrag
|
|
516
|
+
const minIntervalMs = 15 * 60 * 1000;
|
|
517
|
+
|
|
518
|
+
return now.getTime() - lastTimestamp >= minIntervalMs;
|
|
519
|
+
},
|
|
520
|
+
|
|
521
|
+
_buildDayLogText(dayLog) {
|
|
522
|
+
return dayLog.map(item => `${item.time} - ${item.text}`).join('\n');
|
|
523
|
+
},
|
|
524
|
+
|
|
475
525
|
_extractShortWeather(weatherSummary) {
|
|
476
526
|
if (!weatherSummary || weatherSummary.trim() === '') {
|
|
477
527
|
return '';
|
|
478
528
|
}
|
|
479
529
|
|
|
480
530
|
const text = weatherSummary.replace(/\s+/g, ' ').trim();
|
|
531
|
+
const maxLength = 140;
|
|
481
532
|
|
|
482
|
-
if (text.length <=
|
|
533
|
+
if (text.length <= maxLength) {
|
|
483
534
|
return text;
|
|
484
535
|
}
|
|
485
536
|
|
|
486
|
-
|
|
537
|
+
// FIX: Do not cut the weather summary in the middle of a word
|
|
538
|
+
const shortened = text.slice(0, maxLength);
|
|
539
|
+
const lastSpaceIndex = shortened.lastIndexOf(' ');
|
|
540
|
+
|
|
541
|
+
if (lastSpaceIndex > 0) {
|
|
542
|
+
return `${shortened.slice(0, lastSpaceIndex)}…`;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return `${shortened}…`;
|
|
487
546
|
},
|
|
488
547
|
|
|
489
548
|
async _readState(id) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.poolcontrol",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.9",
|
|
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",
|