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.
Files changed (66) hide show
  1. package/README.md +285 -292
  2. package/admin/i18n/de/translations.json +158 -4
  3. package/admin/i18n/en/translations.json +161 -3
  4. package/admin/i18n/es/translations.json +158 -4
  5. package/admin/i18n/fr/translations.json +158 -4
  6. package/admin/i18n/it/translations.json +158 -4
  7. package/admin/i18n/nl/translations.json +158 -4
  8. package/admin/i18n/pl/translations.json +158 -4
  9. package/admin/i18n/pt/translations.json +158 -4
  10. package/admin/i18n/ru/translations.json +158 -4
  11. package/admin/i18n/uk/translations.json +158 -4
  12. package/admin/i18n/zh-cn/translations.json +158 -4
  13. package/admin/jsonConfig.json +180 -602
  14. package/io-package.json +107 -100
  15. package/lib/helpers/actuatorsHelper.js +6 -8
  16. package/lib/helpers/aiChemistryHelpHelper.js +7 -7
  17. package/lib/helpers/aiForecastHelper.js +21 -21
  18. package/lib/helpers/aiHelper.js +53 -63
  19. package/lib/helpers/consumptionHelper.js +23 -25
  20. package/lib/helpers/controlHelper.js +24 -24
  21. package/lib/helpers/controlHelper2.js +17 -17
  22. package/lib/helpers/debugLogHelper.js +12 -14
  23. package/lib/helpers/frostHelper.js +6 -6
  24. package/lib/helpers/heatHelper.js +14 -14
  25. package/lib/helpers/infoHelper.js +2 -2
  26. package/lib/helpers/migrationHelper.js +16 -16
  27. package/lib/helpers/photovoltaicHelper.js +28 -28
  28. package/lib/helpers/pumpHelper.js +16 -18
  29. package/lib/helpers/pumpHelper2.js +8 -10
  30. package/lib/helpers/pumpHelper3.js +9 -9
  31. package/lib/helpers/pumpHelper4.js +9 -9
  32. package/lib/helpers/pumpSpeedHelper.js +6 -6
  33. package/lib/helpers/runtimeHelper.js +14 -14
  34. package/lib/helpers/solarHelper.js +9 -9
  35. package/lib/helpers/speechHelper.js +13 -15
  36. package/lib/helpers/speechTextHelper.js +13 -13
  37. package/lib/helpers/statisticsHelper.js +9 -9
  38. package/lib/helpers/statisticsHelperMonth.js +15 -15
  39. package/lib/helpers/statisticsHelperWeek.js +11 -11
  40. package/lib/helpers/statusHelper.js +9 -9
  41. package/lib/helpers/temperatureHelper.js +9 -11
  42. package/lib/helpers/timeHelper.js +7 -9
  43. package/lib/stateDefinitions/actuatorsStates.js +19 -19
  44. package/lib/stateDefinitions/aiChemistryHelpStates.js +59 -28
  45. package/lib/stateDefinitions/aiStates.js +119 -31
  46. package/lib/stateDefinitions/consumptionStates.js +20 -14
  47. package/lib/stateDefinitions/controlStates.js +90 -37
  48. package/lib/stateDefinitions/debugLogStates.js +28 -13
  49. package/lib/stateDefinitions/generalStates.js +4 -4
  50. package/lib/stateDefinitions/heatStates.js +21 -21
  51. package/lib/stateDefinitions/infoStates.js +11 -5
  52. package/lib/stateDefinitions/photovoltaicStates.js +52 -24
  53. package/lib/stateDefinitions/pumpSpeedStates.js +11 -11
  54. package/lib/stateDefinitions/pumpStates.js +24 -15
  55. package/lib/stateDefinitions/pumpStates2.js +22 -10
  56. package/lib/stateDefinitions/pumpStates3.js +63 -24
  57. package/lib/stateDefinitions/pumpStates4.js +62 -32
  58. package/lib/stateDefinitions/runtimeStates.js +10 -10
  59. package/lib/stateDefinitions/solarStates.js +9 -9
  60. package/lib/stateDefinitions/speechStates.js +24 -21
  61. package/lib/stateDefinitions/statisticsStates.js +107 -29
  62. package/lib/stateDefinitions/statusStates.js +14 -12
  63. package/lib/stateDefinitions/temperatureStates.js +18 -12
  64. package/lib/stateDefinitions/timeStates.js +5 -5
  65. package/main.js +38 -0
  66. package/package.json +7 -8
