iobroker.poolcontrol 0.0.10 → 0.1.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
@@ -94,6 +94,13 @@ Funktionen können sich ändern, bitte regelmäßig den Changelog beachten.
94
94
  ## Changelog
95
95
  Auszug, vollständige Liste siehe `io-package.json`:
96
96
 
97
+ ### 0.1.0
98
+ - Sprachausgabe über **E-Mail** hinzugefügt (konfigurierbar: Instanz, Empfänger, Betreff).
99
+ - Erweiterung der Instanz-Konfiguration im Tab „Sprachausgaben“.
100
+ **Bugfixes**
101
+ - Kleinere Korrekturen und Optimierungen in der Dokumentation (`help.md`).
102
+ - Logging in `speechHelper` verbessert.
103
+
97
104
  ### 0.0.10
98
105
 
99
106
  Statusübersicht
@@ -49,6 +49,21 @@
49
49
  "lg": 3,
50
50
  "xl": 3,
51
51
  "newLine": true
52
+ },
53
+ "divider_season1": {
54
+ "type": "divider",
55
+ "newLine": true
56
+ },
57
+ "season_active": {
58
+ "type": "checkbox",
59
+ "label": "Poolsaison aktiv",
60
+ "default": false,
61
+ "xs": 12,
62
+ "sm": 3,
63
+ "md": 3,
64
+ "lg": 3,
65
+ "xl": 3,
66
+ "newLine": true
52
67
  }
53
68
  }
54
69
  },
@@ -831,6 +846,53 @@
831
846
  "lg": 6,
832
847
  "xl": 6
833
848
  },
