iobroker.poolcontrol 1.2.2 → 1.2.4

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
@@ -195,7 +195,27 @@ New features are added regularly – please refer to the changelog.
195
195
  ---
196
196
 
197
197
  ## Changelog
198
- ### **WORK IN PROGRESS**
198
+
199
+ ### 1.2.4
200
+ Release: 07.03.2026
201
+ - Fix: actuatorsHelper did not synchronize instance configuration with internal states (active/name). Additional actuators could not be activated.
202
+ ### 1.2.3
203
+ Released: 06.03.2026
204
+ - Replaced native timers (setTimeout / setInterval) with adapter timers (adapter.setTimeout / adapter.setInterval)
205
+ - Added proper cleanup of timers on adapter unload
206
+ - Internal code cleanup and maintenance improvements
207
+
208
+ ### 1.2.2
209
+ Released: 06.03.2026
210
+ - Raised required admin version to >=7.6.20
211
+ - Updated translations after jsonConfig i18n refactoring
212
+ - Maintenance update (no functional changes)
213
+
214
+ ### 1.2.1
215
+ Released: 06.03.2026
216
+ - Migration of admin configuration to i18n translation environment
217
+ - jsonConfig now uses English labels with translations managed in admin/i18n
218
+ - Translations generated using `npm run translate`
199
219
 
200
220
  ### 1.2.0
201
221
  Released: 15.02.2026
@@ -245,7 +265,7 @@ Released: 15.02.2026
245
265
  - Purely optional system extension
246
266
 
247
267
 
248
- ## v0.9.0 (WORK IN PROGRESS)
268
+ ## v0.9.0
249
269
  - Introduction of heating / heat pump control (`heatHelper`)
250
270
  - Automatic heating request based on pool temperature
251
271
  - Target and maximum temperature configurable