@@ -38,7 +38,7 @@ const aiChemistryHelpHelper = {
38
38
  */
39
39
  async init(adapter) {
40
40
  this.adapter = adapter;
41
- this.adapter.log.info('[aiChemistryHelpHelper] Initialisierung gestartet');
41
+ this.adapter.log.info('[aiChemistryHelpHelper] initialization started');
42
42
 
43
43
  // NEU: auf Auswahländerungen reagieren
44
44
  this.adapter.subscribeStates('ai.chemistry_help.issue');
@@ -50,10 +50,10 @@ const aiChemistryHelpHelper = {
50
50
  await this._processIssue(String(st.val));
51
51
  }
52
52
  } catch (e) {
53
- this.adapter.log.debug(`[aiChemistryHelpHelper] Init: Konnte issue nicht lesen: ${e.message}`);
53
+ this.adapter.log.debug(`[aiChemistryHelpHelper] init: could not read issue: ${e.message}`);
54
54
  }
55
55
 
56
- this.adapter.log.info('[aiChemistryHelpHelper] Initialisierung abgeschlossen');
56
+ this.adapter.log.info('[aiChemistryHelpHelper] initialization finished');
57
57
  },
58
58
 
59
59
  /**
@@ -61,7 +61,7 @@ const aiChemistryHelpHelper = {
61
61
  */
62
62
  cleanup() {
63
63
  // aktuell keine Timer / Intervalle
64
- this.adapter && this.adapter.log.debug('[aiChemistryHelpHelper] Cleanup abgeschlossen');
64
+ this.adapter && this.adapter.log.debug('[aiChemistryHelpHelper] cleanup finished');
65
65
  },
66
66
 
67
67
  /**
@@ -101,12 +101,12 @@ const aiChemistryHelpHelper = {
101
101
  issue = obj.common.states[state.val] || 'none';
102
102
  }
103
103
  } catch (e) {
104
- this.adapter.log.debug(`[aiChemistryHelpHelper] Konnte Enum-Text nicht auflösen: ${e.message}`);
104
+ this.adapter.log.debug(`[aiChemistryHelpHelper] could not resolve enum text: ${e.message}`);
105
105
  }
106
106
  } else {
107
107
  issue = String(state.val || 'none');
108
108
  }
109
- this.adapter.log.debug(`[aiChemistryHelpHelper] Auswahl geändert: ${issue}`);
109
+ this.adapter.log.debug(`[aiChemistryHelpHelper] selection changed: ${issue}`);
110
110
 
111
111
  await this._processIssue(issue);
112
112
  },
@@ -384,7 +384,7 @@ const aiChemistryHelpHelper = {
384
384
 
385
385
  await this.adapter.setStateAsync(id, { val: value, ack: true });
386
386
  } catch (e) {
387
- this.adapter.log.debug(`[aiChemistryHelpHelper] _setStateIfChanged Fehler (${id}): ${e.message}`);
387
+ this.adapter.log.debug(`[aiChemistryHelpHelper] _setStateIfChanged error (${id}): ${e.message}`);
388
388
  }
389
389
  },
390
390
  };
@@ -34,7 +34,7 @@ const aiForecastHelper = {
34
34
  */
