iobroker.poolcontrol 1.2.0 → 1.2.2

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 +121 -101
  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
@@ -24,7 +24,8 @@
24
24
  * @param {import('iobroker').Adapter} adapter - ioBroker Adapterinstanz
25
25
  */
26
26
  async function createAiChemistryHelpStates(adapter) {
27
- adapter.log.debug('[aiChemistryHelpStates] Initialisierung gestartet');
27
+ // FIX: Logs must be English (mcm requirement)
28
+ adapter.log.debug('[aiChemistryHelpStates] Initialization started');
28
29
 
29
30
  // ----------------------------------------------------------
30
31
  // Channel: ai.chemistry_help
@@ -32,7 +33,11 @@ async function createAiChemistryHelpStates(adapter) {
32
33
  await adapter.setObjectNotExistsAsync('ai.chemistry_help', {
33
34
  type: 'channel',
34
35
  common: {
35
- name: 'Chemie-Hilfe (Erklärungen & Ursachen)',
36
+ // FIX: i18n for name
37
+ name: {
38
+ de: 'Chemie-Hilfe (Erklärungen & Ursachen)',
39
+ en: 'Chemistry help (explanations & causes)',
40
+ },
36
41
  },
37
42
  native: {},
38
43
  });
@@ -43,38 +48,47 @@ async function createAiChemistryHelpStates(adapter) {
43
48
  await adapter.setObjectNotExistsAsync('ai.chemistry_help.issue', {
44
49
  type: 'state',
45
50
  common: {
46
- name: 'Chemie-Hilfe: Problem auswählen',
47
- desc: 'Manuelle Auswahl eines beobachteten Pool-Problems zur Anzeige allgemeiner Erklärungen.',
51
+ // FIX: i18n for name
52
+ name: {
53
+ de: 'Chemie-Hilfe: Problem auswählen',
54
+ en: 'Chemistry help: select issue',
55
+ },
56
+ // FIX: i18n for desc
57
+ desc: {
58
+ de: 'Manuelle Auswahl eines beobachteten Pool-Problems zur Anzeige allgemeiner Erklärungen.',
59
+ en: 'Manual selection of an observed pool issue to display general explanations.',
60
+ },
48
61
  type: 'string',
49
62
  role: 'value',
50
63
  read: true,
51
64
  write: true,
52
65
  def: 'none',
66
+ // FIX: common.states is NOT i18n-capable -> set to English only
53
67
  states: {
54
- none: 'Kein Problem ausgewählt',
68
+ none: 'No issue selected',
55
69
 
56
- // pH-Wert
57
- ph_low: 'pH-Wert ist zu niedrig',
58
- ph_high: 'pH-Wert ist zu hoch',
70
+ // pH
71
+ ph_low: 'pH is too low',
72
+ ph_high: 'pH is too high',
59
73
 
60
- // Chlor / Desinfektion
61
- chlor_low: 'Chlorwert ist zu niedrig',
62
- chlor_high: 'Chlorwert ist zu hoch',
63
- chlor_no_effect: 'Chlor steigt trotz Zugabe nicht',
64
- chlor_smell: 'Starker Chlorgeruch trotz Messwert',
74
+ // Chlorine / disinfection
75
+ chlor_low: 'Chlorine is too low',
76
+ chlor_high: 'Chlorine is too high',
77
+ chlor_no_effect: 'Chlorine does not rise despite dosing',
78
+ chlor_smell: 'Strong chlorine smell despite reading',
65
79
 
66
- // Wasserbild / Optik
67
- water_green: 'Wasser ist grün',
68
- water_cloudy: 'Wasser ist trüb / grau / milchig',
69
- algae_visible: 'Algen an Wänden oder Boden sichtbar',
70
- foam_on_surface: 'Schaumbildung auf der Wasseroberfläche',
80
+ // Water appearance
81
+ water_green: 'Water is green',
82
+ water_cloudy: 'Water is cloudy / gray / milky',
83
+ algae_visible: 'Algae visible on walls or floor',
84
+ foam_on_surface: 'Foam on the water surface',
71
85
 
72
- // Badegefühl / Stabilität
73
- skin_eye_irritation: 'Haut- oder Augenreizungen beim Baden',
74
- values_unstable: 'Wasserwerte sind häufig instabil',
86
+ // Swim feel / stability
87
+ skin_eye_irritation: 'Skin or eye irritation when swimming',
88
+ values_unstable: 'Water values are often unstable',
75
89
 
76
- // Unsicherheit
77
- unknown_problem: 'Problem unklar / nicht eindeutig',
90
+ // Uncertainty
91
+ unknown_problem: 'Issue unclear / not specific',
78
92
  },
79
93
  },
80
94
  native: {},
@@ -86,8 +100,16 @@ async function createAiChemistryHelpStates(adapter) {
86
100
  await adapter.setObjectNotExistsAsync('ai.chemistry_help.help_text', {
87
101
  type: 'state',
88
102
  common: {
89
- name: 'Chemie-Hilfe: Erklärung',
90
- desc: 'Erklärender Text zu Ursachen und allgemeinen Lösungsansätzen (keine Dosierung, keine Steuerung).',
103
+ // FIX: i18n for name
104
+ name: {
105
+ de: 'Chemie-Hilfe: Erklärung',
106
+ en: 'Chemistry help: explanation',
107
+ },
108
+ // FIX: i18n for desc
109
+ desc: {
110
+ de: 'Erklärender Text zu Ursachen und allgemeinen Lösungsansätzen (keine Dosierung, keine Steuerung).',
111
+ en: 'Explanatory text about causes and general approaches (no dosing, no control).',
112
+ },
91
113
  type: 'string',
92
114
  role: 'text',
93
115
  read: true,
@@ -103,8 +125,16 @@ async function createAiChemistryHelpStates(adapter) {
103
125
  await adapter.setObjectNotExistsAsync('ai.chemistry_help.last_issue_time', {
104
126
  type: 'state',
105
127
  common: {
106
- name: 'Chemie-Hilfe: Letzte Auswahl',
107
- desc: 'Zeitpunkt der letzten Auswahl eines Chemie-Hilfe-Problems.',
128
+ // FIX: i18n for name
129
+ name: {
130
+ de: 'Chemie-Hilfe: Letzte Auswahl',
131
+ en: 'Chemistry help: last selection',
132
+ },
133
+ // FIX: i18n for desc
134
+ desc: {
135
+ de: 'Zeitpunkt der letzten Auswahl eines Chemie-Hilfe-Problems.',
136
+ en: 'Timestamp of the last selected chemistry help issue.',
137
+ },
108
138
  type: 'number',
109
139
  role: 'value.time',
110
140
  read: true,
@@ -114,7 +144,8 @@ async function createAiChemistryHelpStates(adapter) {
114
144
  native: {},
115
145
  });
116
146
 
117
- adapter.log.debug('[aiChemistryHelpStates] Initialisierung abgeschlossen');
147
+ // FIX: Logs must be English (mcm requirement)
148
+ adapter.log.debug('[aiChemistryHelpStates] Initialization completed');
118
149
  }
119
150
 
120
151
  module.exports = {
@@ -22,14 +22,21 @@
22
22
  * @param {import('iobroker').Adapter} adapter - ioBroker Adapterinstanz
23
23
  */
24
24
  async function createAiStates(adapter) {
25
- adapter.log.debug('[aiStates] Initialisierung gestartet');
25
+ // FIX: Logs must be English only
26
+ adapter.log.debug('[aiStates] Initialization started');
26
27
 
27
28
  // ------------------------------------------------------
28
29
  // Hauptordner: ai
29
30
  // ------------------------------------------------------
30
31
  await adapter.setObjectNotExistsAsync('ai', {
31
32
  type: 'channel',
32
- common: { name: 'KI / AI-Funktionen' },
33
+ common: {
34
+ // FIX: i18n
35
+ name: {
36
+ de: 'KI / AI-Funktionen',
37
+ en: 'AI functions',
38
+ },
39
+ },
33
40
  native: {},
34
41
  });
35
42
 
@@ -40,8 +47,16 @@ async function createAiStates(adapter) {
40
47
  await adapter.setObjectNotExistsAsync('ai.enabled', {
41
48
  type: 'state',
42
49
  common: {
43
- name: 'KI aktivieren',
44
- desc: 'Globaler Hauptschalter für alle KI-Funktionen',
50
+ // FIX: i18n
51
+ name: {
52
+ de: 'KI aktivieren',
53
+ en: 'Enable AI',
54
+ },
55
+ // FIX: i18n
56
+ desc: {
57
+ de: 'Globaler Hauptschalter für alle KI-Funktionen',
58
+ en: 'Global master switch for all AI functions',
59
+ },
45
60
  type: 'boolean',
46
61
  role: 'switch',
47
62
  read: true,
@@ -58,8 +73,16 @@ async function createAiStates(adapter) {
58
73
  await adapter.setObjectNotExistsAsync('ai.weather', {
59
74
  type: 'channel',
60
75
  common: {
61
- name: 'Wetterbezogene KI-Funktionen',
62
- desc: 'Alle KI-Funktionen rund um Wetter, Vorhersagen und Pooltipps',
76
+ // FIX: i18n
77
+ name: {
78
+ de: 'Wetterbezogene KI-Funktionen',
79
+ en: 'Weather-related AI functions',
80
+ },
81
+ // FIX: i18n
82
+ desc: {
83
+ de: 'Alle KI-Funktionen rund um Wetter, Vorhersagen und Pooltipps',
84
+ en: 'All AI functions about weather, forecasts and pool tips',
85
+ },
63
86
  },
64
87
  native: {},
65
88
  });
@@ -70,8 +93,16 @@ async function createAiStates(adapter) {
70
93
  await adapter.setObjectNotExistsAsync('ai.weather.switches', {
71
94
  type: 'channel',
72
95
  common: {
73
- name: 'Schalter (Wetter-KI)',
74
- desc: 'Einzelne Schalter für wetterbezogene KI-Funktionen',
96
+ // FIX: i18n
97
+ name: {
98
+ de: 'Schalter (Wetter-KI)',
99
+ en: 'Switches (weather AI)',
100
+ },
101
+ // FIX: i18n
102
+ desc: {
103
+ de: 'Einzelne Schalter für wetterbezogene KI-Funktionen',
104
+ en: 'Individual switches for weather-related AI functions',
105
+ },
75
106
  },
76
107
  native: {},
77
108
  });
@@ -80,17 +111,37 @@ async function createAiStates(adapter) {
80
111
  // Alle bisherigen wetterbezogenen Switches liegen jetzt unter ai.weather.switches.*
81
112
  const weatherSwitches = [
82
113
  // Steuerung & Debug für Wetter-KI
83
- { id: 'allow_speech', name: 'Sprachausgabe für Wetter-KI erlauben', def: false }, // GEÄNDERT: von ai.switches → ai.weather.switches
84
- { id: 'debug_mode', name: 'Debugmodus für Wetter-KI', def: false }, // GEÄNDERT: von ai.switches → ai.weather.switches
114
+ {
115
+ id: 'allow_speech',
116
+ name: { de: 'Sprachausgabe für Wetter-KI erlauben', en: 'Allow speech output for weather AI' },
117
+ def: false,
118
+ }, // GEÄNDERT: von ai.switches → ai.weather.switches
119
+ { id: 'debug_mode', name: { de: 'Debugmodus für Wetter-KI', en: 'Debug mode for weather AI' }, def: false }, // GEÄNDERT: von ai.switches → ai.weather.switches
85
120
 
86
121
  // Modulspezifische Schalter
87
- { id: 'daily_summary_enabled', name: 'Tägliche Zusammenfassung aktiv', def: false },
88
- { id: 'daily_pool_tips_enabled', name: 'Tägliche Pool-Tipps aktiv', def: false },
89
- { id: 'weather_advice_enabled', name: 'Wetterhinweise aktiv', def: false },
90
- { id: 'weekend_summary_enabled', name: 'Wochenende-Zusammenfassung aktiv', def: false },
122
+ {
123
+ id: 'daily_summary_enabled',
124
+ name: { de: 'Tägliche Zusammenfassung aktiv', en: 'Enable daily summary' },
125
+ def: false,
126
+ },
127
+ {
128
+ id: 'daily_pool_tips_enabled',
129
+ name: { de: 'Tägliche Pool-Tipps aktiv', en: 'Enable daily pool tips' },
130
+ def: false,
131
+ },
132
+ { id: 'weather_advice_enabled', name: { de: 'Wetterhinweise aktiv', en: 'Enable weather advice' }, def: false },
133
+ {
134
+ id: 'weekend_summary_enabled',
135
+ name: { de: 'Wochenende-Zusammenfassung aktiv', en: 'Enable weekend summary' },
136
+ def: false,
137
+ },
91
138
 
92
139
  // NEU: Schalter für "Vorhersage für morgen"
93
- { id: 'tomorrow_forecast_enabled', name: 'Vorhersage für morgen aktiv', def: false }, // NEU
140
+ {
141
+ id: 'tomorrow_forecast_enabled',
142
+ name: { de: 'Vorhersage für morgen aktiv', en: 'Enable tomorrow forecast' },
143
+ def: false,
144
+ }, // NEU
94
145
  ];
95
146
 
96
147
  for (const s of weatherSwitches) {
@@ -115,8 +166,16 @@ async function createAiStates(adapter) {
115
166
  await adapter.setObjectNotExistsAsync('ai.weather.schedule', {
116
167
  type: 'channel',
117
168
  common: {
118
- name: 'Zeitpläne (Wetter-KI)',
119
- desc: 'Zeitsteuerung für wetterbezogene KI-Ausgaben',
169
+ // FIX: i18n
170
+ name: {
171
+ de: 'Zeitpläne (Wetter-KI)',
172
+ en: 'Schedules (weather AI)',
173
+ },
174
+ // FIX: i18n
175
+ desc: {
176
+ de: 'Zeitsteuerung für wetterbezogene KI-Ausgaben',
177
+ en: 'Time control for weather-related AI outputs',
178
+ },
120
179
  },
121
180
  native: {},
122
181
  });
@@ -124,13 +183,33 @@ async function createAiStates(adapter) {
124
183
  // NEU / GEÄNDERT:
125
184
  // Alle Zeitpläne liegen jetzt unter ai.weather.schedule.*
126
185
  const weatherSchedule = [
127
- { id: 'daily_summary_time', name: 'Zeit für tägliche Zusammenfassung', def: '09:00' },
128
- { id: 'daily_pool_tips_time', name: 'Zeit für tägliche Pool-Tipps', def: '10:00' },
129
- { id: 'weather_advice_time', name: 'Zeit für Wetterhinweise', def: '08:00' },
130
- { id: 'weekend_summary_time', name: 'Zeit für Wochenend-Zusammenfassung', def: '18:00' },
186
+ {
187
+ id: 'daily_summary_time',
188
+ name: { de: 'Zeit für tägliche Zusammenfassung', en: 'Time for daily summary' },
189
+ def: '09:00',
190
+ },
191
+ {
192
+ id: 'daily_pool_tips_time',
193
+ name: { de: 'Zeit für tägliche Pool-Tipps', en: 'Time for daily pool tips' },
194
+ def: '10:00',
195
+ },
196
+ {
197
+ id: 'weather_advice_time',
198
+ name: { de: 'Zeit für Wetterhinweise', en: 'Time for weather advice' },
199
+ def: '08:00',
200
+ },
201
+ {
202
+ id: 'weekend_summary_time',
203
+ name: { de: 'Zeit für Wochenend-Zusammenfassung', en: 'Time for weekend summary' },
204
+ def: '18:00',
205
+ },
131
206
 
132
207
  // NEU: Zeitplan für "Vorhersage für morgen"
133
- { id: 'tomorrow_forecast_time', name: 'Zeit für morgige Vorhersage', def: '19:00' }, // NEU
208
+ {
209
+ id: 'tomorrow_forecast_time',
210
+ name: { de: 'Zeit für morgige Vorhersage', en: 'Time for tomorrow forecast' },
211
+ def: '19:00',
212
+ }, // NEU
134
213
  ];
135
214
 
136
215
  for (const t of weatherSchedule) {
@@ -155,8 +234,16 @@ async function createAiStates(adapter) {
155
234
  await adapter.setObjectNotExistsAsync('ai.weather.outputs', {
156
235
  type: 'channel',
157
236
  common: {
158
- name: 'KI-Ausgaben (Wetter-Texte)',
159
- desc: 'Textausgaben der Wetter-KI (Hinweise, Tipps, Zusammenfassungen)',
237
+ // FIX: i18n
238
+ name: {
239
+ de: 'KI-Ausgaben (Wetter-Texte)',
240
+ en: 'AI outputs (weather texts)',
241
+ },
242
+ // FIX: i18n
243
+ desc: {
244
+ de: 'Textausgaben der Wetter-KI (Hinweise, Tipps, Zusammenfassungen)',
245
+ en: 'Text outputs of the weather AI (advice, tips, summaries)',
246
+ },
160
247
  },
161
248
  native: {},
162
249
  });
@@ -164,16 +251,16 @@ async function createAiStates(adapter) {
164
251
  // NEU / GEÄNDERT:
165
252
  // Alle bisherigen Ausgaben + neue Vorhersage + last_message unter ai.weather.outputs.*
166
253
  const weatherOutputs = [
167
- { id: 'daily_summary', name: 'Tägliche Zusammenfassung' },
168
- { id: 'pool_tips', name: 'Pool-Tipps' },
169
- { id: 'weather_advice', name: 'Wetterhinweise' },
170
- { id: 'weekend_summary', name: 'Wochenende-Zusammenfassung' },
254
+ { id: 'daily_summary', name: { de: 'Tägliche Zusammenfassung', en: 'Daily summary' } },
255
+ { id: 'pool_tips', name: { de: 'Pool-Tipps', en: 'Pool tips' } },
256
+ { id: 'weather_advice', name: { de: 'Wetterhinweise', en: 'Weather advice' } },
257
+ { id: 'weekend_summary', name: { de: 'Wochenende-Zusammenfassung', en: 'Weekend summary' } },
171
258
 
172
259
  // NEU: Ausgabefeld für die Vorhersage für morgen
173
- { id: 'tomorrow_forecast', name: 'Vorhersage für morgen' }, // NEU
260
+ { id: 'tomorrow_forecast', name: { de: 'Vorhersage für morgen', en: 'Tomorrow forecast' } }, // NEU
174
261
 
175
262
  // GEÄNDERT: last_message gehört aktuell zur Wetter-KI
176
- { id: 'last_message', name: 'Letzte Wetter-KI-Meldung' }, // GEÄNDERT: von ai.outputs → ai.weather.outputs
263
+ { id: 'last_message', name: { de: 'Letzte Wetter-KI-Meldung', en: 'Last weather AI message' } }, // GEÄNDERT: von ai.outputs → ai.weather.outputs
177
264
  ];
178
265
 
179
266
  for (const o of weatherOutputs) {
@@ -191,7 +278,8 @@ async function createAiStates(adapter) {
191
278
  });
192
279
  }
193
280
 
194
- adapter.log.debug('[aiStates] Initialisierung abgeschlossen');
281
+ // FIX: Logs must be English only
282
+ adapter.log.debug('[aiStates] Initialization completed');
195
283
  }
196
284
 
197
285
  module.exports = {
@@ -17,18 +17,24 @@ async function createConsumptionStates(adapter) {
17
17
  // --- Kanal consumption ---
18
18
  await adapter.setObjectNotExistsAsync('consumption', {
19
19
  type: 'channel',
20
- common: { name: 'Stromverbrauch' },
20
+ common: { name: { de: 'Stromverbrauch', en: 'Power consumption' } },
21
21
  native: {},
22
22
  });
23
23
 
24
24
  const consumptionStates = {
25
- total_kwh: { name: 'Gesamtverbrauch', unit: 'kWh' },
26
- day_kwh: { name: 'Verbrauch heute', unit: 'kWh' },
27
- week_kwh: { name: 'Verbrauch diese Woche', unit: 'kWh' },
28
- month_kwh: { name: 'Verbrauch dieser Monat', unit: 'kWh' },
29
- year_kwh: { name: 'Verbrauch dieses Jahr', unit: 'kWh' },
30
- last_total_kwh: { name: 'Letzter Zählerstand (Baseline)', unit: 'kWh' },
31
- offset_kwh: { name: 'Offset kWh (interner Zählerausgleich)', unit: 'kWh' },
25
+ total_kwh: { name: { de: 'Gesamtverbrauch', en: 'Total consumption' }, unit: 'kWh' },
26
+ day_kwh: { name: { de: 'Verbrauch heute', en: 'Consumption today' }, unit: 'kWh' },
27
+ week_kwh: { name: { de: 'Verbrauch diese Woche', en: 'Consumption this week' }, unit: 'kWh' },
28
+ month_kwh: { name: { de: 'Verbrauch dieser Monat', en: 'Consumption this month' }, unit: 'kWh' },
29
+ year_kwh: { name: { de: 'Verbrauch dieses Jahr', en: 'Consumption this year' }, unit: 'kWh' },
30
+ last_total_kwh: {
31
+ name: { de: 'Letzter Zählerstand (Baseline)', en: 'Last meter reading (baseline)' },
32
+ unit: 'kWh',
33
+ },
34
+ offset_kwh: {
35
+ name: { de: 'Offset kWh (interner Zählerausgleich)', en: 'Offset kWh (internal counter adjustment)' },
36
+ unit: 'kWh',
37
+ },
32
38
  };
33
39
 
34
40
  for (const [id, cfg] of Object.entries(consumptionStates)) {
@@ -55,16 +61,16 @@ async function createConsumptionStates(adapter) {
55
61
  // --- Kanal costs ---
56
62
  await adapter.setObjectNotExistsAsync('costs', {
57
63
  type: 'channel',
58
- common: { name: 'Kosten' },
64
+ common: { name: { de: 'Kosten', en: 'Costs' } },
59
65
  native: {},
60
66
  });
61
67
 
62
68
  const costStates = {
63
- total_eur: { name: 'Gesamtkosten', unit: '€' },
64
- day_eur: { name: 'Kosten heute', unit: '€' },
65
- week_eur: { name: 'Kosten diese Woche', unit: '€' },
66
- month_eur: { name: 'Kosten dieser Monat', unit: '€' },
67
- year_eur: { name: 'Kosten dieses Jahr', unit: '€' },
69
+ total_eur: { name: { de: 'Gesamtkosten', en: 'Total costs' }, unit: '€' },
70
+ day_eur: { name: { de: 'Kosten heute', en: 'Costs today' }, unit: '€' },
71
+ week_eur: { name: { de: 'Kosten diese Woche', en: 'Costs this week' }, unit: '€' },
72
+ month_eur: { name: { de: 'Kosten dieser Monat', en: 'Costs this month' }, unit: '€' },
73
+ year_eur: { name: { de: 'Kosten dieses Jahr', en: 'Costs this year' }, unit: '€' },
68
74
  };
69
75
 
70
76
  for (const [id, cfg] of Object.entries(costStates)) {