iobroker.poolcontrol 1.2.0 → 1.2.1
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 +285 -292
- package/admin/i18n/de/translations.json +158 -4
- package/admin/i18n/en/translations.json +161 -3
- package/admin/i18n/es/translations.json +158 -4
- package/admin/i18n/fr/translations.json +158 -4
- package/admin/i18n/it/translations.json +158 -4
- package/admin/i18n/nl/translations.json +158 -4
- package/admin/i18n/pl/translations.json +158 -4
- package/admin/i18n/pt/translations.json +158 -4
- package/admin/i18n/ru/translations.json +158 -4
- package/admin/i18n/uk/translations.json +158 -4
- package/admin/i18n/zh-cn/translations.json +158 -4
- package/admin/jsonConfig.json +180 -602
- package/io-package.json +107 -100
- package/lib/helpers/actuatorsHelper.js +6 -8
- package/lib/helpers/aiChemistryHelpHelper.js +7 -7
- package/lib/helpers/aiForecastHelper.js +21 -21
- package/lib/helpers/aiHelper.js +53 -63
- package/lib/helpers/consumptionHelper.js +23 -25
- package/lib/helpers/controlHelper.js +24 -24
- package/lib/helpers/controlHelper2.js +17 -17
- package/lib/helpers/debugLogHelper.js +12 -14
- package/lib/helpers/frostHelper.js +6 -6
- package/lib/helpers/heatHelper.js +14 -14
- package/lib/helpers/infoHelper.js +2 -2
- package/lib/helpers/migrationHelper.js +16 -16
- package/lib/helpers/photovoltaicHelper.js +28 -28
- package/lib/helpers/pumpHelper.js +16 -18
- package/lib/helpers/pumpHelper2.js +8 -10
- package/lib/helpers/pumpHelper3.js +9 -9
- package/lib/helpers/pumpHelper4.js +9 -9
- package/lib/helpers/pumpSpeedHelper.js +6 -6
- package/lib/helpers/runtimeHelper.js +14 -14
- package/lib/helpers/solarHelper.js +9 -9
- package/lib/helpers/speechHelper.js +13 -15
- package/lib/helpers/speechTextHelper.js +13 -13
- package/lib/helpers/statisticsHelper.js +9 -9
- package/lib/helpers/statisticsHelperMonth.js +15 -15
- package/lib/helpers/statisticsHelperWeek.js +11 -11
- package/lib/helpers/statusHelper.js +9 -9
- package/lib/helpers/temperatureHelper.js +9 -11
- package/lib/helpers/timeHelper.js +7 -9
- package/lib/stateDefinitions/actuatorsStates.js +19 -19
- package/lib/stateDefinitions/aiChemistryHelpStates.js +59 -28
- package/lib/stateDefinitions/aiStates.js +119 -31
- package/lib/stateDefinitions/consumptionStates.js +20 -14
- package/lib/stateDefinitions/controlStates.js +90 -37
- package/lib/stateDefinitions/debugLogStates.js +28 -13
- package/lib/stateDefinitions/generalStates.js +4 -4
- package/lib/stateDefinitions/heatStates.js +21 -21
- package/lib/stateDefinitions/infoStates.js +11 -5
- package/lib/stateDefinitions/photovoltaicStates.js +52 -24
- package/lib/stateDefinitions/pumpSpeedStates.js +11 -11
- package/lib/stateDefinitions/pumpStates.js +24 -15
- package/lib/stateDefinitions/pumpStates2.js +22 -10
- package/lib/stateDefinitions/pumpStates3.js +63 -24
- package/lib/stateDefinitions/pumpStates4.js +62 -32
- package/lib/stateDefinitions/runtimeStates.js +10 -10
- package/lib/stateDefinitions/solarStates.js +9 -9
- package/lib/stateDefinitions/speechStates.js +24 -21
- package/lib/stateDefinitions/statisticsStates.js +107 -29
- package/lib/stateDefinitions/statusStates.js +14 -12
- package/lib/stateDefinitions/temperatureStates.js +18 -12
- package/lib/stateDefinitions/timeStates.js +5 -5
- package/main.js +38 -0
- package/package.json +7 -8
|
@@ -27,13 +27,13 @@ const consumptionHelper = {
|
|
|
27
27
|
this.price = parseFloat(String(adapter.config.energy_price_eur_kwh).replace(',', '.')) || 0;
|
|
28
28
|
this.lastKnownPrice = this.price;
|
|
29
29
|
|
|
30
|
-
this.adapter.log.debug(`[consumptionHelper]
|
|
30
|
+
this.adapter.log.debug(`[consumptionHelper] energy price: ${this.price} €/kWh`);
|
|
31
31
|
|
|
32
32
|
if (this.energyId) {
|
|
33
33
|
adapter.subscribeForeignStates(this.energyId);
|
|
34
|
-
adapter.log.debug(`[consumptionHelper]
|
|
34
|
+
adapter.log.debug(`[consumptionHelper] monitoring external kWh meter: ${this.energyId}`);
|
|
35
35
|
} else {
|
|
36
|
-
adapter.log.debug('[consumptionHelper]
|
|
36
|
+
adapter.log.debug('[consumptionHelper] no external kWh meter configured -> consumption logic inactive.');
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
this._scheduleDailyReset();
|
|
@@ -53,12 +53,12 @@ const consumptionHelper = {
|
|
|
53
53
|
this.baseTotalKwh = totalKwh;
|
|
54
54
|
this.baseTotalEur = totalEur;
|
|
55
55
|
this.adapter.log.debug(
|
|
56
|
-
`[consumptionHelper]
|
|
56
|
+
`[consumptionHelper] cost baseline loaded -> ${this.baseTotalEur.toFixed(
|
|
57
57
|
2,
|
|
58
58
|
)} € bei ${this.baseTotalKwh.toFixed(3)} kWh`,
|
|
59
59
|
);
|
|
60
60
|
} catch (err) {
|
|
61
|
-
this.adapter.log.warn(`[consumptionHelper]
|
|
61
|
+
this.adapter.log.warn(`[consumptionHelper] error loading cost baseline: ${err.message}`);
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
|
|
@@ -83,11 +83,11 @@ const consumptionHelper = {
|
|
|
83
83
|
if (totalNowRaw < last) {
|
|
84
84
|
if (offset === 0 && totalNowRaw < 10 && last > 10) {
|
|
85
85
|
this.adapter.log.warn(
|
|
86
|
-
'[consumptionHelper]
|
|
86
|
+
'[consumptionHelper] reinstall protection active - meter value decreased, offset remains unchanged.',
|
|
87
87
|
);
|
|
88
88
|
totalNow = last; // kein Offset addieren
|
|
89
89
|
} else {
|
|
90
|
-
this.adapter.log.warn('[consumptionHelper]
|
|
90
|
+
this.adapter.log.warn('[consumptionHelper] meter reset detected -> adjusting offset');
|
|
91
91
|
const newOffset = offset + last;
|
|
92
92
|
await this.adapter.setStateAsync('consumption.offset_kwh', { val: newOffset, ack: true });
|
|
93
93
|
totalNow = newOffset + totalNowRaw;
|
|
@@ -151,7 +151,7 @@ const consumptionHelper = {
|
|
|
151
151
|
await this.adapter.setStateAsync('consumption.last_total_kwh', { val: totalNowRaw, ack: true });
|
|
152
152
|
await this._saveBaselines();
|
|
153
153
|
} catch (err) {
|
|
154
|
-
this.adapter.log.warn(`[consumptionHelper]
|
|
154
|
+
this.adapter.log.warn(`[consumptionHelper] error during consumption update: ${err.message}`);
|
|
155
155
|
}
|
|
156
156
|
},
|
|
157
157
|
|
|
@@ -167,7 +167,7 @@ const consumptionHelper = {
|
|
|
167
167
|
this.baselines.month = totalNow - (month || 0);
|
|
168
168
|
this.baselines.year = totalNow - (year || 0);
|
|
169
169
|
|
|
170
|
-
this.adapter.log.debug(`[consumptionHelper]
|
|
170
|
+
this.adapter.log.debug(`[consumptionHelper] baselines loaded: ${JSON.stringify(this.baselines)}`);
|
|
171
171
|
},
|
|
172
172
|
|
|
173
173
|
async _restoreBaselinesFromStates() {
|
|
@@ -183,11 +183,9 @@ const consumptionHelper = {
|
|
|
183
183
|
this.baselines.month = totalNow - month;
|
|
184
184
|
this.baselines.year = totalNow - year;
|
|
185
185
|
|
|
186
|
-
this.adapter.log.debug(
|
|
186
|
+
this.adapter.log.debug('[consumptionHelper] existing consumption values restored.');
|
|
187
187
|
} catch (err) {
|
|
188
|
-
this.adapter.log.warn(
|
|
189
|
-
`[consumptionHelper] Fehler beim Wiederherstellen der Verbrauchsstände: ${err.message}`,
|
|
190
|
-
);
|
|
188
|
+
this.adapter.log.warn(`[consumptionHelper] error restoring consumption values: ${err.message}`);
|
|
191
189
|
}
|
|
192
190
|
},
|
|
193
191
|
|
|
@@ -210,14 +208,14 @@ const consumptionHelper = {
|
|
|
210
208
|
ack: true,
|
|
211
209
|
});
|
|
212
210
|
} catch (err) {
|
|
213
|
-
this.adapter.log.warn(`[consumptionHelper]
|
|
211
|
+
this.adapter.log.warn(`[consumptionHelper] error saving baselines: ${err.message}`);
|
|
214
212
|
}
|
|
215
213
|
},
|
|
216
214
|
|
|
217
215
|
async resetAll(adapter) {
|
|
218
216
|
try {
|
|
219
217
|
this.adapter = adapter;
|
|
220
|
-
adapter.log.warn('[consumptionHelper]
|
|
218
|
+
adapter.log.warn('[consumptionHelper] manual reset of all consumption and cost data');
|
|
221
219
|
|
|
222
220
|
const consumptionKeys = [
|
|
223
221
|
'day_kwh',
|
|
@@ -241,9 +239,9 @@ const consumptionHelper = {
|
|
|
241
239
|
this.baseTotalKwh = 0;
|
|
242
240
|
this.baseTotalEur = 0;
|
|
243
241
|
|
|
244
|
-
adapter.log.info('[consumptionHelper]
|
|
242
|
+
adapter.log.info('[consumptionHelper] consumption and costs successfully reset to 0');
|
|
245
243
|
} catch (err) {
|
|
246
|
-
this.adapter.log.error(`[consumptionHelper]
|
|
244
|
+
this.adapter.log.error(`[consumptionHelper] error during manual reset: ${err.message}`);
|
|
247
245
|
}
|
|
248
246
|
},
|
|
249
247
|
|
|
@@ -256,12 +254,12 @@ const consumptionHelper = {
|
|
|
256
254
|
|
|
257
255
|
this.resetTimer = setTimeout(async () => {
|
|
258
256
|
try {
|
|
259
|
-
this.adapter.log.info('[consumptionHelper]
|
|
257
|
+
this.adapter.log.info('[consumptionHelper] daily counter reset (midnight)');
|
|
260
258
|
await this.adapter.setStateAsync('consumption.day_kwh', { val: 0, ack: true });
|
|
261
259
|
await this.adapter.setStateAsync('costs.day_eur', { val: 0, ack: true });
|
|
262
260
|
this.baselines.day = (await this.adapter.getStateAsync('consumption.total_kwh'))?.val || 0;
|
|
263
261
|
} catch (err) {
|
|
264
|
-
this.adapter.log.warn(`[consumptionHelper]
|
|
262
|
+
this.adapter.log.warn(`[consumptionHelper] error during midnight reset: ${err.message}`);
|
|
265
263
|
}
|
|
266
264
|
this._scheduleDailyReset(); // Timer erneut setzen
|
|
267
265
|
}, msUntilMidnight);
|
|
@@ -288,13 +286,13 @@ const consumptionHelper = {
|
|
|
288
286
|
|
|
289
287
|
// Nur wenn heute Montag ist (0 = Sonntag, 1 = Montag)
|
|
290
288
|
if (nowCheck.getDay() === 1) {
|
|
291
|
-
this.adapter.log.info('[consumptionHelper]
|
|
289
|
+
this.adapter.log.info('[consumptionHelper] weekly reset (Monday 00:05)');
|
|
292
290
|
await this.adapter.setStateAsync('consumption.week_kwh', { val: 0, ack: true });
|
|
293
291
|
await this.adapter.setStateAsync('costs.week_eur', { val: 0, ack: true });
|
|
294
292
|
this.baselines.week = (await this.adapter.getStateAsync('consumption.total_kwh'))?.val || 0;
|
|
295
293
|
}
|
|
296
294
|
} catch (err) {
|
|
297
|
-
this.adapter.log.warn(`[consumptionHelper]
|
|
295
|
+
this.adapter.log.warn(`[consumptionHelper] error during weekly reset: ${err.message}`);
|
|
298
296
|
}
|
|
299
297
|
|
|
300
298
|
// Morgen wieder planen
|
|
@@ -323,13 +321,13 @@ const consumptionHelper = {
|
|
|
323
321
|
|
|
324
322
|
// Nur am 1. des Monats
|
|
325
323
|
if (nowCheck.getDate() === 1) {
|
|
326
|
-
this.adapter.log.info('[consumptionHelper]
|
|
324
|
+
this.adapter.log.info('[consumptionHelper] monthly reset (1st 00:05)');
|
|
327
325
|
await this.adapter.setStateAsync('consumption.month_kwh', { val: 0, ack: true });
|
|
328
326
|
await this.adapter.setStateAsync('costs.month_eur', { val: 0, ack: true });
|
|
329
327
|
this.baselines.month = (await this.adapter.getStateAsync('consumption.total_kwh'))?.val || 0;
|
|
330
328
|
}
|
|
331
329
|
} catch (err) {
|
|
332
|
-
this.adapter.log.warn(`[consumptionHelper]
|
|
330
|
+
this.adapter.log.warn(`[consumptionHelper] error during monthly reset: ${err.message}`);
|
|
333
331
|
}
|
|
334
332
|
|
|
335
333
|
// Morgen wieder planen
|
|
@@ -358,13 +356,13 @@ const consumptionHelper = {
|
|
|
358
356
|
|
|
359
357
|
// 👉 Nur wenn wirklich 1. Januar
|
|
360
358
|
if (nowCheck.getMonth() === 0 && nowCheck.getDate() === 1) {
|
|
361
|
-
this.adapter.log.info('[consumptionHelper]
|
|
359
|
+
this.adapter.log.info('[consumptionHelper] yearly reset (January 1st 00:10)');
|
|
362
360
|
await this.adapter.setStateAsync('consumption.year_kwh', { val: 0, ack: true });
|
|
363
361
|
await this.adapter.setStateAsync('costs.year_eur', { val: 0, ack: true });
|
|
364
362
|
this.baselines.year = (await this.adapter.getStateAsync('consumption.total_kwh'))?.val || 0;
|
|
365
363
|
}
|
|
366
364
|
} catch (err) {
|
|
367
|
-
this.adapter.log.warn(`[consumptionHelper]
|
|
365
|
+
this.adapter.log.warn(`[consumptionHelper] error during yearly reset: ${err.message}`);
|
|
368
366
|
}
|
|
369
367
|
|
|
370
368
|
// Morgen wieder prüfen
|
|
@@ -21,7 +21,7 @@ let previousPumpMode = null;
|
|
|
21
21
|
*/
|
|
22
22
|
function init(a) {
|
|
23
23
|
adapter = a;
|
|
24
|
-
adapter.log.info('[controlHelper]
|
|
24
|
+
adapter.log.info('[controlHelper] initialized');
|
|
25
25
|
|
|
26
26
|
// States abonnieren
|
|
27
27
|
adapter.subscribeStates('control.season.active');
|
|
@@ -32,10 +32,10 @@ function init(a) {
|
|
|
32
32
|
|
|
33
33
|
// Täglichen Check planen
|
|
34
34
|
_scheduleDailyCheck().catch(err =>
|
|
35
|
-
adapter.log.error(`[controlHelper]
|
|
35
|
+
adapter.log.error(`[controlHelper] error in _scheduleDailyCheck(): ${err.message}`),
|
|
36
36
|
);
|
|
37
37
|
|
|
38
|
-
adapter.log.debug('[controlHelper]
|
|
38
|
+
adapter.log.debug('[controlHelper] monitoring of control states enabled');
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -58,14 +58,14 @@ async function _scheduleDailyCheck() {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
const diffMs = next - now;
|
|
61
|
-
adapter.log.debug(`[controlHelper]
|
|
61
|
+
adapter.log.debug(`[controlHelper] next daily circulation check scheduled for ${next.toLocaleTimeString()}`);
|
|
62
62
|
|
|
63
63
|
dailyTimer = setTimeout(async () => {
|
|
64
64
|
await _runDailyCirculationCheck();
|
|
65
65
|
await _scheduleDailyCheck();
|
|
66
66
|
}, diffMs);
|
|
67
67
|
} catch (err) {
|
|
68
|
-
adapter.log.error(`[controlHelper]
|
|
68
|
+
adapter.log.error(`[controlHelper] error in _scheduleDailyCheck(): ${err.message}`);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -74,7 +74,7 @@ async function _scheduleDailyCheck() {
|
|
|
74
74
|
*/
|
|
75
75
|
async function _runDailyCirculationCheck() {
|
|
76
76
|
try {
|
|
77
|
-
adapter.log.debug('[controlHelper]
|
|
77
|
+
adapter.log.debug('[controlHelper] starting daily circulation check ...');
|
|
78
78
|
|
|
79
79
|
const seasonActive = (await adapter.getStateAsync('status.season_active'))?.val;
|
|
80
80
|
const mode = (await adapter.getStateAsync('control.circulation.mode'))?.val || 'off';
|
|
@@ -84,7 +84,7 @@ async function _runDailyCirculationCheck() {
|
|
|
84
84
|
const pool = Number((await adapter.getStateAsync('temperature.surface.current'))?.val || 0);
|
|
85
85
|
|
|
86
86
|
if (!seasonActive) {
|
|
87
|
-
adapter.log.debug('[controlHelper]
|
|
87
|
+
adapter.log.debug('[controlHelper] season inactive - daily check skipped.');
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -119,14 +119,14 @@ async function _runDailyCirculationCheck() {
|
|
|
119
119
|
break;
|
|
120
120
|
|
|
121
121
|
default:
|
|
122
|
-
adapter.log.debug(`[controlHelper]
|
|
122
|
+
adapter.log.debug(`[controlHelper] mode '${mode}' -> no action.`);
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
await _sendSpeech(message);
|
|
127
127
|
await adapter.setStateAsync('control.circulation.last_report', { val: new Date().toISOString(), ack: true });
|
|
128
128
|
} catch (err) {
|
|
129
|
-
adapter.log.error(`[controlHelper]
|
|
129
|
+
adapter.log.error(`[controlHelper] error during daily check: ${err.message}`);
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -145,7 +145,7 @@ async function _startAutoPumping(missingLiter) {
|
|
|
145
145
|
await adapter.setStateAsync('pump.reason', { val: 'nachpumpen', ack: true });
|
|
146
146
|
await adapter.setStateAsync('pump.pump_switch', { val: true, ack: false });
|
|
147
147
|
|
|
148
|
-
adapter.log.info(`[controlHelper]
|
|
148
|
+
adapter.log.info(`[controlHelper] automatic pumping started (${missingLiter} l missing).`);
|
|
149
149
|
if (notify) {
|
|
150
150
|
await _sendSpeech(`Automatisches Nachpumpen gestartet. Es fehlen ${missingLiter} Liter.`);
|
|
151
151
|
}
|
|
@@ -162,14 +162,14 @@ async function _startAutoPumping(missingLiter) {
|
|
|
162
162
|
await adapter.setStateAsync('pump.reason', { val: '', ack: true });
|
|
163
163
|
previousPumpMode = null;
|
|
164
164
|
|
|
165
|
-
adapter.log.info('[controlHelper]
|
|
165
|
+
adapter.log.info('[controlHelper] automatic pumping finished - daily target reached.');
|
|
166
166
|
if (notify) {
|
|
167
167
|
await _sendSpeech('Nachpumpen abgeschlossen. Tagesziel erreicht.');
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
}, 60 * 1000);
|
|
171
171
|
} catch (err) {
|
|
172
|
-
adapter.log.error(`[controlHelper]
|
|
172
|
+
adapter.log.error(`[controlHelper] error during automatic pumping: ${err.message}`);
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
|
|
@@ -188,7 +188,7 @@ async function handleStateChange(id, state) {
|
|
|
188
188
|
// === SAISONSTATUS ===
|
|
189
189
|
if (id.endsWith('control.season.active')) {
|
|
190
190
|
const newVal = !!state.val;
|
|
191
|
-
adapter.log.info(`[controlHelper]
|
|
191
|
+
adapter.log.info(`[controlHelper] pool season ${newVal ? 'enabled' : 'disabled'}.`);
|
|
192
192
|
await adapter.setStateAsync('status.season_active', { val: newVal, ack: true });
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -203,7 +203,7 @@ async function handleStateChange(id, state) {
|
|
|
203
203
|
await adapter.setStateAsync('pump.reason', { val: 'wartung', ack: true });
|
|
204
204
|
await adapter.setStateAsync('pump.active_helper', { val: 'controlHelper', ack: true });
|
|
205
205
|
await adapter.setStateAsync('pump.pump_switch', { val: false, ack: false });
|
|
206
|
-
adapter.log.info('[controlHelper]
|
|
206
|
+
adapter.log.info('[controlHelper] maintenance mode enabled. Automation paused.');
|
|
207
207
|
|
|
208
208
|
if (notify) {
|
|
209
209
|
await _sendSpeech('Wartungsmodus aktiviert. Automatikfunktionen deaktiviert.');
|
|
@@ -214,7 +214,7 @@ async function handleStateChange(id, state) {
|
|
|
214
214
|
await adapter.setStateAsync('pump.reason', { val: '', ack: true });
|
|
215
215
|
previousPumpMode = null;
|
|
216
216
|
|
|
217
|
-
adapter.log.info('[controlHelper]
|
|
217
|
+
adapter.log.info('[controlHelper] maintenance mode disabled. Automation active again.');
|
|
218
218
|
if (notify) {
|
|
219
219
|
await _sendSpeech('Wartungsmodus beendet. Automatikbetrieb wieder aktiv.');
|
|
220
220
|
}
|
|
@@ -229,7 +229,7 @@ async function handleStateChange(id, state) {
|
|
|
229
229
|
const active = (await adapter.getStateAsync('control.pump.backwash_active'))?.val;
|
|
230
230
|
|
|
231
231
|
if (active) {
|
|
232
|
-
adapter.log.warn('[controlHelper]
|
|
232
|
+
adapter.log.warn('[controlHelper] backwash already active - rejecting new start.');
|
|
233
233
|
return;
|
|
234
234
|
}
|
|
235
235
|
|
|
@@ -241,7 +241,7 @@ async function handleStateChange(id, state) {
|
|
|
241
241
|
await adapter.setStateAsync('pump.pump_switch', { val: true, ack: false });
|
|
242
242
|
|
|
243
243
|
const durationText = duration === 1 ? 'eine Minute' : `${duration} Minuten`;
|
|
244
|
-
adapter.log.info(`[controlHelper]
|
|
244
|
+
adapter.log.info(`[controlHelper] backwash started (${duration} minutes).`);
|
|
245
245
|
|
|
246
246
|
if (notify) {
|
|
247
247
|
await _sendSpeech(`Rückspülung gestartet. Dauer ${durationText}.`);
|
|
@@ -259,12 +259,12 @@ async function handleStateChange(id, state) {
|
|
|
259
259
|
await adapter.setStateAsync('pump.reason', { val: '', ack: true });
|
|
260
260
|
await adapter.setStateAsync('control.pump.backwash_active', { val: false, ack: true });
|
|
261
261
|
|
|
262
|
-
adapter.log.info('[controlHelper]
|
|
262
|
+
adapter.log.info('[controlHelper] backwash finished. Automation active again.');
|
|
263
263
|
if (notify) {
|
|
264
264
|
await _sendSpeech('Rückspülung abgeschlossen. Automatikmodus wieder aktiv.');
|
|
265
265
|
}
|
|
266
266
|
} catch (err) {
|
|
267
|
-
adapter.log.warn(`[controlHelper]
|
|
267
|
+
adapter.log.warn(`[controlHelper] error while stopping backwash: ${err.message}`);
|
|
268
268
|
}
|
|
269
269
|
},
|
|
270
270
|
duration * 60 * 1000,
|
|
@@ -277,7 +277,7 @@ async function handleStateChange(id, state) {
|
|
|
277
277
|
const timestamp = now.toLocaleString('de-DE');
|
|
278
278
|
const notify = (await adapter.getStateAsync('control.pump.notifications_enabled'))?.val;
|
|
279
279
|
|
|
280
|
-
adapter.log.info(`[controlHelper]
|
|
280
|
+
adapter.log.info(`[controlHelper] energy meter will be fully reset (${timestamp}).`);
|
|
281
281
|
|
|
282
282
|
const consStates = [
|
|
283
283
|
'consumption.total_kwh',
|
|
@@ -301,13 +301,13 @@ async function handleStateChange(id, state) {
|
|
|
301
301
|
await adapter.setStateAsync('control.energy.reset', { val: false, ack: true });
|
|
302
302
|
|
|
303
303
|
const msg = `Energiezähler und Kosten wurden am ${timestamp} vollständig zurückgesetzt.`;
|
|
304
|
-
adapter.log.info(
|
|
304
|
+
adapter.log.info('[controlHelper] energy meter and costs have been fully reset.');
|
|
305
305
|
if (notify) {
|
|
306
306
|
await _sendSpeech(msg);
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
} catch (err) {
|
|
310
|
-
adapter.log.error(`[controlHelper]
|
|
310
|
+
adapter.log.error(`[controlHelper] error on state change: ${err.message}`);
|
|
311
311
|
}
|
|
312
312
|
}
|
|
313
313
|
|
|
@@ -322,9 +322,9 @@ async function _sendSpeech(text) {
|
|
|
322
322
|
}
|
|
323
323
|
try {
|
|
324
324
|
await adapter.setStateAsync('speech.queue', { val: text, ack: false });
|
|
325
|
-
adapter.log.debug(`[controlHelper]
|
|
325
|
+
adapter.log.debug(`[controlHelper] message sent to speech.queue: ${text}`);
|
|
326
326
|
} catch (err) {
|
|
327
|
-
adapter.log.warn(`[controlHelper]
|
|
327
|
+
adapter.log.warn(`[controlHelper] error sending to speech.queue: ${err.message}`);
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
330
|
|
|
@@ -25,14 +25,14 @@ let lastReminderDay = null; // verhindert doppelte tägliche Meldungen
|
|
|
25
25
|
*/
|
|
26
26
|
function init(a) {
|
|
27
27
|
adapter = a;
|
|
28
|
-
adapter.log.info('[controlHelper2]
|
|
28
|
+
adapter.log.info('[controlHelper2] backwash reminder initialized (daily check at 12:00).');
|
|
29
29
|
|
|
30
30
|
// Rückspülstart abonnieren, um Erinnerung zurückzusetzen
|
|
31
31
|
adapter.subscribeStates('control.pump.backwash_start');
|
|
32
32
|
|
|
33
33
|
// Täglichen Check planen
|
|
34
34
|
_scheduleBackwashReminder().catch(err =>
|
|
35
|
-
adapter.log.error(`[controlHelper2]
|
|
35
|
+
adapter.log.error(`[controlHelper2] error in _scheduleBackwashReminder(): ${err.message}`),
|
|
36
36
|
);
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -53,25 +53,25 @@ async function _scheduleBackwashReminder() {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const diffMs = next - now;
|
|
56
|
-
adapter.log.debug(`[controlHelper2]
|
|
56
|
+
adapter.log.debug(`[controlHelper2] next backwash reminder check scheduled for ${next.toLocaleString()}`);
|
|
57
57
|
|
|
58
58
|
backwashReminderTimer = setTimeout(async () => {
|
|
59
59
|
await _runBackwashReminderCheck();
|
|
60
60
|
await _scheduleBackwashReminder(); // neu planen
|
|
61
61
|
}, diffMs);
|
|
62
62
|
} catch (err) {
|
|
63
|
-
adapter.log.error(`[controlHelper2]
|
|
63
|
+
adapter.log.error(`[controlHelper2] error in _scheduleBackwashReminder(): ${err.message}`);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
// NEU: Führt täglichen Erinnerungs-Check aus
|
|
68
68
|
async function _runBackwashReminderCheck() {
|
|
69
69
|
try {
|
|
70
|
-
adapter.log.debug('[controlHelper2]
|
|
70
|
+
adapter.log.debug('[controlHelper2] starting backwash reminder check ...');
|
|
71
71
|
|
|
72
72
|
const reminderActive = (await adapter.getStateAsync('control.pump.backwash_reminder_active'))?.val;
|
|
73
73
|
if (!reminderActive) {
|
|
74
|
-
adapter.log.debug('[controlHelper2]
|
|
74
|
+
adapter.log.debug('[controlHelper2] backwash reminder disabled - check skipped.');
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -83,7 +83,7 @@ async function _runBackwashReminderCheck() {
|
|
|
83
83
|
|
|
84
84
|
// Verhindert doppelte Erinnerungen am selben Tag
|
|
85
85
|
if (lastReminderDay === todayKey) {
|
|
86
|
-
adapter.log.debug('[controlHelper2]
|
|
86
|
+
adapter.log.debug('[controlHelper2] reminder already sent for today.');
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -95,7 +95,7 @@ async function _runBackwashReminderCheck() {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
if (daysSince === null) {
|
|
98
|
-
adapter.log.debug('[controlHelper2]
|
|
98
|
+
adapter.log.debug('[controlHelper2] no last backwash date known - no reminder.');
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -114,17 +114,17 @@ async function _runBackwashReminderCheck() {
|
|
|
114
114
|
text = `Erinnerung: Rückspülung ist seit ${over} Tag${over === 1 ? '' : 'en'} überfällig.`;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
adapter.log.info(
|
|
117
|
+
adapter.log.info('[controlHelper2] backwash reminder triggered.');
|
|
118
118
|
if (speechEnabled) {
|
|
119
119
|
await _sendSpeech(text);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
lastReminderDay = todayKey;
|
|
123
123
|
} else {
|
|
124
|
-
adapter.log.debug(`[controlHelper2]
|
|
124
|
+
adapter.log.debug(`[controlHelper2] backwash not due yet (${daysSince}/${intervalDays} days).`);
|
|
125
125
|
}
|
|
126
126
|
} catch (err) {
|
|
127
|
-
adapter.log.warn(`[controlHelper2]
|
|
127
|
+
adapter.log.warn(`[controlHelper2] error during reminder check: ${err.message}`);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
@@ -144,7 +144,7 @@ async function handleStateChange(id, state) {
|
|
|
144
144
|
return;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
adapter.log.debug('[controlHelper2]
|
|
147
|
+
adapter.log.debug('[controlHelper2] backwash start detected - resetting reminder.');
|
|
148
148
|
|
|
149
149
|
await adapter.setStateAsync('control.pump.backwash_required', { val: false, ack: true });
|
|
150
150
|
await adapter.setStateAsync('control.pump.backwash_last_date', {
|
|
@@ -155,11 +155,11 @@ async function handleStateChange(id, state) {
|
|
|
155
155
|
const notify = (await adapter.getStateAsync('control.pump.notifications_enabled'))?.val;
|
|
156
156
|
if (notify) {
|
|
157
157
|
const text = 'Rückspülerinnerung wurde zurückgesetzt. Rückspülzyklus neu gestartet.';
|
|
158
|
-
adapter.log.info(
|
|
158
|
+
adapter.log.info('[controlHelper2] backwash reminder has been reset.');
|
|
159
159
|
await _sendSpeech(text);
|
|
160
160
|
}
|
|
161
161
|
} catch (err) {
|
|
162
|
-
adapter.log.warn(`[controlHelper2]
|
|
162
|
+
adapter.log.warn(`[controlHelper2] error in handleStateChange(): ${err.message}`);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -170,9 +170,9 @@ async function _sendSpeech(text) {
|
|
|
170
170
|
}
|
|
171
171
|
try {
|
|
172
172
|
await adapter.setStateAsync('speech.queue', { val: text, ack: false });
|
|
173
|
-
adapter.log.debug(`[controlHelper2]
|
|
173
|
+
adapter.log.debug(`[controlHelper2] message sent to speech.queue: ${text}`);
|
|
174
174
|
} catch (err) {
|
|
175
|
-
adapter.log.warn(`[controlHelper2]
|
|
175
|
+
adapter.log.warn(`[controlHelper2] error sending to speech.queue: ${err.message}`);
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -188,7 +188,7 @@ function cleanup() {
|
|
|
188
188
|
backwashReminderTimer = null;
|
|
189
189
|
}
|
|
190
190
|
lastReminderDay = null;
|
|
191
|
-
adapter.log.debug('[controlHelper2]
|
|
191
|
+
adapter.log.debug('[controlHelper2] cleanup done.');
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
// NEU: Exporte
|
|
@@ -42,10 +42,10 @@ const debugLogHelper = {
|
|
|
42
42
|
if (target !== 'none') {
|
|
43
43
|
this._subscribeTarget(target);
|
|
44
44
|
} else {
|
|
45
|
-
adapter.log.debug('[debugLogHelper]
|
|
45
|
+
adapter.log.debug('[debugLogHelper] No area selected - logger inactive.');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
adapter.log.debug('[debugLogHelper]
|
|
48
|
+
adapter.log.debug('[debugLogHelper] Initialization completed');
|
|
49
49
|
},
|
|
50
50
|
|
|
51
51
|
/**
|
|
@@ -88,7 +88,7 @@ const debugLogHelper = {
|
|
|
88
88
|
this.lastChange[id] = now;
|
|
89
89
|
|
|
90
90
|
if (now - last < this.thresholdMs) {
|
|
91
|
-
const msg = `[${new Date().toISOString()}] ${id}
|
|
91
|
+
const msg = `[${new Date().toISOString()}] ${id} changed too fast (${now - last} ms, val=${state.val}, ack=${state.ack})\n`;
|
|
92
92
|
await this._appendLog(msg);
|
|
93
93
|
}
|
|
94
94
|
},
|
|
@@ -104,21 +104,19 @@ const debugLogHelper = {
|
|
|
104
104
|
}
|
|
105
105
|
if (this.subscribedTarget && this.subscribedTarget !== 'none') {
|
|
106
106
|
this.adapter.unsubscribeStates(`${this.subscribedTarget}.*`);
|
|
107
|
-
this.adapter.log.debug(`[debugLogHelper]
|
|
107
|
+
this.adapter.log.debug(`[debugLogHelper] Monitoring stopped for area "${this.subscribedTarget}".`);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
this.subscribedTarget = newTarget;
|
|
111
111
|
|
|
112
112
|
if (newTarget === 'none') {
|
|
113
|
-
this.adapter.log.debug('[debugLogHelper]
|
|
113
|
+
this.adapter.log.debug('[debugLogHelper] No area active.');
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
this._subscribeTarget(newTarget);
|
|
118
|
-
this.adapter.log.debug(`[debugLogHelper]
|
|
119
|
-
await this._appendLog(
|
|
120
|
-
`\n=== Debug-Log gestartet: Bereich "${newTarget}" @ ${new Date().toLocaleString()} ===\n`,
|
|
121
|
-
);
|
|
118
|
+
this.adapter.log.debug(`[debugLogHelper] Monitoring started for area "${newTarget}".`);
|
|
119
|
+
await this._appendLog(`\n=== Debug log started: area "${newTarget}" @ ${new Date().toLocaleString()} ===\n`);
|
|
122
120
|
},
|
|
123
121
|
|
|
124
122
|
/**
|
|
@@ -147,7 +145,7 @@ const debugLogHelper = {
|
|
|
147
145
|
this.bufferTimer = setTimeout(() => this._flushBuffer(), 5000);
|
|
148
146
|
}
|
|
149
147
|
} catch (err) {
|
|
150
|
-
this.adapter.log.warn(`[debugLogHelper]
|
|
148
|
+
this.adapter.log.warn(`[debugLogHelper] Error while appending to log: ${err.message}`);
|
|
151
149
|
}
|
|
152
150
|
},
|
|
153
151
|
|
|
@@ -165,7 +163,7 @@ const debugLogHelper = {
|
|
|
165
163
|
this.buffer = '';
|
|
166
164
|
this.bufferTimer = null;
|
|
167
165
|
} catch (err) {
|
|
168
|
-
this.adapter.log.warn(`[debugLogHelper]
|
|
166
|
+
this.adapter.log.warn(`[debugLogHelper] Error while writing to log: ${err.message}`);
|
|
169
167
|
}
|
|
170
168
|
},
|
|
171
169
|
|
|
@@ -176,9 +174,9 @@ const debugLogHelper = {
|
|
|
176
174
|
try {
|
|
177
175
|
await this.adapter.setStateAsync('SystemCheck.debug_logs.log', { val: '', ack: true });
|
|
178
176
|
this.buffer = '';
|
|
179
|
-
this.adapter.log.info('[debugLogHelper] Debug
|
|
177
|
+
this.adapter.log.info('[debugLogHelper] Debug log cleared');
|
|
180
178
|
} catch (err) {
|
|
181
|
-
this.adapter.log.warn(`[debugLogHelper]
|
|
179
|
+
this.adapter.log.warn(`[debugLogHelper] Error while clearing the log: ${err.message}`);
|
|
182
180
|
}
|
|
183
181
|
},
|
|
184
182
|
|
|
@@ -186,7 +184,7 @@ const debugLogHelper = {
|
|
|
186
184
|
if (this.bufferTimer) {
|
|
187
185
|
clearTimeout(this.bufferTimer);
|
|
188
186
|
}
|
|
189
|
-
this.adapter.log.debug('[debugLogHelper] Cleanup
|
|
187
|
+
this.adapter.log.debug('[debugLogHelper] Cleanup done');
|
|
190
188
|
},
|
|
191
189
|
};
|
|
192
190
|
|
|
@@ -22,7 +22,7 @@ const frostHelper = {
|
|
|
22
22
|
// Minütlicher Check
|
|
23
23
|
this._scheduleCheck();
|
|
24
24
|
|
|
25
|
-
this.adapter.log.debug('[frostHelper]
|
|
25
|
+
this.adapter.log.debug('[frostHelper] initialized (check every 60s)');
|
|
26
26
|
},
|
|
27
27
|
|
|
28
28
|
_scheduleCheck() {
|
|
@@ -39,13 +39,13 @@ const frostHelper = {
|
|
|
39
39
|
// --- NEU: Vorrangprüfung durch ControlHelper ---
|
|
40
40
|
const activeHelper = (await this.adapter.getStateAsync('pump.active_helper'))?.val || '';
|
|
41
41
|
if (activeHelper === 'controlHelper') {
|
|
42
|
-
this.adapter.log.debug('[frostHelper]
|
|
42
|
+
this.adapter.log.debug('[frostHelper] Priority by ControlHelper active - frost protection paused.');
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
// --- NEU: Vorrangprüfung durch TimeHelper ---
|
|
47
47
|
if (activeHelper === 'timeHelper') {
|
|
48
|
-
this.adapter.log.debug('[frostHelper]
|
|
48
|
+
this.adapter.log.debug('[frostHelper] Priority by TimeHelper active - frost protection paused.');
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -64,7 +64,7 @@ const frostHelper = {
|
|
|
64
64
|
// Außentemperatur laden
|
|
65
65
|
const outside = (await this.adapter.getStateAsync('temperature.outside.current'))?.val;
|
|
66
66
|
if (outside == null) {
|
|
67
|
-
this.adapter.log.debug('[frostHelper]
|
|
67
|
+
this.adapter.log.debug('[frostHelper] No outside temperature available');
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -124,11 +124,11 @@ const frostHelper = {
|
|
|
124
124
|
ack: false,
|
|
125
125
|
});
|
|
126
126
|
this.adapter.log.info(
|
|
127
|
-
`[frostHelper]
|
|
127
|
+
`[frostHelper] Frost protection -> pump ${shouldRun ? 'ON' : 'OFF'} (outside=${outside}°C, limit=${frostTemp}°C)`,
|
|
128
128
|
);
|
|
129
129
|
}
|
|
130
130
|
} catch (err) {
|
|
131
|
-
this.adapter.log.warn(`[frostHelper]
|
|
131
|
+
this.adapter.log.warn(`[frostHelper] Error in check: ${err.message}`);
|
|
132
132
|
}
|
|
133
133
|
},
|
|
134
134
|
|