35
35
  async init(adapter) {
36
36
  this.adapter = adapter;
37
- this.adapter.log.info('[aiForecastHelper] Initialisierung gestartet');
37
+ this.adapter.log.info('[aiForecastHelper] initialization started');
38
38
 
39
39
  await this._refreshTimer();
40
40
 
@@ -48,15 +48,15 @@ const aiForecastHelper = {
48
48
  // ----------------------------------------------------------
49
49
  const enabled = await this._getBool('ai.weather.switches.tomorrow_forecast_enabled', false);
50
50
  if (enabled) {
51
- this.adapter.log.info('[aiForecastHelper] Starte einmalige Sofort-Vorhersage (Adapterstart)');
51
+ this.adapter.log.info('[aiForecastHelper] running one-time immediate forecast (adapter start)');
52
52
  try {
53
53
  await this._runForecast();
54
54
  } catch (err) {
55
- this.adapter.log.warn(`[aiForecastHelper] Fehler bei Sofort-Vorhersage: ${err.message}`);
55
+ this.adapter.log.warn(`[aiForecastHelper] error during immediate forecast: ${err.message}`);
56
56
  }
57
57
  }
58
58
 
59
- this.adapter.log.info('[aiForecastHelper] Initialisierung abgeschlossen');
59
+ this.adapter.log.info('[aiForecastHelper] initialization finished');
60
60
  },
61
61
 
62
62
  /**
@@ -67,7 +67,7 @@ const aiForecastHelper = {
67
67
  clearInterval(this.timer);
68
68
  this.timer = null;
69
69
  }
70
- this.adapter && this.adapter.log.debug('[aiForecastHelper] Cleanup abgeschlossen');
70
+ this.adapter && this.adapter.log.debug('[aiForecastHelper] cleanup finished');
71
71
  },
72
72
 
73
73
  /**
@@ -95,15 +95,15 @@ const aiForecastHelper = {
95
95
  // NEU: Sofortige Ausführung, wenn der Forecast aktiviert wird
96
96
  // ----------------------------------------------------------
97
97
  if (id.endsWith('ai.weather.switches.tomorrow_forecast_enabled') && state.val === true) {
98
- this.adapter.log.info('[aiForecastHelper] Forecast aktiviert einmalige sofortige Ausführung');
98
+ this.adapter.log.info('[aiForecastHelper] forecast enabled -> one-time immediate run');
99
99
  try {
100
100
  await this._runForecast();
101
101
  } catch (err) {
102
- this.adapter.log.warn(`[aiForecastHelper] Fehler bei Sofort-Ausführung: ${err.message}`);
102
+ this.adapter.log.warn(`[aiForecastHelper] error during immediate run: ${err.message}`);
103
103
  }
104
104
  }
105
105
 
106
- this.adapter.log.info(`[aiForecastHelper] Änderung erkannt: ${id} = ${state.val}`);
106
+ this.adapter.log.info(`[aiForecastHelper] change detected: ${id} = ${state.val}`);
107
107
  await this._refreshTimer();
108
108
  },
109
109
 
@@ -121,14 +121,14 @@ const aiForecastHelper = {
121
121
  this._debugMode = await this._getBool('ai.weather.switches.debug_mode', false);
122
122
 
123
123
  if (!enabled) {
124
- this.adapter.log.info('[aiForecastHelper] Forecast deaktiviert kein Timer aktiv');
124
+ this.adapter.log.info('[aiForecastHelper] forecast disabled - no timer active');
125
125
  return;
126
126
  }
127
127
 
128
128
  const time = await this._getTimeOrDefault('ai.weather.schedule.tomorrow_forecast_time', '19:00');
129
129
 
130
130
  this.adapter.log.info(
131
- `[aiForecastHelper] Forecast-Timer gesetzt für ${time.hour}:${String(time.minute).padStart(2, '0')}`,
131
+ `[aiForecastHelper] forecast timer set for ${time.hour}:${String(time.minute).padStart(2, '0')}`,
132
132
  );
133
133
 
134
134
  // minütlicher Check
@@ -138,7 +138,7 @@ const aiForecastHelper = {
138
138
  try {
139
139
  await this._runForecast();
140
140
  } catch (err) {
141
- this.adapter.log.warn(`[aiForecastHelper] Fehler im Timer: ${err.message}`);
141
+ this.adapter.log.warn(`[aiForecastHelper] timer error: ${err.message}`);
142
142
  }
143
143
  }
144
144
  }, 60 * 1000);
@@ -149,17 +149,17 @@ const aiForecastHelper = {
149
149
  // ---------------------------------------------------------------------
150
150
  async _runForecast() {
151
151
  try {
152
- this.adapter.log.info('[aiForecastHelper] Erzeuge Vorhersage für morgen ...');
152
+ this.adapter.log.info('[aiForecastHelper] creating forecast for tomorrow ...');
153
153
 
154
154
  const geo = await this._loadGeoLocation();
155
155
  if (!geo) {
156
- this.adapter.log.warn('[aiForecastHelper] Abbruch keine Geodaten verfügbar');
156
+ this.adapter.log.warn('[aiForecastHelper] abort - no geo data available');
157
157
  return;
158
158
  }
159
159
 
160
160
  const weather = await this._fetchWeather(geo.lat, geo.lon);
161
161
  if (!weather) {
162
- this.adapter.log.warn('[aiForecastHelper] Abbruch keine Wetterdaten');
162
+ this.adapter.log.warn('[aiForecastHelper] abort - no weather data available');
163
163
  return;
164
164
  }
165
165
 
@@ -168,9 +168,9 @@ const aiForecastHelper = {
168
168
  await this._writeOutput('tomorrow_forecast', text);
169
169
  await this._maybeSpeak(text);
170
170
 
171
- this.adapter.log.info('[aiForecastHelper] Vorhersage für morgen erzeugt');
171
+ this.adapter.log.info('[aiForecastHelper] forecast for tomorrow created');
172
172
  } catch (err) {
173
- this.adapter.log.warn(`[aiForecastHelper] Fehler bei _runForecast(): ${err.message}`);
173
+ this.adapter.log.warn(`[aiForecastHelper] error in _runForecast(): ${err.message}`);
174
174
  }
175
175
  },
176
176
 
@@ -331,7 +331,7 @@ const aiForecastHelper = {
331
331
  `&timezone=auto`;
332
332
 
333
333
  if (this._debugMode) {
334
- this.adapter.log.debug(`[aiForecastHelper] Abruf: ${url}`);
334
+ this.adapter.log.debug(`[aiForecastHelper] request: ${url}`);
335
335
  }
336
336
 
337
337
  return new Promise(resolve => {
@@ -363,10 +363,10 @@ const aiForecastHelper = {
363
363
  await this.adapter.setStateAsync(`ai.weather.outputs.${id}`, { val: text, ack: true });
364
364
 
365
365
  if (this._debugMode) {
366
- this.adapter.log.debug(`[aiForecastHelper] Output geschrieben: ai.weather.outputs.${id}`);
366
+ this.adapter.log.debug(`[aiForecastHelper] output written: ai.weather.outputs.${id}`);
367
367
  }
368
368
  } catch (err) {
369
- this.adapter.log.error(`[aiForecastHelper] Fehler beim Schreiben eines Outputs (${id}): ${err.message}`);
369
+ this.adapter.log.error(`[aiForecastHelper] error writing output (${id}): ${err.message}`);
370
370
  }
371
371
  },
372
372
 
@@ -378,9 +378,9 @@ const aiForecastHelper = {
378
378
 
379
379
  try {
380
380
  await this.adapter.setStateAsync('speech.queue', { val: text, ack: false });
381
- this.adapter.log.info('[aiForecastHelper] Sprachausgabe gestartet');
381
+ this.adapter.log.info('[aiForecastHelper] speech output started');
382
382
  } catch (err) {
383
- this.adapter.log.warn(`[aiForecastHelper] Fehler bei Sprachausgabe: ${err.message}`);
383
+ this.adapter.log.warn(`[aiForecastHelper] speech output error: ${err.message}`);
384
384
  }
385
385
  },
386
386
 
@@ -61,12 +61,12 @@ const aiHelper = {
61
61
  */
62
62
  async init(adapter) {
63
63
  this.adapter = adapter;
64
- this.adapter.log.info('[aiHelper] Initialisierung gestartet');
64
+ this.adapter.log.info('[aiHelper] initialization started');
65
65
 
66
66
  // Ersten Settings-Load + Timeraufbau
67
67
  await this._refreshTimers();
68
68
 
69
- this.adapter.log.info('[aiHelper] Initialisierung abgeschlossen');
69
+ this.adapter.log.info('[aiHelper] initialization finished');
70
70
  },
71
71
 
72
72
  /**
@@ -74,7 +74,7 @@ const aiHelper = {
74
74
  */
75
75
  cleanup() {
76
76
  this._clearTimers();
77
- this.adapter && this.adapter.log.debug('[aiHelper] Cleanup abgeschlossen (Timer gestoppt)');
77
+ this.adapter && this.adapter.log.debug('[aiHelper] cleanup finished (timers stopped)');
78
78
  },
79
79
 
80
80
  /**
@@ -112,9 +112,7 @@ const aiHelper = {
112
112
  const oldVal = this._lastScheduleValues[id];
113
113
  const newVal = state.val;
114
114
 
115
- this.adapter.log.info(
116
- `[aiHelper] Uhrzeit geändert: ${id}: ${oldVal || '(kein vorheriger Wert)'} → ${newVal}`,
117
- );
115
+ this.adapter.log.info(`[aiHelper] time changed: ${id}: ${oldVal || '(no previous value)'} -> ${newVal}`);
118
116
 
119
117
  // neuen Wert speichern
120
118
  this._lastScheduleValues[id] = newVal;
@@ -141,7 +139,7 @@ const aiHelper = {
141
139
  // Nur wenn Zielzeit HEUTE noch bevorsteht
142
140
  if (target > now) {
143
141
  this.adapter.log.info(
144
- `[aiHelper] Neue Uhrzeit liegt heute noch in der Zukunft führe Modul sofort aus (${id})`,
142
+ `[aiHelper] new time is still in the future today -> running module immediately (${id})`,
145
143
  );
146
144
 
147
145
  if (id.endsWith('weather_advice_time')) {
@@ -159,7 +157,7 @@ const aiHelper = {
159
157
  }
160
158
  }
161
159
  } catch (e) {
162
- this.adapter.log.warn(`[aiHelper] Fehler bei Sofortausführung nach Zeitänderung: ${e.message}`);
160
+ this.adapter.log.warn(`[aiHelper] error during immediate run after time change: ${e.message}`);
163
161
  }
164
162
 
165
163
  return;
@@ -169,7 +167,7 @@ const aiHelper = {
169
167
  // FIX 3: Schalteränderungen immer melden
170
168
  // ---------------------------------------------------------
171
169
  if (id.includes('.ai.weather.switches.')) {
172
- this.adapter.log.info(`[aiHelper] Schalter geändert: ${id} = ${state.val} Timer werden neu aufgebaut`);
170
+ this.adapter.log.info(`[aiHelper] switch changed: ${id} = ${state.val} - rebuilding timers`);
173
171
 
174
172
  await this._refreshTimers();
175
173
  return;
@@ -200,11 +198,11 @@ const aiHelper = {
200
198
  this._debugMode = await this._getBool('ai.weather.switches.debug_mode', false);
201
199
 
202
200
  if (!aiEnabled) {
203
- this.adapter.log.info('[aiHelper] KI ist deaktiviert (ai.enabled = false) keine Timer aktiv');
201
+ this.adapter.log.info('[aiHelper] AI is disabled (ai.enabled = false) - no timers active');
204
202
  return;
205
203
  }
206
204
 
207
- this.adapter.log.info('[aiHelper] KI ist aktiv Timer werden gesetzt');
205
+ this.adapter.log.info('[aiHelper] AI is enabled - setting timers');
208
206
 
209
207
  // --- Wetterhinweise ---
210
208
  const weatherEnabled = await this._getBool('ai.weather.switches.weather_advice_enabled', false);
@@ -214,7 +212,7 @@ const aiHelper = {
214
212
  await this._runWeatherAdvice();
215
213
  });
216
214
  this.adapter.log.debug(
217
- `[aiHelper] Wetterhinweis-Timer gesetzt für ${time.hour}:${String(time.minute).padStart(2, '0')}`,
215
+ `[aiHelper] weather advice timer set for ${time.hour}:${String(time.minute).padStart(2, '0')}`,
218
216
  );
219
217
  }
220
218
 
@@ -226,7 +224,7 @@ const aiHelper = {
226
224
  await this._runDailySummary();
227
225
  });
228
226
  this.adapter.log.debug(
229
- `[aiHelper] Daily-Summary-Timer gesetzt für ${time.hour}:${String(time.minute).padStart(2, '0')}`,
227
+ `[aiHelper] daily summary timer set for ${time.hour}:${String(time.minute).padStart(2, '0')}`,
230
228
  );
231
229
  }
232
230
 
@@ -238,7 +236,7 @@ const aiHelper = {
238
236
  await this._runDailyPoolTips();
239
237
  });
240
238
  this.adapter.log.debug(
241
- `[aiHelper] Pool-Tipps-Timer gesetzt für ${time.hour}:${String(time.minute).padStart(2, '0')}`,
239
+ `[aiHelper] pool tips timer set for ${time.hour}:${String(time.minute).padStart(2, '0')}`,
242
240
  );
243
241
  }
244
242
 
@@ -250,27 +248,27 @@ const aiHelper = {
250
248
  await this._runWeekendSummary();
251
249
  });
252
250
  this.adapter.log.debug(
253
- `[aiHelper] Wochenend-Timer gesetzt für ${time.hour}:${String(time.minute).padStart(2, '0')}`,
251
+ `[aiHelper] weekend summary timer set for ${time.hour}:${String(time.minute).padStart(2, '0')}`,
254
252
  );
255
253
  }
256
254
 
257
255
  //--------------------------------------------------------
258
256
  // NEU: Stündlicher Wetter-Update-Timer
259
257
  //--------------------------------------------------------
260
- this.adapter.log.debug('[aiHelper] Stündlicher Wetter-Update-Timer wird gesetzt');
258
+ this.adapter.log.debug('[aiHelper] setting hourly weather update timer');
261
259
 
262
260
  const hourlyTimer = setInterval(
263
261
  async () => {
264
262
  try {
265
263
  const geo = await this._loadGeoLocation();
266
264
  if (!geo) {
267
- this.adapter.log.info('[aiHelper] Wetter-Update abgebrochen keine Geodaten verfügbar');
265
+ this.adapter.log.info('[aiHelper] weather update aborted - no geo data available');
268
266
  return;
269
267
  }
270
268
 
271
269
  const weather = await this._fetchWeather(geo.lat, geo.lon);
272
270
  if (!weather) {
273
- this.adapter.log.info('[aiHelper] Wetter-Update abgebrochen keine Wetterdaten verfügbar');
271
+ this.adapter.log.info('[aiHelper] weather update aborted - no weather data available');
274
272
  return;
275
273
  }
276
274
 
@@ -284,12 +282,10 @@ const aiHelper = {
284
282
  await this._writeOutput('pool_tips', poolTipsText);
285
283
 
286
284
  if (this._debugMode) {
287
- this.adapter.log.debug(
288
- '[aiHelper] Stündliches Wetter-Update durchgeführt (Weather + Pool-Tipps)',
289
- );
285
+ this.adapter.log.debug('[aiHelper] hourly weather update completed (weather + pool tips)');
290
286
  }
291
287
  } catch (err) {
292
- this.adapter.log.warn(`[aiHelper] Fehler beim stündlichen Wetter-Update: ${err.message}`);
288
+ this.adapter.log.warn(`[aiHelper] error during hourly weather update: ${err.message}`);
293
289
  }
294
290
  },
295
291
  60 * 60 * 1000,
@@ -319,23 +315,21 @@ const aiHelper = {
319
315
  if (withinStartupWindow && diffMinutes > 0 && diffMinutes <= 2) {
320
316
  try {
321
317
  await callback();
322
- this.adapter.log.info(
323
- '[aiHelper] Nachholung ausgeführt (innerhalb der ersten 3 Minuten nach Start)',
324
- );
318
+ this.adapter.log.info('[aiHelper] catch-up executed (within the first 3 minutes after start)');
325
319
  } catch (err) {
326
- this.adapter.log.warn(`[aiHelper] Fehler bei Nachholung: ${err.message}`);
320
+ this.adapter.log.warn(`[aiHelper] catch-up error: ${err.message}`);
327
321
  }
328
322
  }
329
323
 
330
324
  if (now.getHours() === hour && now.getMinutes() === minute) {
331
325
  this.adapter.log.debug(
332
- `[aiHelper] Timer ausgelöst: ${hour}:${String(minute).padStart(2, '0')} Callback wird ausgeführt`,
326
+ `[aiHelper] timer triggered: ${hour}:${String(minute).padStart(2, '0')} -> running callback`,
333
327
  ); // NEU
334
328
 
335
329
  try {
336
330
  await callback();
337
331
  } catch (err) {
338
- this.adapter.log.warn(`[aiHelper] Fehler im Timer-Callback: ${err.message}`);
332
+ this.adapter.log.warn(`[aiHelper] timer callback error: ${err.message}`);
339
333
  }
340
334
  }
341
335
  }, 60 * 1000); // jede Minute prüfen
@@ -354,13 +348,13 @@ const aiHelper = {
354
348
  try {
355
349
  const geo = await this._loadGeoLocation();
356
350
  if (!geo) {
357
- this.adapter.log.info('[aiHelper] Wetterhinweis abgebrochen keine Geodaten verfügbar');
351
+ this.adapter.log.info('[aiHelper] weather advice aborted - no geo data available');
358
352
  return;
359
353
  }
360
354
 
361
355
  const weather = await this._fetchWeather(geo.lat, geo.lon);
362
356
  if (!weather) {
363
- this.adapter.log.info('[aiHelper] Wetterhinweis abgebrochen keine Wetterdaten');
357
+ this.adapter.log.info('[aiHelper] weather advice aborted - no weather data available');
364
358
  return;
365
359
  }
366
360
 
@@ -368,9 +362,9 @@ const aiHelper = {
368
362
  await this._writeOutput('weather_advice', text);
369
363
  await this._maybeSpeak(text);
370
364
 
371
- this.adapter.log.info('[aiHelper] Neuer Wetterhinweis erzeugt');
365
+ this.adapter.log.info('[aiHelper] new weather advice created');
372
366
  } catch (err) {
373
- this.adapter.log.warn(`[aiHelper] Fehler bei _runWeatherAdvice(): ${err.message}`);
367
+ this.adapter.log.warn(`[aiHelper] error in _runWeatherAdvice(): ${err.message}`);
374
368
  }
375
369
  },
376
370
 
@@ -398,9 +392,9 @@ const aiHelper = {
398
392
  await this._writeOutput('daily_summary', text);
399
393
  await this._maybeSpeak(text);
400
394
 
401
- this.adapter.log.info('[aiHelper] Neue Tageszusammenfassung erzeugt');
395
+ this.adapter.log.info('[aiHelper] new daily summary created');
402
396
  } catch (err) {
403
- this.adapter.log.warn(`[aiHelper] Fehler bei _runDailySummary(): ${err.message}`);
397
+ this.adapter.log.warn(`[aiHelper] error in _runDailySummary(): ${err.message}`);
404
398
  }
405
399
  },
406
400
 
@@ -418,9 +412,9 @@ const aiHelper = {
418
412
  await this._writeOutput('pool_tips', text);
419
413
  await this._maybeSpeak(text);
420
414
 
421
- this.adapter.log.info('[aiHelper] Neue Pool-Tipps erzeugt');
415
+ this.adapter.log.info('[aiHelper] new pool tips created');
422
416
  } catch (err) {
423
- this.adapter.log.warn(`[aiHelper] Fehler bei _runDailyPoolTips(): ${err.message}`);
417
+ this.adapter.log.warn(`[aiHelper] error in _runDailyPoolTips(): ${err.message}`);
424
418
  }
425
419
  },
426
420
 
@@ -434,9 +428,7 @@ const aiHelper = {
434
428
 
435
429
  // Nur Freitag oder Samstag sinnvoll
436
430
  if (weekday !== 5 && weekday !== 6) {
437
- this.adapter.log.info(
438
- '[aiHelper] Wochenend-Zusammenfassung übersprungen – heute ist weder Freitag noch Samstag',
439
- );
431
+ this.adapter.log.info('[aiHelper] weekend summary skipped - today is neither Friday nor Saturday');
440
432
  return;
441
433
  }
442
434
 
@@ -449,9 +441,9 @@ const aiHelper = {
449
441
  await this._writeOutput('weekend_summary', text);
450
442
  await this._maybeSpeak(text);
451
443
 
452
- this.adapter.log.info('[aiHelper] Neue Wochenend-Zusammenfassung erzeugt');
444
+ this.adapter.log.info('[aiHelper] new weekend summary created');
453
445
  } catch (err) {
454
- this.adapter.log.warn(`[aiHelper] Fehler bei _runWeekendSummary(): ${err.message}`);
446
+ this.adapter.log.warn(`[aiHelper] error in _runWeekendSummary(): ${err.message}`);
455
447
  }
456
448
  },
457
449
 
@@ -462,13 +454,13 @@ const aiHelper = {
462
454
  try {
463
455
  const geo = await this._loadGeoLocation();
464
456
  if (!geo) {
465
- this.adapter.log.info('[aiHelper] Auto-Wetterupdate abgebrochen keine Geodaten verfügbar');
457
+ this.adapter.log.info('[aiHelper] auto weather update aborted - no geo data available');
466
458
  return;
467
459
  }
468
460
 
469
461
  const weather = await this._fetchWeather(geo.lat, geo.lon);
470
462
  if (!weather) {
471
- this.adapter.log.info('[aiHelper] Auto-Wetterupdate abgebrochen keine Wetterdaten verfügbar');
463
+ this.adapter.log.info('[aiHelper] auto weather update aborted - no weather data available');
472
464
  return;
473
465
  }
474
466
 
@@ -477,10 +469,10 @@ const aiHelper = {
477
469
  await this._writeOutput('weather_advice', text);
478
470
 
479
471
  if (this._debugMode) {
480
- this.adapter.log.debug('[aiHelper] Auto-Wetterupdate erfolgreich durchgeführt');
472
+ this.adapter.log.debug('[aiHelper] auto weather update completed successfully');
481
473
  }
482
474
  } catch (err) {
483
- this.adapter.log.warn(`[aiHelper] Fehler bei Auto-Wetterupdate: ${err.message}`);
475
+ this.adapter.log.warn(`[aiHelper] error during auto weather update: ${err.message}`);
484
476
  }
485
477
  },
486
478
 
@@ -497,7 +489,7 @@ const aiHelper = {
497
489
  try {
498
490
  const obj = await this.adapter.getForeignObjectAsync('system.config');
499
491
  if (!obj || !obj.common) {
500
- this.adapter.log.warn('[aiHelper] Konnte system.config nicht laden');
492
+ this.adapter.log.warn('[aiHelper] could not load system.config');
501
493
  return null;
502
494
  }
503
495
 
@@ -505,17 +497,17 @@ const aiHelper = {
505
497
  const lon = Number(obj.common.longitude);
506
498
 
507
499
  if (Number.isNaN(lat) || Number.isNaN(lon)) {
508
- this.adapter.log.warn('[aiHelper] Geodaten ungültig bitte in Admin unter System/Standort eintragen');
500
+ this.adapter.log.warn('[aiHelper] invalid geo data - please set it in Admin under System/Location');
509
501
  return null;
510
502
  }
511
503
 
512
504
  if (this._debugMode) {
513
- this.adapter.log.debug(`[aiHelper] Geodaten geladen: lat=${lat}, lon=${lon}`);
505
+ this.adapter.log.debug(`[aiHelper] geo data loaded: lat=${lat}, lon=${lon}`);
514
506
  }
515
507
 
516
508
  return { lat, lon };
517
509
  } catch (err) {
518
- this.adapter.log.error(`[aiHelper] Fehler beim Laden der Geodaten: ${err.message}`);
510
+ this.adapter.log.error(`[aiHelper] error loading geo data: ${err.message}`);
519
511
  return null;
520
512
  }
521
513
  },
@@ -537,7 +529,7 @@ const aiHelper = {
537
529
  `&timezone=auto`;
538
530
 
539
531
  if (this._debugMode) {
540
- this.adapter.log.debug(`[aiHelper] Rufe Wetterdaten ab: ${url}`);
532
+ this.adapter.log.debug(`[aiHelper] fetching weather data: ${url}`);
541
533
  }
542
534
 
543
535
  return new Promise(resolve => {
@@ -551,23 +543,23 @@ const aiHelper = {
551
543
  res.on('end', () => {
552
544
  try {
553
545
  if (!data) {
554
- this.adapter.log.warn('[aiHelper] Wetterabfrage: leere Antwort erhalten');
546
+ this.adapter.log.warn('[aiHelper] weather request: received empty response');
555
547
  return resolve(null);
556
548
  }
557
549
  const json = JSON.parse(data);
558
550
  resolve(json);
559
551
  } catch (err) {
560
- this.adapter.log.warn(`[aiHelper] Fehler beim Parsen der Wetterdaten: ${err.message}`);
552
+ this.adapter.log.warn(`[aiHelper] error parsing weather data: ${err.message}`);
561
553
  resolve(null);
562
554
  }
563
555
  });
564
556
  })
565
557
  .on('error', err => {
566
- this.adapter.log.warn(`[aiHelper] Fehler bei Wetterabfrage: ${err.message}`);
558
+ this.adapter.log.warn(`[aiHelper] weather request error: ${err.message}`);
567
559
  resolve(null);
568
560
  });
569
561
  } catch (err) {
570
- this.adapter.log.warn(`[aiHelper] Unerwarteter Fehler bei Wetterabfrage: ${err.message}`);
562
+ this.adapter.log.warn(`[aiHelper] unexpected weather request error: ${err.message}`);
571
563
  resolve(null);
572
564
  }
573
565
  });
@@ -975,10 +967,10 @@ const aiHelper = {
975
967
  await this.adapter.setStateAsync('ai.weather.outputs.last_message', { val: text, ack: true });
976
968
 
977
969
  if (this._debugMode) {
978
- this.adapter.log.debug(`[aiHelper] Output geschrieben ai.weather.outputs.${id}: ${text}`);
970
+ this.adapter.log.debug(`[aiHelper] output written -> ai.weather.outputs.${id}: ${text}`);
979
971
  }
980
972
  } catch (err) {
981
- this.adapter.log.error(`[aiHelper] Fehler beim Schreiben eines Outputs (${id}): ${err.message}`);
973
+ this.adapter.log.error(`[aiHelper] error writing output (${id}): ${err.message}`);
982
974
  }
983
975
  },
984
976
 
@@ -998,18 +990,16 @@ const aiHelper = {
998
990
  const allowSpeech = await this._getBool('ai.weather.switches.allow_speech', false);
999
991
  if (!allowSpeech) {
1000
992
  if (this._debugMode) {
1001
- this.adapter.log.debug(
1002
- '[aiHelper] Sprachausgabe deaktiviert (ai.weather.switches.allow_speech = false)',
1003
- );
993
+ this.adapter.log.debug('[aiHelper] speech output disabled (ai.weather.switches.allow_speech = false)');
1004
994
  }
1005
995
  return;
1006
996
  }
1007
997
 
1008
998
  try {
1009
999
  await this.adapter.setStateAsync('speech.queue', { val: text, ack: false });
1010
- this.adapter.log.info('[aiHelper] Text an speech.queue übergeben');
1000
+ this.adapter.log.info('[aiHelper] text sent to speech.queue');
1011
1001
  } catch (err) {
1012
- this.adapter.log.warn(`[aiHelper] Fehler bei Sprachausgabe: ${err.message}`);
1002
+ this.adapter.log.warn(`[aiHelper] speech output error: ${err.message}`);
1013
1003
  }
1014
1004
  },
1015
1005
 
@@ -1082,14 +1072,14 @@ const aiHelper = {
1082
1072
  const str = await this._getString(id, def);
1083
1073
 
1084
1074
  // NEU: Log, welche Uhrzeit der Helper tatsächlich verwendet
1085
- this.adapter.log.debug(`[aiHelper] Uhrzeit geladen: ${id} = "${str}" (Default: ${def})`);
1075
+ this.adapter.log.debug(`[aiHelper] time loaded: ${id} = "${str}" (default: ${def})`);
1086
1076
 
1087
1077
  const match = /^(\d{1,2}):(\d{2})$/.exec(str || '');
1088
1078
  let hour = 0;
1089
1079
  let minute = 0;
1090
1080
 
1091
1081
  if (!match) {
1092
- this.adapter.log.warn(`[aiHelper] Ungültiges Zeitformat in ${id}: "${str}" verwende Default ${def}`);
1082
+ this.adapter.log.warn(`[aiHelper] invalid time format in ${id}: "${str}" - using default ${def}`);
1093
1083
  const defMatch = /^(\d{1,2}):(\d{2})$/.exec(def);
1094
1084
  if (defMatch) {
1095
1085
  hour = Number(defMatch[1]);