iobroker.poolcontrol 1.3.17 → 1.3.18

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,14 @@ New features are added regularly – please refer to the changelog.
188
188
  ---
189
189
 
190
190
  ## Changelog
191
+ ### 1.3.18 (2026-05-11)
192
+
193
+ - Fixed incorrect date display in the pH, ORP and TDS areas.
194
+ - Time states with `value.time` are now stored as numeric timestamps instead of localized date strings.
195
+ - Improved compatibility with ioBroker/Admin date handling.
196
+ - Added backward-compatible handling for previously stored German date strings.
197
+ - Kept history JSON output unchanged with readable date strings for users and VIS displays.
198
+
191
199
  ### 1.3.17 (2026-05-11)
192
200
 
193
201
  - Fixed release/upload issue from v1.3.16.
@@ -272,11 +280,6 @@ New features are added regularly – please refer to the changelog.
272
280
  - Added numeric runtime second states for robust persistence and recovery
273
281
  - Converted runtime timers to adapter-managed timers for improved ioBroker compatibility
274
282
 
275
- ### 1.3.13 (2026-05-08)
276
- - (copilot) Adapter requires node.js >= 22 now
277
- - Fixed invalid `common.installedFrom` entry in `io-package.json`
278
- - Added German and English function overview documentation
279
-
280
283
  ## Support
