iobroker.utility-monitor 1.4.2 → 1.4.5

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 CHANGED
@@ -96,11 +96,11 @@ Für jede aktivierte Verbrauchsart (Gas/Wasser/Strom/PV) werden folgende Ordner
96
96
  | `daily` | Kosten **heute** | daily × Arbeitspreis | 2,27 € |
97
97
  | `monthly` | Kosten **diesen Monat** | monthly × Arbeitspreis | 21,61 € |
98
98
  | `yearly` | **Verbrauchskosten** seit Vertragsbeginn | yearly × Arbeitspreis | 137,61 € |
99
- | `totalYearly` | **Gesamtkosten Jahr** (Verbrauch + alle Fixkosten) | yearly-cost + basicCharge + annualFee | 162,64 € |
100
- | `basicCharge` | **Grundgebühr akkumuliert** (inkl. Jahresgebühr anteilig) | (Grundgebühr + (Jahresgebühr/12)) × Monate | 19,20 € |
101
- | `annualFee` | **Jahresgebühr akkumuliert** | (Jahresgebühr / 12) × Monate | 4,17 |
99
+ | `totalYearly` | **Gesamtkosten Jahr** (Verbrauch + alle Fixkosten) | yearly-cost + basicCharge + annualFee | 212,64 € |
100
+ | `basicCharge` | **Grundgebühr akkumuliert** | Grundgebühr × Monate | 15,03 € |
101
+ | `annualFee` | **Jahresgebühr** (fester Wert pro Jahr) | Jahresgebühr (aus Config) | 60,00 |
102
102
  | `paidTotal` | **Bezahlt** via Abschlag | Abschlag × Monate | 150,00 € |
103
- | `balance` | **🎯 WICHTIGSTER Wert!**<br>Nachzahlung (+) oder Guthaben (-) | totalYearly - paidTotal | **+12,64 €**<br>→ Nachzahlung! |
103
+ | `balance` | **🎯 WICHTIGSTER Wert!**<br>Nachzahlung (+) oder Guthaben (-) | totalYearly - paidTotal | **+62,64 €**<br>→ Nachzahlung! |
104
104
 
105
105
  #### 🔍 **balance** genauer erklärt:
106
106
 
@@ -112,13 +112,14 @@ Für jede aktivierte Verbrauchsart (Gas/Wasser/Strom/PV) werden folgende Ordner
112
112
 
113
113
  ```
114
114
  Verbrauchskosten: 137,61 € (yearly)
115
- Grundgebühr: + 15,03 € (basicCharge)
115
+ Grundgebühr: + 15,03 € (basicCharge - 1 Monat × 15,03€)
116
+ Jahresgebühr: + 60,00 € (annualFee - fester Wert)
116
117
  ────────────────────────────
117
- Gesamtkosten: 152,64 €
118
+ Gesamtkosten: 212,64 € (totalYearly)
118
119
 
119
- Bezahlt (Abschlag): 150,00 € (paidTotal)
120
+ Bezahlt (Abschlag): 150,00 € (paidTotal - 1 Monat × 150€)
120
121
  ────────────────────────────
121
- Balance: +2,64 € → Nachzahlung
122
+ Balance: +62,64 € → Nachzahlung
122
123
  ```
123
124
 
124
125
  ---
@@ -228,7 +229,20 @@ Der Adapter setzt Zähler automatisch zurück:
228
229
 
229
230
  ## Changelog
230
231
 
