iobroker.poolcontrol 1.3.20 → 1.3.22

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,40 @@ New features are added regularly – please refer to the changelog.
188
188
  ---
189
189
 
190
190
  ## Changelog
191
+ ### 1.3.22 (2026-05-24)
192
+
193
+ - Improved ORP pH reference synchronization
194
+ - ORP helper now updates pH reference independently from ORP value processing
195
+ - Immediate update of ORP pH reference when pH enabled state or pH value changes
196
+ - Fixed missing pH reference updates when ORP evaluation was blocked, invalid or waiting for measurement conditions
197
+
198
+ ### 1.3.21 (2026-05-17)
199
+
200
+ NEW: Follow-pump devices
201
+
202
+ Added a new `actuators.follow_pump_devices` area.
203
+
204
+ Up to three external devices can now automatically follow the operation of the main pump.
205
+
206
+ Typical examples:
207
+
208
+ - UV systems
209
+ - Water features
210
+ - Auxiliary filters
211
+ - Additional circulation devices
212
+
213
+ Features:
214
+
215
+ - Automatic ON when the main pump starts
216
+ - Automatic OFF when the main pump stops
217
+ - Configurable target state per device
218
+ - Validation of target states:
219
+ - state exists
220
+ - boolean type required
221
+ - writable required
222
+ - Protection against invalid internal follow-pump targets
223
+ - Persistent configuration values
224
+
191
225
  ### 1.3.20 (2026-05-13)
192
226
 
193
227
  - Added runtime self-healing for missed pump start events.
@@ -211,65 +245,6 @@ New features are added regularly – please refer to the changelog.
211
245
  - Added backward-compatible handling for previously stored German date strings.
212
246
  - Kept history JSON output unchanged with readable date strings for users and VIS displays.
213
247
 
214
- ### 1.3.17 (2026-05-11)
215
-
216
- - Fixed release/upload issue from v1.3.16.
217
- - Fixed circulation calculation in time mode when live flow values were not recalculated after helper-driven pump starts.
218
- - Improved speech system stability.
219
- - Stabilized runtime persistence.
220
- - Reduced repeated solar notifications.
221
- - Added internal stability improvements.
222
-
223
- - Added new ORP/Redox chemistry preparation:
224
- - new `chemistryOrpStates.js`
225
- - new `chemistryOrpHelper.js`
226
- - integrated ORP handling into `main.js`
227
- - supports disabled/manual/state input modes
228
- - ORP value handling in mV
229
- - pH reference from `chemistry.ph.enabled` and `chemistry.ph.input.current_value`
230
- - measurement location, pump and stabilization logic aligned with pH/TDS
231
- - ORP evaluation without automatic dosing or chlorine control
232
- - ORP 24h/7d/30d trend support
233
- - ORP history support
234
- - ORP text/HTML/JSON outputs
235
-
236
- - Added ORP i18n texts.
237
- - Aligned pH structure with TDS/ORP:
238
- - added `chemistry.ph.history.*`
239
- - added `chemistry.ph.trend.*`
240
- - added `chemistry.ph.outputs.*`
241
- - extended pH helper with history, trend and summary logic
242
- - existing pH input, evaluation and mix-run logic remain backward compatible
243
-
244
- ### 1.3.16 (2026-05-11)
245
-
246
- - Fixed circulation calculation in time mode when live flow values were not recalculated after helper-driven pump starts.
247
- - Improved speech system stability.
248
- - Stabilized runtime persistence.
249
- - Reduced repeated solar notifications.
250
- - Added internal stability improvements.
251
-
252
- - Added new ORP/Redox chemistry preparation:
253
- - new `chemistryOrpStates.js`
254
- - new `chemistryOrpHelper.js`
255
- - integrated ORP handling into `main.js`
256
- - supports disabled/manual/state input modes
257
- - ORP value handling in mV
258
- - pH reference from `chemistry.ph.enabled` and `chemistry.ph.input.current_value`
259
- - measurement location, pump and stabilization logic aligned with pH/TDS
260
- - ORP evaluation without automatic dosing or chlorine control
261
- - ORP 24h/7d/30d trend support
262
- - ORP history support
263
- - ORP text/HTML/JSON outputs
264
-
265
- - Added ORP i18n texts.
266
- - Aligned pH structure with TDS/ORP:
267
- - added `chemistry.ph.history.*`
268
- - added `chemistry.ph.trend.*`
269
- - added `chemistry.ph.outputs.*`
270
- - extended pH helper with history, trend and summary logic
271
- - existing pH input, evaluation and mix-run logic remain backward compatible
272
-
273
248
  ## Support