package/io-package.json CHANGED
@@ -1,8 +1,25 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "poolcontrol",
4
- "version": "1.2.2",
4
+ "version": "1.2.4",
5
5
  "news": {
6
+ "1.2.4": {
7
+ "en": "Fix: actuatorsHelper did not synchronize instance configuration with internal states (active/name). Additional actuators could not be activated.",
8
+ "de": "Fix: actuatorsHelper synchronisierte die Instanzkonfiguration nicht mit den internen States (active/name). Zusatzaktoren konnten dadurch nicht aktiviert werden."
9
+ },
10
+ "1.2.3": {
11
+ "en": "Replaced native timers with adapter timers and improved timer cleanup",
12
+ "de": "Native Timer durch Adapter-Timer ersetzt und Timer-Cleanup verbessert",
13
+ "ru": "Заменены собственные таймеры на таймеры адаптера и улучшена очистка таймера.",
14
+ "pt": "Temporizadores nativos substituídos por temporizadores de adaptador e limpeza aprimorada do temporizador",
15
+ "nl": "Native timers vervangen door adaptertimers en verbeterde timeropschoning",
16
+ "fr": "Remplacement des minuteries natives par des minuteries d'adaptateur et un nettoyage amélioré des minuteries",
17
+ "it": "Sostituiti i timer nativi con timer adattatori e migliorata la pulizia dei timer",
18
+ "es": "Se reemplazaron los temporizadores nativos con temporizadores adaptadores y se mejoró la limpieza del temporizador.",
19
+ "pl": "Zastąpiono liczniki czasu natywnego licznikami adaptera i ulepszono czyszczenie licznika czasu",
20
+ "uk": "Вбудовані таймери замінено на адаптерні та покращено очищення таймерів",
21
+ "zh-cn": "用适配器计时器替换了本机计时器并改进了计时器清理"
22
+ },
6
23
  "1.2.2": {
7
24
  "en": "Maintenance update: Raised required admin version to >=7.6.20 and refreshed translations after jsonConfig i18n changes.",
8
25
  "de": "Wartungsupdate: Mindestversion für admin auf >=7.6.20 erhöht und Übersetzungen nach jsonConfig-i18n-Änderungen aktualisiert.",
@@ -24,12 +24,16 @@ const actuatorsHelper = {
24
24
  // ======================================================
25
25
  // Init
26
26
  // ======================================================
27
- init(adapter) {
27
+ async init(adapter) {
28
28
  this.adapter = adapter;
29
29
 
30
30
  // 🔥 WICHTIG: Actuator-States abonnieren
31
31
  this.adapter.subscribeStates('actuators.*');
32
32
 
33
+ // FIX: Config-Werte in interne States übernehmen
34
+
35
+ await this._syncConfigToStates();
36
+
33
37
  this.adapter.log.info('[actuatorsHelper] initialized');
34
38
  },
35
39
 
@@ -64,6 +68,31 @@ const actuatorsHelper = {
64
68
  }
65
69
  },
66
70
 
71
+ // ======================================================
72
+ // FIX: Config -> interne States synchronisieren
73
+ // ======================================================
74
+ async _syncConfigToStates() {
75
+ const cfg = this.adapter.config || {};
76
+
77
+ for (let i = 1; i <= 3; i++) {
78
+ // Beleuchtung
79
+ await this._set(`actuators.lighting.light${i}.active`, !!cfg[`light_${i}_active`]);
80
+ await this._set(`actuators.lighting.light${i}.name`, String(cfg[`light_${i}_name`] || ''));
81
+
82
+ if (!cfg[`light_${i}_active`]) {
83
+ await this._set(`actuators.lighting.light${i}.status`, 'DEAKTIVIERT');
84
+ }
85
+
86
+ // Zusatzpumpen
87
+ await this._set(`actuators.extrapumps.pump${i}.active`, !!cfg[`extrapump_${i}_active`]);
88
+ await this._set(`actuators.extrapumps.pump${i}.name`, String(cfg[`extrapump_${i}_name`] || ''));
89
+
90
+ if (!cfg[`extrapump_${i}_active`]) {
91
+ await this._set(`actuators.extrapumps.pump${i}.status`, 'DEAKTIVIERT');
92
+ }
93
+ }
94
+ },
95
+
67
96
  // ======================================================
68
97
  // Switch EIN / AUS
69
98
  // ======================================================
@@ -166,7 +195,7 @@ const actuatorsHelper = {
166
195
  await this._set(`${base}.remaining_minutes`, remaining);
167
196
  await this._set(`${base}.status`, `EIN (noch ${remaining} min)`);
168
197
 
169
- this._timers[base] = setInterval(async () => {
198
+ this._timers[base] = this.adapter.setInterval(async () => {
170
199
  try {
171
200
  remaining--;
172
201
 
@@ -187,7 +216,7 @@ const actuatorsHelper = {
187
216
 
188
217
  async _stopTimer(base) {
189
218
  if (this._timers[base]) {
190
- clearInterval(this._timers[base]);
219
+ this.adapter.clearInterval(this._timers[base]);
191
220
  delete this._timers[base];
192
221
  }
193
222
  },
@@ -254,6 +283,20 @@ const actuatorsHelper = {
254
283
  return fallback;
255
284
  }
256
285
  },
286
+
287
+ cleanup() {
288
+ try {
289
+ for (const base of Object.keys(this._timers)) {
290
+ if (this._timers[base]) {
291
+ this.adapter.clearInterval(this._timers[base]);
292
+ delete this._timers[base];
293
+ }
294
+ }
295
+ this.adapter.log.debug('[actuatorsHelper] cleanup done');
296
+ } catch (err) {
297
+ this.adapter.log.debug(`[actuatorsHelper] cleanup error: ${err.message}`);
298
+ }
299
+ },
257
300
  };
258
301
 
259
302
  module.exports = actuatorsHelper;
@@ -12,6 +12,7 @@
12
12
  let adapter;
13
13
  let backwashTimer = null;
14
14
  let dailyTimer = null;
15
+ let autoPumpingInterval = null; // FIX
15
16
  let previousPumpMode = null;
16
17
 
17
18
  /**
@@ -44,7 +45,7 @@ function init(a) {
44
45
  async function _scheduleDailyCheck() {
45
46
  try {
46
47
  if (dailyTimer) {
47
- clearTimeout(dailyTimer);
48
+ adapter.clearTimeout(dailyTimer);
48
49
  }
49
50
 
50
51
  const timeStr = (await adapter.getStateAsync('control.circulation.check_time'))?.val || '18:00';
@@ -60,7 +61,7 @@ async function _scheduleDailyCheck() {
60
61
  const diffMs = next - now;
61
62
  adapter.log.debug(`[controlHelper] next daily circulation check scheduled for ${next.toLocaleTimeString()}`);
62
63
 
63
- dailyTimer = setTimeout(async () => {
64
+ dailyTimer = adapter.setTimeout(async () => {
64
65
  await _runDailyCirculationCheck();
65
66
  await _scheduleDailyCheck();
66
67
  }, diffMs);
@@ -150,12 +151,18 @@ async function _startAutoPumping(missingLiter) {
150
151
  await _sendSpeech(`Automatisches Nachpumpen gestartet. Es fehlen ${missingLiter} Liter.`);
151
152
  }
152
153
 
153
- const interval = setInterval(async () => {
154
+ if (autoPumpingInterval) {
155
+ adapter.clearInterval(autoPumpingInterval);
156
+ autoPumpingInterval = null;
157
+ }
158
+
159
+ autoPumpingInterval = adapter.setInterval(async () => {
154
160
  const total = Math.round((await adapter.getStateAsync('circulation.daily_total'))?.val || 0);
155
161
  const required = Math.round((await adapter.getStateAsync('circulation.daily_required'))?.val || 0);
156
162
 
157
163
  if (total >= required) {
158
- clearInterval(interval);
164
+ adapter.clearInterval(autoPumpingInterval);
165
+ autoPumpingInterval = null;
159
166
  await adapter.setStateAsync('pump.pump_switch', { val: false, ack: false });
160
167
  await adapter.setStateAsync('pump.mode', { val: previousPumpMode, ack: true });
161
168
  await adapter.setStateAsync('pump.active_helper', { val: '', ack: true });
@@ -248,9 +255,9 @@ async function handleStateChange(id, state) {
248
255
  }
249
256
 
250
257
  if (backwashTimer) {
251
- clearTimeout(backwashTimer);
258
+ adapter.clearTimeout(backwashTimer);
252
259
  }
253
- backwashTimer = setTimeout(
260
+ backwashTimer = adapter.setTimeout(
254
261
  async () => {
255
262
  try {
256
263
  await adapter.setStateAsync('pump.pump_switch', { val: false, ack: false });
@@ -333,13 +340,17 @@ async function _sendSpeech(text) {
333
340
  */
334
341
  function cleanup() {
335
342
  if (backwashTimer) {
336
- clearTimeout(backwashTimer);
343
+ adapter.clearTimeout(backwashTimer);
337
344
  backwashTimer = null;
338
345
  }
339
346
  if (dailyTimer) {
340
- clearTimeout(dailyTimer);
347
+ adapter.clearTimeout(dailyTimer);
341
348
  dailyTimer = null;
342
349
  }
350
+ if (autoPumpingInterval) {
351
+ adapter.clearInterval(autoPumpingInterval);
352
+ autoPumpingInterval = null;
353
+ }
343
354
  previousPumpMode = null;
344
355
  }
345
356
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.poolcontrol",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
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",