iobroker.poolcontrol 1.3.9 → 1.3.11

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,444 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * photovoltaicInsightsStates.js
5
+ * -----------------------------
6
+ * Erstellt die States für analytics.insights.photovoltaic.
7
+ *
8
+ * Block 1:
9
+ * analytics.insights.photovoltaic.inputs.*
10
+ *
11
+ * Wichtig:
12
+ * - Nur Analyse-States, keine Steuerlogik
13
+ * - Aufbau analog zu solarInsightsStates.js
14
+ * - EN + DE direkt enthalten
15
+ * - Weitere Blöcke (calculation, results, debug) folgen später schrittweise
16
+ */
17
+
18
+ /**
19
+ * @param {ioBroker.Adapter} adapter - Instanz des ioBroker-Adapters
20
+ */
21
+ async function createPhotovoltaicInsightsStates(adapter) {
22
+ adapter.log.debug('photovoltaicInsightsStates: Photovoltaic insights initialization started.');
23
+
24
+ // Oberstruktur
25
+ await adapter.setObjectNotExistsAsync('analytics', {
26
+ type: 'channel',
27
+ common: {
28
+ name: {
29
+ en: 'Analytics & insights (statistics, history, reports)',
30
+ de: 'Analysen & Statistiken (Verlauf, Berichte)',
31
+ },
32
+ },
33
+ native: {},
34
+ });
35
+
36
+ await adapter.setObjectNotExistsAsync('analytics.insights', {
37
+ type: 'channel',
38
+ common: {
39
+ name: {
40
+ en: 'Insights & analysis',
41
+ de: 'Erkenntnisse & Analysen',
42
+ },
43
+ },
44
+ native: {},
45
+ });
46
+
47
+ await adapter.setObjectNotExistsAsync('analytics.insights.photovoltaic', {
48
+ type: 'channel',
49
+ common: {
50
+ name: {
51
+ en: 'Photovoltaic insights (analysis)',
52
+ de: 'Photovoltaik Insights (Analyse)',
53
+ },
54
+ },
55
+ native: {},
56
+ });
57
+
58
+ // -------------------------------------------------------------
59
+ // BLOCK 1: INPUTS
60
+ // -------------------------------------------------------------
61
+ await adapter.setObjectNotExistsAsync('analytics.insights.photovoltaic.inputs', {
62
+ type: 'channel',
63
+ common: {
64
+ name: {
65
+ en: 'Inputs (PV & pump data)',
66
+ de: 'Eingänge (PV- & Pumpendaten)',
67
+ },
68
+ },
69
+ native: {},
70
+ });
71
+
72
+ const inputStates = [
73
+ {
74
+ id: 'pv_surplus_active',
75
+ name: {
76
+ en: 'PV surplus active',
77
+ de: 'PV-Überschuss aktiv',
78
+ },
79
+ desc: {
80
+ en: 'Shows whether photovoltaic surplus is currently active',
81
+ de: 'Zeigt an, ob aktuell Photovoltaik-Überschuss aktiv ist',
82
+ },
83
+ type: 'boolean',
84
+ role: 'indicator',
85
+ def: false,
86
+ },
87
+ {
88
+ id: 'pv_surplus_w',
89
+ name: {
90
+ en: 'PV surplus power (W)',
91
+ de: 'PV-Überschussleistung (W)',
92
+ },
93
+ desc: {
94
+ en: 'Current photovoltaic surplus power in watts used as input for the analysis',
95
+ de: 'Aktuelle Photovoltaik-Überschussleistung in Watt als Eingangswert für die Analyse',
96
+ },
97
+ type: 'number',
98
+ role: 'value.power',
99
+ unit: 'W',
100
+ def: 0,
101
+ },
102
+ {
103
+ id: 'pump_power_w',
104
+ name: {
105
+ en: 'Pump power (W)',
106
+ de: 'Pumpenleistung (W)',
107
+ },
108
+ desc: {
109
+ en: 'Current pump power in watts used as input for the photovoltaic analysis',
110
+ de: 'Aktuelle Pumpenleistung in Watt als Eingangswert für die Photovoltaik-Analyse',
111
+ },
112
+ type: 'number',
113
+ role: 'value.power',
114
+ unit: 'W',
115
+ def: 0,
116
+ },
117
+ ];
118
+
119
+ for (const state of inputStates) {
120
+ await adapter.setObjectNotExistsAsync(`analytics.insights.photovoltaic.inputs.${state.id}`, {
121
+ type: 'state',
122
+ common: {
123
+ name: state.name,
124
+ desc: state.desc,
125
+ type: state.type,
126
+ role: state.role,
127
+ unit: state.unit || '',
128
+ read: true,
129
+ write: false,
130
+ def: state.def,
131
+ persist: true,
132
+ },
133
+ native: {},
134
+ });
135
+ }
136
+
137
+ // -------------------------------------------------------------
138
+ // BLOCK 2: CALCULATION
139
+ // -------------------------------------------------------------
140
+ await adapter.setObjectNotExistsAsync('analytics.insights.photovoltaic.calculation', {
141
+ type: 'channel',
142
+ common: {
143
+ name: {
144
+ en: 'Calculation',
145
+ de: 'Berechnung',
146
+ },
147
+ },
148
+ native: {},
149
+ });
150
+
151
+ const calculationStates = [
152
+ {
153
+ id: 'mode',
154
+ name: {
155
+ en: 'Calculation mode',
156
+ de: 'Berechnungsmodus',
157
+ },
158
+ desc: {
159
+ en: 'Current calculation mode for photovoltaic insights',
160
+ de: 'Aktueller Berechnungsmodus für die Photovoltaik-Insights',
161
+ },
162
+ type: 'string',
163
+ role: 'text',
164
+ def: '',
165
+ },
166
+ {
167
+ id: 'price_source',
168
+ name: {
169
+ en: 'Electricity price source',
170
+ de: 'Strompreisquelle',
171
+ },
172
+ desc: {
173
+ en: 'Source of the electricity price used for savings calculation',
174
+ de: 'Quelle des Strompreises für die Einsparungsberechnung',
175
+ },
176
+ type: 'string',
177
+ role: 'text',
178
+ def: '',
179
+ },
180
+ {
181
+ id: 'note',
182
+ name: {
183
+ en: 'Calculation note',
184
+ de: 'Berechnungshinweis',
185
+ },
186
+ desc: {
187
+ en: 'Short note about the current photovoltaic insights calculation',
188
+ de: 'Kurzer Hinweis zur aktuellen Photovoltaik-Insights-Berechnung',
189
+ },
190
+ type: 'string',
191
+ role: 'text',
192
+ def: '',
193
+ },
194
+ ];
195
+
196
+ for (const state of calculationStates) {
197
+ await adapter.setObjectNotExistsAsync(`analytics.insights.photovoltaic.calculation.${state.id}`, {
198
+ type: 'state',
199
+ common: {
200
+ name: state.name,
201
+ desc: state.desc,
202
+ type: state.type,
203
+ role: state.role,
204
+ read: true,
205
+ write: false,
206
+ def: state.def,
207
+ persist: true,
208
+ },
209
+ native: {},
210
+ });
211
+ }
212
+
213
+ // -------------------------------------------------------------
214
+ // BLOCK 3: RESULTS
215
+ // -------------------------------------------------------------
216
+ await adapter.setObjectNotExistsAsync('analytics.insights.photovoltaic.results', {
217
+ type: 'channel',
218
+ common: {
219
+ name: {
220
+ en: 'Results',
221
+ de: 'Ergebnisse',
222
+ },
223
+ },
224
+ native: {},
225
+ });
226
+
227
+ const resultStates = [
228
+ {
229
+ id: 'active_today',
230
+ name: {
231
+ en: 'PV active today',
232
+ de: 'PV heute aktiv',
233
+ },
234
+ desc: {
235
+ en: 'Shows whether the pump was operated by photovoltaic surplus today',
236
+ de: 'Zeigt an, ob die Pumpe heute durch Photovoltaik-Überschuss betrieben wurde',
237
+ },
238
+ type: 'boolean',
239
+ role: 'indicator',
240
+ def: false,
241
+ },
242
+ {
243
+ id: 'runtime_today_min',
244
+ name: {
245
+ en: 'Runtime today',
246
+ de: 'Laufzeit heute',
247
+ },
248
+ desc: {
249
+ en: 'Pump runtime today caused by photovoltaic surplus',
250
+ de: 'Pumpenlaufzeit heute durch Photovoltaik-Überschuss',
251
+ },
252
+ type: 'number',
253
+ role: 'value',
254
+ unit: 'min',
255
+ def: 0,
256
+ },
257
+ {
258
+ id: 'energy_used_today_kwh',
259
+ name: {
260
+ en: 'Energy used today',
261
+ de: 'Genutzte Energie heute',
262
+ },
263
+ desc: {
264
+ en: 'Estimated pump energy used today during photovoltaic surplus operation',
265
+ de: 'Geschätzte Pumpenenergie heute während des PV-Überschussbetriebs',
266
+ },
267
+ type: 'number',
268
+ role: 'value.power.consumption',
269
+ unit: 'kWh',
270
+ def: 0,
271
+ },
272
+ {
273
+ id: 'savings_today_eur',
274
+ name: {
275
+ en: 'Savings today',
276
+ de: 'Einsparung heute',
277
+ },
278
+ desc: {
279
+ en: 'Estimated savings today based on photovoltaic surplus operation',
280
+ de: 'Geschätzte Einsparung heute durch Photovoltaik-Überschussbetrieb',
281
+ },
282
+ type: 'number',
283
+ role: 'value',
284
+ unit: '€',
285
+ def: 0,
286
+ },
287
+ {
288
+ id: 'starts_today',
289
+ name: {
290
+ en: 'Starts today',
291
+ de: 'Starts heute',
292
+ },
293
+ desc: {
294
+ en: 'Number of photovoltaic surplus pump starts today',
295
+ de: 'Anzahl der heutigen Pumpenstarts durch Photovoltaik-Überschuss',
296
+ },
297
+ type: 'number',
298
+ role: 'value',
299
+ def: 0,
300
+ },
301
+ {
302
+ id: 'summary_text',
303
+ name: {
304
+ en: 'Summary text',
305
+ de: 'Zusammenfassungstext',
306
+ },
307
+ desc: {
308
+ en: 'Short readable summary of today’s photovoltaic surplus usage',
309
+ de: 'Kurze lesbare Zusammenfassung der heutigen PV-Überschussnutzung',
310
+ },
311
+ type: 'string',
312
+ role: 'text',
313
+ def: '',
314
+ },
315
+ {
316
+ id: 'summary_json',
317
+ name: {
318
+ en: 'Summary JSON',
319
+ de: 'Zusammenfassung JSON',
320
+ },
321
+ desc: {
322
+ en: 'Structured JSON summary of today’s photovoltaic surplus usage',
323
+ de: 'Strukturierte JSON-Zusammenfassung der heutigen PV-Überschussnutzung',
324
+ },
325
+ type: 'string',
326
+ role: 'json',
327
+ def: '{}',
328
+ },
329
+ {
330
+ id: 'summary_html',
331
+ name: {
332
+ en: 'Summary HTML',
333
+ de: 'Zusammenfassung HTML',
334
+ },
335
+ desc: {
336
+ en: 'HTML summary of today’s photovoltaic surplus usage',
337
+ de: 'HTML-Zusammenfassung der heutigen PV-Überschussnutzung',
338
+ },
339
+ type: 'string',
340
+ role: 'html',
341
+ def: '',
342
+ },
343
+ ];
344
+
345
+ for (const state of resultStates) {
346
+ await adapter.setObjectNotExistsAsync(`analytics.insights.photovoltaic.results.${state.id}`, {
347
+ type: 'state',
348
+ common: {
349
+ name: state.name,
350
+ desc: state.desc,
351
+ type: state.type,
352
+ role: state.role,
353
+ unit: state.unit || '',
354
+ read: true,
355
+ write: false,
356
+ def: state.def,
357
+ persist: true,
358
+ },
359
+ native: {},
360
+ });
361
+ }
362
+
363
+ // -------------------------------------------------------------
364
+ // BLOCK 4: DEBUG
365
+ // -------------------------------------------------------------
366
+ await adapter.setObjectNotExistsAsync('analytics.insights.photovoltaic.debug', {
367
+ type: 'channel',
368
+ common: {
369
+ name: {
370
+ en: 'Debug',
371
+ de: 'Debug',
372
+ },
373
+ },
374
+ native: {},
375
+ });
376
+
377
+ const debugStates = [
378
+ {
379
+ id: 'last_update',
380
+ name: {
381
+ en: 'Last update',
382
+ de: 'Letzte Aktualisierung',
383
+ },
384
+ desc: {
385
+ en: 'Timestamp of the last photovoltaic insights update',
386
+ de: 'Zeitstempel der letzten Photovoltaik-Insights-Aktualisierung',
387
+ },
388
+ type: 'string',
389
+ role: 'date',
390
+ def: '',
391
+ },
392
+ {
393
+ id: 'last_recalculation_reason',
394
+ name: {
395
+ en: 'Last recalculation reason',
396
+ de: 'Letzter Neuberechnungsgrund',
397
+ },
398
+ desc: {
399
+ en: 'Reason for the last photovoltaic insights recalculation',
400
+ de: 'Grund der letzten Photovoltaik-Insights-Neuberechnung',
401
+ },
402
+ type: 'string',
403
+ role: 'text',
404
+ def: '',
405
+ },
406
+ {
407
+ id: 'debug_text',
408
+ name: {
409
+ en: 'Debug text',
410
+ de: 'Debug-Text',
411
+ },
412
+ desc: {
413
+ en: 'Readable debug information for photovoltaic insights',
414
+ de: 'Lesbare Debug-Informationen für Photovoltaik-Insights',
415
+ },
416
+ type: 'string',
417
+ role: 'text',
418
+ def: '',
419
+ },
420
+ ];
421
+
422
+ for (const state of debugStates) {
423
+ await adapter.setObjectNotExistsAsync(`analytics.insights.photovoltaic.debug.${state.id}`, {
424
+ type: 'state',
425
+ common: {
426
+ name: state.name,
427
+ desc: state.desc,
428
+ type: state.type,
429
+ role: state.role,
430
+ read: true,
431
+ write: false,
432
+ def: state.def,
433
+ persist: true,
434
+ },
435
+ native: {},
436
+ });
437
+ }
438
+
439
+ adapter.log.debug(
440
+ 'photovoltaicInsightsStates: Block 1 inputs, Block 2 calculation, Block 3 results and Block 4 debug created successfully.',
441
+ );
442
+ }
443
+
444
+ module.exports = { createPhotovoltaicInsightsStates };
package/main.js CHANGED
@@ -24,9 +24,12 @@ const solarExtendedHelper = require('./lib/helpers/solarExtendedHelper'); // NEU
24
24
  const frostHelper = require('./lib/helpers/frostHelper');