849
+ "divider_speech_email": {
850
+ "type": "divider",
851
+ "newLine": true
852
+ },
853
+ "speech_email_enabled": {
854
+ "type": "checkbox",
855
+ "label": "Ausgabe über E-Mail aktivieren",
856
+ "default": false,
857
+ "xs": 12,
858
+ "sm": 3,
859
+ "md": 3,
860
+ "lg": 3,
861
+ "xl": 3,
862
+ "newLine": true
863
+ },
864
+ "speech_email_instance": {
865
+ "type": "instance",
866
+ "adapter": "email",
867
+ "label": "E-Mail Adapter-Instanz",
868
+ "default": "email.0",
869
+ "xs": 12,
870
+ "sm": 6,
871
+ "md": 6,
872
+ "lg": 6,
873
+ "xl": 6
874
+ },
875
+ "speech_email_recipient": {
876
+ "type": "text",
877
+ "label": "Empfänger-Adresse",
878
+ "default": "meineadresse@example.com",
879
+ "xs": 12,
880
+ "sm": 6,
881
+ "md": 6,
882
+ "lg": 6,
883
+ "xl": 6,
884
+ "newLine": true
885
+ },
886
+ "speech_email_subject": {
887
+ "type": "text",
888
+ "label": "E-Mail Betreff",
889
+ "default": "PoolControl Nachricht",
890
+ "xs": 12,
891
+ "sm": 6,
892
+ "md": 6,
893
+ "lg": 6,
894
+ "xl": 6
895
+ },
834
896
  "divider_speech4": {
835
897
  "type": "divider",
836
898
  "newLine": true
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "poolcontrol",
4
- "version": "0.0.10",
4
+ "version": "0.1.0",
5
5
  "news": {
6
+ "0.1.0": {
7
+ "en": "Added speech output via E-Mail (configurable: instance, recipient, subject)",
8
+ "de": "Sprachausgabe per E-Mail hinzugefügt (konfigurierbar: Instanz, Empfänger, Betreff)",
9
+ "ru": "Добавлен вывод речи по электронной почте (настраивается: экземпляр, получатель, тема)",
10
+ "pt": "Adicionada saída de fala por e-mail (configurável: instância, destinatário, assunto)",
11
+ "nl": "Spraakuitvoer via e-mail toegevoegd (configureerbaar: instantie, ontvanger, onderwerp)",
12
+ "fr": "Ajout de la sortie vocale par e-mail (configurable : instance, destinataire, sujet)",
13
+ "it": "Aggiunta uscita vocale via e-mail (configurabile: istanza, destinatario, oggetto)",
14
+ "es": "Se agregó salida de voz por correo electrónico (configurable: instancia, destinatario, asunto)",
15
+ "pl": "Dodano wyjście głosowe przez e-mail (konfigurowalne: instancja, odbiorca, temat)",
16
+ "uk": "Додано озвучення електронною поштою (налаштовується: екземпляр, одержувач, тема)",
17
+ "zh-cn": "新增通过电子邮件的语音输出(可配置:实例、收件人、主题)"
18
+ },
6
19
  "0.0.10": {
7
20
  "en": "Added extended status overview with pump statistics, system flags and JSON summary",
8
21
  "de": "Erweiterte Statusübersicht mit Pumpenstatistiken, Systemanzeigen und JSON-Zusammenfassung hinzugefügt",
@@ -28,19 +41,6 @@
28
41
  "pl": "Stany czasu pracy, cyrkulacji, zużycia/kosztów i temp. min/max są teraz zachowane po restartach",
29
42
  "uk": "Стан часу роботи, циркуляції, споживання/вартості та мін/макс температури тепер зберігаються після перезапусків",
30
43
  "zh-cn": "运行时间、循环、消耗/成本和温度最小/最大状态现在在重启后保持"
31
- },
32
- "0.0.8": {
33
- "en": "Added Help tab in instance configuration with link to GitHub documentation",
34
- "de": "Hilfetab in der Instanzkonfiguration hinzugefügt mit Link zur GitHub-Dokumentation",
35
- "ru": "Добавлена вкладка помощи в настройке экземпляра со ссылкой на документацию GitHub",
36
- "pt": "Guia de ajuda adicionado na configuração da instância com link para a documentação do GitHub",
37
- "nl": "Help-tab toegevoegd in de instance-configuratie met link naar GitHub-documentatie",
38
- "fr": "Onglet d'aide ajouté dans la configuration de l'instance avec lien vers la documentation GitHub",
39
- "it": "Aggiunta scheda di aiuto nella configurazione dell'istanza con collegamento alla documentazione GitHub",
40
- "es": "Se agregó pestaña de ayuda en la configuración de la instancia con enlace a la documentación de GitHub",
41
- "pl": "Dodano kartę pomocy w konfiguracji instancji z linkiem do dokumentacji GitHub",
42
- "uk": "Додано вкладку довідки в конфігурацію екземпляра з посиланням на документацію GitHub",
43
- "zh-cn": "在实例配置中添加了帮助选项卡,并链接到 документацию GitHub"
44
44
  }
45
45
  },
46
46
  "titleLang": {
@@ -92,6 +92,15 @@ const pumpHelper = {
92
92
  return;
93
93
  }
94
94
 
95
+ // Saisonprüfung
96
+ const season = (await this.adapter.getStateAsync('status.season_active'))?.val;
97
+ if (!season) {
98
+ this.adapter.log.debug(
99
+ '[pumpHelper] Saison inaktiv – Pumpenlogik übersprungen (Frostschutz läuft separat)',
100
+ );
101
+ return;
102
+ }
103
+
95
104
  // 1) Leistung aus Fremd-State spiegeln
96
105
  if (this.currentPowerId && id === this.currentPowerId) {
97
106
  const val = this._parseNumber(state.val);
@@ -32,17 +32,14 @@ const solarHelper = {
32
32
 
33
33
  async _checkSolar() {
34
34
  try {
35
+ // --- NEU: Saisonstatus ---
36
+ const season = (await this.adapter.getStateAsync('status.season_active'))?.val;
37
+
35
38
  // Solarsteuerung aktiv?
36
39
  const active = (await this.adapter.getStateAsync('solar.solar_control_active'))?.val;
37
- if (!active) {
38
- return;
39
- }
40
40
 
41
- // Pumpenmodus muss AUTO sein
41
+ // Pumpenmodus
42
42
  const mode = (await this.adapter.getStateAsync('pump.mode'))?.val;
43
- if (mode !== 'auto') {
44
- return;
45
- }
46
43
 
47
44
  // Grenzwerte laden
48
45
  const tempOn = (await this.adapter.getStateAsync('solar.temp_on'))?.val;
@@ -58,32 +55,45 @@ const solarHelper = {
58
55
  return;
59
56
  }
60
57
 
61
- let shouldRun = false;
62
- const delta = collector - pool;
58
+ // --- Schaltlogik nur ausführen, wenn Saison aktiv, Solar aktiv und Modus AUTO ---
59
+ if (season && active && mode === 'auto') {
60
+ let shouldRun = false;
61
+ const delta = collector - pool;
63
62
 
64
- // Logik: Einschalten, wenn Collector > tempOn und Delta > 0
65
- if (collector >= tempOn && delta > 0) {
66
- shouldRun = true;
67
- }
63
+ // Logik: Einschalten, wenn Collector > tempOn und Delta > 0
64
+ if (collector >= tempOn && delta > 0) {
65
+ shouldRun = true;
66
+ }
68
67
 
69
- // Ausschalten, wenn Collector < tempOff oder Delta <= 0
70
- if (collector <= tempOff || delta <= 0) {
71
- shouldRun = false;
72
- }
68
+ // Ausschalten, wenn Collector < tempOff oder Delta <= 0
69
+ if (collector <= tempOff || delta <= 0) {
70
+ shouldRun = false;
71
+ }
73
72
 
74
- // Optional Hysterese (kann später erweitert werden)
75
- if (hysteresis) {
76
- // z. B. Ausschaltgrenze etwas absenken
77
- }
73
+ // Optional Hysterese (kann später erweitert werden)
74
+ if (hysteresis) {
75
+ // z. B. Ausschaltgrenze etwas absenken
76
+ }
78
77
 
79
- // ZENTRAL: Pumpe über Bool-Schalter setzen
80
- await this.adapter.setStateAsync('pump.pump_switch', {
81
- val: shouldRun,
82
- ack: false,
83
- });
84
- this.adapter.log.debug(
85
- `[solarHelper] Solarregelung → Pumpe ${shouldRun ? 'EIN' : 'AUS'} (Collector=${collector}°C, Pool=${pool}°C, Delta=${delta}°C)`,
86
- );
78
+ // ZENTRAL: Pumpe über Bool-Schalter setzen
79
+ await this.adapter.setStateAsync('pump.pump_switch', {
80
+ val: shouldRun,
81
+ ack: false,
82
+ });
83
+ this.adapter.log.debug(
84
+ `[solarHelper] Solarregelung → Pumpe ${shouldRun ? 'EIN' : 'AUS'} (Collector=${collector}°C, Pool=${pool}°C, Delta=${delta}°C)`,
85
+ );
86
+ } else {
87
+ // Keine Schaltung – Grund protokollieren
88
+ const reason = !season
89
+ ? 'Saison inaktiv'
90
+ : !active
91
+ ? 'Solarsteuerung aus'
92
+ : mode !== 'auto'
93
+ ? 'Pumpenmodus != auto'
94
+ : 'unbekannt';
95
+ this.adapter.log.debug(`[solarHelper] Solarregelung übersprungen (${reason})`);
96
+ }
87
97
 
88
98
  // --- Kollektor-Warnung ---
89
99
  const warnActive = (await this.adapter.getStateAsync('solar.warn_active'))?.val;
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * speechHelper
5
- * - Sendet Texte an Alexa und/oder Telegram
5
+ * - Sendet Texte an Alexa, Telegram und optional per E-Mail
6
6
  * - Verwendet Config (jsonConfig) + States aus speechStates.js
7
7
  */
8
8
 
@@ -95,6 +95,24 @@ const speechHelper = {
95
95
  });
96
96
  this.adapter.log.info(`[speechHelper] Telegram sendet: ${text}`);
97
97
  }
98
+
99
+ // E-Mail-Ausgabe
100
+ if (this.adapter.config.speech_email_enabled && this.adapter.config.speech_email_instance) {
101
+ const instance = this.adapter.config.speech_email_instance;
102
+ const sendState = `${instance}.mail`;
103
+
104
+ await this.adapter.setForeignStateAsync(sendState, {
105
+ val: {
106
+ to: this.adapter.config.speech_email_recipient,
107
+ subject: this.adapter.config.speech_email_subject || 'PoolControl Nachricht',
108
+ text: text,
109
+ },
110
+ ack: false,
111
+ });
112
+ this.adapter.log.info(
113
+ `[speechHelper] E-Mail gesendet an ${this.adapter.config.speech_email_recipient}: ${text}`,
114
+ );
115
+ }
98
116
  } catch (err) {
99
117
  this.adapter.log.warn(`[speechHelper] Fehler beim Sprechen: ${err.message}`);
100
118
  }
@@ -171,9 +171,9 @@ async function createStatusStates(adapter) {
171
171
  common: {
172
172
  name: 'Poolsaison aktiv',
173
173
  type: 'boolean',
174
- role: 'indicator',
174
+ role: 'switch',
175
175
  read: true,
176
- write: false,
176
+ write: true,
177
177
  },
178
178
  native: {},
179
179
  });
package/main.js CHANGED
@@ -65,6 +65,12 @@ class Poolcontrol extends utils.Adapter {
65
65
  // --- Statusübersicht ---
66
66
  await createStatusStates(this);
67
67
 
68
+ // Saisonstatus aus Config übernehmen
69
+ await this.setStateAsync('status.season_active', {
70
+ val: this.config.season_active,
71
+ ack: true,
72
+ });
73
+
68
74
  // --- Helper starten ---
69
75
  temperatureHelper.init(this);
70
76
  timeHelper.init(this);
@@ -113,12 +119,20 @@ class Poolcontrol extends utils.Adapter {
113
119
  }
114
120
  }
115
121
 
116
- onStateChange(id, state) {
122
+ async onStateChange(id, state) {
117
123
  if (state) {
118
124
  this.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
119
125
  } else {
120
126
  this.log.debug(`state ${id} deleted`);
121
127
  }
128
+
129
+ // Saisonstatus manuell ändern (z.B. über VIS)
130
+ if (id.endsWith('status.season_active') && state && state.ack === false) {
131
+ this.log.info(`[main] Saisonstatus geändert: ${state.val}`);
132
+ await this.setStateAsync('status.season_active', { val: state.val, ack: true });
133
+ return; // danach keine Helper mehr aufrufen
134
+ }
135
+
122
136
  try {
123
137
  temperatureHelper.handleStateChange(id, state);
124
138
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.poolcontrol",
3
- "version": "0.0.10",
3
+ "version": "0.1.0",
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",