281
284
  - [ioBroker Forum](https://forum.iobroker.net/)
282
285
  - [GitHub Issues](https://github.com/DasBo1975/ioBroker.poolcontrol/issues)
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "poolcontrol",
4
- "version": "1.3.17",
4
+ "version": "1.3.18",
5
5
  "news": {
6
+ "1.3.18": {
7
+ "en": "Fixed incorrect date display for pH, ORP and TDS time states by storing value.time states as numeric timestamps.",
8
+ "de": "Falsche Datumsanzeige für pH-, ORP- und TDS-Zeitzustände behoben, indem value.time-Zustände als numerische Zeitstempel gespeichert wurden.",
9
+ "ru": "Исправлено неправильное отображение даты для состояний времени pH, ОВП и TDS за счет сохранения состояний value.time в виде числовых меток времени.",
10
+ "pt": "Corrigida a exibição incorreta de data para estados de tempo de pH, ORP e TDS, armazenando estados de valor.tempo como carimbos de data/hora numéricos.",
11
+ "nl": "Foutieve datumweergave voor pH-, ORP- en TDS-tijdstatussen opgelost door value.time-statussen op te slaan als numerieke tijdstempels.",
12
+ "fr": "Correction de l'affichage incorrect de la date pour les états temporels pH, ORP et TDS en stockant les états value.time sous forme d'horodatages numériques.",
13
+ "it": "Risolto il problema con la visualizzazione errata della data per gli stati temporali pH, ORP e TDS memorizzando gli stati value.time come timestamp numerici.",
14
+ "es": "Se corrigió la visualización de fecha incorrecta para los estados de tiempo de pH, ORP y TDS al almacenar los estados de valor.hora como marcas de tiempo numéricas.",
15
+ "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.",
16
+ "uk": "Виправлено неправильне відображення дати для часових станів pH, ORP і TDS шляхом збереження станів value.time як числових позначок часу.",
17
+ "zh-cn": "通过将 value.time 状态存储为数字时间戳,修复了 pH、ORP 和 TDS 时间状态的不正确日期显示。"
18
+ },
6
19
  "1.3.17": {
7
20
  "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.",
8
21
  "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.",
@@ -54,19 +67,6 @@
54
67
  "pl": "Poprawiona obsługa i trwałość środowiska wykonawczego. Naprawiono obliczanie czasu wykonania sezonu w celu wykorzystania prawidłowego stanu sezonu, ulepszono aktualizacje czasu działania na żywo, dodano solidne numeryczne drugie stany czasu działania dla bezpieczniejszej trwałości i odzyskiwania oraz przekonwertowano liczniki czasu działania na zegary zarządzane przez adapter dla lepszej kompatybilności z ioBroker.",
55
68
  "uk": "Покращена обробка та збереження часу виконання. Виправлено розрахунок часу виконання сезону для використання правильного стану сезону, покращено поточні оновлення середовища виконання, додано надійні численні секунди часу виконання для безпечнішого збереження та відновлення, а також перетворено таймери часу виконання на таймери, керовані адаптером, для кращої сумісності з ioBroker.",
56
69
  "zh-cn": "改进了运行时处理和持久性。修复了季节运行时计算以使用正确的季节状态,改进了实时运行时更新,添加了强大的数字运行时第二状态以实现更安全的持久性和恢复,并将运行时计时器转换为适配器管理的计时器以实现更好的 ioBroker 兼容性。"
57
- },
58
- "1.3.13": {
59
- "en": "Added German and English function overview documentation. Fixed invalid common.installedFrom entry in io-package.json.",
60
- "de": "Deutsche und englische Funktionsübersicht ergänzt. Ungültigen common.installedFrom-Eintrag in der io-package.json korrigiert.",
61
- "ru": "Добавлена ​​обзорная документация по функциям на немецком и английском языках. Исправлена ​​неверная запись common.installedFrom в io-package.json.",
62
- "pt": "Adicionada documentação de visão geral das funções em alemão e inglês. Corrigida entrada common.installedFrom inválida em io-package.json.",
63
- "nl": "Duitse en Engelse functieoverzichtdocumentatie toegevoegd. Ongeldige common.installedFrom-vermelding in io-package.json opgelost.",
64
- "fr": "Ajout d'une documentation de présentation des fonctions en allemand et en anglais. Correction de l'entrée common.installedFrom invalide dans io-package.json.",
65
- "it": "Aggiunta la documentazione panoramica delle funzioni in tedesco e inglese. Risolto il problema con la voce common.installedFrom non valida in io-package.json.",
66
- "es": "Se agregó documentación de descripción general de funciones en alemán e inglés. Se corrigió la entrada common.installedFrom no válida en io-package.json.",
67
- "pl": "Dodano dokumentację przeglądu funkcji w języku niemieckim i angielskim. Naprawiono nieprawidłowy wpis common.installedFrom w io-package.json.",
68
- "uk": "Додано документацію щодо огляду функцій німецькою та англійською мовами. Виправлено недійсний запис common.installedFrom у io-package.json.",
69
- "zh-cn": "添加了德语和英语功能概述文档。修复了 io-package.json 中无效的 common.installedFrom 条目。"
70
70
  }
71
71
  },
72
72
  "titleLang": {
@@ -238,7 +238,7 @@ const chemistryOrpHelper = {
238
238
  const now = new Date();
239
239
  const value = Number(rawValue);
240
240
 
241
- await this._setString('chemistry.orp.input.last_value_at', this._formatDateTime(now));
241
+ await this._setNumber('chemistry.orp.input.last_value_at', now.getTime()); // FIX: value.time uses numeric ms timestamp.
242
242
 
243
243
  if (source === 'manual') {
244
244
  await this._setBool('chemistry.orp.input.source_valid', true);
@@ -277,7 +277,7 @@ const chemistryOrpHelper = {
277
277
  recommendation: measurementAllowed.recommendation,
278
278
  });
279
279
  await this._setString('chemistry.orp.debug.last_reason', reason || measurementAllowed.reason);
280
- await this._setString('chemistry.orp.debug.last_update', this._formatDateTime(now));
280
+ await this._setNumber('chemistry.orp.debug.last_update', now.getTime()); // FIX: value.time uses numeric ms timestamp.
281
281
  return;
282
282
  }
283
283
 
@@ -296,7 +296,7 @@ const chemistryOrpHelper = {
296
296
  await this._writeOutputs(value, phReference, trend, evaluation);
297
297
 
298
298
  await this._setString('chemistry.orp.debug.last_reason', reason || 'value_processed');
299
- await this._setString('chemistry.orp.debug.last_update', this._formatDateTime(now));
299
+ await this._setNumber('chemistry.orp.debug.last_update', now.getTime()); // FIX: value.time uses numeric ms timestamp.
300
300
  },
301
301
 
302
302
  async _checkMeasurementAllowed(now) {
@@ -385,22 +385,18 @@ const chemistryOrpHelper = {
385
385
 
386
386
  async _updateLastValues(value, now) {
387
387
  const lastValid = await this._readNumberOrNull('chemistry.orp.input.last_valid_value');
388
- const lastValidAt = await this._readString('chemistry.orp.input.last_valid_value_at');
388
+ const lastValidAt = await this._readTimestampOrNull('chemistry.orp.input.last_valid_value_at'); // FIX: accept numeric ms timestamps and legacy German strings.
389
389
 
390
390
  if (lastValid !== null && lastValidAt) {
391
391
  await this._setNumber('chemistry.orp.input.previous_value', lastValid);
392
- await this._setString('chemistry.orp.input.previous_value_at', lastValidAt);
392
+ await this._setNumber('chemistry.orp.input.previous_value_at', lastValidAt); // FIX: pass stored timestamp through unchanged.
393
393
 
394
- const previousDate = this._parseGermanDateTime(lastValidAt);
395
-
396
- if (previousDate) {
397
- const minutes = Math.max(0, Math.round((now.getTime() - previousDate.getTime()) / 60000));
398
- await this._setNumber('chemistry.orp.input.minutes_since_previous_value', minutes);
399
- }
394
+ const minutes = Math.max(0, Math.round((now.getTime() - lastValidAt) / 60000)); // FIX: calculate from numeric ms timestamp.
395
+ await this._setNumber('chemistry.orp.input.minutes_since_previous_value', minutes);
400
396
  }
401
397
 
402
398
  await this._setNumber('chemistry.orp.input.last_valid_value', value);
403
- await this._setString('chemistry.orp.input.last_valid_value_at', this._formatDateTime(now));
399
+ await this._setNumber('chemistry.orp.input.last_valid_value_at', now.getTime()); // FIX: value.time uses numeric ms timestamp.
404
400
  },
405
401
 
406
402
  async _updateHistory(value, now, forceSample) {
@@ -430,13 +426,15 @@ const chemistryOrpHelper = {
430
426
  await this._setNumber('chemistry.orp.history.samples_count', samples.length);
431
427
 
432
428
  if (samples.length) {
433
- await this._setString(
429
+ await this._setNumber(
430
+ // FIX: history value.time states store sample timestamps, not readable strings.
434
431
  'chemistry.orp.history.oldest_sample_at',
435
- samples[0].time || this._formatDateTime(new Date(samples[0].ts)),
432
+ Number(samples[0].ts),
436
433
  );
437
- await this._setString(
434
+ await this._setNumber(
435
+ // FIX: history value.time states store sample timestamps, not readable strings.
438
436
  'chemistry.orp.history.newest_sample_at',
439
- samples[samples.length - 1].time || this._formatDateTime(new Date(samples[samples.length - 1].ts)),
437
+ Number(samples[samples.length - 1].ts),
440
438
  );
441
439
  }
442
440
 
@@ -544,15 +542,15 @@ const chemistryOrpHelper = {
544
542
 
545
543
  async _writeTrend(trend) {
546
544
  await this._setNumber('chemistry.orp.trend.reference_24h_value', trend.ref24h ? trend.ref24h.value : 0);
547
- await this._setString('chemistry.orp.trend.reference_24h_at', trend.ref24h ? trend.ref24h.time : '');
545
+ await this._setNumber('chemistry.orp.trend.reference_24h_at', trend.ref24h ? trend.ref24h.ts : 0); // FIX
548
546
  await this._setNumber('chemistry.orp.trend.delta_24h', trend.ref24h ? trend.delta24h : 0);
549
547
 
550
548
  await this._setNumber('chemistry.orp.trend.reference_7d_value', trend.ref7d ? trend.ref7d.value : 0);
551
- await this._setString('chemistry.orp.trend.reference_7d_at', trend.ref7d ? trend.ref7d.time : '');
549
+ await this._setNumber('chemistry.orp.trend.reference_7d_at', trend.ref7d ? trend.ref7d.ts : 0); // FIX
552
550
  await this._setNumber('chemistry.orp.trend.delta_7d', trend.ref7d ? trend.delta7d : 0);
553
551
 
554
552
  await this._setNumber('chemistry.orp.trend.reference_30d_value', trend.ref30d ? trend.ref30d.value : 0);
555
- await this._setString('chemistry.orp.trend.reference_30d_at', trend.ref30d ? trend.ref30d.time : '');
553
+ await this._setNumber('chemistry.orp.trend.reference_30d_at', trend.ref30d ? trend.ref30d.ts : 0); // FIX
556
554
  await this._setNumber('chemistry.orp.trend.delta_30d', trend.ref30d ? trend.delta30d : 0);
557
555
 
558
556
  await this._setString('chemistry.orp.trend.direction', trend.direction);
@@ -692,7 +690,8 @@ const chemistryOrpHelper = {
692
690
  await this._setString('chemistry.orp.evaluation.recommendation', I18n.translate('ORP evaluation is disabled.'));
693
691
  await this._setBool('chemistry.orp.evaluation.action_required', false);
694
692
  await this._setString('chemistry.orp.debug.last_reason', reason);
695
- await this._setString('chemistry.orp.debug.last_update', this._formatDateTime(new Date()));
693
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
694
+ await this._setNumber('chemistry.orp.debug.last_update', now.getTime()); // FIX
696
695
  },
697
696
 
698
697
  async _writeInvalid(recommendation, reason) {
@@ -705,7 +704,8 @@ const chemistryOrpHelper = {
705
704
  await this._setString('chemistry.orp.evaluation.recommendation', recommendation);
706
705
  await this._setBool('chemistry.orp.evaluation.action_required', false);
707
706
  await this._setString('chemistry.orp.debug.last_reason', reason);
708
- await this._setString('chemistry.orp.debug.last_update', this._formatDateTime(new Date()));
707
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
708
+ await this._setNumber('chemistry.orp.debug.last_update', now.getTime()); // FIX
709
709
  },
710
710
 
711
711
  async _readString(id) {
@@ -725,6 +725,19 @@ const chemistryOrpHelper = {
725
725
  return Number.isFinite(value) ? value : null;
726
726
  },
727
727
 
728
+ async _readTimestampOrNull(id) {
729
+ const state = await this.adapter.getStateAsync(id);
730
+ const value = state?.val;
731
+ const numberValue = Number(value);
732
+
733
+ if (Number.isFinite(numberValue) && numberValue > 0) {
734
+ return numberValue; // FIX: numeric value.time timestamps are used directly.
735
+ }
736
+
737
+ const legacyDate = this._parseGermanDateTime(value); // FIX: keep backward compatibility for old string values.
738
+ return legacyDate ? legacyDate.getTime() : null;
739
+ },
740
+
728
741
  async _readBoolean(id) {
729
742
  const state = await this.adapter.getStateAsync(id);
730
743
  return !!state?.val;
@@ -215,7 +215,8 @@ const chemistryPhHelper = {
215
215
  await this._setBool('chemistry.ph.measurement.allowed', false);
216
216
  await this._setString('chemistry.ph.measurement.ignored_reason', 'disabled');
217
217
  await this._setString('chemistry.ph.debug.last_reason', reason || 'disabled');
218
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(new Date()));
218
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
219
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX
219
220
  return;
220
221
  }
221
222
 
@@ -234,7 +235,8 @@ const chemistryPhHelper = {
234
235
  await this._setBool('chemistry.ph.measurement.allowed', false);
235
236
  await this._setString('chemistry.ph.measurement.ignored_reason', 'source_disabled');
236
237
  await this._setString('chemistry.ph.debug.last_reason', reason || 'source_disabled');
237
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(new Date()));
238
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
239
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX
238
240
  return;
239
241
  }
240
242
 
@@ -263,7 +265,8 @@ const chemistryPhHelper = {
263
265
  await this._setBool('chemistry.ph.measurement.allowed', false);
264
266
  await this._setString('chemistry.ph.measurement.ignored_reason', 'missing_source_state');
265
267
  await this._setString('chemistry.ph.debug.last_reason', reason || 'missing_source_state');
266
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(new Date()));
268
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
269
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX
267
270
  return;
268
271
  }
269
272
 
@@ -287,7 +290,8 @@ const chemistryPhHelper = {
287
290
  await this._setBool('chemistry.ph.measurement.allowed', false);
288
291
  await this._setString('chemistry.ph.measurement.ignored_reason', 'source_read_error');
289
292
  await this._setString('chemistry.ph.debug.last_reason', `source_read_error: ${err.message}`);
290
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(new Date()));
293
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
294
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX
291
295
  return;
292
296
  }
293
297
 
@@ -307,7 +311,8 @@ const chemistryPhHelper = {
307
311
  await this._setBool('chemistry.ph.measurement.allowed', false);
308
312
  await this._setString('chemistry.ph.measurement.ignored_reason', 'source_not_found');
309
313
  await this._setString('chemistry.ph.debug.last_reason', reason || 'source_not_found');
310
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(new Date()));
314
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
315
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX
311
316
  return;
312
317
  }
313
318
 
@@ -320,7 +325,8 @@ const chemistryPhHelper = {
320
325
  await this._setBool('chemistry.ph.evaluation.action_required', false);
321
326
  await this._setString('chemistry.ph.measurement.ignored_reason', 'unknown_source_mode');
322
327
  await this._setString('chemistry.ph.debug.last_reason', reason || 'unknown_source_mode');
323
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(new Date()));
328
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
329
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX
324
330
  } catch (err) {
325
331
  this.adapter.log.warn(`[chemistryPhHelper] Evaluation failed: ${err.message}`);
326
332
  }
@@ -330,7 +336,7 @@ const chemistryPhHelper = {
330
336
  const now = new Date();
331
337
  const value = Number(rawValue);
332
338
 
333
- await this._setString('chemistry.ph.input.last_value_at', this._formatDateTime(now));
339
+ await this._setNumber('chemistry.ph.input.last_value_at', now.getTime()); // FIX: value.time uses numeric ms timestamp.
334
340
 
335
341
  if (source === 'manual') {
336
342
  await this._setBool('chemistry.ph.input.source_valid', true);
@@ -355,7 +361,7 @@ const chemistryPhHelper = {
355
361
  await this._setBool('chemistry.ph.measurement.allowed', false);
356
362
  await this._setString('chemistry.ph.measurement.ignored_reason', 'invalid_value');
357
363
  await this._setString('chemistry.ph.debug.last_reason', reason || 'invalid_value');
358
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(now));
364
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX: value.time uses numeric ms timestamp.
359
365
  return;
360
366
  }
361
367
 
@@ -368,7 +374,7 @@ const chemistryPhHelper = {
368
374
  await this._setBool('chemistry.ph.measurement.allowed', false);
369
375
  await this._setString('chemistry.ph.measurement.ignored_reason', measurementAllowed.reason);
370
376
  await this._setString('chemistry.ph.debug.last_reason', reason || measurementAllowed.reason);
371
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(now));
377
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX: value.time uses numeric ms timestamp.
372
378
  return;
373
379
  }
374
380
 
@@ -385,7 +391,7 @@ const chemistryPhHelper = {
385
391
  await this._writeOutputs(value, trend, evaluation);
386
392
 
387
393
  await this._setString('chemistry.ph.debug.last_reason', reason || 'value_processed');
388
- await this._setString('chemistry.ph.debug.last_update', this._formatDateTime(now));
394
+ await this._setNumber('chemistry.ph.debug.last_update', now.getTime()); // FIX: value.time uses numeric ms timestamp.
389
395
  },
390
396
 
391
397
  async _checkMeasurementAllowed(now) {
@@ -442,22 +448,18 @@ const chemistryPhHelper = {
442
448
 
443
449
  async _updateLastValues(value, now) {
444
450
  const lastValid = await this._readNumberOrNull('chemistry.ph.input.last_valid_value');
445
- const lastValidAt = await this._readString('chemistry.ph.input.last_valid_value_at');
451
+ const lastValidAt = await this._readTimestampOrNull('chemistry.ph.input.last_valid_value_at'); // FIX: accept numeric ms timestamps and legacy German strings.
446
452
 
447
453
  if (lastValid !== null && lastValidAt) {
448
454
  await this._setNumber('chemistry.ph.input.previous_value', lastValid);
449
- await this._setString('chemistry.ph.input.previous_value_at', lastValidAt);
455
+ await this._setNumber('chemistry.ph.input.previous_value_at', lastValidAt); // FIX: pass stored timestamp through unchanged.
450
456
 
451
- const previousDate = this._parseGermanDateTime(lastValidAt);
452
-
453
- if (previousDate) {
454
- const minutes = Math.max(0, Math.round((now.getTime() - previousDate.getTime()) / 60000));
455
- await this._setNumber('chemistry.ph.input.minutes_since_previous_value', minutes);
456
- }
457
+ const minutes = Math.max(0, Math.round((now.getTime() - lastValidAt) / 60000)); // FIX: calculate from numeric ms timestamp.
458
+ await this._setNumber('chemistry.ph.input.minutes_since_previous_value', minutes);
457
459
  }
458
460
 
459
461
  await this._setNumber('chemistry.ph.input.last_valid_value', value);
460
- await this._setString('chemistry.ph.input.last_valid_value_at', this._formatDateTime(now));
462
+ await this._setNumber('chemistry.ph.input.last_valid_value_at', now.getTime()); // FIX: value.time uses numeric ms timestamp.
461
463
  },
462
464
 
463
465
  async _updateHistory(value, now, forceSample) {
@@ -487,13 +489,15 @@ const chemistryPhHelper = {
487
489
  await this._setNumber('chemistry.ph.history.samples_count', samples.length);
488
490
 
489
491
  if (samples.length) {
490
- await this._setString(
492
+ await this._setNumber(
493
+ // FIX: history value.time states store sample timestamps, not readable strings.
491
494
  'chemistry.ph.history.oldest_sample_at',
492
- samples[0].time || this._formatDateTime(new Date(samples[0].ts)),
495
+ Number(samples[0].ts),
493
496
  );
494
- await this._setString(
497
+ await this._setNumber(
498
+ // FIX: history value.time states store sample timestamps, not readable strings.
495
499
  'chemistry.ph.history.newest_sample_at',
496
- samples[samples.length - 1].time || this._formatDateTime(new Date(samples[samples.length - 1].ts)),
500
+ Number(samples[samples.length - 1].ts),
497
501
  );
498
502
  }
499
503
 
@@ -601,15 +605,15 @@ const chemistryPhHelper = {
601
605
 
602
606
  async _writeTrend(trend) {
603
607
  await this._setNumber('chemistry.ph.trend.reference_24h_value', trend.ref24h ? trend.ref24h.value : 0);
604
- await this._setString('chemistry.ph.trend.reference_24h_at', trend.ref24h ? trend.ref24h.time : '');
608
+ await this._setNumber('chemistry.ph.trend.reference_24h_at', trend.ref24h ? trend.ref24h.ts : 0); // FIX
605
609
  await this._setNumber('chemistry.ph.trend.delta_24h', trend.ref24h ? trend.delta24h : 0);
606
610
 
607
611
  await this._setNumber('chemistry.ph.trend.reference_7d_value', trend.ref7d ? trend.ref7d.value : 0);
608
- await this._setString('chemistry.ph.trend.reference_7d_at', trend.ref7d ? trend.ref7d.time : '');
612
+ await this._setNumber('chemistry.ph.trend.reference_7d_at', trend.ref7d ? trend.ref7d.ts : 0); // FIX
609
613
  await this._setNumber('chemistry.ph.trend.delta_7d', trend.ref7d ? trend.delta7d : 0);
610
614
 
611
615
  await this._setNumber('chemistry.ph.trend.reference_30d_value', trend.ref30d ? trend.ref30d.value : 0);
612
- await this._setString('chemistry.ph.trend.reference_30d_at', trend.ref30d ? trend.ref30d.time : '');
616
+ await this._setNumber('chemistry.ph.trend.reference_30d_at', trend.ref30d ? trend.ref30d.ts : 0); // FIX
613
617
  await this._setNumber('chemistry.ph.trend.delta_30d', trend.ref30d ? trend.delta30d : 0);
614
618
 
615
619
  await this._setString('chemistry.ph.trend.direction', trend.direction);
@@ -869,6 +873,19 @@ const chemistryPhHelper = {
869
873
  return Number.isFinite(value) ? value : null;
870
874
  },
871
875
 
876
+ async _readTimestampOrNull(id) {
877
+ const state = await this.adapter.getStateAsync(id);
878
+ const value = state?.val;
879
+ const numberValue = Number(value);
880
+
881
+ if (Number.isFinite(numberValue) && numberValue > 0) {
882
+ return numberValue; // FIX: numeric value.time timestamps are used directly.
883
+ }
884
+
885
+ const legacyDate = this._parseGermanDateTime(value); // FIX: keep backward compatibility for old string values.
886
+ return legacyDate ? legacyDate.getTime() : null;
887
+ },
888
+
872
889
  async _readJsonArray(id) {
873
890
  const state = await this.adapter.getStateAsync(id);
874
891
 
@@ -246,7 +246,7 @@ const chemistryTdsHelper = {
246
246
  const now = new Date();
247
247
  const value = Number(rawValue);
248
248
 
249
- await this._setString('chemistry.tds.input.last_value_at', this._formatDateTime(now));
249
+ await this._setNumber('chemistry.tds.input.last_value_at', now.getTime()); // FIX: value.time uses numeric ms timestamp.
250
250
 
251
251
  if (source === 'manual') {
252
252
  await this._setBool('chemistry.tds.input.source_valid', true);
@@ -278,7 +278,7 @@ const chemistryTdsHelper = {
278
278
  await this._setString('chemistry.tds.evaluation.recommendation', measurementAllowed.recommendation);
279
279
  await this._setBool('chemistry.tds.evaluation.action_required', false);
280
280
  await this._setString('chemistry.tds.debug.last_reason', reason || measurementAllowed.reason);
281
- await this._setString('chemistry.tds.debug.last_update', this._formatDateTime(now));
281
+ await this._setNumber('chemistry.tds.debug.last_update', now.getTime()); // FIX: value.time uses numeric ms timestamp.
282
282
  return;
283
283
  }
284
284
 
@@ -297,7 +297,7 @@ const chemistryTdsHelper = {
297
297
  await this._writeOutputs(value, reference, trend, evaluation);
298
298
 
299
299
  await this._setString('chemistry.tds.debug.last_reason', reason || 'value_processed');
300
- await this._setString('chemistry.tds.debug.last_update', this._formatDateTime(now));
300
+ await this._setNumber('chemistry.tds.debug.last_update', now.getTime()); // FIX: value.time uses numeric ms timestamp.
301
301
  },
302
302
 
303
303
  async _checkMeasurementAllowed(now) {
@@ -357,22 +357,18 @@ const chemistryTdsHelper = {
357
357
 
358
358
  async _updateLastValues(value, now) {
359
359
  const lastValid = await this._readNumberOrNull('chemistry.tds.input.last_valid_value');
360
- const lastValidAt = await this._readString('chemistry.tds.input.last_valid_value_at');
360
+ const lastValidAt = await this._readTimestampOrNull('chemistry.tds.input.last_valid_value_at'); // FIX: accept numeric ms timestamps and legacy German strings.
361
361
 
362
362
  if (lastValid !== null && lastValidAt) {
363
363
  await this._setNumber('chemistry.tds.input.previous_value', lastValid);
364
- await this._setString('chemistry.tds.input.previous_value_at', lastValidAt);
364
+ await this._setNumber('chemistry.tds.input.previous_value_at', lastValidAt); // FIX: pass stored timestamp through unchanged.
365
365
 
366
- const previousDate = this._parseGermanDateTime(lastValidAt);
367
-
368
- if (previousDate) {
369
- const minutes = Math.max(0, Math.round((now.getTime() - previousDate.getTime()) / 60000));
370
- await this._setNumber('chemistry.tds.input.minutes_since_previous_value', minutes);
371
- }
366
+ const minutes = Math.max(0, Math.round((now.getTime() - lastValidAt) / 60000)); // FIX: calculate from numeric ms timestamp.
367
+ await this._setNumber('chemistry.tds.input.minutes_since_previous_value', minutes);
372
368
  }
373
369
 
374
370
  await this._setNumber('chemistry.tds.input.last_valid_value', value);
375
- await this._setString('chemistry.tds.input.last_valid_value_at', this._formatDateTime(now));
371
+ await this._setNumber('chemistry.tds.input.last_valid_value_at', now.getTime()); // FIX: value.time uses numeric ms timestamp.
376
372
  },
377
373
 
378
374
  async _updateHistory(value, now, forceSample) {
@@ -402,13 +398,15 @@ const chemistryTdsHelper = {
402
398
  await this._setNumber('chemistry.tds.history.samples_count', samples.length);
403
399
 
404
400
  if (samples.length) {
405
- await this._setString(
401
+ await this._setNumber(
402
+ // FIX: history value.time states store sample timestamps, not readable strings.
406
403
  'chemistry.tds.history.oldest_sample_at',
407
- samples[0].time || this._formatDateTime(new Date(samples[0].ts)),
404
+ Number(samples[0].ts),
408
405
  );
409
- await this._setString(
406
+ await this._setNumber(
407
+ // FIX: history value.time states store sample timestamps, not readable strings.
410
408
  'chemistry.tds.history.newest_sample_at',
411
- samples[samples.length - 1].time || this._formatDateTime(new Date(samples[samples.length - 1].ts)),
409
+ Number(samples[samples.length - 1].ts),
412
410
  );
413
411
  }
414
412
 
@@ -424,7 +422,7 @@ const chemistryTdsHelper = {
424
422
  initialSet = true;
425
423
 
426
424
  await this._setNumber('chemistry.tds.reference.initial_value', initialValue);
427
- await this._setString('chemistry.tds.reference.initial_value_at', this._formatDateTime(now));
425
+ await this._setNumber('chemistry.tds.reference.initial_value_at', now.getTime()); // FIX: value.time uses numeric ms timestamp.
428
426
  await this._setBool('chemistry.tds.reference.initial_set', true);
429
427
  }
430
428
 
@@ -450,11 +448,11 @@ const chemistryTdsHelper = {
450
448
  const now = new Date();
451
449
 
452
450
  await this._setNumber('chemistry.tds.reference.initial_value', currentValue);
453
- await this._setString('chemistry.tds.reference.initial_value_at', this._formatDateTime(now));
451
+ await this._setNumber('chemistry.tds.reference.initial_value_at', now.getTime()); // FIX: value.time uses numeric ms timestamp.
454
452
  await this._setBool('chemistry.tds.reference.initial_set', true);
455
453
  await this._setNumber('chemistry.tds.reference.delta_since_initial', 0);
456
454
  await this._setString('chemistry.tds.debug.last_reason', 'reference_reset');
457
- await this._setString('chemistry.tds.debug.last_update', this._formatDateTime(now));
455
+ await this._setNumber('chemistry.tds.debug.last_update', now.getTime()); // FIX: value.time uses numeric ms timestamp.
458
456
 
459
457
  this._scheduleEvaluation('reference_reset', 500);
460
458
  },
@@ -560,15 +558,15 @@ const chemistryTdsHelper = {
560
558
 
561
559
  async _writeTrend(trend) {
562
560
  await this._setNumber('chemistry.tds.trend.reference_24h_value', trend.ref24h ? trend.ref24h.value : 0);
563
- await this._setString('chemistry.tds.trend.reference_24h_at', trend.ref24h ? trend.ref24h.time : '');
561
+ await this._setNumber('chemistry.tds.trend.reference_24h_at', trend.ref24h ? trend.ref24h.ts : 0); // FIX
564
562
  await this._setNumber('chemistry.tds.trend.delta_24h', trend.ref24h ? trend.delta24h : 0);
565
563
 
566
564
  await this._setNumber('chemistry.tds.trend.reference_7d_value', trend.ref7d ? trend.ref7d.value : 0);
567
- await this._setString('chemistry.tds.trend.reference_7d_at', trend.ref7d ? trend.ref7d.time : '');
565
+ await this._setNumber('chemistry.tds.trend.reference_7d_at', trend.ref7d ? trend.ref7d.ts : 0); // FIX
568
566
  await this._setNumber('chemistry.tds.trend.delta_7d', trend.ref7d ? trend.delta7d : 0);
569
567
 
570
568
  await this._setNumber('chemistry.tds.trend.reference_30d_value', trend.ref30d ? trend.ref30d.value : 0);
571
- await this._setString('chemistry.tds.trend.reference_30d_at', trend.ref30d ? trend.ref30d.time : '');
569
+ await this._setNumber('chemistry.tds.trend.reference_30d_at', trend.ref30d ? trend.ref30d.ts : 0); // FIX
572
570
  await this._setNumber('chemistry.tds.trend.delta_30d', trend.ref30d ? trend.delta30d : 0);
573
571
 
574
572
  await this._setString('chemistry.tds.trend.direction', trend.direction);
@@ -718,7 +716,8 @@ const chemistryTdsHelper = {
718
716
  await this._setString('chemistry.tds.evaluation.recommendation', I18n.translate('TDS evaluation is disabled.'));
719
717
  await this._setBool('chemistry.tds.evaluation.action_required', false);
720
718
  await this._setString('chemistry.tds.debug.last_reason', reason);
721
- await this._setString('chemistry.tds.debug.last_update', this._formatDateTime(new Date()));
719
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
720
+ await this._setNumber('chemistry.tds.debug.last_update', now.getTime()); // FIX
722
721
  },
723
722
 
724
723
  async _writeInvalid(recommendation, reason) {
@@ -730,7 +729,8 @@ const chemistryTdsHelper = {
730
729
  await this._setString('chemistry.tds.evaluation.recommendation', recommendation);
731
730
  await this._setBool('chemistry.tds.evaluation.action_required', false);
732
731
  await this._setString('chemistry.tds.debug.last_reason', reason);
733
- await this._setString('chemistry.tds.debug.last_update', this._formatDateTime(new Date()));
732
+ const now = new Date(); // FIX: write value.time as numeric Unix timestamp in milliseconds.
733
+ await this._setNumber('chemistry.tds.debug.last_update', now.getTime()); // FIX
734
734
  },
735
735
 
736
736
  async _readString(id) {
@@ -750,6 +750,19 @@ const chemistryTdsHelper = {
750
750
  return Number.isFinite(value) ? value : null;
751
751
  },
752
752
 
753
+ async _readTimestampOrNull(id) {
754
+ const state = await this.adapter.getStateAsync(id);
755
+ const value = state?.val;
756
+ const numberValue = Number(value);
757
+
758
+ if (Number.isFinite(numberValue) && numberValue > 0) {
759
+ return numberValue; // FIX: numeric value.time timestamps are used directly.
760
+ }
761
+
762
+ const legacyDate = this._parseGermanDateTime(value); // FIX: keep backward compatibility for old string values.
763
+ return legacyDate ? legacyDate.getTime() : null;
764
+ },
765
+
753
766
  async _readBoolean(id) {
754
767
  const state = await this.adapter.getStateAsync(id);
755
768
  return !!state?.val;
@@ -214,11 +214,11 @@ async function createChemistryOrpStates(adapter) {
214
214
  en: 'Readable date and time when the last ORP value was received.',
215
215
  de: 'Lesbares Datum und Uhrzeit, wann der letzte ORP-Wert empfangen wurde.',
216
216
  },
217
- type: 'string',
217
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
218
218
  role: 'value.time',
219
219
  read: true,
220
220
  write: false,
221
- def: '',
221
+ def: 0, // FIX: numeric timestamp default for value.time.
222
222
  persist: true,
223
223
  });
224
224
 
@@ -251,11 +251,11 @@ async function createChemistryOrpStates(adapter) {
251
251
  en: 'Readable date and time of the last valid ORP value.',
252
252
  de: 'Lesbares Datum und Uhrzeit des letzten gültigen ORP-Werts.',
253
253
  },
254
- type: 'string',
254
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
255
255
  role: 'value.time',
256
256
  read: true,
257
257
  write: false,
258
- def: '',
258
+ def: 0, // FIX: numeric timestamp default for value.time.
259
259
  persist: true,
260
260
  });
261
261
 
@@ -288,11 +288,11 @@ async function createChemistryOrpStates(adapter) {
288
288
  en: 'Readable date and time of the previous valid ORP value.',
289
289
  de: 'Lesbares Datum und Uhrzeit des vorherigen gültigen ORP-Werts.',
290
290
  },
291
- type: 'string',
291
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
292
292
  role: 'value.time',
293
293
  read: true,
294
294
  write: false,
295
- def: '',
295
+ def: 0, // FIX: numeric timestamp default for value.time.
296
296
  persist: true,
297
297
  });
298
298
 
@@ -685,11 +685,11 @@ async function createChemistryOrpStates(adapter) {
685
685
  en: 'Readable timestamp of the 24h ORP reference value.',
686
686
  de: 'Lesbarer Zeitstempel des 24h-ORP-Referenzwerts.',
687
687
  },
688
- type: 'string',
688
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
689
689
  role: 'value.time',
690
690
  read: true,
691
691
  write: false,
692
- def: '',
692
+ def: 0, // FIX: numeric timestamp default for value.time.
693
693
  persist: true,
694
694
  });
695
695
 
@@ -738,11 +738,11 @@ async function createChemistryOrpStates(adapter) {
738
738
  en: 'Readable timestamp of the 7 day ORP reference value.',
739
739
  de: 'Lesbarer Zeitstempel des 7-Tage-ORP-Referenzwerts.',
740
740
  },
741
- type: 'string',
741
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
742
742
  role: 'value.time',
743
743
  read: true,
744
744
  write: false,
745
- def: '',
745
+ def: 0, // FIX: numeric timestamp default for value.time.
746
746
  persist: true,
747
747
  });
748
748
 
@@ -791,11 +791,11 @@ async function createChemistryOrpStates(adapter) {
791
791
  en: 'Readable timestamp of the 30 day ORP reference value.',
792
792
  de: 'Lesbarer Zeitstempel des 30-Tage-ORP-Referenzwerts.',
793
793
  },
794
- type: 'string',
794
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
795
795
  role: 'value.time',
796
796
  read: true,
797
797
  write: false,
798
- def: '',
798
+ def: 0, // FIX: numeric timestamp default for value.time.
799
799
  persist: true,
800
800
  });
801
801
 
@@ -934,11 +934,11 @@ async function createChemistryOrpStates(adapter) {
934
934
  en: 'Readable timestamp of the oldest stored ORP sample.',
935
935
  de: 'Lesbarer Zeitstempel des ältesten gespeicherten ORP-Messwerts.',
936
936
  },
937
- type: 'string',
937
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
938
938
  role: 'value.time',
939
939
  read: true,
940
940
  write: false,
941
- def: '',
941
+ def: 0, // FIX: numeric timestamp default for value.time.
942
942
  persist: true,
943
943
  });
944
944
 
@@ -951,11 +951,11 @@ async function createChemistryOrpStates(adapter) {
951
951
  en: 'Readable timestamp of the newest stored ORP sample.',
952
952
  de: 'Lesbarer Zeitstempel des neuesten gespeicherten ORP-Messwerts.',
953
953
  },
954
- type: 'string',
954
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
955
955
  role: 'value.time',
956
956
  read: true,
957
957
  write: false,
958
- def: '',
958
+ def: 0, // FIX: numeric timestamp default for value.time.
959
959
  persist: true,
960
960
  });
961
961
 
@@ -1035,11 +1035,11 @@ async function createChemistryOrpStates(adapter) {
1035
1035
  en: 'Readable timestamp of the last ORP evaluation update.',
1036
1036
  de: 'Lesbarer Zeitstempel der letzten ORP-Auswertung.',
1037
1037
  },
1038
- type: 'string',
1038
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
1039
1039
  role: 'value.time',
1040
1040
  read: true,
1041
1041
  write: false,
1042
- def: '',
1042
+ def: 0, // FIX: numeric timestamp default for value.time.
1043
1043
  persist: true,
1044
1044
  });
1045
1045
 
@@ -209,11 +209,11 @@ async function createChemistryPhStates(adapter) {
209
209
  en: 'Readable date and time when the last pH value was received.',
210
210
  de: 'Lesbares Datum und Uhrzeit, wann der letzte pH-Wert empfangen wurde.',
211
211
  },
212
- type: 'string',
212
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
213
213
  role: 'value.time',
214
214
  read: true,
215
215
  write: false,
216
- def: '',
216
+ def: 0, // FIX: numeric timestamp default for value.time.
217
217
  persist: true,
218
218
  });
219
219
 
@@ -245,11 +245,11 @@ async function createChemistryPhStates(adapter) {
245
245
  en: 'Readable date and time of the last valid pH value.',
246
246
  de: 'Lesbares Datum und Uhrzeit des letzten gültigen pH-Werts.',
247
247
  },
248
- type: 'string',
248
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
249
249
  role: 'value.time',
250
250
  read: true,
251
251
  write: false,
252
- def: '',
252
+ def: 0, // FIX: numeric timestamp default for value.time.
253
253
  persist: true,
254
254
  });
255
255
 
@@ -281,11 +281,11 @@ async function createChemistryPhStates(adapter) {
281
281
  en: 'Readable date and time of the previous valid pH value.',
282
282
  de: 'Lesbares Datum und Uhrzeit des vorherigen gültigen pH-Werts.',
283
283
  },
284
- type: 'string',
284
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
285
285
  role: 'value.time',
286
286
  read: true,
287
287
  write: false,
288
- def: '',
288
+ def: 0, // FIX: numeric timestamp default for value.time.
289
289
  persist: true,
290
290
  });
291
291
 
@@ -698,11 +698,11 @@ async function createChemistryPhStates(adapter) {
698
698
  en: 'Oldest sample time',
699
699
  de: 'Ältester Messwert',
700
700
  },
701
- type: 'string',
701
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
702
702
  role: 'value.time',
703
703
  read: true,
704
704
  write: false,
705
- def: '',
705
+ def: 0, // FIX: numeric timestamp default for value.time.
706
706
  persist: true,
707
707
  });
708
708
 
@@ -711,11 +711,11 @@ async function createChemistryPhStates(adapter) {
711
711
  en: 'Newest sample time',
712
712
  de: 'Neuester Messwert',
713
713
  },
714
- type: 'string',
714
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
715
715
  role: 'value.time',
716
716
  read: true,
717
717
  write: false,
718
- def: '',
718
+ def: 0, // FIX: numeric timestamp default for value.time.
719
719
  persist: true,
720
720
  });
721
721
 
@@ -763,11 +763,11 @@ async function createChemistryPhStates(adapter) {
763
763
  en: enName,
764
764
  de: deName,
765
765
  },
766
- type: 'string',
766
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
767
767
  role: 'value.time',
768
768
  read: true,
769
769
  write: false,
770
- def: '',
770
+ def: 0, // FIX: numeric timestamp default for value.time.
771
771
  persist: true,
772
772
  });