231
- ### **WORK IN PROGRESS**
232
+ ### 1.4.5 (2026-01-20)
233
+
234
+ - **FIX:** 🐛 **Critical Multi-Meter Cost Calculation Bugs** - Comprehensive fixes for multi-meter functionality:
235
+ - **Main Meter Sync Issue**: Removed duplicate initialization that prevented `lastSync` updates on main meter
236
+ - **basicCharge Accumulation**: Now correctly calculates `basicCharge = grundgebuehr × months` (was showing only 1 month)
237
+ - **paidTotal Accumulation**: Now correctly calculates `paidTotal = abschlag × months` (was showing only 1 month)
238
+ - **annualFee as Fixed Value**: Jahresgebühr is now used as fixed yearly value (e.g., 60€ stays 60€)
239
+ - Previously incorrectly treated as monthly fee and multiplied by months
240
+ - User-entered value in config (e.g., 60€) is now used directly as intended
241
+ - **Balance Formula Corrected**: Fixed reversed formula `balance = totalYearly - paidTotal`
242
+ - Positive balance = Nachzahlung (you owe money)
243
+ - Negative balance = Guthaben (you get money back)
244
+ - **IMPROVED:** 📦 **Dev-Dependencies**: Updated from tilde (~) to caret (^) versioning for better security updates
245
+ - **CLEANUP:** 🧹 **Repository Compliance**: Removed unpublished versions from changelog (resolves ioBroker Bot Issue #1)
232
246
 
233
247
  ### 1.4.2 (2026-01-18)
234
248
 
@@ -252,129 +266,6 @@ Der Adapter setzt Zähler automatisch zurück:
252
266
  - Prevents silent failures in StateManager
253
267
  - **IMPROVED:** 🧪 **Code Quality** - All tests passing (31 unit + 57 package tests)
254
268
 
255
- ### 1.4.1 (2026-01-18)
256
-
257
- - **FIX:** 🐛 **Multi-Meter Critical Bugs** - Comprehensive fixes for multi-meter functionality:
258
- - Fixed `updateCosts()` to correctly delegate to multiMeterManager for all meters
259
- - Fixed `closeBillingPeriod()` to archive totals instead of only main meter values
260
- - Fixed `checkMonthlyReport()` to display totals in reports for multi-meter setups
261
- - Fixed state type mismatch: `lastDayStart`, `lastMonthStart`, `lastYearStart` now use number (timestamp) instead of string
262
- - **NEW:** 🎯 **Per-Meter Billing Closure** - Each meter can now be closed individually with its own `billing.closePeriod` button
263
- - Main meter: `gas.billing.closePeriod`
264
- - Additional meters: `gas.erdgeschoss.billing.closePeriod`, `gas.keller.billing.closePeriod`, etc.
265
- - Each meter uses its own contract date for yearly resets
266
- - **NEW:** 📅 **Individual Contract Anniversary Resets** - Each meter resets on its own contract date
267
- - Primary: Manual `closePeriod` triggers yearly reset immediately
268
- - Fallback: Automatic reset on contract anniversary if user forgets to close period
269
- - Contract date is preserved when closing period early (no drift)
270
- - **IMPROVED:** 💰 **Billing Period Closure** - No longer resets `basicCharge` and `annualFee` to zero
271
- - These values now persist from config (user must update config if tariff changes)
272
- - Helpful reminder message added after closing period
273
- - **FIX:** 🤖 **ioBroker Bot Compliance** - All bot checker issues resolved:
274
- - Removed non-existent version 1.3.4 from news
275
- - Added complete translations for all news entries (9 languages)
276
- - Removed `.npmignore` file (using `files` field in package.json)
277
- - DevDependencies already use `~` syntax (compliant)
278
-
279
- ### 1.4.0 (2026-01-17)
280
-
281
- - **NEW:** 🎉 **Multi-Meter Support** - Verwende mehrere Zähler pro Typ (z.B. Gas Hauptzähler + Werkstatt-Zähler)
282
- - Beliebig viele zusätzliche Zähler mit eigenen Namen konfigurierbar
283
- - Separate Kostenberechnung und Statistiken pro Zähler
284
- - Automatische Totals-Berechnung über alle Zähler
285
- - **NEW:** ✨ **Komma-Dezimaltrenner Support** - Admin UI akzeptiert jetzt sowohl Komma als auch Punkt (z.B. `12,50` oder `12.50`)
286
- - **NEW:** 📊 **Pro-Meter Billing** - Jeder Zähler hat eigene `billing.daysRemaining` und `billing.periodEnd` Werte
287
- - **NEW:** 🔧 **Config-Parser** - Automatische Konvertierung von String→Number mit Komma-Support
288
- - **FIX:** 💰 **Balance-Berechnung korrigiert** - Nutzt jetzt begonnene Monate statt volle Monate (17 Tage = 1 Monat gezahlt)
289
- - **FIX:** 🐛 **String-Type Fehler** behoben - Config-Werte werden korrekt als Numbers verarbeitet
290
- - **IMPROVED:** 🔍 **Debug-Logging** - Hilfreiche Debug-Logs für Troubleshooting (nur in Debug-Modus sichtbar)
291
- - **CLEANUP:** 🧹 Repository aufgeräumt - Alte Backup-Dateien und temporäre Scripts entfernt
292
-
293
- ### 1.3.5 (2026-01-11)
294
-
295
- - **NEW:** **Monatlicher Status-Bericht** - Optionaler monatlicher Bericht per Benachrichtigung.
296
- - **NEW:** Datenpunkte `statistics.lastDay` (Verbrauch gestern) für alle Typen und `lastDayVolume` (Gas) hinzugefügt.
297
- - **FIX:** **PV-Reset Bug** behoben (Tages- und Monatswerte wurden nicht zurückgesetzt).
298
- - **FIX:** Schema-Validierung für Preisfelder korrigiert (Fix für Kommastellen).
299
- - **FIX:** HT/NT-Anzeige korrigiert.
300
- - **IMPROVED:** **Admin-UI Info-Tab** komplett optimiert (Sauberes Markdown & Layout).
301
- - **IMPROVED:** Einheitliche Rundung berechneter Werte auf **2 Nachkommastellen** (daily, monthly, yearly).
302
- - **ROBUSTNESS:** ioBroker Bot Compliance Check (Grid-Attribute in Admin-UI vereinheitlicht).
303
-
304
- ### 1.3.4 (2026-01-10)
305
-
306
- - **FIX:** Kritischer Fix: Kommastellen für Gebühren-Felder (Grundgebühr, Arbeitspreis) werden nun korrekt gespeichert (Erlaubt 4 Nachkommastellen).
307
-
308
- ### 1.3.3 (2026-01-09)
309
-
310
- - **IMPROVED:** Konfigurations-Reihenfolge optimiert (Gebühren logisch gruppiert).
311
- - **NEW:** **PV-Benachrichtigungen** - Erhalte Erinnerungen auch für deine PV-Anlage (Abrechnung/Vertrag).
312
-
313
- ### 1.3.2 (2026-01-09)
314
-
315
- - **NEW:** **PV / Einspeise-Unterstützung** ☀️ - Neuer Tab für Photovoltaik:
316
- - Überwache deine Netzeinspeisung (kWh).
317
- - Berechne deine Vergütung (Earnings) automatisch.
318
- - Volle Unterstützung für Zählerstände, Abrechnungszeiträume und Historie.
319
-
320
- ### 1.3.1 (2026-01-09)
321
-
322
- - **FIX:** Kritischer Fehler behoben: HT/NT-Datenpunkte wurden aufgrund eines internen Namensfehlers (electricity vs. strom) nicht angelegt.
323
- - **FIX:** Warnungen im Log "State ... has no existing object" beseitigt.
324
-
325
- ### 1.3.0 (2026-01-09)
326
-
327
- - **NEW:** **Differenzierte Benachrichtigungen** - Zwei getrennte Erinnerungstypen:
328
- - **Abrechnungsende**: Erinnerung zum Zählerstand ablesen (z.B. 7 Tage vorher).
329
- - **Vertragswechsel**: Erinnerung zum Tarif-Check / Kündigen (z.B. 60 Tage vorher).
330
- - **NEW:** **Interaktives Benachrichtigungs-Feedback** - Der Test-Button zeigt nun direkt Erfolgs- oder Fehlermeldungen via Popup an (inkl. SMTP-Fehler vom Email-Adapter).
331
- - **NEW:** **Live-Test ohne Speichern** - Benachrichtigungen können jetzt sofort getestet werden, ohne die Konfiguration vorher speichern zu müssen.
332
- - **NEW:** **Modularer Code-Aufbau** - Umstellung auf eine moderne Architektur mit spezialisierten Managern für bessere Performance und Wartbarkeit.
333
- - **IMPROVED:** **Responsives Admin-UI** - Kompakteres Button-Design und optimierte Darstellung auf mobilen Geräten.
334
- - **FIX:** Redundante Volumen-Datenpunkte (`dailyVolume` etc.) für Strom und Wasser entfernt, um Log-Warnungen zu vermeiden.
335
- - **FIX:** Mandatory bot requirements (Changelog header, News cleanup).
336
-
337
- ### 1.2.7 (2026-01-08)
338
-
339
- - **NEW:** Universelles Benachrichtigungssystem für Abrechnungszeitraum-Erinnerungen (Telegram, Pushover, Email, etc.)
340
- - **NEW:** Optionale PayPal-Unterstützung (Links in README und Config)
341
- - **FIX:** Dezimalstellen für Tagesverbrauch auf 3 erhöht (bessere Unterstützung für Sensoren mit kleinen Deltas wie Shelly)
342
- - **FIX:** Erlauben von leeren Preisen/Gebühren in der Konfiguration (verhindert Speicher-Fehler)
343
-
344
- ### 1.2.6 (2026-01-08)
345
-
346
- - **FIX:** Erlaube leere Felder für Grundgebühr/Jahresgebühr/Abschlag in der Konfiguration (verhindert Speicher-Block im Admin-UI)
347
-
348
- ### 1.2.5 (2026-01-08)
349
-
350
- - **NEW:** Transparente Anzeige des Vertragsbeginns bei jedem Adapter-Start im Log
351
- - **NEW:** Unterstützung für zusätzliche **Jahresgebühren** (z.B. Zählermiete)
352
- - **NEW:** Datenpunkt `costs.totalYearly` für die echten Gesamtkosten
353
- - **FIX:** Kritischer Fehler in der Verbrauchs-Delta-Berechnung behoben (v1.2.4)
354
- - **FIX:** Arbeitspreis-Anzeige bei Strom korrigiert
355
- - **FIX:** Gas m³ → kWh Umrechnung für Anpassungswerte
356
- - **FIX:** Korrekte Initialisierung des Vertragsjahres bei Neustart
357
- - **FIX:** Vereinheitlichung der Konfigurationsschlüssel (`wasserInitialReading`)
358
- - **ROBUSTNESS:** Schutz vor Datenverlust bei Adapter-Neustart (Zählerstand-Persistierung)
359
- - **ROBUSTNESS:** Integration von manuellen Anpassungen in die HT/NT-Kostenrechnung
360
- - **NEW:** Volle Unterstützung für **HT/NT-Tarife** für alle Energieträger (Strom, Gas, Wasser)
361
- - **NEW:** Automatische Archivierung von HT/NT-Verbräuchen und Kosten in der Historie
362
- - **DOCS:** Internationalisierung von Titel und Beschreibung
363
-
364
- ### 1.2.2 (2026-01-08)
365
-
366
- - **NEW:** Manuelle Anpassung für Sensor-Abdrift-Korrektur
367
- - **NEW:** Abrechnungszeitraum-Management mit automatischer Archivierung
368
- - **NEW:** Unterstützung für zusätzliche **Jahresgebühren** (z.B. Zählermiete)
369
- - **NEW:** Datenpunkt `costs.totalYearly` für die echten Gesamtkosten
370
- - **FIX:** Arbeitspreis-Anzeige bei Strom korrigiert
371
- - **FIX:** Gas m³ → kWh Umrechnung für Anpassungswerte
372
- - **DOCS:** Internationalisierung von Titel und Beschreibung
373
-
374
- ---
375
-
376
- - Initial release
377
-
378
269
  ---
379
270
 
380
271
  ## License
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "utility-monitor",
4
- "version": "1.4.2",
4
+ "version": "1.4.5",
5
5
  "news": {
6
+ "1.4.5": {
7
+ "en": "Fix: Critical multi-meter cost calculation bugs (main meter sync, basicCharge/paidTotal accumulation, annualFee as fixed yearly value). Fix: Balance formula corrected. Fix: Removed duplicate initialization causing sync issues.",
8
+ "de": "Fix: Kritische Multi-Meter Kostenberechnungsfehler (Hauptzähler-Sync, basicCharge/paidTotal Akkumulation, Jahresgebühr als fester Jahreswert). Fix: Balance-Formel korrigiert. Fix: Doppelte Initialisierung entfernt.",
9
+ "ru": "Исправление: Критические ошибки расчета затрат multi-meter (синхронизация главного счетчика, накопление basicCharge/paidTotal, annualFee как фиксированное годовое значение). Исправление: Формула баланса исправлена. Исправление: Удалена дублирующая инициализация.",
10
+ "pt": "Correção: Bugs críticos de cálculo de custos multi-medidor (sincronização medidor principal, acumulação basicCharge/paidTotal, annualFee como valor anual fixo). Correção: Fórmula de saldo corrigida. Correção: Inicialização duplicada removida.",
11
+ "nl": "Fix: Kritieke multi-meter kostenberekeningsfouten (hoofdmeter sync, basicCharge/paidTotal accumulatie, annualFee als vaste jaarwaarde). Fix: Balans formule gecorrigeerd. Fix: Dubbele initialisatie verwijderd.",
12
+ "fr": "Correction: Bugs critiques calcul coûts multi-compteurs (sync compteur principal, accumulation basicCharge/paidTotal, annualFee comme valeur annuelle fixe). Correction: Formule de solde corrigée. Correction: Initialisation en double supprimée.",
13
+ "it": "Correzione: Bug critici calcolo costi multi-contatore (sync contatore principale, accumulazione basicCharge/paidTotal, annualFee come valore annuale fisso). Correzione: Formula bilancio corretta. Correzione: Inizializzazione duplicata rimossa.",
14
+ "es": "Corrección: Bugs críticos cálculo costos multi-medidor (sincronización medidor principal, acumulación basicCharge/paidTotal, annualFee como valor anual fijo). Corrección: Fórmula balance corregida. Corrección: Inicialización duplicada eliminada.",
15
+ "pl": "Naprawa: Krytyczne błędy obliczania kosztów multi-meter (synchronizacja głównego licznika, akumulacja basicCharge/paidTotal, annualFee jako stała wartość roczna). Naprawa: Formuła salda poprawiona. Naprawa: Usunięto podwójną inicjalizację.",
16
+ "uk": "Виправлення: Критичні помилки розрахунку витрат multi-meter (синхронізація головного лічильника, накопичення basicCharge/paidTotal, annualFee як фіксоване річне значення). Виправлення: Формула балансу виправлена. Виправлення: Видалено подвійну ініціалізацію.",
17
+ "zh-cn": "修复:关键多表成本计算错误(主表同步、basicCharge/paidTotal累积、annualFee作为固定年值)。修复:余额公式已更正。修复:删除重复初始化。"
18
+ },
6
19
  "1.4.2": {
7
20
  "en": "Fix: Critical multi-meter balance bug (hardcoded 12 months). Fix: TypeScript errors resolved. New: Enhanced input validation. New: Extended constants. New: Error handling wrapper.",
8
21
  "de": "Fix: Kritischer Multi-Meter Balance-Bug (hardcodierte 12 Monate). Fix: TypeScript-Fehler behoben. Neu: Erweiterte Eingabevalidierung. Neu: Erweiterte Konstanten. Neu: Fehlerbehandlungs-Wrapper.",
@@ -15,71 +28,6 @@
15
28
  "pl": "Naprawa: Krytyczny błąd salda multi-meter (zakodowane 12 miesięcy). Naprawa: Naprawione błędy TypeScript. Nowe: Ulepszona walidacja danych. Nowe: Rozszerzone stałe. Nowe: Wrapper obsługi błędów.",
16
29
  "uk": "Виправлення: Критична помилка балансу multi-meter (жорстко задані 12 місяців). Виправлення: Усунено помилки TypeScript. Нове: Покращена перевірка даних. Нове: Розширені константи. Нове: Обробник помилок.",
17
30
  "zh-cn": "修复:关键多表余额错误(硬编码12个月)。修复:解决TypeScript错误。新增:增强输入验证。新增:扩展常量。新增:错误处理包装器。"
18
- },
19
- "1.4.1": {
20
- "en": "Fix: Multi-meter bugs (cost calculation, billing period closure, monthly reports, yearly resets). Fix: Per-meter billing closure support. Fix: State type corrections (lastDayStart). Fix: ioBroker Bot compliance.",
21
- "de": "Fix: Multi-Meter-Fehler (Kostenberechnung, Periodenabschluss, Monatsberichte, Jahres-Resets). Fix: Zähler-individuelle Periodenabschlüsse. Fix: State-Typ-Korrekturen (lastDayStart). Fix: ioBroker Bot-Compliance.",
22
- "ru": "Исправление: Ошибки нескольких счетчиков (расчет затрат, закрытие периода, ежемесячные отчеты, годовые сбросы). Исправление: Поддержка закрытия периода для каждого счетчика. Исправление: Исправления типов состояний. Исправление: Соответствие ioBroker Bot.",
23
- "pt": "Correção: Bugs multi-medidor (cálculo custos, fechamento período, relatórios mensais, resets anuais). Correção: Suporte fechamento período por medidor. Correção: Correções tipo estado. Correção: Conformidade Bot ioBroker.",
24
- "nl": "Fix: Multi-meter bugs (kostenberekening, periode afsluiting, maandraporten, jaarlijkse resets). Fix: Per-meter periode afsluiting. Fix: State type correcties. Fix: ioBroker Bot compliance.",
25
- "fr": "Correction: Bugs multi-compteurs (calcul coûts, clôture période, rapports mensuels, réinitialisations annuelles). Correction: Support clôture période par compteur. Correction: Corrections type d'état. Correction: Conformité Bot ioBroker.",
26
- "it": "Correzione: Bug multi-contatore (calcolo costi, chiusura periodo, report mensili, reset annuali). Correzione: Supporto chiusura periodo per contatore. Correzione: Correzioni tipo stato. Correzione: Conformità Bot ioBroker.",
27
- "es": "Corrección: Bugs multi-medidor (cálculo costos, cierre período, informes mensuales, reinicios anuales). Corrección: Soporte cierre período por medidor. Corrección: Correcciones tipo estado. Corrección: Cumplimiento Bot ioBroker.",
28
- "pl": "Naprawa: Błędy wielu liczników (obliczanie kosztów, zamknięcie okresu, raporty miesięczne, resety roczne). Naprawa: Wsparcie zamknięcia okresu dla licznika. Naprawa: Poprawki typu stanu. Naprawa: Zgodność z Bot ioBroker.",
29
- "uk": "Виправлення: Помилки кількох лічильників (розрахунок витрат, закриття періоду, місячні звіти, річні скидання). Виправлення: Підтримка закриття періоду для лічильника. Виправлення: Виправлення типу стану. Виправлення: Відповідність ioBroker Bot.",
30
- "zh-cn": "修复:多表错误(成本计算、期间关闭、月度报告、年度重置)。修复:每表期间关闭支持。修复:状态类型更正。修复:ioBroker Bot合规性。"
31
- },
32
- "1.4.0": {
33
- "en": "New: Multi-Meter Support! Add unlimited custom-named meters per utility type (gas, water, electricity). Automatic totals calculation. Fully backward compatible.",
34
- "de": "Neu: Multi-Meter-Unterstützung! Unbegrenzt viele Zähler pro Medium (Gas, Wasser, Strom) mit benutzerdefinierten Namen. Automatische Gesamt-Summen. Vollständig rückwärtskompatibel.",
35
- "ru": "Новое: Поддержка нескольких счетчиков! Добавьте неограниченное количество пользовательских счетчиков для каждого типа коммунальных услуг (газ, вода, электричество). Автоматический расчет итогов. Полная обратная совместимость.",
36
- "pt": "Novo: Suporte Multi-Medidor! Adicione medidores personalizados ilimitados por tipo de utilidade (gás, água, eletricidade). Cálculo automático de totais. Totalmente compatível com versões anteriores.",
37
- "nl": "Nieuw: Multi-Meter Ondersteuning! Voeg onbeperkt aangepaste meters toe per type (gas, water, elektriciteit). Automatische totaalberekening. Volledig achterwaarts compatibel.",
38
- "fr": "Nouveau: Support Multi-Compteur! Ajoutez des compteurs personnalisés illimités par type de service (gaz, eau, électricité). Calcul automatique des totaux. Entièrement rétrocompatible.",
39
- "it": "Nuovo: Supporto Multi-Contatore! Aggiungi contatori personalizzati illimitati per tipo di servizio (gas, acqua, elettricità). Calcolo automatico dei totali. Completamente retrocompatibile.",
40
- "es": "Nuevo: Soporte Multi-Medidor! Agregue medidores personalizados ilimitados por tipo de servicio (gas, agua, electricidad). Cálculo automático de totales. Totalmente compatible con versiones anteriores.",
41
- "pl": "Nowe: Obsługa Wielu Liczników! Dodaj nieograniczoną liczbę niestandardowych liczników dla każdego typu mediów (gaz, woda, prąd). Automatyczne obliczanie sum. Pełna kompatybilność wsteczna.",
42
- "uk": "Нове: Підтримка кількох лічильників! Додайте необмежену кількість власних лічильників для кожного типу комунальних послуг (газ, вода, електрика). Автоматичний розрахунок підсумків. Повна зворотна сумісність.",
43
- "zh-cn": "新增:多表支持!为每种公用事业类型(燃气、水、电)添加无限的自定义计量表。自动总计计算。完全向后兼容。"
44
- },
45
- "1.3.5": {
46
- "en": "New: Monthly Status Report. New: Added lastDay statistics. Fix: PV period reset bug. Fix: Schema validation for prices. Improved: Admin UI Info-Tab optimized. Improved: Consistent rounding (2 decimals). Improved: Bot compliance grid attributes.",
47
- "de": "Neu: Monatlicher Status-Bericht. Neu: lastDay-Statistiken hinzugefügt. Fix: PV Perioden-Reset Fehler behoben. Fix: Schema-Validierung für Preisfelder. Verbessert: Admin-UI Info-Tab optimiert. Verbessert: Einheitliche Rundung (2 Stellen). Verbessert: Bot-Compliance Grid-Attribute.",
48
- "ru": "Новое: Ежемесячный отчет о состоянии. Новое: Добавлена статистика lastDay. Исправление: Ошибка сброса периода PV. Исправление: Проверка схемы для цен. Улучшено: Оптимизирована вкладка информации Admin UI. Улучшено: Последовательное округление (2 знака). Улучшено: Атрибуты сетки соответствия ботов.",
49
- "pt": "Novo: Relatório de Status Mensal. Novo: Adicionadas estatísticas lastDay. Correção: Bug de redefinição de período PV. Correção: Validação de esquema para preços. Melhorado: Guia de informações da Admin UI otimizada. Melhorado: Arredondamento consistente (2 decimais). Melhorado: Atributos de grade de conformidade do bot.",
50
- "nl": "Nieuw: Maandelijks statusrapport. Nieuw: lastDay statistieken toegevoegd. Fix: PV periode reset bug. Fix: Schema validatie voor prijzen. Verbeterd: Admin UI Info-Tab geoptimaliseerd. Verbeterd: Consistente afronding (2 decimalen). Verbeterd: Bot compliance grid attributen.",
51
- "fr": "Nouveau: Rapport d'état mensuel. Nouveau: Ajout de statistiques lastDay. Correction: Bug de réinitialisation de période PV. Correction: Validation de schéma pour les prix. Amélioré: Onglet d'informations Admin UI optimisé. Amélioré: Arrondi cohérent (2 décimales). Amélioré: Attributs de grille de conformité des bots.",
52
- "it": "Nuovo: Rapporto di stato mensile. Nuovo: Aggiunte statistiche lastDay. Correzione: Bug di reset periodo PV. Correzione: Convalida dello schema per i prezzi. Migliorato: Scheda informazioni Admin UI ottimizzata. Migliorato: Arrotondamento coerente (2 decimali). Migliorato: Attributi griglia conformità bot.",
53
- "es": "Nuevo: Informe de Estado Mensual. Nuevo: Agregadas estadísticas lastDay. Corrección: Error de reinicio de período PV. Corrección: Validación de esquema para precios. Mejorado: Pestaña de información de Admin UI optimizada. Mejorado: Redondeo consistente (2 decimales). Mejorado: Atributos de cuadrícula de cumplimiento de bots.",
54
- "pl": "Nowe: Miesięczny raport statusu. Nowe: Dodano statystyki lastDay. Naprawa: Błąd resetowania okresu PV. Naprawa: Walidacja schematu dla cen. Ulepszone: Zoptymalizowana zakładka informacji Admin UI. Ulepszone: Spójne zaokrąglanie (2 miejsca dziesiętne). Ulepszone: Atrybuty siatki zgodności botów.",
55
- "uk": "Нове: Щомісячний звіт про стан. Нове: Додано статистику lastDay. Виправлення: Помилка скидання періоду PV. Виправлення: Перевірка схеми для цін. Покращено: Оптимізовано вкладку інформації Admin UI. Покращено: Послідовне округлення (2 знаки). Покращено: Атрибути сітки відповідності ботів.",
56
- "zh-cn": "新增:每月状态报告。新增:添加了lastDay统计信息。修复:PV周期重置错误。修复:价格架构验证。改进:优化了Admin UI信息选项卡。改进:一致的四舍五入(2位小数)。改进:机器人合规网格属性。"
57
- },
58
- "1.3.3": {
59
- "en": "New: PV/Feed-in integration! Monitor your solar feed-in and earnings. New: Notifications for PV. Improved: Reorganized config UI.",
60
- "de": "Neu: PV/Einspeise-Integration! Überwache deine Solareinspeisung und Vergütung. Neu: Benachrichtigungen für PV. Verbessert: Aufgeräumte Konfigurations-Oberfläche.",
61
- "ru": "Новое: Интеграция PV/Feed-in! Отслеживайте свою солнечную подачу и доходы. Новое: Уведомления для PV. Улучшено: Реорганизован интерфейс конфигурации.",
62
- "pt": "Novo: Integração PV/Feed-in! Monitore sua alimentação solar e ganhos. Novo: Notificações para PV. Melhorado: IU de configuração reorganizada.",
63
- "nl": "Nieuw: PV/Feed-in integratie! Monitor je zonne-invoeding en inkomsten. Nieuw: Meldingen voor PV. Verbeterd: Gereorganiseerde configuratie-UI.",
64
- "fr": "Nouveau: Intégration PV/Feed-in! Surveillez votre injection solaire et vos revenus. Nouveau: Notifications pour PV. Amélioré: Interface de configuration réorganisée.",
65
- "it": "Nuovo: Integrazione PV/Feed-in! Monitora il tuo immissione solare e i guadagni. Nuovo: Notifiche per PV. Migliorato: IU di configurazione riorganizzata.",
66
- "es": "Nuevo: Integración PV/Feed-in! Monitorea tu alimentación solar y ganancias. Nuevo: Notificaciones para PV. Mejorado: IU de configuración reorganizada.",
67
- "pl": "Nowe: Integracja PV/Feed-in! Monitoruj swoje zasilanie słoneczne i zarobki. Nowe: Powiadomienia dla PV. Ulepszone: Zreorganizowany interfejs konfiguracji.",
68
- "uk": "Нове: Інтеграція PV/Feed-in! Відстежуйте своє сонячне живлення та доходи. Нове: Сповіщення для PV. Покращено: Реорганізований інтерфейс конфігурації.",
69
- "zh-cn": "新增:PV/Feed-in集成!监控您的太阳能馈入和收益。新增:PV通知。改进:重新组织的配置界面。"
70
- },
71
- "1.3.2": {
72
- "en": "New: Initial support for PV integration.",
73
- "de": "Neu: Erste Unterstützung für PV-Integration.",
74
- "ru": "Новое: Начальная поддержка интеграции PV.",
75
- "pt": "Novo: Suporte inicial para integração PV.",
76
- "nl": "Nieuw: Initiële ondersteuning voor PV-integratie.",
77
- "fr": "Nouveau: Support initial pour l'intégration PV.",
78
- "it": "Nuovo: Supporto iniziale per l'integrazione PV.",
79
- "es": "Nuevo: Soporte inicial para integración PV.",
80
- "pl": "Nowe: Wstępne wsparcie dla integracji PV.",
81
- "uk": "Нове: Початкова підтримка інтеграції PV.",
82
- "zh-cn": "新增:PV集成的初始支持。"
83
31
  }
84
32
  },
85
33
  "titleLang": {
@@ -155,10 +155,14 @@ class BillingManager {
155
155
  monthsSinceContract = Math.max(1, yDiff * 12 + mDiff + 1);
156
156
  }
157
157
 
158
+ // Calculate accumulated basic charge (monthly fee × months)
158
159
  const basicChargeAccumulated = basicChargeMonthly * monthsSinceContract;
159
- const annualFeeAccumulated = (annualFeePerYear / 12) * monthsSinceContract;
160
- const totalFixCostsAccumulated = basicChargeAccumulated + annualFeeAccumulated;
161
- const totalYearlyCost = yearlyConsumptionCost + totalFixCostsAccumulated;
160
+
161
+ // Jahresgebühr ist ein FIXER Wert pro Jahr (z.B. 60€)
162
+ // NICHT pro-rata nach Monaten/Tagen berechnen!
163
+ const annualFeeAccumulated = annualFeePerYear;
164
+
165
+ const totalYearlyCost = yearlyConsumptionCost + basicChargeAccumulated + annualFeeAccumulated;
162
166
 
163
167
  // Update states
164
168
  await this.adapter.setStateAsync(
@@ -186,9 +190,11 @@ class BillingManager {
186
190
  calculator.roundToDecimals(annualFeeAccumulated, 2),
187
191
  true,
188
192
  );
193
+ // basicCharge enthält NUR die monatliche Grundgebühr (akkumuliert)
194
+ // Jahresgebühr ist separat in annualFee
189
195
  await this.adapter.setStateAsync(
190
196
  `${type}.costs.basicCharge`,
191
- calculator.roundToDecimals(totalFixCostsAccumulated, 2),
197
+ calculator.roundToDecimals(basicChargeAccumulated, 2),
192
198
  true,
193
199
  );
194
200
 
@@ -438,7 +444,7 @@ class BillingManager {
438
444
  const configType = this.adapter.consumptionManager.getConfigType(type);
439
445
  contractStartDate = this.adapter.config[`${configType}ContractStart`];
440
446
  } else {
441
- contractStartDate = meter.config?.vertragsbeginn;
447
+ contractStartDate = meter.config?.contractStart;
442
448
  }
443
449
 
444
450
  if (!contractStartDate) {
@@ -587,7 +593,7 @@ class BillingManager {
587
593
  contractStartDate = this.adapter.config[`${configType}ContractStart`];
588
594
  } else {
589
595
  // Additional meter: use meter's individual config
590
- contractStartDate = meter.config?.vertragsbeginn;
596
+ contractStartDate = meter.config?.contractStart;
591
597
  }
592
598
 
593
599
  if (contractStartDate) {
@@ -665,6 +671,18 @@ class BillingManager {
665
671
  await this.adapter.setStateAsync(`${basePath}.consumption.dailyVolume`, 0, true);
666
672
  }
667
673
 
674
+ // Reset HT/NT daily counters if enabled
675
+ const configType = this.adapter.consumptionManager.getConfigType(type);
676
+ const htNtEnabled = this.adapter.config[`${configType}HtNtEnabled`] || false;
677
+ if (htNtEnabled) {
678
+ const dailyHT = await this.adapter.getStateAsync(`${basePath}.consumption.dailyHT`);
679
+ const dailyNT = await this.adapter.getStateAsync(`${basePath}.consumption.dailyNT`);
680
+ await this.adapter.setStateAsync(`${basePath}.statistics.lastDayHT`, dailyHT?.val || 0, true);
681
+ await this.adapter.setStateAsync(`${basePath}.statistics.lastDayNT`, dailyNT?.val || 0, true);
682
+ await this.adapter.setStateAsync(`${basePath}.consumption.dailyHT`, 0, true);
683
+ await this.adapter.setStateAsync(`${basePath}.consumption.dailyNT`, 0, true);
684
+ }
685
+
668
686
  await this.adapter.setStateAsync(`${basePath}.costs.daily`, 0, true);
669
687
 
670
688
  // Update lastDayStart timestamp
@@ -715,6 +733,14 @@ class BillingManager {
715
733
  await this.adapter.setStateAsync(`${basePath}.consumption.monthlyVolume`, 0, true);
716
734
  }
717
735
 
736
+ // Reset HT/NT monthly counters if enabled
737
+ const configType = this.adapter.consumptionManager.getConfigType(type);
738
+ const htNtEnabled = this.adapter.config[`${configType}HtNtEnabled`] || false;
739
+ if (htNtEnabled) {
740
+ await this.adapter.setStateAsync(`${basePath}.consumption.monthlyHT`, 0, true);
741
+ await this.adapter.setStateAsync(`${basePath}.consumption.monthlyNT`, 0, true);
742
+ }
743
+
718
744
  await this.adapter.setStateAsync(`${basePath}.costs.monthly`, 0, true);
719
745
 
720
746
  // Update lastMonthStart timestamp
@@ -244,7 +244,7 @@ class ConsumptionManager {
244
244
  const lastValue = this.lastSensorValues[sensorDP];
245
245
  this.lastSensorValues[sensorDP] = consumption;
246
246
 
247
- if (lastValue === undefined || consumption <= lastValue) {
247
+ if (lastValue === undefined || consumption < lastValue) {
248
248
  if (lastValue !== undefined && consumption < lastValue) {
249
249
  this.adapter.log.warn(
250
250
  `${type}: Sensor value decreased (${lastValue} -> ${consumption}). Assuming meter reset or replacement.`,
@@ -221,43 +221,46 @@ class MultiMeterManager {
221
221
  }
222
222
 
223
223
  // Initialize period start timestamps
224
- const nowIso = calculator.formatDateString(new Date());
225
224
  const timestampRoles = ['lastDayStart', 'lastMonthStart', 'lastYearStart'];
226
225
 
227
226
  for (const role of timestampRoles) {
228
227
  const statePath = `${basePath}.statistics.${role}`;
229
228
  const state = await this.adapter.getStateAsync(statePath);
230
229
 
231
- if (!state || !state.val || typeof state.val === 'number') {
232
- if (role === 'lastYearStart' && (!state || !state.val)) {
233
- const contractStart = calculator.parseGermanDate(config.contractStart);
234
- let yearStartDate;
235
-
236
- if (contractStart && !isNaN(contractStart.getTime())) {
237
- const now = new Date();
238
- yearStartDate = new Date(
239
- now.getFullYear(),
240
- contractStart.getMonth(),
241
- contractStart.getDate(),
242
- 12,
243
- 0,
244
- 0,
245
- );
246
-
247
- if (yearStartDate > now) {
248
- yearStartDate.setFullYear(now.getFullYear() - 1);
249
- }
250
- }
230
+ if (role === 'lastYearStart') {
231
+ // Calculate expected yearStart based on contract
232
+ const contractStart = calculator.parseGermanDate(config.contractStart);
233
+ let expectedYearStart;
234
+
235
+ if (contractStart && !isNaN(contractStart.getTime())) {
236
+ const now = new Date();
237
+ expectedYearStart = new Date(
238
+ now.getFullYear(),
239
+ contractStart.getMonth(),
240
+ contractStart.getDate(),
241
+ 12,
242
+ 0,
243
+ 0,
244
+ );
251
245
 
252
- if (!yearStartDate) {
253
- yearStartDate = new Date(new Date().getFullYear(), 0, 1, 12, 0, 0);
246
+ if (expectedYearStart > now) {
247
+ expectedYearStart.setFullYear(now.getFullYear() - 1);
254
248
  }
255
- await this.adapter.setStateAsync(statePath, calculator.formatDateString(yearStartDate), true);
256
- } else if (typeof state?.val === 'number') {
257
- await this.adapter.setStateAsync(statePath, calculator.formatDateString(new Date(state.val)), true);
258
- } else {
259
- await this.adapter.setStateAsync(statePath, nowIso, true);
260
249
  }
250
+
251
+ if (!expectedYearStart) {
252
+ expectedYearStart = new Date(new Date().getFullYear(), 0, 1, 12, 0, 0);
253
+ }
254
+
255
+ // Always set to expected value (fixes mismatches from config changes)
256
+ await this.adapter.setStateAsync(statePath, expectedYearStart.getTime(), true);
257
+ } else {
258
+ // For lastDayStart and lastMonthStart
259
+ if (!state || !state.val || typeof state.val === 'string') {
260
+ // Initialize with current timestamp (convert string to number if needed)
261
+ await this.adapter.setStateAsync(statePath, Date.now(), true);
262
+ }
263
+ // If already a valid number, no action needed (already correct in state)
261
264
  }
262
265
  }
263
266
 
@@ -546,84 +549,60 @@ class MultiMeterManager {
546
549
  await this.adapter.setStateAsync(`${basePath}.costs.monthly`, calculator.roundToDecimals(monthlyCost, 2), true);
547
550
  await this.adapter.setStateAsync(`${basePath}.costs.yearly`, calculator.roundToDecimals(yearlyCost, 2), true);
548
551
 
549
- await this.adapter.setStateAsync(`${basePath}.costs.basicCharge`, Number(config.grundgebuehr) || 0, true);
550
-
551
- // Calculate annual fee (prorated)
552
+ // Calculate accumulated costs based on contract start
552
553
  const yearStartState = await this.adapter.getStateAsync(`${basePath}.statistics.lastYearStart`);
553
- let annualFeeAccumulated = 0;
554
+ let monthsSinceYearStart = 1;
555
+ let basicChargeAccumulated = 0;
554
556
 
555
557
  if (yearStartState && yearStartState.val) {
556
- const yearStartDate = calculator.parseDateString(yearStartState.val);
557
- if (yearStartDate && !isNaN(yearStartDate.getTime())) {
558
+ // yearStartState.val is a timestamp (number)
559
+ const yearStartDate = new Date(yearStartState.val);
560
+ if (!isNaN(yearStartDate.getTime())) {
558
561
  const now = new Date();
559
- const yearStartTime = yearStartDate.getTime();
560
- const nowTime = now.getTime();
561
- const daysSinceYearStart = Math.floor((nowTime - yearStartTime) / (1000 * 60 * 60 * 24));
562
- const daysInYear = calculator.isLeapYear(now.getFullYear()) ? 366 : 365;
563
- annualFeeAccumulated = ((config.jahresgebuehr || 0) / daysInYear) * daysSinceYearStart;
562
+
563
+ // Calculate months since contract start (started months, including current)
564
+ monthsSinceYearStart = calculator.getMonthsDifference(yearStartDate, now) + 1;
565
+
566
+ // Calculate accumulated basic charge (monthly fee × months)
567
+ basicChargeAccumulated = (config.grundgebuehr || 0) * monthsSinceYearStart;
564
568
  }
565
569
  }
566
570
 
571
+ // Jahresgebühr ist ein FIXER Wert pro Jahr (z.B. 60€)
572
+ // NICHT pro-rata nach Monaten/Tagen berechnen!
573
+ const annualFeeAccumulated = config.jahresgebuehr || 0;
574
+
575
+ // Update basicCharge with accumulated value (not just monthly!)
576
+ await this.adapter.setStateAsync(
577
+ `${basePath}.costs.basicCharge`,
578
+ calculator.roundToDecimals(basicChargeAccumulated, 2),
579
+ true,
580
+ );
581
+
567
582
  await this.adapter.setStateAsync(
568
583
  `${basePath}.costs.annualFee`,
569
584
  calculator.roundToDecimals(annualFeeAccumulated, 2),
570
585
  true,
571
586
  );
572
587
 
573
- // Calculate balance and total yearly costs
574
- if (yearStartState && yearStartState.val) {
575
- const yearStartDate = calculator.parseDateString(yearStartState.val);
576
- if (yearStartDate && !isNaN(yearStartDate.getTime())) {
577
- const now = new Date();
578
- // Calculate paid total based on started months (not just completed months)
579
- // If current month has started, count it as paid
580
- const monthsSinceYearStart = calculator.getMonthsDifference(yearStartDate, now) + 1;
588
+ // Calculate total yearly costs and balance
589
+ const totalYearlyCost = yearlyCost + basicChargeAccumulated + annualFeeAccumulated;
581
590
 
582
- // Calculate total yearly costs with correct months
583
- const basicChargeAccumulated = (config.grundgebuehr || 0) * monthsSinceYearStart;
584
- const totalYearlyCost = yearlyCost + basicChargeAccumulated + annualFeeAccumulated;
585
-
586
- await this.adapter.setStateAsync(
587
- `${basePath}.costs.totalYearly`,
588
- calculator.roundToDecimals(totalYearlyCost, 2),
589
- true,
590
- );
591
+ await this.adapter.setStateAsync(
592
+ `${basePath}.costs.totalYearly`,
593
+ calculator.roundToDecimals(totalYearlyCost, 2),
594
+ true,
595
+ );
591
596
 
592
- const paidTotal = (config.abschlag || 0) * monthsSinceYearStart;
593
- const balance = paidTotal - totalYearlyCost;
597
+ const paidTotal = (config.abschlag || 0) * monthsSinceYearStart;
598
+ const balance = totalYearlyCost - paidTotal;
594
599
 
595
- this.adapter.log.debug(
596
- `[${basePath}] Balance calculation: abschlag=${config.abschlag}, months=${monthsSinceYearStart}, paidTotal=${paidTotal.toFixed(2)}, totalYearly=${totalYearlyCost.toFixed(2)}, balance=${balance.toFixed(2)}`,
597
- );
600
+ this.adapter.log.debug(
601
+ `[${basePath}] Balance calculation: grundgebuehr=${config.grundgebuehr}, jahresgebuehr=${config.jahresgebuehr}, abschlag=${config.abschlag}, months=${monthsSinceYearStart}, basicCharge=${basicChargeAccumulated.toFixed(2)}, annualFee=${annualFeeAccumulated.toFixed(2)}, paidTotal=${paidTotal.toFixed(2)}, totalYearly=${totalYearlyCost.toFixed(2)}, balance=${balance.toFixed(2)}`,
602
+ );
598
603
 
599
- await this.adapter.setStateAsync(
600
- `${basePath}.costs.paidTotal`,
601
- calculator.roundToDecimals(paidTotal, 2),
602
- true,
603
- );
604
- await this.adapter.setStateAsync(
605
- `${basePath}.costs.balance`,
606
- calculator.roundToDecimals(balance, 2),
607
- true,
608
- );
609
- } else {
610
- // Fallback if yearStartDate parsing fails
611
- const totalYearlyCost = yearlyCost + annualFeeAccumulated;
612
- await this.adapter.setStateAsync(
613
- `${basePath}.costs.totalYearly`,
614
- calculator.roundToDecimals(totalYearlyCost, 2),
615
- true,
616
- );
617
- }
618
- } else {
619
- // Fallback if no yearStartState exists
620
- const totalYearlyCost = yearlyCost + annualFeeAccumulated;
621
- await this.adapter.setStateAsync(
622
- `${basePath}.costs.totalYearly`,
623
- calculator.roundToDecimals(totalYearlyCost, 2),
624
- true,
625
- );
626
- }
604
+ await this.adapter.setStateAsync(`${basePath}.costs.paidTotal`, calculator.roundToDecimals(paidTotal, 2), true);
605
+ await this.adapter.setStateAsync(`${basePath}.costs.balance`, calculator.roundToDecimals(balance, 2), true);
627
606
  }
628
607
 
629
608
  /**
@@ -718,6 +718,37 @@ async function createUtilityStateStructure(adapter, type, _config = {}) {
718
718
  native: {},
719
719
  });
720
720
 
721
+ // HT/NT lastDay states - only create if HT/NT tariff is enabled
722
+ if (_config[htNtEnabledKey]) {
723
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.lastDayHT`, {
724
+ type: 'state',
725
+ common: {
726
+ name: `Verbrauch gestern HT (${label.unit})`,
727
+ type: 'number',
728
+ role: STATE_ROLES.consumption,
729
+ read: true,
730
+ write: false,
731
+ unit: label.unit,
732
+ def: 0,
733
+ },
734
+ native: {},
735
+ });
736
+
737
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.lastDayNT`, {
738
+ type: 'state',
739
+ common: {
740
+ name: `Verbrauch gestern NT (${label.unit})`,
741
+ type: 'number',
742
+ role: STATE_ROLES.consumption,
743
+ read: true,
744
+ write: false,
745
+ unit: label.unit,
746
+ def: 0,
747
+ },
748
+ native: {},
749
+ });
750
+ }
751
+
721
752
  if (type === 'gas') {
722
753
  await adapter.setObjectNotExistsAsync(`${type}.statistics.lastDayVolume`, {
723
754
  type: 'state',
package/main.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  /*
4
- * ioBroker Nebenkosten-Monitor Adapter
4
+ * ioBroker Utility Monitor Adapter
5
5
  * Monitors gas, water, and electricity consumption with cost calculation
6
6
  */
7
7
 
@@ -11,14 +11,14 @@ const BillingManager = require('./lib/billingManager');
11
11
  const MessagingHandler = require('./lib/messagingHandler');
12
12
  const MultiMeterManager = require('./lib/multiMeterManager');
13
13
 
14
- class NebenkostenMonitor extends utils.Adapter {
14
+ class UtilityMonitor extends utils.Adapter {
15
15
  /**
16
16
  * @param {Partial<utils.AdapterOptions>} [options] - Adapter options
17
17
  */
18
18
  constructor(options) {
19
19
  super({
20
20
  ...options,
21
- name: 'nebenkosten-monitor',
21
+ name: 'utility-monitor',
22
22
  });
23
23
  this.on('ready', this.onReady.bind(this));
24
24
  this.on('stateChange', this.onStateChange.bind(this));
@@ -44,26 +44,12 @@ class NebenkostenMonitor extends utils.Adapter {
44
44
  this.multiMeterManager = new MultiMeterManager(this, this.consumptionManager, this.billingManager);
45
45
 
46
46
  // Initialize each utility type based on configuration
47
+ // Note: initializeUtility() internally calls multiMeterManager.initializeType()
47
48
  await this.initializeUtility('gas', this.config.gasAktiv);
48
49
  await this.initializeUtility('water', this.config.wasserAktiv);
49
50
  await this.initializeUtility('electricity', this.config.stromAktiv);
50
-
51
51
  await this.initializeUtility('pv', this.config.pvAktiv);
52
52
 
53
- // Initialize Multi-Meter structures for each active type
54
- if (this.config.gasAktiv) {
55
- await this.multiMeterManager.initializeType('gas');
56
- }
57
- if (this.config.wasserAktiv) {
58
- await this.multiMeterManager.initializeType('water');
59
- }
60
- if (this.config.stromAktiv) {
61
- await this.multiMeterManager.initializeType('electricity');
62
- }
63
- if (this.config.pvAktiv) {
64
- await this.multiMeterManager.initializeType('pv');
65
- }
66
-
67
53
  // Initialize General Info States
68
54
  await this.setObjectNotExistsAsync('info', {
69
55
  type: 'channel',
@@ -290,8 +276,8 @@ if (require.main !== module) {
290
276
  /**
291
277
  * @param {Partial<utils.AdapterOptions>} [options] - Adapter options
292
278
  */
293
- module.exports = options => new NebenkostenMonitor(options);
279
+ module.exports = options => new UtilityMonitor(options);
294
280
  } else {
295
281
  // otherwise start the instance directly
296
- new NebenkostenMonitor();
282
+ new UtilityMonitor();
297
283
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.utility-monitor",
3
- "version": "1.4.2",
3
+ "version": "1.4.5",
4
4
  "description": "Monitor gas, water, and electricity consumption with cost calculation",
5
5
  "author": {
6
6
  "name": "fischi87",
@@ -39,18 +39,18 @@
39
39
  "@iobroker/adapter-core": "^3.3.2"
40
40
  },
41
41
  "devDependencies": {
42
- "@alcalzone/release-script": "~5.0.0",
43
- "@alcalzone/release-script-plugin-iobroker": "~4.0.0",
44
- "@alcalzone/release-script-plugin-license": "~4.0.0",
45
- "@alcalzone/release-script-plugin-manual-review": "~4.0.0",
46
- "@iobroker/adapter-dev": "~1.5.0",
47
- "@iobroker/dev-server": "~0.8.0",
48
- "@iobroker/eslint-config": "~2.2.0",
49
- "@iobroker/testing": "~5.2.2",
50
- "@tsconfig/node20": "~20.1.8",
51
- "@types/iobroker": "npm:@iobroker/types@~7.1.0",
52
- "@types/node": "~20.19.27",
53
- "typescript": "~5.9.3"
42
+ "@alcalzone/release-script": "^5.0.0",
43
+ "@alcalzone/release-script-plugin-iobroker": "^4.0.0",
44
+ "@alcalzone/release-script-plugin-license": "^4.0.0",
45
+ "@alcalzone/release-script-plugin-manual-review": "^4.0.0",
46
+ "@iobroker/adapter-dev": "^1.5.0",
47
+ "@iobroker/dev-server": "^0.8.0",
48
+ "@iobroker/eslint-config": "^2.2.0",
49
+ "@iobroker/testing": "^5.2.2",
50
+ "@tsconfig/node20": "^20.1.8",
51
+ "@types/iobroker": "npm:@iobroker/types@^7.1.0",
52
+ "@types/node": "^20.19.27",
53
+ "typescript": "^5.9.3"
54
54
  },
55
55
  "main": "main.js",
56
56
  "files": [