25
25
  const statusHelper = require('./lib/helpers/statusHelper');
26
26
  const photovoltaicHelper = require('./lib/helpers/photovoltaicHelper');
27
+ const photovoltaicInsightsHelper = require('./lib/helpers/photovoltaicInsightsHelper');
27
28
  const aiHelper = require('./lib/helpers/aiHelper');
28
29
  const aiForecastHelper = require('./lib/helpers/aiForecastHelper');
29
30
  const aiChemistryHelpHelper = require('./lib/helpers/aiChemistryHelpHelper');
31
+ const chemistryPhHelper = require('./lib/helpers/chemistryPhHelper');
32
+ const chemistryTdsHelper = require('./lib/helpers/chemistryTdsHelper');
30
33
  const controlHelper = require('./lib/helpers/controlHelper');
31
34
  const controlHelper2 = require('./lib/helpers/controlHelper2');
32
35
  const debugLogHelper = require('./lib/helpers/debugLogHelper');
@@ -58,9 +61,12 @@ const { createDebugLogStates } = require('./lib/stateDefinitions/debugLogStates'
58
61
  const { createInfoStates } = require('./lib/stateDefinitions/infoStates');
59
62
  const { createAiStates } = require('./lib/stateDefinitions/aiStates'); // NEU: KI-States
60
63
  const { createAiChemistryHelpStates } = require('./lib/stateDefinitions/aiChemistryHelpStates'); // NEU: KI-Chemie-Hilfe
64
+ const { createChemistryPhStates } = require('./lib/stateDefinitions/chemistryPhStates');
65
+ const { createChemistryTdsStates } = require('./lib/stateDefinitions/chemistryTdsStates');
61
66
  const { createHeatStates } = require('./lib/stateDefinitions/heatStates');
62
67
  const { createActuatorsStates } = require('./lib/stateDefinitions/actuatorsStates');
63
68
  const { createSolarInsightsStates } = require('./lib/stateDefinitions/solarInsightsStates');
69
+ const { createPhotovoltaicInsightsStates } = require('./lib/stateDefinitions/photovoltaicInsightsStates');
64
70
 
65
71
  class Poolcontrol extends utils.Adapter {
66
72
  constructor(options) {
@@ -135,6 +141,9 @@ class Poolcontrol extends utils.Adapter {
135
141
  // --- Solar Insights / Analyse ---
136
142
  await createSolarInsightsStates(this);
137
143
 
144
+ // --- Photovoltaic Insights / Analyse ---
145
+ await createPhotovoltaicInsightsStates(this);
146
+
138
147
  // --- Sprachausgaben ---
139
148
  await createSpeechStates(this);
140
149
 
@@ -157,6 +166,12 @@ class Poolcontrol extends utils.Adapter {
157
166
  await createAiStates(this); // NEU: KI-States anlegen
158
167
  await createAiChemistryHelpStates(this); // NEU: KI-Chemie-Hilfe-States
159
168
 
169
+ // --- Chemistry / pH evaluation ---
170
+ await createChemistryPhStates(this);
171
+
172
+ // --- Chemistry / TDS evaluation ---
173
+ await createChemistryTdsStates(this);
174
+
160
175
  // --- Zusatz-Aktoren (Beleuchtung & Zusatzpumpen) ---
161
176
  await createActuatorsStates(this);
162
177
 
@@ -181,9 +196,12 @@ class Poolcontrol extends utils.Adapter {
181
196
  solarExtendedHelper.init(this); // NEU
182
197
  heatHelper.init(this); // ← NEU
183
198
  photovoltaicHelper.init(this);
199
+ photovoltaicInsightsHelper.init(this);
184
200
  aiHelper.init(this);
185
201
  aiForecastHelper.init(this);
186
202
  aiChemistryHelpHelper.init(this);
203
+ chemistryPhHelper.init(this);
204
+ chemistryTdsHelper.init(this);
187
205
  frostHelper.init(this);
188
206
  statusHelper.init(this);
189
207
  infoHelper.init(this);
@@ -270,6 +288,18 @@ class Poolcontrol extends utils.Adapter {
270
288
  if (aiForecastHelper.cleanup) {
271
289
  aiForecastHelper.cleanup();
272
290
  }
291
+ if (photovoltaicHelper.cleanup) {
292
+ photovoltaicHelper.cleanup();
293
+ }
294
+ if (photovoltaicInsightsHelper.cleanup) {
295
+ photovoltaicInsightsHelper.cleanup();
296
+ }
297
+ if (chemistryPhHelper.cleanup) {
298
+ chemistryPhHelper.cleanup();
299
+ }
300
+ if (chemistryTdsHelper.cleanup) {
301
+ chemistryTdsHelper.cleanup();
302
+ }
273
303
  if (aiChemistryHelpHelper.cleanup) {
274
304
  aiChemistryHelpHelper.cleanup();
275
305
  }
@@ -367,6 +397,11 @@ class Poolcontrol extends utils.Adapter {
367
397
  } catch (e) {
368
398
  this.log.warn(`[photovoltaicHelper] Error in handleStateChange: ${e.message}`);
369
399
  }
400
+ try {
401
+ photovoltaicInsightsHelper.handleStateChange(id, state);
402
+ } catch (e) {
403
+ this.log.warn(`[photovoltaicInsightsHelper] Error in handleStateChange: ${e.message}`);
404
+ }
370
405
  try {
371
406
  heatHelper.handleStateChange(id, state);
372
407
  } catch (e) {
@@ -393,6 +428,16 @@ class Poolcontrol extends utils.Adapter {
393
428
  } catch (e) {
394
429
  this.log.warn(`[main] Error in aiChemistryHelpHelper.handleStateChange: ${e.message}`);
395
430
  }
431
+ try {
432
+ await chemistryPhHelper.handleStateChange(id, state);
433
+ } catch (e) {
434
+ this.log.warn(`[chemistryPhHelper] Error in handleStateChange: ${e.message}`);
435
+ }
436
+ try {
437
+ await chemistryTdsHelper.handleStateChange(id, state);
438
+ } catch (e) {
439
+ this.log.warn(`[chemistryTdsHelper] Error in handleStateChange: ${e.message}`);
440
+ }
396
441
  try {
397
442
  statusHelper.handleStateChange(id, state);
398
443
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.poolcontrol",
3
- "version": "1.3.9",
3
+ "version": "1.3.11",
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",