773
773
  }
@@ -882,11 +882,11 @@ async function createChemistryPhStates(adapter) {
882
882
  en: 'Readable timestamp of the last pH evaluation update.',
883
883
  de: 'Lesbarer Zeitstempel der letzten pH-Auswertung.',
884
884
  },
885
- type: 'string',
885
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
886
886
  role: 'value.time',
887
887
  read: true,
888
888
  write: false,
889
- def: '',
889
+ def: 0, // FIX: numeric timestamp default for value.time.
890
890
  persist: true,
891
891
  });
892
892
 
@@ -211,11 +211,11 @@ async function createChemistryTdsStates(adapter) {
211
211
  en: 'Readable date and time when the last TDS value was received.',
212
212
  de: 'Lesbares Datum und Uhrzeit, wann der letzte TDS-Wert empfangen wurde.',
213
213
  },
214
- type: 'string',
214
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
215
215
  role: 'value.time',
216
216
  read: true,
217
217
  write: false,
218
- def: '',
218
+ def: 0, // FIX: numeric timestamp default for value.time.
219
219
  persist: true,
220
220
  });
221
221
 
@@ -247,11 +247,11 @@ async function createChemistryTdsStates(adapter) {
247
247
  en: 'Readable date and time of the last valid TDS value.',
248
248
  de: 'Lesbares Datum und Uhrzeit des letzten gültigen TDS-Werts.',
249
249
  },
