iobroker.poolcontrol 1.3.15 → 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.
@@ -0,0 +1,1068 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * chemistryOrpStates.js
5
+ * -------------------------------------------------------------
6
+ * States for the ORP / Redox evaluation area.
7
+ *
8
+ * Scope:
9
+ * - ORP input via manual value or external ioBroker state
10
+ * - Measurement location handling
11
+ * - pH reference display from existing pH evaluation states
12
+ * - ORP evaluation and recommendation states
13
+ * - Text, HTML and JSON output states
14
+ *
15
+ * No automatic dosing.
16
+ * No automatic chlorine control.
17
+ * No automatic pump or actuator control based on ORP.
18
+ * -------------------------------------------------------------
19
+ */
20
+
21
+ async function createChannel(adapter, id, name) {
22
+ await adapter.setObjectNotExistsAsync(id, {
23
+ type: 'channel',
24
+ common: { name },
25
+ native: {},
26
+ });
27
+ }
28
+
29
+ async function createState(adapter, id, common) {
30
+ await adapter.setObjectNotExistsAsync(id, {
31
+ type: 'state',
32
+ common,
33
+ native: {},
34
+ });
35
+ }
36
+
37
+ /**
38
+ * @param {import('iobroker').Adapter} adapter - ioBroker adapter instance
39
+ */
40
+ async function createChemistryOrpStates(adapter) {
41
+ adapter.log.debug('[chemistryOrpStates] Initialization started');
42
+
43
+ await createChannel(adapter, 'chemistry', {
44
+ en: 'Chemistry',
45
+ de: 'Chemie',
46
+ });
47
+
48
+ await createChannel(adapter, 'chemistry.orp', {
49
+ en: 'ORP / Redox evaluation',
50
+ de: 'ORP-/Redox-Auswertung',
51
+ });
52
+
53
+ await createState(adapter, 'chemistry.orp.enabled', {
54
+ name: {
55
+ en: 'Enable ORP / Redox evaluation',
56
+ de: 'ORP-/Redox-Auswertung aktivieren',
57
+ },
58
+ desc: {
59
+ en: 'Enables the ORP / Redox evaluation. No automatic dosing or chlorine control is performed.',
60
+ de: 'Aktiviert die ORP-/Redox-Auswertung. Es erfolgt keine automatische Dosierung oder Chlorsteuerung.',
61
+ },
62
+ type: 'boolean',
63
+ role: 'switch',
64
+ read: true,
65
+ write: true,
66
+ def: false,
67
+ persist: true,
68
+ });
69
+
70
+ // -------------------------------------------------------------
71
+ // Input
72
+ // -------------------------------------------------------------
73
+ await createChannel(adapter, 'chemistry.orp.input', {
74
+ en: 'Input',
75
+ de: 'Eingang',
76
+ });
77
+
78
+ await createState(adapter, 'chemistry.orp.input.source_mode', {
79
+ name: {
80
+ en: 'Source mode',
81
+ de: 'Quellenmodus',
82
+ },
83
+ desc: {
84
+ en: 'Defines how the ORP / Redox value is provided.',
85
+ de: 'Legt fest, wie der ORP-/Redox-Wert bereitgestellt wird.',
86
+ },
87
+ type: 'string',
88
+ role: 'level',
89
+ read: true,
90
+ write: true,
91
+ def: 'disabled',
92
+ states: {
93
+ disabled: 'disabled',
94
+ manual: 'manual',
95
+ state: 'state',
96
+ },
97
+ persist: true,
98
+ });
99
+
100
+ await createState(adapter, 'chemistry.orp.input.source_state_id', {
101
+ name: {
102
+ en: 'Source state ID',
103
+ de: 'Quell-Datenpunkt',
104
+ },
105
+ desc: {
106
+ en: 'External ioBroker state ID that provides the ORP / Redox value in mV.',
107
+ de: 'Externer ioBroker-Datenpunkt, der den ORP-/Redox-Wert in mV liefert.',
108
+ },
109
+ type: 'string',
110
+ role: 'text',
111
+ read: true,
112
+ write: true,
113
+ def: '',
114
+ persist: true,
115
+ });
116
+
117
+ await createState(adapter, 'chemistry.orp.input.manual_value', {
118
+ name: {
119
+ en: 'Manual ORP value',
120
+ de: 'Manueller ORP-Wert',
121
+ },
122
+ desc: {
123
+ en: 'Manually entered ORP / Redox value in millivolts.',
124
+ de: 'Manuell eingetragener ORP-/Redox-Wert in Millivolt.',
125
+ },
126
+ type: 'number',
127
+ role: 'value',
128
+ read: true,
129
+ write: true,
130
+ def: 650,
131
+ min: 0,
132
+ max: 1200,
133
+ unit: 'mV',
134
+ persist: true,
135
+ });
136
+
137
+ await createState(adapter, 'chemistry.orp.input.current_value', {
138
+ name: {
139
+ en: 'Current ORP value',
140
+ de: 'Aktueller ORP-Wert',
141
+ },
142
+ desc: {
143
+ en: 'Current ORP / Redox value used or received by PoolControl.',
144
+ de: 'Aktueller von PoolControl verwendeter oder empfangener ORP-/Redox-Wert.',
145
+ },
146
+ type: 'number',
147
+ role: 'value',
148
+ read: true,
149
+ write: false,
150
+ def: 0,
151
+ min: 0,
152
+ max: 1200,
153
+ unit: 'mV',
154
+ persist: true,
155
+ });
156
+
157
+ await createState(adapter, 'chemistry.orp.input.source_valid', {
158
+ name: {
159
+ en: 'Source valid',
160
+ de: 'Quelle gültig',
161
+ },
162
+ desc: {
163
+ en: 'Shows whether the configured ORP source exists and can be used.',
164
+ de: 'Zeigt an, ob die konfigurierte ORP-Quelle existiert und genutzt werden kann.',
165
+ },
166
+ type: 'boolean',
167
+ role: 'indicator',
168
+ read: true,
169
+ write: false,
170
+ def: false,
171
+ persist: true,
172
+ });
173
+
174
+ await createState(adapter, 'chemistry.orp.input.value_valid', {
175
+ name: {
176
+ en: 'Value valid',
177
+ de: 'Wert gültig',
178
+ },
179
+ desc: {
180
+ en: 'Shows whether the current ORP value is plausible.',
181
+ de: 'Zeigt an, ob der aktuelle ORP-Wert plausibel ist.',
182
+ },
183
+ type: 'boolean',
184
+ role: 'indicator',
185
+ read: true,
186
+ write: false,
187
+ def: false,
188
+ persist: true,
189
+ });
190
+
191
+ await createState(adapter, 'chemistry.orp.input.source_status', {
192
+ name: {
193
+ en: 'Source status',
194
+ de: 'Quellenstatus',
195
+ },
196
+ desc: {
197
+ en: 'Readable status of the ORP input source.',
198
+ de: 'Lesbarer Status der ORP-Eingangsquelle.',
199
+ },
200
+ type: 'string',
201
+ role: 'text',
202
+ read: true,
203
+ write: false,
204
+ def: '',
205
+ persist: true,
206
+ });
207
+
208
+ await createState(adapter, 'chemistry.orp.input.last_value_at', {
209
+ name: {
210
+ en: 'Last value time',
211
+ de: 'Zeitpunkt des letzten Werts',
212
+ },
213
+ desc: {
214
+ en: 'Readable date and time when the last ORP value was received.',
215
+ de: 'Lesbares Datum und Uhrzeit, wann der letzte ORP-Wert empfangen wurde.',
216
+ },
217
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
218
+ role: 'value.time',
219
+ read: true,
220
+ write: false,
221
+ def: 0, // FIX: numeric timestamp default for value.time.
222
+ persist: true,
223
+ });
224
+
225
+ await createState(adapter, 'chemistry.orp.input.last_valid_value', {
226
+ name: {
227
+ en: 'Last valid ORP value',
228
+ de: 'Letzter gültiger ORP-Wert',
229
+ },
230
+ desc: {
231
+ en: 'Last valid and plausible ORP value.',
232
+ de: 'Letzter gültiger und plausibler ORP-Wert.',
233
+ },
234
+ type: 'number',
235
+ role: 'value',
236
+ read: true,
237
+ write: false,
238
+ def: 0,
239
+ min: 0,
240
+ max: 1200,
241
+ unit: 'mV',
242
+ persist: true,
243
+ });
244
+
245
+ await createState(adapter, 'chemistry.orp.input.last_valid_value_at', {
246
+ name: {
247
+ en: 'Last valid value time',
248
+ de: 'Zeitpunkt des letzten gültigen Werts',
249
+ },
250
+ desc: {
251
+ en: 'Readable date and time of the last valid ORP value.',
252
+ de: 'Lesbares Datum und Uhrzeit des letzten gültigen ORP-Werts.',
253
+ },
254
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
255
+ role: 'value.time',
256
+ read: true,
257
+ write: false,
258
+ def: 0, // FIX: numeric timestamp default for value.time.
259
+ persist: true,
260
+ });
261
+
262
+ await createState(adapter, 'chemistry.orp.input.previous_value', {
263
+ name: {
264
+ en: 'Previous valid ORP value',
265
+ de: 'Vorheriger gültiger ORP-Wert',
266
+ },
267
+ desc: {
268
+ en: 'Valid ORP value before the latest valid value.',
269
+ de: 'Gültiger ORP-Wert vor dem letzten gültigen Wert.',
270
+ },
271
+ type: 'number',
272
+ role: 'value',
273
+ read: true,
274
+ write: false,
275
+ def: 0,
276
+ min: 0,
277
+ max: 1200,
278
+ unit: 'mV',
279
+ persist: true,
280
+ });
281
+
282
+ await createState(adapter, 'chemistry.orp.input.previous_value_at', {
283
+ name: {
284
+ en: 'Previous valid value time',
285
+ de: 'Zeitpunkt des vorherigen gültigen Werts',
286
+ },
287
+ desc: {
288
+ en: 'Readable date and time of the previous valid ORP value.',
289
+ de: 'Lesbares Datum und Uhrzeit des vorherigen gültigen ORP-Werts.',
290
+ },
291
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
292
+ role: 'value.time',
293
+ read: true,
294
+ write: false,
295
+ def: 0, // FIX: numeric timestamp default for value.time.
296
+ persist: true,
297
+ });
298
+
299
+ await createState(adapter, 'chemistry.orp.input.minutes_since_previous_value', {
300
+ name: {
301
+ en: 'Minutes since previous value',
302
+ de: 'Minuten seit vorherigem Wert',
303
+ },
304
+ desc: {
305
+ en: 'Time difference between the last two valid ORP values.',
306
+ de: 'Zeitdifferenz zwischen den letzten beiden gültigen ORP-Werten.',
307
+ },
308
+ type: 'number',
309
+ role: 'value',
310
+ read: true,
311
+ write: false,
312
+ def: 0,
313
+ unit: 'min',
314
+ persist: true,
315
+ });
316
+
317
+ // -------------------------------------------------------------
318
+ // pH reference
319
+ // -------------------------------------------------------------
320
+ await createChannel(adapter, 'chemistry.orp.ph_reference', {
321
+ en: 'pH reference',
322
+ de: 'pH-Referenz',
323
+ });
324
+
325
+ await createState(adapter, 'chemistry.orp.ph_reference.enabled', {
326
+ name: {
327
+ en: 'pH evaluation enabled',
328
+ de: 'pH-Auswertung aktiv',
329
+ },
330
+ desc: {
331
+ en: 'Read-only reference showing whether the existing pH evaluation is enabled.',
332
+ de: 'Schreibgeschützte Referenz, ob die bestehende pH-Auswertung aktiv ist.',
333
+ },
334
+ type: 'boolean',
335
+ role: 'indicator',
336
+ read: true,
337
+ write: false,
338
+ def: false,
339
+ persist: true,
340
+ });
341
+
342
+ await createState(adapter, 'chemistry.orp.ph_reference.current_value', {
343
+ name: {
344
+ en: 'Current pH reference value',
345
+ de: 'Aktueller pH-Referenzwert',
346
+ },
347
+ desc: {
348
+ en: 'Read-only reference value from chemistry.ph.input.current_value.',
349
+ de: 'Schreibgeschützter Referenzwert aus chemistry.ph.input.current_value.',
350
+ },
351
+ type: 'number',
352
+ role: 'value',
353
+ read: true,
354
+ write: false,
355
+ def: 0,
356
+ min: 0,
357
+ max: 14,
358
+ persist: true,
359
+ });
360
+
361
+ await createState(adapter, 'chemistry.orp.ph_reference.status', {
362
+ name: {
363
+ en: 'pH reference status',
364
+ de: 'pH-Referenzstatus',
365
+ },
366
+ desc: {
367
+ en: 'Shows whether the pH reference can be used for ORP interpretation.',
368
+ de: 'Zeigt an, ob die pH-Referenz für die ORP-Einordnung nutzbar ist.',
369
+ },
370
+ type: 'string',
371
+ role: 'text',
372
+ read: true,
373
+ write: false,
374
+ def: 'unknown',
375
+ states: {
376
+ unknown: 'unknown',
377
+ disabled: 'disabled',
378
+ missing: 'missing',
379
+ out_of_range: 'out_of_range',
380
+ valid: 'valid',
381
+ },
382
+ persist: true,
383
+ });
384
+
385
+ // -------------------------------------------------------------
386
+ // Measurement
387
+ // -------------------------------------------------------------
388
+ await createChannel(adapter, 'chemistry.orp.measurement', {
389
+ en: 'Measurement',
390
+ de: 'Messung',
391
+ });
392
+
393
+ await createState(adapter, 'chemistry.orp.measurement.location', {
394
+ name: {
395
+ en: 'Measurement location',
396
+ de: 'Messort',
397
+ },
398
+ desc: {
399
+ en: 'Defines where the ORP value is measured.',
400
+ de: 'Legt fest, wo der ORP-Wert gemessen wird.',
401
+ },
402
+ type: 'string',
403
+ role: 'level',
404
+ read: true,
405
+ write: true,
406
+ def: 'manual',
407
+ states: {
408
+ manual: 'manual',
409
+ pool: 'pool',
410
+ measurement_cell: 'measurement_cell',
411
+ pipe_section: 'pipe_section',
412
+ },
413
+ persist: true,
414
+ });
415
+
416
+ await createState(adapter, 'chemistry.orp.measurement.flow_required', {
417
+ name: {
418
+ en: 'Flow required',
419
+ de: 'Durchfluss erforderlich',
420
+ },
421
+ desc: {
422
+ en: 'If enabled, ORP values are only evaluated when the pool pump is running.',
423
+ de: 'Wenn aktiv, werden ORP-Werte nur bei laufender Poolpumpe ausgewertet.',
424
+ },
425
+ type: 'boolean',
426
+ role: 'switch',
427
+ read: true,
428
+ write: true,
429
+ def: false,
430
+ persist: true,
431
+ });
432
+
433
+ await createState(adapter, 'chemistry.orp.measurement.stabilization_time_sec', {
434
+ name: {
435
+ en: 'Stabilization time',
436
+ de: 'Stabilisierungszeit',
437
+ },
438
+ desc: {
439
+ en: 'Delay after pump start before ORP values from a measurement section are evaluated.',
440
+ de: 'Wartezeit nach Pumpenstart, bevor ORP-Werte aus einer Messstrecke ausgewertet werden.',
441
+ },
442
+ type: 'number',
443
+ role: 'level',
444
+ read: true,
445
+ write: true,
446
+ def: 120,
447
+ min: 0,
448
+ unit: 's',
449
+ persist: true,
450
+ });
451
+
452
+ await createState(adapter, 'chemistry.orp.measurement.pump_running', {
453
+ name: {
454
+ en: 'Pump running',
455
+ de: 'Pumpe läuft',
456
+ },
457
+ desc: {
458
+ en: 'Shows whether the pool pump is currently detected as running.',
459
+ de: 'Zeigt an, ob die Poolpumpe aktuell als laufend erkannt wird.',
460
+ },
461
+ type: 'boolean',
462
+ role: 'indicator',
463
+ read: true,
464
+ write: false,
465
+ def: false,
466
+ persist: true,
467
+ });
468
+
469
+ await createState(adapter, 'chemistry.orp.measurement.stabilized', {
470
+ name: {
471
+ en: 'Measurement stabilized',
472
+ de: 'Messung stabilisiert',
473
+ },
474
+ desc: {
475
+ en: 'Shows whether the stabilization time after pump start has elapsed.',
476
+ de: 'Zeigt an, ob die Stabilisierungszeit nach Pumpenstart abgelaufen ist.',
477
+ },
478
+ type: 'boolean',
479
+ role: 'indicator',
480
+ read: true,
481
+ write: false,
482
+ def: false,
483
+ persist: true,
484
+ });
485
+
486
+ await createState(adapter, 'chemistry.orp.measurement.allowed', {
487
+ name: {
488
+ en: 'Measurement allowed',
489
+ de: 'Messung erlaubt',
490
+ },
491
+ desc: {
492
+ en: 'Shows whether ORP values are currently allowed to be evaluated.',
493
+ de: 'Zeigt an, ob ORP-Werte aktuell ausgewertet werden dürfen.',
494
+ },
495
+ type: 'boolean',
496
+ role: 'indicator',
497
+ read: true,
498
+ write: false,
499
+ def: false,
500
+ persist: true,
501
+ });
502
+
503
+ await createState(adapter, 'chemistry.orp.measurement.ignored_reason', {
504
+ name: {
505
+ en: 'Ignored reason',
506
+ de: 'Ignorierter Grund',
507
+ },
508
+ desc: {
509
+ en: 'Reason why the current ORP value is not evaluated.',
510
+ de: 'Grund, warum der aktuelle ORP-Wert nicht ausgewertet wird.',
511
+ },
512
+ type: 'string',
513
+ role: 'text',
514
+ read: true,
515
+ write: false,
516
+ def: '',
517
+ persist: true,
518
+ });
519
+
520
+ // -------------------------------------------------------------
521
+ // Evaluation
522
+ // -------------------------------------------------------------
523
+ await createChannel(adapter, 'chemistry.orp.evaluation', {
524
+ en: 'Evaluation',
525
+ de: 'Auswertung',
526
+ });
527
+
528
+ await createState(adapter, 'chemistry.orp.evaluation.target_min_mv', {
529
+ name: {
530
+ en: 'Target minimum',
531
+ de: 'Zielwert Minimum',
532
+ },
533
+ desc: {
534
+ en: 'Lower ORP reference limit in millivolts. This is only used for cautious evaluation hints.',
535
+ de: 'Untere ORP-Referenzgrenze in Millivolt. Diese wird nur für vorsichtige Bewertungshinweise genutzt.',
536
+ },
537
+ type: 'number',
538
+ role: 'level',
539
+ read: true,
540
+ write: true,
541
+ def: 650,
542
+ min: 0,
543
+ max: 1200,
544
+ unit: 'mV',
545
+ persist: true,
546
+ });
547
+
548
+ await createState(adapter, 'chemistry.orp.evaluation.target_max_mv', {
549
+ name: {
550
+ en: 'Target maximum',
551
+ de: 'Zielwert Maximum',
552
+ },
553
+ desc: {
554
+ en: 'Upper ORP reference limit in millivolts. This is only used for cautious evaluation hints.',
555
+ de: 'Obere ORP-Referenzgrenze in Millivolt. Diese wird nur für vorsichtige Bewertungshinweise genutzt.',
556
+ },
557
+ type: 'number',
558
+ role: 'level',
559
+ read: true,
560
+ write: true,
561
+ def: 800,
562
+ min: 0,
563
+ max: 1200,
564
+ unit: 'mV',
565
+ persist: true,
566
+ });
567
+
568
+ await createState(adapter, 'chemistry.orp.evaluation.status', {
569
+ name: {
570
+ en: 'ORP status',
571
+ de: 'ORP-Status',
572
+ },
573
+ desc: {
574
+ en: 'Compact ORP evaluation status.',
575
+ de: 'Kompakter Status der ORP-Auswertung.',
576
+ },
577
+ type: 'string',
578
+ role: 'text',
579
+ read: true,
580
+ write: false,
581
+ def: 'disabled',
582
+ states: {
583
+ disabled: 'disabled',
584
+ invalid: 'invalid',
585
+ waiting_for_pump: 'waiting_for_pump',
586
+ waiting_for_stabilization: 'waiting_for_stabilization',
587
+ ph_reference_missing: 'ph_reference_missing',
588
+ low: 'low',
589
+ ok: 'ok',
590
+ high: 'high',
591
+ observe: 'observe',
592
+ },
593
+ persist: true,
594
+ });
595
+
596
+ await createState(adapter, 'chemistry.orp.evaluation.level', {
597
+ name: {
598
+ en: 'Evaluation level',
599
+ de: 'Bewertungsstufe',
600
+ },
601
+ desc: {
602
+ en: 'Severity level of the current ORP evaluation.',
603
+ de: 'Schweregrad der aktuellen ORP-Auswertung.',
604
+ },
605
+ type: 'string',
606
+ role: 'level',
607
+ read: true,
608
+ write: false,
609
+ def: 'none',
610
+ states: {
611
+ none: 'none',
612
+ info: 'info',
613
+ warning: 'warning',
614
+ critical: 'critical',
615
+ },
616
+ persist: true,
617
+ });
618
+
619
+ await createState(adapter, 'chemistry.orp.evaluation.recommendation', {
620
+ name: {
621
+ en: 'Recommendation',
622
+ de: 'Empfehlung',
623
+ },
624
+ desc: {
625
+ en: 'Readable recommendation for the user. No automatic dosing or chlorine control.',
626
+ de: 'Lesbare Empfehlung für den Nutzer. Keine automatische Dosierung oder Chlorsteuerung.',
627
+ },
628
+ type: 'string',
629
+ role: 'text',
630
+ read: true,
631
+ write: false,
632
+ def: '',
633
+ persist: true,
634
+ });
635
+
636
+ await createState(adapter, 'chemistry.orp.evaluation.action_required', {
637
+ name: {
638
+ en: 'Action required',
639
+ de: 'Handlung erforderlich',
640
+ },
641
+ desc: {
642
+ en: 'Shows whether user action is recommended.',
643
+ de: 'Zeigt an, ob eine Handlung durch den Nutzer empfohlen wird.',
644
+ },
645
+ type: 'boolean',
646
+ role: 'indicator',
647
+ read: true,
648
+ write: false,
649
+ def: false,
650
+ persist: true,
651
+ });
652
+
653
+ // -------------------------------------------------------------
654
+ // Trend
655
+ // -------------------------------------------------------------
656
+ await createChannel(adapter, 'chemistry.orp.trend', {
657
+ en: 'Trend',
658
+ de: 'Trend',
659
+ });
660
+
661
+ await createState(adapter, 'chemistry.orp.trend.reference_24h_value', {
662
+ name: {
663
+ en: '24h reference value',
664
+ de: '24h-Referenzwert',
665
+ },
666
+ desc: {
667
+ en: 'ORP comparison value from about 24 hours ago.',
668
+ de: 'ORP-Vergleichswert von etwa vor 24 Stunden.',
669
+ },
670
+ type: 'number',
671
+ role: 'value',
672
+ read: true,
673
+ write: false,
674
+ def: 0,
675
+ unit: 'mV',
676
+ persist: true,
677
+ });
678
+
679
+ await createState(adapter, 'chemistry.orp.trend.reference_24h_at', {
680
+ name: {
681
+ en: '24h reference time',
682
+ de: 'Zeitpunkt des 24h-Referenzwerts',
683
+ },
684
+ desc: {
685
+ en: 'Readable timestamp of the 24h ORP reference value.',
686
+ de: 'Lesbarer Zeitstempel des 24h-ORP-Referenzwerts.',
687
+ },
688
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
689
+ role: 'value.time',
690
+ read: true,
691
+ write: false,
692
+ def: 0, // FIX: numeric timestamp default for value.time.
693
+ persist: true,
694
+ });
695
+
696
+ await createState(adapter, 'chemistry.orp.trend.delta_24h', {
697
+ name: {
698
+ en: '24h ORP change',
699
+ de: '24h-ORP-Änderung',
700
+ },
701
+ desc: {
702
+ en: 'Difference between the current ORP value and the comparison value from about 24 hours ago.',
703
+ de: 'Differenz zwischen aktuellem ORP-Wert und Vergleichswert von etwa vor 24 Stunden.',
704
+ },
705
+ type: 'number',
706
+ role: 'value',
707
+ read: true,
708
+ write: false,
709
+ def: 0,
710
+ unit: 'mV',
711
+ persist: true,
712
+ });
713
+
714
+ await createState(adapter, 'chemistry.orp.trend.reference_7d_value', {
715
+ name: {
716
+ en: '7 day reference value',
717
+ de: '7-Tage-Referenzwert',
718
+ },
719
+ desc: {
720
+ en: 'ORP comparison value from about 7 days ago.',
721
+ de: 'ORP-Vergleichswert von etwa vor 7 Tagen.',
722
+ },
723
+ type: 'number',
724
+ role: 'value',
725
+ read: true,
726
+ write: false,
727
+ def: 0,
728
+ unit: 'mV',
729
+ persist: true,
730
+ });
731
+
732
+ await createState(adapter, 'chemistry.orp.trend.reference_7d_at', {
733
+ name: {
734
+ en: '7 day reference time',
735
+ de: 'Zeitpunkt des 7-Tage-Referenzwerts',
736
+ },
737
+ desc: {
738
+ en: 'Readable timestamp of the 7 day ORP reference value.',
739
+ de: 'Lesbarer Zeitstempel des 7-Tage-ORP-Referenzwerts.',
740
+ },
741
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
742
+ role: 'value.time',
743
+ read: true,
744
+ write: false,
745
+ def: 0, // FIX: numeric timestamp default for value.time.
746
+ persist: true,
747
+ });
748
+
749
+ await createState(adapter, 'chemistry.orp.trend.delta_7d', {
750
+ name: {
751
+ en: '7 day ORP change',
752
+ de: '7-Tage-ORP-Änderung',
753
+ },
754
+ desc: {
755
+ en: 'Difference between the current ORP value and the comparison value from about 7 days ago.',
756
+ de: 'Differenz zwischen aktuellem ORP-Wert und Vergleichswert von etwa vor 7 Tagen.',
757
+ },
758
+ type: 'number',
759
+ role: 'value',
760
+ read: true,
761
+ write: false,
762
+ def: 0,
763
+ unit: 'mV',
764
+ persist: true,
765
+ });
766
+
767
+ await createState(adapter, 'chemistry.orp.trend.reference_30d_value', {
768
+ name: {
769
+ en: '30 day reference value',
770
+ de: '30-Tage-Referenzwert',
771
+ },
772
+ desc: {
773
+ en: 'ORP comparison value from about 30 days ago.',
774
+ de: 'ORP-Vergleichswert von etwa vor 30 Tagen.',
775
+ },
776
+ type: 'number',
777
+ role: 'value',
778
+ read: true,
779
+ write: false,
780
+ def: 0,
781
+ unit: 'mV',
782
+ persist: true,
783
+ });
784
+
785
+ await createState(adapter, 'chemistry.orp.trend.reference_30d_at', {
786
+ name: {
787
+ en: '30 day reference time',
788
+ de: 'Zeitpunkt des 30-Tage-Referenzwerts',
789
+ },
790
+ desc: {
791
+ en: 'Readable timestamp of the 30 day ORP reference value.',
792
+ de: 'Lesbarer Zeitstempel des 30-Tage-ORP-Referenzwerts.',
793
+ },
794
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
795
+ role: 'value.time',
796
+ read: true,
797
+ write: false,
798
+ def: 0, // FIX: numeric timestamp default for value.time.
799
+ persist: true,
800
+ });
801
+
802
+ await createState(adapter, 'chemistry.orp.trend.delta_30d', {
803
+ name: {
804
+ en: '30 day ORP change',
805
+ de: '30-Tage-ORP-Änderung',
806
+ },
807
+ desc: {
808
+ en: 'Difference between the current ORP value and the comparison value from about 30 days ago.',
809
+ de: 'Differenz zwischen aktuellem ORP-Wert und Vergleichswert von etwa vor 30 Tagen.',
810
+ },
811
+ type: 'number',
812
+ role: 'value',
813
+ read: true,
814
+ write: false,
815
+ def: 0,
816
+ unit: 'mV',
817
+ persist: true,
818
+ });
819
+
820
+ await createState(adapter, 'chemistry.orp.trend.direction', {
821
+ name: {
822
+ en: 'Trend direction',
823
+ de: 'Trendrichtung',
824
+ },
825
+ desc: {
826
+ en: 'Current ORP trend direction.',
827
+ de: 'Aktuelle ORP-Trendrichtung.',
828
+ },
829
+ type: 'string',
830
+ role: 'text',
831
+ read: true,
832
+ write: false,
833
+ def: 'unknown',
834
+ states: {
835
+ unknown: 'unknown',
836
+ stable: 'stable',
837
+ rising: 'rising',
838
+ falling: 'falling',
839
+ },
840
+ persist: true,
841
+ });
842
+
843
+ await createState(adapter, 'chemistry.orp.trend.status', {
844
+ name: {
845
+ en: 'Trend status',
846
+ de: 'Trendstatus',
847
+ },
848
+ desc: {
849
+ en: 'Readable status of the ORP trend evaluation.',
850
+ de: 'Lesbarer Status der ORP-Trendauswertung.',
851
+ },
852
+ type: 'string',
853
+ role: 'text',
854
+ read: true,
855
+ write: false,
856
+ def: 'unknown',
857
+ states: {
858
+ unknown: 'unknown',
859
+ not_enough_data: 'not_enough_data',
860
+ stable: 'stable',
861
+ rising_slowly: 'rising_slowly',
862
+ rising_noticeable: 'rising_noticeable',
863
+ rising_fast: 'rising_fast',
864
+ falling: 'falling',
865
+ },
866
+ persist: true,
867
+ });
868
+
869
+ await createState(adapter, 'chemistry.orp.trend.summary_text', {
870
+ name: {
871
+ en: 'Trend summary',
872
+ de: 'Trendzusammenfassung',
873
+ },
874
+ desc: {
875
+ en: 'Readable summary of the ORP trend.',
876
+ de: 'Lesbare Zusammenfassung des ORP-Trends.',
877
+ },
878
+ type: 'string',
879
+ role: 'text',
880
+ read: true,
881
+ write: false,
882
+ def: '',
883
+ persist: true,
884
+ });
885
+
886
+ // -------------------------------------------------------------
887
+ // History
888
+ // -------------------------------------------------------------
889
+ await createChannel(adapter, 'chemistry.orp.history', {
890
+ en: 'History',
891
+ de: 'Historie',
892
+ });
893
+
894
+ await createState(adapter, 'chemistry.orp.history.samples_json', {
895
+ name: {
896
+ en: 'ORP history samples',
897
+ de: 'ORP-Historienwerte',
898
+ },
899
+ desc: {
900
+ en: 'Internal list of valid ORP measurement samples for trend calculation.',
901
+ de: 'Interne Liste gültiger ORP-Messwerte für die Trendberechnung.',
902
+ },
903
+ type: 'string',
904
+ role: 'json',
905
+ read: true,
906
+ write: false,
907
+ def: '[]',
908
+ persist: true,
909
+ });
910
+
911
+ await createState(adapter, 'chemistry.orp.history.samples_count', {
912
+ name: {
913
+ en: 'ORP sample count',
914
+ de: 'ORP-Anzahl Messwerte',
915
+ },
916
+ desc: {
917
+ en: 'Number of stored ORP history samples.',
918
+ de: 'Anzahl gespeicherter ORP-Historienwerte.',
919
+ },
920
+ type: 'number',
921
+ role: 'value',
922
+ read: true,
923
+ write: false,
924
+ def: 0,
925
+ persist: true,
926
+ });
927
+
928
+ await createState(adapter, 'chemistry.orp.history.oldest_sample_at', {
929
+ name: {
930
+ en: 'Oldest ORP sample time',
931
+ de: 'Ältester ORP-Messwertzeitpunkt',
932
+ },
933
+ desc: {
934
+ en: 'Readable timestamp of the oldest stored ORP sample.',
935
+ de: 'Lesbarer Zeitstempel des ältesten gespeicherten ORP-Messwerts.',
936
+ },
937
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
938
+ role: 'value.time',
939
+ read: true,
940
+ write: false,
941
+ def: 0, // FIX: numeric timestamp default for value.time.
942
+ persist: true,
943
+ });
944
+
945
+ await createState(adapter, 'chemistry.orp.history.newest_sample_at', {
946
+ name: {
947
+ en: 'Newest ORP sample time',
948
+ de: 'Neuester ORP-Messwertzeitpunkt',
949
+ },
950
+ desc: {
951
+ en: 'Readable timestamp of the newest stored ORP sample.',
952
+ de: 'Lesbarer Zeitstempel des neuesten gespeicherten ORP-Messwerts.',
953
+ },
954
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
955
+ role: 'value.time',
956
+ read: true,
957
+ write: false,
958
+ def: 0, // FIX: numeric timestamp default for value.time.
959
+ persist: true,
960
+ });
961
+
962
+ // -------------------------------------------------------------
963
+ // Outputs
964
+ // -------------------------------------------------------------
965
+ await createChannel(adapter, 'chemistry.orp.outputs', {
966
+ en: 'Outputs',
967
+ de: 'Ausgaben',
968
+ });
969
+
970
+ await createState(adapter, 'chemistry.orp.outputs.summary_text', {
971
+ name: {
972
+ en: 'Summary text',
973
+ de: 'Zusammenfassung Text',
974
+ },
975
+ desc: {
976
+ en: 'Readable ORP summary text for object tree, VIS or other outputs.',
977
+ de: 'Lesbare ORP-Zusammenfassung für Objektbaum, VIS oder andere Ausgaben.',
978
+ },
979
+ type: 'string',
980
+ role: 'text',
981
+ read: true,
982
+ write: false,
983
+ def: '',
984
+ persist: true,
985
+ });
986
+
987
+ await createState(adapter, 'chemistry.orp.outputs.summary_html', {
988
+ name: {
989
+ en: 'Summary HTML',
990
+ de: 'Zusammenfassung HTML',
991
+ },
992
+ desc: {
993
+ en: 'HTML summary of the ORP evaluation for VIS or widgets.',
994
+ de: 'HTML-Zusammenfassung der ORP-Auswertung für VIS oder Widgets.',
995
+ },
996
+ type: 'string',
997
+ role: 'html',
998
+ read: true,
999
+ write: false,
1000
+ def: '',
1001
+ persist: true,
1002
+ });
1003
+
1004
+ await createState(adapter, 'chemistry.orp.outputs.summary_json', {
1005
+ name: {
1006
+ en: 'Summary JSON',
1007
+ de: 'Zusammenfassung JSON',
1008
+ },
1009
+ desc: {
1010
+ en: 'Structured JSON summary of the ORP evaluation for further processing.',
1011
+ de: 'Strukturierte JSON-Zusammenfassung der ORP-Auswertung zur Weiterverarbeitung.',
1012
+ },
1013
+ type: 'string',
1014
+ role: 'json',
1015
+ read: true,
1016
+ write: false,
1017
+ def: '',
1018
+ persist: true,
1019
+ });
1020
+
1021
+ // -------------------------------------------------------------
1022
+ // Debug
1023
+ // -------------------------------------------------------------
1024
+ await createChannel(adapter, 'chemistry.orp.debug', {
1025
+ en: 'Debug',
1026
+ de: 'Debug',
1027
+ });
1028
+
1029
+ await createState(adapter, 'chemistry.orp.debug.last_update', {
1030
+ name: {
1031
+ en: 'Last update',
1032
+ de: 'Letzte Aktualisierung',
1033
+ },
1034
+ desc: {
1035
+ en: 'Readable timestamp of the last ORP evaluation update.',
1036
+ de: 'Lesbarer Zeitstempel der letzten ORP-Auswertung.',
1037
+ },
1038
+ type: 'number', // FIX: ioBroker value.time states must store Unix timestamps in milliseconds.
1039
+ role: 'value.time',
1040
+ read: true,
1041
+ write: false,
1042
+ def: 0, // FIX: numeric timestamp default for value.time.
1043
+ persist: true,
1044
+ });
1045
+
1046
+ await createState(adapter, 'chemistry.orp.debug.last_reason', {
1047
+ name: {
1048
+ en: 'Last reason',
1049
+ de: 'Letzter Grund',
1050
+ },
1051
+ desc: {
1052
+ en: 'Reason for the last ORP evaluation update.',
1053
+ de: 'Grund der letzten ORP-Auswertung.',
1054
+ },
1055
+ type: 'string',
1056
+ role: 'text',
1057
+ read: true,
1058
+ write: false,
1059
+ def: '',
1060
+ persist: true,
1061
+ });
1062
+
1063
+ adapter.log.debug('[chemistryOrpStates] Initialization completed');
1064
+ }
1065
+
1066
+ module.exports = {
1067
+ createChemistryOrpStates,
1068
+ };