274
249
  - [ioBroker Forum](https://forum.iobroker.net/)
275
250
  - [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.20",
4
+ "version": "1.3.22",
5
5
  "news": {
6
+ "1.3.22": {
7
+ "en": "Improved ORP pH reference synchronization. The ORP helper now updates the pH reference independently from ORP value processing and immediately reflects pH state changes.",
8
+ "de": "ORP-pH-Referenz verbessert. Der ORP-Helper aktualisiert die pH-Referenz jetzt unabhängig von der ORP-Wertverarbeitung und übernimmt pH-Änderungen sofort.",
9
+ "ru": "Улучшена синхронизация эталонного значения pH ОВП. Помощник по ОВП теперь обновляет эталонное значение pH независимо от обработки значений ОВП и немедленно отражает изменения состояния pH.",
10
+ "pt": "Sincronização de referência de pH ORP aprimorada. O auxiliar ORP agora atualiza a referência de pH independentemente do processamento do valor ORP e reflete imediatamente as alterações do estado de pH.",
11
+ "nl": "Verbeterde ORP pH-referentiesynchronisatie. De ORP-helper werkt nu de pH-referentie onafhankelijk van de ORP-waardeverwerking bij en weerspiegelt onmiddellijk veranderingen in de pH-toestand.",
12
+ "fr": "Synchronisation améliorée de la référence ORP pH. L'assistant ORP met désormais à jour la référence pH indépendamment du traitement de la valeur ORP et reflète immédiatement les changements d'état du pH.",
13
+ "it": "Sincronizzazione del riferimento pH ORP migliorata. L'assistente ORP ora aggiorna il riferimento del pH indipendentemente dall'elaborazione del valore ORP e riflette immediatamente i cambiamenti dello stato del pH.",
14
+ "es": "Sincronización de referencia de pH ORP mejorada. El asistente de ORP ahora actualiza la referencia de pH independientemente del procesamiento del valor de ORP y refleja inmediatamente los cambios en el estado del pH.",
15
+ "pl": "Ulepszona synchronizacja odniesienia pH ORP. Pomocnik ORP aktualizuje teraz wartość odniesienia pH niezależnie od przetwarzania wartości ORP i natychmiast odzwierciedla zmiany stanu pH.",
16
+ "uk": "Покращена синхронізація еталонного pH ОВП. Помічник ОВП тепер оновлює еталонний рН незалежно від обробки значення ОВП і негайно відображає зміни стану рН.",
17
+ "zh-cn": "改进了 ORP pH 参考同步。 ORP 助手现在独立于 ORP 值处理更新 pH 参考值,并立即反映 pH 状态变化。"
18
+ },
19
+ "1.3.21": {
20
+ "en": "Added new follow-pump devices. Up to three external devices can now automatically follow the main pump operation. Added validation for target states including existence, boolean type and writable checks. Added protection against internal follow-pump loops.",
21
+ "de": "Neue Geräte mit Pumpenlauf hinzugefügt. Bis zu drei externe Geräte können jetzt automatisch dem Lauf der Hauptpumpe folgen. Zusätzlich wurden Prüfungen für Ziel-Datenpunkte (Existenz, Boolean-Typ und Schreibbarkeit) ergänzt. Schutz gegen interne Follow-Pump-Schleifen hinzugefügt.",
22
+ "ru": "Добавлены новые устройства, следующие за работой насоса. До трёх внешних устройств теперь могут автоматически следовать за работой основного насоса. Добавлена проверка целевых состояний (существование, тип boolean и возможность записи). Добавлена защита от внутренних циклов Follow-Pump.",
23
+ "pt": "Adicionados novos dispositivos dependentes da bomba. Até três dispositivos externos podem agora seguir automaticamente o funcionamento da bomba principal. Adicionadas verificações para estados alvo (existência, tipo booleano e permissão de escrita). Adicionada proteção contra loops internos Follow-Pump.",
24
+ "nl": "Nieuwe apparaten met pompkoppeling toegevoegd. Tot drie externe apparaten kunnen nu automatisch de hoofdpomp volgen. Validatie voor doelstatussen toegevoegd inclusief bestaan, boolean-type en schrijfbaarheid. Bescherming tegen interne Follow-Pump-lussen toegevoegd.",
25
+ "fr": "Ajout de nouveaux appareils liés à la pompe. Jusqu'à trois appareils externes peuvent désormais suivre automatiquement le fonctionnement de la pompe principale. Validation des états cibles ajoutée (existence, type booléen et écriture). Protection contre les boucles internes Follow-Pump ajoutée.",
26
+ "it": "Aggiunti nuovi dispositivi collegati alla pompa. Fino a tre dispositivi esterni possono ora seguire automaticamente il funzionamento della pompa principale. Aggiunti controlli per gli stati di destinazione (esistenza, tipo booleano e scrivibilità). Aggiunta protezione contro i loop interni Follow-Pump.",
27
+ "es": "Añadidos nuevos dispositivos dependientes de la bomba. Hasta tres dispositivos externos ahora pueden seguir automáticamente el funcionamiento de la bomba principal. Se añadieron validaciones para estados destino (existencia, tipo booleano y escritura). Añadida protección contra bucles internos Follow-Pump.",
28
+ "pl": "Dodano nowe urządzenia podążające za pompą. Do trzech urządzeń zewnętrznych może teraz automatycznie podążać za pracą głównej pompy. Dodano sprawdzanie stanów docelowych (istnienie, typ boolean i możliwość zapisu). Dodano ochronę przed wewnętrznymi pętlami Follow-Pump.",
29
+ "uk": "Додано нові пристрої, що слідують за насосом. До трьох зовнішніх пристроїв тепер можуть автоматично працювати разом з головним насосом. Додано перевірку цільових станів (існування, тип boolean та можливість запису). Додано захист від внутрішніх циклів Follow-Pump.",
30
+ "zh-cn": "新增随泵运行设备。现在最多可让三个外部设备自动跟随主泵运行。增加了目标状态验证(存在性、布尔类型和可写性)。增加了内部 Follow-Pump 循环保护。"
31
+ },
6
32
  "1.3.20": {
7
33
  "en": "Added runtime self-healing for missed pump start events and protected time control states from being overwritten during adapter updates.",
8
34
  "de": "Runtime-Selbstheilung für verpasste Pumpenstart-Ereignisse ergänzt und Zeitsteuerungs-Datenpunkte vor dem Überschreiben bei Adapter-Updates geschützt.",
@@ -41,32 +67,6 @@
41
67
  "pl": "Naprawiono nieprawidłowe wyświetlanie daty dla stanów czasowych pH, ​​ORP i TDS poprzez przechowywanie stanów wartość.czas jako numeryczne znaczniki czasu.",
42
68
  "uk": "Виправлено неправильне відображення дати для часових станів pH, ORP і TDS шляхом збереження станів value.time як числових позначок часу.",
43
69
  "zh-cn": "通过将 value.time 状态存储为数字时间戳,修复了 pH、ORP 和 TDS 时间状态的不正确日期显示。"
44
- },
45
- "1.3.17": {
46
- "en": "Fixed release packaging issue from v1.3.16. Improved speech system stability, stabilized runtime persistence, reduced repeated solar notifications, fixed circulation calculation in time mode and prepared new ORP/Redox chemistry analysis area.",
47
- "de": "Release-/Uploadproblem aus v1.3.16 behoben. Sprachsystem verbessert, Runtime-Persistenz stabilisiert, wiederholte Solarbenachrichtigungen reduziert, Umwälzberechnung im Zeitmodus korrigiert und neuer ORP-/Redox-Chemiebereich vorbereitet.",
48
- "ru": "Исправлена ​​проблема с упаковкой выпуска версии 1.3.16. Улучшена стабильность речевой системы, стабилизировано постоянство времени выполнения, уменьшено количество повторных уведомлений о солнечной радиации, исправлен расчет циркуляции во временном режиме и подготовлена ​​новая область химического анализа ОВП/окислительно-восстановительного потенциала.",
49
- "pt": "Problema de empacotamento de lançamento corrigido da v1.3.16. Melhor estabilidade do sistema de fala, persistência de tempo de execução estabilizada, redução de notificações solares repetidas, cálculo de circulação fixo no modo de tempo e nova área de análise química ORP/Redox preparada.",
50
- "nl": "Probleem met releaseverpakking vanaf v1.3.16 opgelost. Verbeterde stabiliteit van het spraaksysteem, gestabiliseerde runtime-persistentie, minder herhaalde zonnemeldingen, vaste circulatieberekening in tijdmodus en voorbereid voor een nieuw ORP/Redox-chemieanalysegebied.",
51
- "fr": "Correction d'un problème d'emballage de version à partir de la v1.3.16. Amélioration de la stabilité du système vocal, persistance d'exécution stabilisée, réduction des notifications solaires répétées, calcul de la circulation fixe en mode temps et préparation d'une nouvelle zone d'analyse chimique ORP/Redox.",
52
- "it": "Risolto il problema relativo al pacchetto di rilascio dalla v1.3.16. Stabilità del sistema vocale migliorata, persistenza del tempo di esecuzione stabilizzata, notifiche solari ripetute ridotte, calcolo della circolazione fissa in modalità temporale e nuova area di analisi chimica ORP/Redox preparata.",
53
- "es": "Se solucionó el problema del paquete de lanzamiento desde v1.3.16. Se mejoró la estabilidad del sistema de voz, se estabilizó la persistencia del tiempo de ejecución, se redujeron las notificaciones solares repetidas, se arregló el cálculo de la circulación en el modo de tiempo y se preparó una nueva área de análisis de química ORP/Redox.",
54
- "pl": "Naprawiono problem z pakowaniem wersji od wersji 1.3.16. Poprawiona stabilność systemu mowy, ustabilizowana trwałość czasu działania, zmniejszona liczba powtarzających się powiadomień słonecznych, stałe obliczanie cyrkulacji w trybie czasowym i przygotowany nowy obszar analizy chemicznej ORP/Redox.",
55
- "uk": "Виправлена ​​проблема упаковки випуску з версії 1.3.16. Покращена стабільність мовної системи, стабілізована стійкість під час виконання, зменшено кількість повторюваних сонячних сповіщень, виправлено обчислення циркуляції в часовому режимі та підготовлено нову область аналізу ORP/Redox.",
56
- "zh-cn": "修复了 v1.3.16 版本的打包问题。提高了语音系统的稳定性,稳定了运行时间的持久性,减少了重复的太阳通知,修复了时间模式下的循环计算,并准备了新的ORP/氧化还原化学分析区域。"
57
- },
58
- "1.3.16": {
59
- "en": "Improved speech system stability, stabilized runtime persistence, reduced repeated solar notifications, fixed circulation calculation in time mode and prepared new ORP/Redox chemistry analysis area.",
60
- "de": "Sprachsystem verbessert, Runtime-Persistenz stabilisiert, wiederholte Solarbenachrichtigungen reduziert, Umwälzberechnung im Zeitmodus korrigiert und neuer ORP-/Redox-Chemiebereich vorbereitet.",
61
- "ru": "Улучшена стабильность речевой системы, стабилизировано постоянство времени выполнения, уменьшено количество повторных уведомлений о солнечной радиации, исправлен расчет циркуляции во временном режиме и подготовлена ​​новая область химического анализа ОВП/окислительно-восстановительного потенциала.",
62
- "pt": "Melhor estabilidade do sistema de fala, persistência de tempo de execução estabilizada, redução de notificações solares repetidas, cálculo de circulação fixo no modo de tempo e nova área de análise química ORP/Redox preparada.",
63
- "nl": "Verbeterde stabiliteit van het spraaksysteem, gestabiliseerde runtime-persistentie, minder herhaalde zonnemeldingen, vaste circulatieberekening in tijdmodus en voorbereid voor een nieuw ORP/Redox-chemieanalysegebied.",
64
- "fr": "Amélioration de la stabilité du système vocal, persistance d'exécution stabilisée, réduction des notifications solaires répétées, calcul de la circulation fixe en mode temps et préparation d'une nouvelle zone d'analyse chimique ORP/Redox.",
65
- "it": "Stabilità del sistema vocale migliorata, persistenza del tempo di esecuzione stabilizzata, notifiche solari ripetute ridotte, calcolo della circolazione fissa in modalità temporale e nuova area di analisi chimica ORP/Redox preparata.",
66
- "es": "Se mejoró la estabilidad del sistema de voz, se estabilizó la persistencia del tiempo de ejecución, se redujeron las notificaciones solares repetidas, se arregló el cálculo de la circulación en el modo de tiempo y se preparó una nueva área de análisis de química ORP/Redox.",
67
- "pl": "Poprawiona stabilność systemu mowy, ustabilizowana trwałość czasu działania, zmniejszona liczba powtarzających się powiadomień słonecznych, stałe obliczanie cyrkulacji w trybie czasowym i przygotowany nowy obszar analizy chemicznej ORP/Redox.",
68
- "uk": "Покращена стабільність мовної системи, стабілізована стійкість під час виконання, зменшено кількість повторюваних сонячних сповіщень, виправлено обчислення циркуляції в часовому режимі та підготовлено нову область аналізу ORP/Redox.",
69
- "zh-cn": "提高了语音系统的稳定性,稳定了运行时间的持久性,减少了重复的太阳通知,修复了时间模式下的循环计算,并准备了新的ORP/氧化还原化学分析区域。"
70
70
  }
71
71
  },
72
72
  "titleLang": {
@@ -30,10 +30,16 @@ const actuatorsHelper = {
30
30
  // 🔥 WICHTIG: Actuator-States abonnieren
31
31
  this.adapter.subscribeStates('actuators.*');
32
32
 
33
+ // NEU: Hauptpumpe abonnieren, damit Follow-Pump-Geräte reagieren können
34
+ this.adapter.subscribeStates('pump.pump_switch');
35
+
33
36
  // FIX: Config-Werte in interne States übernehmen
34
37
 
35
38
  await this._syncConfigToStates();
36
39
 
40
+ // NEU: Follow-Pump-Geräte beim Start prüfen und passend setzen
41
+ await this._updateFollowPumpDevices();
42
+
37
43
  this.adapter.log.info('[actuatorsHelper] initialized');
38
44
  },
39
45
 
@@ -41,7 +47,7 @@ const actuatorsHelper = {
41
47
  // Zentrale StateChange-Anbindung (aus main.js)
42
48
  // ======================================================
43
49
  async handleStateChange(id, state) {
44
- if (!state || state.ack) {
50
+ if (!state) {
45
51
  return;
46
52
  }
47
53
 
@@ -49,6 +55,26 @@ const actuatorsHelper = {
49
55
  // FIX: ID normalisieren (poolcontrol.0.x -> x)
50
56
  const relId = this._toRelId(id);
51
57
 
58
+ // NEU: Follow-Pump-Geräte reagieren auch auf ack=true der internen Pumpenlogik
59
+ if (relId === 'pump.pump_switch') {
60
+ await this._updateFollowPumpDevices();
61
+ return;
62
+ }
63
+
64
+ if (!relId.startsWith('actuators.')) {
65
+ return;
66
+ }
67
+
68
+ if (state.ack) {
69
+ return;
70
+ }
71
+
72
+ // NEU: Änderungen an Follow-Pump-Geräten verarbeiten
73
+ if (relId.startsWith('actuators.follow_pump_devices.')) {
74
+ await this._handleFollowPumpDeviceChange(relId);
75
+ return;
76
+ }
77
+
52
78
  if (relId.endsWith('.switch')) {
53
79
  await this._handleSwitch(relId, !!state.val);
54
80
  return;
@@ -221,6 +247,155 @@ const actuatorsHelper = {
221
247
  }
222
248
  },
223
249
 
250
+ // ======================================================
251
+ // NEU: Follow-Pump-Geräte
252
+ // ======================================================
253
+ async _handleFollowPumpDeviceChange(relId) {
254
+ const parts = relId.split('.');
255
+
256
+ if (parts.length < 4) {
257
+ return;
258
+ }
259
+
260
+ const base = parts.slice(0, 3).join('.');
261
+
262
+ if (relId.endsWith('.enabled') || relId.endsWith('.target_state_id')) {
263
+ await this._validateFollowPumpDevice(base);
264
+ await this._syncFollowPumpDevice(base);
265
+ }
266
+ },
267
+
268
+ async _validateAllFollowPumpDevices() {
269
+ for (let i = 1; i <= 3; i++) {
270
+ await this._validateFollowPumpDevice(`actuators.follow_pump_devices.device${i}`);
271
+ }
272
+ },
273
+
274
+ async _updateFollowPumpDevices() {
275
+ for (let i = 1; i <= 3; i++) {
276
+ const base = `actuators.follow_pump_devices.device${i}`;
277
+
278
+ await this._validateFollowPumpDevice(base);
279
+ await this._syncFollowPumpDevice(base);
280
+ }
281
+ },
282
+
283
+ async _validateFollowPumpDevice(base) {
284
+ const targetId = String((await this._get(`${base}.target_state_id`, '')) || '').trim();
285
+
286
+ if (!targetId) {
287
+ await this._set(`${base}.target_valid`, false);
288
+ await this._set(`${base}.target_writeable`, false);
289
+ await this._set(`${base}.validation_text`, 'target_empty');
290
+ return false;
291
+ }
292
+
293
+ // NEU: Interne PoolControl-Ziele mit Schleifen-/Nebenwirkungsgefahr blockieren
294
+ const namespace = this.adapter?.namespace || '';
295
+
296
+ if (
297
+ namespace &&
298
+ (targetId === `${namespace}.pump.pump_switch` ||
299
+ targetId.startsWith(`${namespace}.actuators.follow_pump_devices.`))
300
+ ) {
301
+ await this._set(`${base}.target_valid`, false);
302
+ await this._set(`${base}.target_writeable`, false);
303
+ await this._set(`${base}.validation_text`, 'internal_target_not_allowed');
304
+ return false;
305
+ }
306
+
307
+ try {
308
+ const obj = await this.adapter.getForeignObjectAsync(targetId);
309
+
310
+ if (!obj || obj.type !== 'state') {
311
+ await this._set(`${base}.target_valid`, false);
312
+ await this._set(`${base}.target_writeable`, false);
313
+ await this._set(`${base}.validation_text`, 'state_not_found');
314
+ return false;
315
+ }
316
+
317
+ const isBoolean = obj.common && obj.common.type === 'boolean';
318
+ const isWriteable = obj.common && obj.common.write === true;
319
+
320
+ await this._set(`${base}.target_valid`, isBoolean);
321
+ await this._set(`${base}.target_writeable`, isWriteable);
322
+
323
+ if (!isBoolean) {
324
+ await this._set(`${base}.validation_text`, 'state_is_not_boolean');
325
+ return false;
326
+ }
327
+
328
+ if (!isWriteable) {
329
+ await this._set(`${base}.validation_text`, 'state_not_writeable');
330
+ return false;
331
+ }
332
+
333
+ await this._set(`${base}.validation_text`, 'OK');
334
+ return true;
335
+ } catch (err) {
336
+ await this._set(`${base}.target_valid`, false);
337
+ await this._set(`${base}.target_writeable`, false);
338
+ await this._set(`${base}.validation_text`, `validation_error: ${err.message}`);
339
+ return false;
340
+ }
341
+ },
342
+
343
+ async _syncFollowPumpDevice(base) {
344
+ const enabled = await this._get(`${base}.enabled`, false);
345
+ const targetValid = await this._get(`${base}.target_valid`, false);
346
+ const targetWriteable = await this._get(`${base}.target_writeable`, false);
347
+ const pumpRunning = await this._get('pump.pump_switch', false);
348
+
349
+ if (!enabled) {
350
+ if (targetValid && targetWriteable) {
351
+ await this._applyFollowPumpTarget(base, false);
352
+ }
353
+
354
+ await this._set(`${base}.active`, false);
355
+ await this._set(`${base}.status`, 'disabled');
356
+ return;
357
+ }
358
+
359
+ if (!targetValid || !targetWriteable) {
360
+ await this._set(`${base}.active`, false);
361
+ await this._set(`${base}.status`, 'invalid_target');
362
+ return;
363
+ }
364
+
365
+ if (pumpRunning) {
366
+ await this._applyFollowPumpTarget(base, true);
367
+ await this._set(`${base}.active`, true);
368
+ await this._set(`${base}.status`, 'running_with_pump');
369
+ } else {
370
+ await this._applyFollowPumpTarget(base, false);
371
+ await this._set(`${base}.active`, false);
372
+ await this._set(`${base}.status`, 'waiting_for_pump');
373
+ }
374
+ },
375
+
376
+ async _applyFollowPumpTarget(base, on) {
377
+ const targetId = String((await this._get(`${base}.target_state_id`, '')) || '').trim();
378
+
379
+ if (!targetId) {
380
+ return;
381
+ }
382
+
383
+ try {
384
+ await this.adapter.setForeignStateAsync(targetId, {
385
+ val: !!on,
386
+ ack: false,
387
+ });
388
+
389
+ this.adapter.log.debug(
390
+ `[actuatorsHelper] ${base}: follow-pump target "${targetId}" -> ${on ? 'ON' : 'OFF'}`,
391
+ );
392
+ } catch (err) {
393
+ this.adapter.log.warn(
394
+ `[actuatorsHelper] ${base}: follow-pump target set failed (${targetId}): ${err.message}`,
395
+ );
396
+ }
397
+ },
398
+
224
399
  // ======================================================
225
400
  // Externes Ziel schalten (aus jsonConfig)
226
401
  // ======================================================
@@ -16,6 +16,7 @@ const chemistryOrpHelper = {
16
16
 
17
17
  void this._subscribeStates();
18
18
  void this._loadSourceState();
19
+ void this._updatePhReference();
19
20
  this._scheduleEvaluation('init', 500);
20
21
 
21
22
  this.adapter.log.debug('[chemistryOrpHelper] Initialized');
@@ -86,6 +87,10 @@ const chemistryOrpHelper = {
86
87
  return;
87
88
  }
88
89
 
90
+ if (id.endsWith('chemistry.ph.enabled') || id.endsWith('chemistry.ph.input.current_value')) {
91
+ await this._updatePhReference();
92
+ }
93
+
89
94
  if (this._isRelevantOwnState(id)) {
90
95
  this._scheduleEvaluation(`state_change:${id}`, 500);
91
96
  }
@@ -395,6 +395,198 @@ async function createActuatorsStates(adapter) {
395
395
  native: {},
396
396
  });
397
397
  }
398
+
399
+ // ======================================================
400
+ // Follow-Pump Geräte
401
+ // ======================================================
402
+ await adapter.setObjectNotExistsAsync('actuators.follow_pump_devices', {
403
+ type: 'channel',
404
+ common: {
405
+ name: {
406
+ en: 'Follow-pump devices',
407
+ de: 'Geräte mit Pumpenlauf',
408
+ },
409
+ },
410
+ native: {},
411
+ });
412
+
413
+ for (let i = 1; i <= 3; i++) {
414
+ const base = `actuators.follow_pump_devices.device${i}`;
415
+
416
+ await adapter.setObjectNotExistsAsync(base, {
417
+ type: 'channel',
418
+ common: {
419
+ name: {
420
+ en: `Follow-pump device ${i}`,
421
+ de: `Gerät mit Pumpenlauf ${i}`,
422
+ },
423
+ },
424
+ native: {},
425
+ });
426
+
427
+ await adapter.setObjectNotExistsAsync(`${base}.enabled`, {
428
+ type: 'state',
429
+ common: {
430
+ name: {
431
+ en: 'Enabled',
432
+ de: 'Aktiviert',
433
+ },
434
+ desc: {
435
+ en: 'Enables this follow-pump device. If enabled, the configured target state is switched on when the main pump is running and switched off when the main pump stops.',
436
+ de: 'Aktiviert dieses Gerät mit Pumpenlauf. Wenn aktiviert, wird der eingetragene Ziel-Datenpunkt eingeschaltet, sobald die Hauptpumpe läuft, und ausgeschaltet, sobald die Hauptpumpe stoppt.',
437
+ },
438
+ type: 'boolean',
439
+ role: 'switch',
440
+ read: true,
441
+ write: true,
442
+ def: false,
443
+ persist: true,
444
+ },
445
+ native: {},
446
+ });
447
+
448
+ await adapter.setObjectNotExistsAsync(`${base}.name`, {
449
+ type: 'state',
450
+ common: {
451
+ name: {
452
+ en: 'Name',
453
+ de: 'Name',
454
+ },
455
+ desc: {
456
+ en: 'Custom display name for this follow-pump device, for example UV lamp, water feature or auxiliary filter.',
457
+ de: 'Frei vergebener Anzeigename für dieses Gerät mit Pumpenlauf, zum Beispiel UV-Lampe, Wasserspiel oder Zusatzfilter.',
458
+ },
459
+ type: 'string',
460
+ role: 'text',
461
+ read: true,
462
+ write: true,
463
+ def: '',
464
+ persist: true,
465
+ },
466
+ native: {},
467
+ });
468
+
469
+ await adapter.setObjectNotExistsAsync(`${base}.target_state_id`, {
470
+ type: 'state',
471
+ common: {
472
+ name: {
473
+ en: 'Target state ID',
474
+ de: 'Ziel-Datenpunkt',
475
+ },
476
+ desc: {
477
+ en: 'ioBroker state ID of the device that should follow the main pump. The target state must exist, must be writable and must be of type boolean.',
478
+ de: 'ioBroker-Datenpunkt des Geräts, das dem Lauf der Hauptpumpe folgen soll. Der Ziel-Datenpunkt muss existieren, beschreibbar sein und den Typ boolean haben.',
479
+ },
480
+ type: 'string',
481
+ role: 'text',
482
+ read: true,
483
+ write: true,
484
+ def: '',
485
+ persist: true,
486
+ },
487
+ native: {},
488
+ });
489
+
490
+ await adapter.setObjectNotExistsAsync(`${base}.target_valid`, {
491
+ type: 'state',
492
+ common: {
493
+ name: {
494
+ en: 'Target valid',
495
+ de: 'Ziel gültig',
496
+ },
497
+ desc: {
498
+ en: 'Shows whether the configured target state exists and is of type boolean.',
499
+ de: 'Zeigt an, ob der eingetragene Ziel-Datenpunkt existiert und vom Typ boolean ist.',
500
+ },
501
+ type: 'boolean',
502
+ role: 'indicator',
503
+ read: true,
504
+ write: false,
505
+ def: false,
506
+ },
507
+ native: {},
508
+ });
509
+
510
+ await adapter.setObjectNotExistsAsync(`${base}.target_writeable`, {
511
+ type: 'state',
512
+ common: {
513
+ name: {
514
+ en: 'Target writable',
515
+ de: 'Ziel beschreibbar',
516
+ },
517
+ desc: {
518
+ en: 'Shows whether the configured target state can be written by PoolControl.',
519
+ de: 'Zeigt an, ob der eingetragene Ziel-Datenpunkt von PoolControl beschrieben werden kann.',
520
+ },
521
+ type: 'boolean',
522
+ role: 'indicator',
523
+ read: true,
524
+ write: false,
525
+ def: false,
526
+ },
527
+ native: {},
528
+ });
529
+
530
+ await adapter.setObjectNotExistsAsync(`${base}.validation_text`, {
531
+ type: 'state',
532
+ common: {
533
+ name: {
534
+ en: 'Validation text',
535
+ de: 'Prüfmeldung',
536
+ },
537
+ desc: {
538
+ en: 'Readable validation result for the configured target state, for example OK, target empty, state not found, state is not boolean or state is not writable.',
539
+ de: 'Lesbare Prüfausgabe für den eingetragenen Ziel-Datenpunkt, zum Beispiel OK, Ziel leer, Datenpunkt nicht gefunden, Datenpunkt ist nicht boolean oder Datenpunkt ist nicht beschreibbar.',
540
+ },
541
+ type: 'string',
542
+ role: 'text',
543
+ read: true,
544
+ write: false,
545
+ def: '',
546
+ },
547
+ native: {},
548
+ });
549
+
550
+ await adapter.setObjectNotExistsAsync(`${base}.active`, {
551
+ type: 'state',
552
+ common: {
553
+ name: {
554
+ en: 'Active with pump',
555
+ de: 'Mit Pumpe aktiv',
556
+ },
557
+ desc: {
558
+ en: 'Shows whether this follow-pump device is currently switched on by PoolControl because the main pump is running.',
559
+ de: 'Zeigt an, ob dieses Gerät aktuell von PoolControl eingeschaltet wurde, weil die Hauptpumpe läuft.',
560
+ },
561
+ type: 'boolean',
562
+ role: 'indicator',
563
+ read: true,
564
+ write: false,
565
+ def: false,
566
+ },
567
+ native: {},
568
+ });
569
+
570
+ await adapter.setObjectNotExistsAsync(`${base}.status`, {
571
+ type: 'state',
572
+ common: {
573
+ name: {
574
+ en: 'Status',
575
+ de: 'Status',
576
+ },
577
+ desc: {
578
+ en: 'Current status of this follow-pump device, for example disabled, waiting_for_pump, running_with_pump or invalid_target.',
579
+ de: 'Aktueller Status dieses Geräts mit Pumpenlauf, zum Beispiel deaktiviert, wartet auf Pumpenlauf, läuft mit Pumpe oder ungültiger Ziel-Datenpunkt.',
580
+ },
581
+ type: 'string',
582
+ role: 'text',
583
+ read: true,
584
+ write: false,
585
+ def: '',
586
+ },
587
+ native: {},
588
+ });
589
+ }
398
590
  }
399
591
 
400
592
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.poolcontrol",
3
- "version": "1.3.20",
3
+ "version": "1.3.22",
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",