250
- type: 'string',
250
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
251
251
  role: 'value.time',
252
252
  read: true,
253
253
  write: false,
254
- def: '',
254
+ def: 0, // FIX: numeric timestamp default for value.time.
255
255
  persist: true,
256
256
  });
257
257
 
@@ -283,11 +283,11 @@ async function createChemistryTdsStates(adapter) {
283
283
  en: 'Readable date and time of the previous valid TDS value.',
284
284
  de: 'Lesbares Datum und Uhrzeit des vorherigen gültigen TDS-Werts.',
285
285
  },
286
- type: 'string',
286
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
287
287
  role: 'value.time',
288
288
  read: true,
289
289
  write: false,
290
- def: '',
290
+ def: 0, // FIX: numeric timestamp default for value.time.
291
291
  persist: true,
292
292
  });
293
293
 
@@ -480,11 +480,11 @@ async function createChemistryTdsStates(adapter) {
480
480
  en: 'Readable date and time when the initial reference value was set.',
481
481
  de: 'Lesbares Datum und Uhrzeit, wann der Referenzwert gesetzt wurde.',
482
482
  },
483
- type: 'string',
483
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
484
484
  role: 'value.time',
485
485
  read: true,
486
486
  write: false,
487
- def: '',
487
+ def: 0, // FIX: numeric timestamp default for value.time.
488
488
  persist: true,
