iobroker.poolcontrol 0.5.1 → 0.5.3

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
@@ -121,6 +121,14 @@ Funktionen können sich ändern – bitte regelmäßig den Changelog beachten.
121
121
  ## Changelog
122
122
  ### **WORK IN PROGRESS**
123
123
 
124
+ ## v0.5.3 (2025-10-30)
125
+ - Telegram-Benutzerwahl hinzugefügt
126
+
127
+ ## v0.5.2 (2025-10-30)
128
+ - Erweitertes Helper-Vorrangssystem: Konflikte zwischen Zeit- und Solarsteuerung behoben
129
+ - Frostschutz pausiert während Zeitfenster. Nun stabiles Pumpenverhalten und Verbesserte
130
+ Koordination zwischen den Helpern
131
+
124
132
  ## v0.5.0 (2025-10-28)
125
133
  - Erweiterung der Temperaturstatistik um Wochen- und Monatsauswertung
126
134
  (`analytics.statistics.temperature.week` / `.month`)
@@ -849,7 +849,30 @@
849
849
  "lg": 6,
850
850
  "xl": 6
851
851
  },
852
- "divider_speech_email": {
852
+ "speech_telegram_placeholder": {
853
+ "type": "staticText",
854
+ "label": "",
855
+ "text": "",
856
+ "xs": 12,
857
+ "sm": 3,
858
+ "md": 3,
859
+ "lg": 3,
860
+ "xl": 3,
861
+ "newLine": true
862
+ },
863
+ "speech_telegram_users": {
864
+ "type": "text",
865
+ "label": "Telegram-Empfänger (Benutzernamen, Komma-getrennt / leer = an alle Benutzer)",
866
+ "attr": "speech_telegram_users",
867
+ "tooltip": "Beispiel: Dirk,Dennis (leer = an alle Benutzer senden)",
868
+ "default": "",
869
+ "xs": 12,
870
+ "sm": 6,
871
+ "md": 6,
872
+ "lg": 6,
873
+ "xl": 6
874
+ },
875
+ "divider_speech_email": {
853
876
  "type": "divider",
854
877
  "newLine": true
855
878
  },
package/io-package.json CHANGED
@@ -1,8 +1,33 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "poolcontrol",
4
- "version": "0.5.1",
4
+ "version": "0.5.3",
5
5
  "news": {
6
+ "0.5.3": {
7
+ "en": "Added user selection for Telegram notifications. If no user is selected, messages are sent globally as before; if one or more usernames are specified, only those users receive the messages. Admin UI visually improved (recipient field indented under the instance). speechHelper and jsonConfig.json updated.",
8
+ "de": "Benutzerauswahl für Telegram-Benachrichtigungen hinzugefügt. Wenn kein Benutzer ausgewählt ist, werden Nachrichten wie bisher global gesendet; bei einem oder mehreren Benutzernamen erhalten nur diese die Nachrichten. Admin-UI optisch verbessert (Empfängerfeld unter der Instanz eingerückt). speechHelper und jsonConfig.json aktualisiert.",
9
+ "ru": "Добавлен выбор пользователей для уведомлений Telegram. Если пользователь не выбран, сообщения отправляются глобально, как и раньше; при указании одного или нескольких имен сообщения получают только эти пользователи. Улучшен интерфейс админки (поле получателей расположено под экземпляром). Обновлены speechHelper и jsonConfig.json.",
10
+ "pt": "Adicionada seleção de usuários para notificações do Telegram. Se nenhum usuário for selecionado, as mensagens serão enviadas globalmente como antes; se um ou mais nomes forem informados, apenas esses usuários receberão as mensagens. UI de administração melhorada visualmente (campo de destinatários recuado sob a instância). speechHelper e jsonConfig.json atualizados.",
11
+ "nl": "Gebruikersselectie toegevoegd voor Telegram-meldingen. Als er geen gebruiker is geselecteerd, worden berichten zoals voorheen wereldwijd verzonden; bij één of meer opgegeven gebruikersnamen ontvangen alleen die gebruikers de berichten. Admin-UI visueel verbeterd (ontvanger-veld ingesprongen onder de instantie). speechHelper en jsonConfig.json bijgewerkt.",
12
+ "fr": "Ajout de la sélection d’utilisateurs pour les notifications Telegram. Si aucun utilisateur n’est sélectionné, les messages sont envoyés globalement comme auparavant ; si un ou plusieurs noms sont spécifiés, seuls ces utilisateurs reçoivent les messages. Amélioration visuelle de l’interface d’admin (champ destinataire indenté sous l’instance). speechHelper et jsonConfig.json mis à jour.",
13
+ "it": "Aggiunta la selezione degli utenti per le notifiche Telegram. Se non viene selezionato alcun utente, i messaggi vengono inviati globalmente come prima; indicando uno o più nomi utente, solo questi riceveranno i messaggi. Migliorata l’UI di amministrazione (campo destinatari rientrato sotto l’istanza). Aggiornati speechHelper e jsonConfig.json.",
14
+ "es": "Se añadió la selección de usuarios para notificaciones de Telegram. Si no se selecciona ningún usuario, los mensajes se envían globalmente como antes; si se especifican uno o más nombres de usuario, solo esos usuarios reciben los mensajes. Mejora visual en la interfaz de administración (campo de destinatarios sangrado bajo la instancia). speechHelper y jsonConfig.json actualizados.",
15
+ "pl": "Dodano wybór użytkowników dla powiadomień Telegram. Gdy nie wybrano żadnego użytkownika, wiadomości są wysyłane globalnie jak wcześniej; po podaniu jednego lub kilku nazw użytkowników wiadomości otrzymują tylko oni. Ulepszono UI administracyjne (pole odbiorców pod instancją). Zaktualizowano speechHelper i jsonConfig.json.",
16
+ "uk": "Додано вибір користувачів для сповіщень Telegram. Якщо користувача не вибрано, повідомлення надсилаються глобально, як і раніше; якщо вказано одне чи кілька імен, їх отримують лише ці користувачі. Візуально покращено інтерфейс адміністрування (поле одержувача під екземпляром). Оновлено speechHelper та jsonConfig.json.",
17
+ "zh-cn": "新增 Telegram 通知的用户选择功能。未选择用户时消息将像以前一样全局发送;指定一个或多个用户名时,仅这些用户会收到消息。优化了管理界面显示(收件人字段缩进至实例下方)。已更新 speechHelper 和 jsonConfig.json。"
18
+ },
19
+ "0.5.2": {
20
+ "en": "Extended helper priority system: fixed time/solar conflicts, frost pauses during time windows. Stable pump behavior and improved coordination between helpers.",
21
+ "de": "Erweitertes Helper-Vorrangsystem: Konflikte zwischen Zeit- und Solarsteuerung behoben, Frostschutz pausiert während Zeitfenstern. Stabiles Pumpenverhalten und verbesserte Koordination zwischen den Helpern.",
22
+ "ru": "Расширена система приоритетов помощников: устранены конфликты между таймером и солнечным управлением, мороз приостанавливается во время временных окон. Стабильная работа насоса и улучшенная координация между помощниками.",
23
+ "pt": "Sistema de prioridade dos helpers expandido: corrigidos conflitos de tempo/solar, proteção contra geada pausa durante janelas de tempo. Comportamento estável da bomba e melhor coordenação entre helpers.",
24
+ "nl": "Uitgebreid helperprioriteitssysteem: conflicten tussen tijd- en zonregeling opgelost, vorstbeveiliging pauzeert tijdens tijdvensters. Stabiel pompgedrag en betere coördinatie tussen helpers.",
25
+ "fr": "Système de priorité des helpers étendu : conflits temps/solaire corrigés, protection antigel en pause pendant les plages horaires. Comportement de pompe stable et meilleure coordination entre les helpers.",
26
+ "it": "Sistema di priorità degli helper esteso: risolti i conflitti tempo/solare, la protezione antigelo si mette in pausa durante le finestre temporali. Comportamento stabile della pompa e migliore coordinamento tra gli helper.",
27
+ "es": "Sistema de prioridad de helpers ampliado: solucionados los conflictos de tiempo/solar, la protección contra heladas se pausa durante las ventanas de tiempo. Comportamiento estable de la bomba y mejor coordinación entre helpers.",
28
+ "pl": "Rozszerzony system priorytetów helperów: naprawiono konflikty między czasem a sterowaniem solarnym, ochrona przed mrozem wstrzymuje się podczas okien czasowych. Stabilne działanie pompy i lepsza koordynacja między helperami.",
29
+ "zh-cn": "扩展的助手优先级系统:修复时间/太阳能冲突,防冻在时间窗口内暂停。泵运行稳定,助手之间协调更好。"
30
+ },
6
31
  "0.5.1": {
7
32
  "en": "Extended week and month statistics with persistent data, unified JSON format, and installation protection.",
8
33
  "de": "Erweiterte Wochen- und Monatsstatistik mit persistenten Daten, einheitlichem JSON-Format und Überinstallationsschutz.",
@@ -53,18 +78,6 @@
53
78
  "pl": "Ustabilizowano logikę ochrony przed zamarzaniem: stała histereza +2 °C i zaokrąglone wartości temperatury, aby uniknąć wahań przełączania pompy w okolicach 3 °C.",
54
79
  "uk": "Стабілізовано логіку захисту від замерзання: фіксована гістерезис +2 °C і округлені значення температури, щоб уникнути коливань увімкнення насоса біля 3 °C.",
55
80
  "zh-cn": "防冻逻辑稳定:固定 +2 °C 滞后并四舍五入温度值,以避免泵在 3 °C 附近频繁切换。"
56
- },
57
- "0.3.0": {
58
- "en": "Added real pump flow calculation, live monitoring, and self-learning normal range system for pump analysis.",
59
- "de": "Reelle Durchflussberechnung, Liveüberwachung und selbstlernendes Normalbereich-System zur Pumpenanalyse hinzugefügt.",
60
- "ru": "Добавлен расчет реального расхода насоса, живой мониторинг и самообучающаяся система нормальных диапазонов для анализа насоса.",
61
- "pt": "Adicionada cálculo de fluxo real da bomba, monitoramento ao vivo e sistema autoaprendente de faixa normal para análise da bomba.",
62
- "nl": "Reële pompdebietberekening, livebewaking en zelflerend normaalbereiksysteem voor pompanalyse toegevoegd.",
63
- "fr": "Ajout du calcul du débit réel de la pompe, de la surveillance en direct et d’un système de plage normale auto-apprenant pour l’analyse de la pompe.",
64
- "it": "Aggiunto calcolo del flusso reale della pompa, monitoraggio live e sistema autoapprendente di intervallo normale per l'analisi della pompa.",
65
- "es": "Se añadió el cálculo del caudal real de la bomba, la monitorización en vivo y un sistema de rango normal autoaprendente para el análisis de la bomba.",
66
- "pl": "Dodano obliczanie rzeczywistego przepływu pompy, monitorowanie na żywo i samouczący się system normalnego zakresu do analizy pompy.",
67
- "zh-cn": "添加了实际泵流量计算、实时监控以及用于泵分析的自学习正常范围系统。"
68
81
  }
69
82
  },
70
83
  "titleLang": {
@@ -40,6 +40,12 @@ const frostHelper = {
40
40
  return;
41
41
  }
42
42
 
43
+ // --- NEU: Vorrangprüfung durch TimeHelper ---
44
+ if (activeHelper === 'timeHelper') {
45
+ this.adapter.log.debug('[frostHelper] Vorrang durch TimeHelper aktiv – Frostschutz pausiert.');
46
+ return;
47
+ }
48
+
43
49
  // Frostschutz aktiviert?
44
50
  const frostActive = (await this.adapter.getStateAsync('pump.frost_protection_active'))?.val;
45
51
  if (!frostActive) {
@@ -39,6 +39,12 @@ const solarHelper = {
39
39
  return;
40
40
  }
41
41
 
42
+ // --- NEU: Vorrangprüfung durch TimeHelper ---
43
+ if (activeHelper === 'timeHelper') {
44
+ this.adapter.log.debug('[solarHelper] Vorrang durch TimeHelper aktiv – Solarregelung pausiert.');
45
+ return;
46
+ }
47
+
42
48
  // --- NEU: Saisonstatus ---
43
49
  const season = (await this.adapter.getStateAsync('status.season_active'))?.val;
44
50
 
@@ -148,8 +148,24 @@ const speechHelper = {
148
148
  if (this.adapter.config.speech_telegram_enabled && this.adapter.config.speech_telegram_instance) {
149
149
  const instance = this.adapter.config.speech_telegram_instance;
150
150
  try {
151
- this.adapter.sendTo(instance, { text, parse_mode: 'Markdown' });
152
- this.adapter.log.info(`[speechHelper] Telegram sendet: ${text}`);
151
+ // NEU: Benutzerliste aus Admin lesen (Komma-getrennte Namen)
152
+ const rawUsers = this.adapter.config.speech_telegram_users || '';
153
+ const users = rawUsers
154
+ .split(',')
155
+ .map(u => u.trim())
156
+ .filter(Boolean);
157
+
158
+ // Wenn keine Benutzer angegeben → Standard: global an alle senden
159
+ if (users.length === 0) {
160
+ await this.adapter.sendToAsync(instance, { text, parse_mode: 'Markdown' });
161
+ this.adapter.log.info(`[speechHelper] Telegram (global): ${text}`);
162
+ } else {
163
+ // Nur an ausgewählte Benutzer senden
164
+ for (const user of users) {
165
+ await this.adapter.sendToAsync(instance, { user, text, parse_mode: 'Markdown' });
166
+ this.adapter.log.info(`[speechHelper] Telegram an ${user}: ${text}`);
167
+ }
168
+ }
153
169
  } catch (err) {
154
170
  this.adapter.log.warn(
155
171
  `[speechHelper] Telegram-Versand fehlgeschlagen (${instance}): ${err.message}`,
@@ -76,6 +76,35 @@ const temperatureHelper = {
76
76
  : 'keine Sensoren konfiguriert'
77
77
  }`,
78
78
  );
79
+ // ------------------------------------------------------
80
+ // NEU: Re-Subscribe-Überwachung für hängende Sensoren
81
+ // ------------------------------------------------------
82
+ setInterval(
83
+ async () => {
84
+ for (const [key, id] of Object.entries(this.sensors)) {
85
+ try {
86
+ const state = await this.adapter.getStateAsync(`temperature.${key}.current`);
87
+ const lastTs = state?.ts || 0;
88
+ const minutes = (Date.now() - lastTs) / 60000;
89
+
90
+ // Wenn länger als 10 Minuten keine Aktualisierung, Subscribe erneuern
91
+ if (minutes > 10) {
92
+ this.adapter.log.warn(
93
+ `[temperatureHelper] Keine Aktualisierung für ${key} seit ${Math.round(
94
+ minutes,
95
+ )} Min – re-subscribing ${id}`,
96
+ );
97
+ this.adapter.subscribeForeignStates(id);
98
+ }
99
+ } catch (err) {
100
+ this.adapter.log.debug(
101
+ `[temperatureHelper] Re-Subscribe-Prüfung für ${key} fehlgeschlagen: ${err.message}`,
102
+ );
103
+ }
104
+ }
105
+ },
106
+ 10 * 60 * 1000,
107
+ ); // alle 10 Minuten prüfen
79
108
  },
80
109
 
81
110
  _collectActiveSensors(adapter) {
@@ -4,7 +4,8 @@
4
4
  * timeHelper
5
5
  * - Überwacht Zeitfenster (time1, time2, time3)
6
6
  * - Schaltet Pumpe, wenn Modus "time" aktiv ist
7
- * - Schaltet über die reale Steckdosen-ID aus der Config
7
+ * - Schaltet über den internen Pumpenschalter (pump.pump_switch)
8
+ * - Die eigentliche Steckdose wird vom pumpHelper gespiegelt
8
9
  */
9
10
 
10
11
  const timeHelper = {
@@ -32,15 +33,19 @@ const timeHelper = {
32
33
  async _checkWindows() {
33
34
  try {
34
35
  const mode = (await this.adapter.getStateAsync('pump.mode'))?.val;
36
+
37
+ // NEU: Wenn nicht im Zeitmodus, ggf. Vorrang freigeben
35
38
  if (mode !== 'time') {
39
+ const activeHelper = (await this.adapter.getStateAsync('pump.active_helper'))?.val;
40
+ if (activeHelper === 'timeHelper') {
41
+ await this.adapter.setStateAsync('pump.active_helper', { val: '', ack: true });
42
+ this.adapter.log.debug('[timeHelper] Zeitmodus beendet – Vorrang an Solar/Control freigegeben.');
43
+ }
36
44
  return;
37
45
  } // nur aktiv im Zeitmodus
38
46
 
39
- const pumpSwitchId = this.adapter.config.pump_switch;
40
- if (!pumpSwitchId) {
41
- this.adapter.log.warn('[timeHelper] Keine pump_switch (Fremd-ID) konfiguriert!');
42
- return;
43
- }
47
+ // Interner Pumpenschalter statt externer Steckdose
48
+ const pumpStateId = 'pump.pump_switch';
44
49
 
45
50
  const now = new Date();
46
51
  const hhmm = now.toTimeString().slice(0, 5); // "HH:MM"
@@ -59,7 +64,7 @@ const timeHelper = {
59
64
  }
60
65
  }
61
66
 
62
- // --- NEU: Sprachsignal für Zeitsteuerung setzen ---
67
+ // --- Sprachsignal für Zeitsteuerung setzen ---
63
68
  const oldVal = (await this.adapter.getStateAsync('speech.time_active'))?.val;
64
69
  if (oldVal !== shouldRun) {
65
70
  await this.adapter.setStateAsync('speech.time_active', {
@@ -68,14 +73,25 @@ const timeHelper = {
68
73
  });
69
74
  }
70
75
 
71
- // --- NEU: nur schalten, wenn sich der Zustand wirklich ändert ---
72
- const currentState = (await this.adapter.getForeignStateAsync(pumpSwitchId))?.val;
76
+ // NEU: Vorrangverwaltung (active_helper)
77
+ const activeHelper = (await this.adapter.getStateAsync('pump.active_helper'))?.val;
78
+ if (shouldRun && activeHelper !== 'timeHelper') {
79
+ await this.adapter.setStateAsync('pump.active_helper', { val: 'timeHelper', ack: true });
80
+ this.adapter.log.debug('[timeHelper] Vorrang übernommen (Zeitfenster aktiv).');
81
+ }
82
+ if (!shouldRun && activeHelper === 'timeHelper') {
83
+ await this.adapter.setStateAsync('pump.active_helper', { val: '', ack: true });
84
+ this.adapter.log.debug('[timeHelper] Vorrang zurückgegeben (Zeitfenster beendet).');
85
+ }
86
+
87
+ // --- Nur schalten, wenn sich der Zustand wirklich ändert ---
88
+ const currentState = (await this.adapter.getStateAsync(pumpStateId))?.val;
73
89
  if (currentState !== shouldRun) {
74
- await this.adapter.setForeignStateAsync(pumpSwitchId, {
90
+ await this.adapter.setStateAsync(pumpStateId, {
75
91
  val: shouldRun,
76
92
  ack: false,
77
93
  });
78
- this.adapter.log.debug(`[timeHelper] Pumpe ${shouldRun ? 'EIN' : 'AUS'} (${hhmm})`);
94
+ this.adapter.log.debug(`[timeHelper] Pumpenschalter ${shouldRun ? 'EIN' : 'AUS'} (${hhmm})`);
79
95
  } else {
80
96
  this.adapter.log.debug(
81
97
  `[timeHelper] Keine Änderung (${hhmm}) – Zustand bleibt ${shouldRun ? 'EIN' : 'AUS'}.`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.poolcontrol",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
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",