489
489
  });
490
490
 
@@ -584,11 +584,11 @@ async function createChemistryTdsStates(adapter) {
584
584
  en: enName,
585
585
  de: deName,
586
586
  },
587
- type: 'string',
587
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
588
588
  role: 'value.time',
589
589
  read: true,
590
590
  write: false,
591
- def: '',
591
+ def: 0, // FIX: numeric timestamp default for value.time.
592
592
  persist: true,
593
593
  });
594
594
  }
@@ -767,11 +767,11 @@ async function createChemistryTdsStates(adapter) {
767
767
  en: 'Oldest sample time',
768
768
  de: 'Ältester Messwert',
769
769
  },
770
- type: 'string',
770
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
771
771
  role: 'value.time',
772
772
  read: true,
773
773
  write: false,
774
- def: '',
774
+ def: 0, // FIX: numeric timestamp default for value.time.
775
775
  persist: true,
776
776
  });
777
777
 
@@ -780,11 +780,11 @@ async function createChemistryTdsStates(adapter) {
780
780
  en: 'Newest sample time',
781
781
  de: 'Neuester Messwert',
782
782
  },
783
- type: 'string',
783
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
784
784
  role: 'value.time',
785
785
  read: true,
786
786
  write: false,
787
- def: '',
787
+ def: 0, // FIX: numeric timestamp default for value.time.
788
788
  persist: true,
789
789
  });
790
790
 
@@ -860,11 +860,11 @@ async function createChemistryTdsStates(adapter) {
860
860
  en: 'Last update',
861
861
  de: 'Letzte Aktualisierung',
862
862
  },
863
- type: 'string',
863
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
864
864
  role: 'value.time',
865
865
  read: true,
866
866
  write: false,
867
- def: '',
867
+ def: 0, // FIX: numeric timestamp default for value.time.
868
868
  persist: true,
869
869
  });
870
870
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.poolcontrol",
3
- "version": "1.3.17",
3
+ "version": "1.3.18",
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",