iobroker.laundrylens 0.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/LICENSE +21 -0
- package/README.md +174 -0
- package/admin/i18n/de/translations.json +186 -0
- package/admin/i18n/en/translations.json +186 -0
- package/admin/i18n/es/translations.json +186 -0
- package/admin/i18n/fr/translations.json +186 -0
- package/admin/i18n/it/translations.json +186 -0
- package/admin/i18n/nl/translations.json +186 -0
- package/admin/i18n/pl/translations.json +186 -0
- package/admin/i18n/pt/translations.json +186 -0
- package/admin/i18n/ru/translations.json +186 -0
- package/admin/i18n/uk/translations.json +186 -0
- package/admin/i18n/zh-cn/translations.json +186 -0
- package/admin/icon.png +0 -0
- package/admin/jsonConfig.json +266 -0
- package/admin/tab_m.html +2489 -0
- package/io-package.json +211 -0
- package/lib/cycleDetector.js +488 -0
- package/lib/mathUtils.js +180 -0
- package/lib/profileStore.js +770 -0
- package/lib/traceStore.js +297 -0
- package/lib/washDataManager.js +1852 -0
- package/main.js +1965 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 backfisch88
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# ioBroker.laundrylens
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/iobroker.laundrylens)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
Self-learning ioBroker adapter for automatic detection of washing machine and dryer cycles via smart plug power measurement. Recognizes running programs, estimates remaining time and sends Telegram notifications – fully local, no cloud.
|
|
9
|
+
|
|
10
|
+
> **Alpha release.** Tested on Siemens iQ washing machine and dryer. Other brands and models may require tuning. Feedback welcome.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## How it works
|
|
15
|
+
|
|
16
|
+
LaundryLens records the power consumption curve of each cycle and compares it against stored program profiles using segment-weighted correlation and a DTW-lite algorithm. Confidence is accumulated over multiple matching rounds before a program is accepted, which prevents single outliers from triggering a wrong match. Remaining time is estimated dynamically based on both elapsed time and the current energy rate – not just a fixed average.
|
|
17
|
+
|
|
18
|
+
The adapter is self-learning: there are no pre-built profiles. Every program is trained on your specific device. Recognition improves with each completed cycle.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- Cycle detection via state machine (OFF → STARTING → RUNNING ↔ PAUSED → ENDING)
|
|
25
|
+
- Self-learning program matching (segment-weighted correlation + DTW tiebreak)
|
|
26
|
+
- Score accumulation over multiple rounds with device-specific confidence thresholds
|
|
27
|
+
- Override lock: manually selected programs are not overwritten by background matching
|
|
28
|
+
- Adaptive remaining time estimation combining time-based and energy-rate signals
|
|
29
|
+
- Admin UI with expandable cycle list, inline power graph (canvas), phase legend, trim and split per touch/drag
|
|
30
|
+
- Telegram notifications with configurable update thresholds, placeholders (`{progress}`, `{prevTime}`) and conditional text blocks
|
|
31
|
+
- Also supports Pushover, Signal, WhatsApp, Matrix, notify-my-android, Prowl, and email (via [ioBroker.email](https://github.com/iobroker-community-adapters/ioBroker.email)) as notification targets
|
|
32
|
+
- Multiple devices: one instance per device (washing machine, dryer, …)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- ioBroker with js-controller ≥ 5.0.0
|
|
39
|
+
- Node.js ≥ 18
|
|
40
|
+
- A smart plug or power meter adapter providing a watt data point per device (e.g. Shelly EM)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
Install **LaundryLens** via the ioBroker Admin adapter list (tab "Adapters"), then create a separate adapter instance for each device and select the watt data point in the instance configuration.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Configuration
|
|
51
|
+
|
|
52
|
+
Each instance has the following settings:
|
|
53
|
+
|
|
54
|
+
| Setting | Description |
|
|
55
|
+
|---|---|
|
|
56
|
+
| Device name | Display name for this device |
|
|
57
|
+
| Device type | `washing_machine` or `dryer` (affects phase detection logic) |
|
|
58
|
+
| Power sensor (W) | ioBroker data point providing watt values |
|
|
59
|
+
| Power threshold (W) | Minimum wattage to consider the device as running |
|
|
60
|
+
| Off delay (min) | Time to wait after power drops before ending the cycle |
|
|
61
|
+
| Start energy gate (Wh) | Minimum energy consumed before matching starts (filters short spikes) |
|
|
62
|
+
| Duration tolerance | Allowed deviation from learned average duration (0.05–0.5) |
|
|
63
|
+
| Matching interval (min) | How often matching runs during a cycle |
|
|
64
|
+
| Match confirmations | Number of consecutive rounds a match must hold before being accepted |
|
|
65
|
+
| Auto-confirm threshold (%) | Confidence at which a match is confirmed automatically |
|
|
66
|
+
| Instant-confirm threshold (%) | Confidence at which a match is accepted immediately (2 rounds in a row) |
|
|
67
|
+
| Program detection threshold (%) | Minimum confidence for a candidate to be considered at all |
|
|
68
|
+
| Notify on probable match | Send a notification even before a match is officially confirmed |
|
|
69
|
+
| Ignore anti-crease | Ignore anti-crease phases at the end of dryer cycles |
|
|
70
|
+
|
|
71
|
+
The defaults are tuned for Siemens iQ appliances. Detection threshold is a trade-off: lower means faster notifications but higher risk of wrong matches. Some experimentation is expected.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Data points per device
|
|
76
|
+
|
|
77
|
+
| Data point | Type | Description |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `state` | string | off / starting / running / paused / ending |
|
|
80
|
+
| `running` | boolean | Simple on/off indicator |
|
|
81
|
+
| `program` | string | Detected program name |
|
|
82
|
+
| `confidence` | number | Match confidence in % |
|
|
83
|
+
| `timeRemaining` | number | Estimated remaining time in seconds |
|
|
84
|
+
| `totalDuration` | number | Estimated total cycle duration in seconds |
|
|
85
|
+
| `cycleProgress` | number | Cycle progress 0–100 % |
|
|
86
|
+
| `phase` | string | Current cycle phase |
|
|
87
|
+
| `lastCycleProgram` | string | Program of the last completed cycle |
|
|
88
|
+
| `lastCycleDuration` | number | Duration of the last cycle in minutes |
|
|
89
|
+
| `lastCycleEnergy` | number | Energy consumed in the last cycle in Wh |
|
|
90
|
+
| `availablePrograms` | string (JSON) | Array of all saved program names, e.g. for external dropdowns |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Getting started tips
|
|
95
|
+
|
|
96
|
+
- Let the device run at least 3–5 cycles per program before expecting reliable detection.
|
|
97
|
+
- Start with fewer programs. The fewer profiles you have, the higher the match accuracy.
|
|
98
|
+
- Use the **Cycles tab** in the admin UI to review past cycles, trim noise from the start/end of a recorded trace, or split a trace that captured two programs.
|
|
99
|
+
- Use the **Export** function before any update to back up your learned profiles and cycle history.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Changelog
|
|
104
|
+
|
|
105
|
+
### **WORK IN PROGRESS**
|
|
106
|
+
|
|
107
|
+
### 0.4.5 (2026-08-08)
|
|
108
|
+
- Fix: a finished cycle could stay stuck showing "running" indefinitely if the power sensor stopped reporting after settling at a flat value (many sensors, incl. Shelly, only report on change) - the state machine is now re-evaluated periodically (heartbeat) so it can still finish on schedule
|
|
109
|
+
- Fix: repository checker findings from issue #39 (real `test:package` validation instead of a no-op stub, corrected `adminUI.tab`/`materializeTab` config, responsive `jsonConfig.json` layout, various CI/tooling fixes)
|
|
110
|
+
- (copilot) Adapter requires node.js >= 22 now
|
|
111
|
+
- (ioBroker-Bot) Adapter requires js-controller >= 6.0.11 now.
|
|
112
|
+
- (ioBroker-Bot) Adapter requires admin >= 7.8.23 now.
|
|
113
|
+
|
|
114
|
+
### 0.4.1 (2026-07-30)
|
|
115
|
+
- Fix: `ReferenceError: _suggestedApplied is not defined` crashing the admin tab in some browsers/modes
|
|
116
|
+
- Fix: some Admin instances (especially the newer React-based rendering) showed a 404 "File tab.html not found" instead of loading the admin tab correctly - caused by an earlier cleanup that removed the `materializeTab` flag, which actually controls which filename (`tab.html` vs. `tab_m.html`) Admin resolves the custom tab to
|
|
117
|
+
|
|
118
|
+
### 0.4.0 (2026-07-30)
|
|
119
|
+
- New: full multilingual support - admin UI, notifications, and program phase names now translate automatically into 11 languages (en, de, ru, pt, nl, fr, it, es, pl, uk, zh-cn) based on the ioBroker system language
|
|
120
|
+
- New: all code comments translated to English, full compliance with the official `@iobroker/eslint-config` (formatting + JSDoc)
|
|
121
|
+
- Fix: the "All devices" status column and default notification templates weren't going through translation
|
|
122
|
+
- Infrastructure: CI no longer needs a committed `package-lock.json`; real integration test added; git history cleaned up
|
|
123
|
+
- Note: cycles recorded before this update show phases as an uncolored/unrecognized segment in the graph legend (the old German phase names no longer match the new internal phase keys) - purely cosmetic, only affects historical data
|
|
124
|
+
|
|
125
|
+
### 0.3.0 (2026-07-28)
|
|
126
|
+
- New: proper dishwasher phase detection, both live and in the historical cycle graph
|
|
127
|
+
- New: email notification support via [ioBroker.email](https://github.com/iobroker-community-adapters/ioBroker.email)
|
|
128
|
+
- Fix: `instance` URL parameter and hash-based deep-linking in the admin tab
|
|
129
|
+
- Fix: Anti-Knitter checkbox polarity was inverted - "ignorieren" checked/unchecked did the opposite of what it should
|
|
130
|
+
- Fix: dryer cycles were cut off immediately on any power drop even with no Anti-Knitter reference pattern saved
|
|
131
|
+
- New: delete button for the saved Anti-Knitter reference pattern
|
|
132
|
+
- Infrastructure: migrated to the official `@iobroker/eslint-config`, added a real `package-lock.json` and integration test, restructured CI to the current ioBroker workflow template (`check-and-lint`/`adapter-tests`), and reached full compliance with the shared config (Prettier formatting + complete JSDoc coverage, no rules disabled)
|
|
133
|
+
|
|
134
|
+
### 0.2.8 (2026-07-26)
|
|
135
|
+
- New: proper phase detection for dishwashers, both in the historical cycle graph and the live status display (Vorspülen/Hauptspülgang/Klarspülgang/Trocknen based on ordinal heating-block count, instead of a flat per-reading power threshold that mislabeled every heat spike as "Aufheizen")
|
|
136
|
+
- Fix: `instance` URL parameter was ignored for initial device pre-selection in the admin tab
|
|
137
|
+
- Fix attempt: hash-based deep-linking no longer triggers premature data loading before device discovery completes
|
|
138
|
+
|
|
139
|
+
### 0.2.7 (2026-07-22)
|
|
140
|
+
- Attempted fix: hash-based deep-linking no longer triggers data loading for the target tab before device discovery has completed (visual tab switch only; data loading deferred until devices are known). Addresses a suspected race where early sendTo() calls with an empty deviceId may have interfered with device discovery.
|
|
141
|
+
|
|
142
|
+
### 0.2.6 (2026-07-22)
|
|
143
|
+
- Fix: hash-based deep-linking (`#1`–`#6`) could get stuck showing an empty page when device loading was slow or failed (e.g. standalone access outside Admin). Tab switching via hash now happens immediately on page load, independent of the device data pipeline.
|
|
144
|
+
|
|
145
|
+
### 0.2.5 (2026-07-14)
|
|
146
|
+
- New: separate "Notifications" tab (previously buried under "Export", which testers found unintuitive)
|
|
147
|
+
- New: hash-based deep-linking to admin tabs using numbers (`#1`–`#6`), independent of UI language
|
|
148
|
+
- New: `availablePrograms` JSON data point per device listing all saved program names, for use in external dropdowns (e.g. VIS program override selector)
|
|
149
|
+
|
|
150
|
+
### 0.2.4 (2026-07-11)
|
|
151
|
+
- Fix: power sensor readings with `ack=false` were silently ignored, causing the adapter to stay "off" forever even at full power. This affects power sensors fed by user scripts (common for `0_userdata.0.*` datapoints) that don't explicitly set `ack: true`.
|
|
152
|
+
|
|
153
|
+
### 0.2.3 (2026-07-07)
|
|
154
|
+
- Fix: `startEnergyThreshold = 0` (and `powerThreshold = 0`) was silently replaced by the default value due to a falsy-zero check — this blocked correct detection for devices with a very low initial power draw (e.g. dishwashers during pump-out)
|
|
155
|
+
- Fix: restarting the adapter while the device was already running (with no cycle to restore) could leave the cycle stuck in "starting" instead of resuming "running"
|
|
156
|
+
|
|
157
|
+
### 0.2.2 (2026-07-01)
|
|
158
|
+
- beta release
|
|
159
|
+
|
|
160
|
+
Older changelog entries can be found in [CHANGELOG_OLD.md](CHANGELOG_OLD.md).
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Contributing
|
|
165
|
+
|
|
166
|
+
Issues and pull requests are welcome: [Issues](https://github.com/backfisch88/ioBroker.laundrylens/issues)
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
MIT License
|
|
173
|
+
|
|
174
|
+
Copyright (c) 2026 backfisch88
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Device name": "Gerätename",
|
|
3
|
+
"e.g. Washing machine": "z.B. Waschmaschine",
|
|
4
|
+
"Display name in the dashboard": "Anzeigename im Dashboard",
|
|
5
|
+
"Device type": "Gerätetyp",
|
|
6
|
+
"🧺 Washing machine": "🧺 Waschmaschine",
|
|
7
|
+
"🍽️ Dishwasher": "🍽️ Spülmaschine",
|
|
8
|
+
"♨️ Dryer": "♨️ Trockner",
|
|
9
|
+
"🔄 Washer-dryer": "🔄 Waschtrockner",
|
|
10
|
+
"⚙️ Other": "⚙️ Sonstiges",
|
|
11
|
+
"Power sensor (watt)": "Leistungs-Sensor (Watt)",
|
|
12
|
+
"ioBroker data point providing the current power draw in watts": "ioBroker-Datenpunkt der aktuellen Leistungsaufnahme in Watt",
|
|
13
|
+
"Detection thresholds": "Erkennungs-Schwellen",
|
|
14
|
+
"Power-on threshold (W)": "Einschalt-Schwelle (W)",
|
|
15
|
+
"Power level from which the device is considered running. Recommended: 10W for all device types": "Ab wann gilt das Gerät als eingeschaltet. Empfehlung: 10W für alle Geräte",
|
|
16
|
+
"Off delay (min)": "Ausschaltverzögerung (min)",
|
|
17
|
+
"How long power must stay below the threshold before the cycle ends. Recommended: washing machine 5 min · dryer 8 min · dishwasher 8 min · washer-dryer 10 min": "Wie lange unter der Schwelle bevor Zyklus endet. Empfehlung: Waschmaschine 5 min · Trockner 8 min · Spülmaschine 8 min · Waschtrockner 10 min",
|
|
18
|
+
"Start energy gate (Wh)": "Start-Energie-Gate (Wh)",
|
|
19
|
+
"Minimum energy after start before the cycle is counted (prevents false starts). Recommended: washing machine 2 Wh · dryer 5 Wh · washer-dryer 5 Wh": "Mindest-Energie nach Start bevor Zyklus gezählt wird (verhindert Fehlstarts). Empfehlung: Waschmaschine 2 Wh · Trockner 5 Wh · Waschtrockner 5 Wh",
|
|
20
|
+
"Program detection": "Programm-Erkennung",
|
|
21
|
+
"Duration tolerance (0.05–0.5)": "Dauer-Toleranz (0.05–0.5)",
|
|
22
|
+
"How much the run time may deviate from the profile. 0.2 = ±20%": "Wie stark die Laufzeit vom Profil abweichen darf. 0.2 = ±20%",
|
|
23
|
+
"Matching interval (min)": "Matching-Intervall (min)",
|
|
24
|
+
"How often the program is matched. Recommended: 5 min for all device types": "Wie oft das Programm erkannt wird. Empfehlung: 5 min für alle Geräte",
|
|
25
|
+
"Match confirmations (count)": "Match-Bestätigung (Anzahl)",
|
|
26
|
+
"How many times in a row the same program must be detected. 3 = reliable · 2 = faster": "Wie oft das gleiche Programm hintereinander erkannt werden muss. 3 = zuverlässig · 2 = schneller",
|
|
27
|
+
"Auto-confirm from confidence (%)": "Auto-Bestätigung ab Konfidenz (%)",
|
|
28
|
+
"From this confidence level the cycle is confirmed automatically. 0 = disabled · 85 = recommended": "Ab dieser Konfidenz wird der Zyklus automatisch bestätigt. 0 = deaktiviert · 85 = empfohlen",
|
|
29
|
+
"Instant adoption from confidence (%)": "Sofortübernahme ab Konfidenz (%)",
|
|
30
|
+
"During a running cycle: if the live preview repeatedly (2x) shows at least this confidence, the program is adopted immediately instead of waiting for the normal, slower detection.": "Während des laufenden Zyklus: wenn die Live-Vorschau wiederholt (2x) mindestens diese Konfidenz zeigt, wird das Programm sofort übernommen, statt auf die normale, langsamere Erkennung zu warten.",
|
|
31
|
+
"Program detection threshold (%)": "Programm-Erkennungs-Schwelle (%)",
|
|
32
|
+
"From this confidence a program counts as detected (and is shown). Below it, it stays 'detecting...'. 55 = recommended": "Ab dieser Konfidenz gilt ein Programm als erkannt (wird angezeigt). Darunter bleibt es 'detecting...'. 55 = empfohlen",
|
|
33
|
+
"Notify also for probable program": "Benachrichtigung auch bei wahrscheinlichem Programm",
|
|
34
|
+
"Send a Telegram update as soon as a program is detected - even if confidence is below the auto-confirm threshold": "Telegram-Update senden sobald ein Programm erkannt wird – auch wenn die Konfidenz unter der Auto-Bestätigungs-Schwelle liegt",
|
|
35
|
+
"Dryer settings": "Trockner-Einstellungen",
|
|
36
|
+
"Ignore anti-crease phase": "Anti-Knitter ignorieren",
|
|
37
|
+
"ON: cycle ends immediately at the beep, the anti-crease phase is ignored (simple, sufficient for most dryers). OFF: the adapter actively tries to detect when the cycle is really finished across the anti-crease phase (needs a saved reference pattern under 'Programs').": "AN: Zyklus endet sofort beim Piepton, Anti-Knitter-Phase wird ignoriert (einfach, für die meisten Trockner ausreichend). AUS: Adapter versucht aktiv, über die Anti-Knitter-Phase hinweg zu erkennen, wann der Zyklus wirklich fertig ist (braucht ein gespeichertes Referenzmuster unter 'Programme').",
|
|
38
|
+
"+ Create": "+ Anlegen",
|
|
39
|
+
"Adapter": "Adapter",
|
|
40
|
+
"All (broadcast)": "Alle (broadcast)",
|
|
41
|
+
"All cycles confirmed!": "Alle Zyklen bestätigt!",
|
|
42
|
+
"All data deleted!": "Alle Daten gelöscht!",
|
|
43
|
+
"All devices": "Alle Geräte",
|
|
44
|
+
"Anti-crease pattern deleted": "Anti-Knitter-Muster gelöscht",
|
|
45
|
+
"Anti-crease pattern saved!": "Anti-Knitter gespeichert!",
|
|
46
|
+
"Apply": "Anwenden",
|
|
47
|
+
"Assign program": "Programm zuweisen",
|
|
48
|
+
"Automatic": "Automatik",
|
|
49
|
+
"Back up configuration": "Konfiguration sichern",
|
|
50
|
+
"Based on": "Basierend auf",
|
|
51
|
+
"Cancel": "Abbrechen",
|
|
52
|
+
"Choose a recorded cycle as the anti-crease reference. The adapter will then automatically ignore this pattern after drying.": "Wähle einen aufgezeichneten Zyklus als Anti-Knitter Referenz. Der Adapter ignoriert danach dieses Muster automatisch nach dem Trocknen.",
|
|
53
|
+
"Choose a split point in the graph": "Teilungspunkt im Graph wählen",
|
|
54
|
+
"Choose the program for this cycle:": "Wähle das Programm für diesen Zyklus:",
|
|
55
|
+
"Confidence": "Konfidenz",
|
|
56
|
+
"Confirm or correct cycles marked with ❓. This automatically improves detection.": "Zyklen mit ❓ bestätigen oder korrigieren. Verbessert die Erkennung automatisch.",
|
|
57
|
+
"Confirmed": "Bestätigt",
|
|
58
|
+
"Confirmed – adapter is learning!": "Bestätigt – Adapter lernt!",
|
|
59
|
+
"Consumption": "Verbrauch",
|
|
60
|
+
"Correct & learn": "Korrigieren & Lernen",
|
|
61
|
+
"Correct – confirm": "Stimmt – bestätigen",
|
|
62
|
+
"Corrected – adapter is learning!": "Korrigiert – Adapter lernt!",
|
|
63
|
+
"Create new program": "Neues Programm anlegen",
|
|
64
|
+
"Cycle deleted": "Zyklus gelöscht",
|
|
65
|
+
"Cycle history": "Zyklushistorie",
|
|
66
|
+
"Delete": "Löschen",
|
|
67
|
+
"Delete all data for \"": "Alle Daten für \"",
|
|
68
|
+
"Deleted": "Gelöscht",
|
|
69
|
+
"Detected as": "Erkannt als",
|
|
70
|
+
"Device": "Gerät",
|
|
71
|
+
"Device:": "Gerät:",
|
|
72
|
+
"Duration": "Dauer",
|
|
73
|
+
"Duration (min)": "Dauer (min)",
|
|
74
|
+
"Duration tolerance": "Dauer-Toleranz",
|
|
75
|
+
"Elapsed time": "Verstrichene Zeit",
|
|
76
|
+
"Ending…": "Endet…",
|
|
77
|
+
"Error": "Fehler",
|
|
78
|
+
"Error loading": "Fehler beim Laden",
|
|
79
|
+
"Export downloaded": "Export heruntergeladen",
|
|
80
|
+
"Export failed": "Export fehlgeschlagen",
|
|
81
|
+
"Go to review →": "Zur Lernkontrolle →",
|
|
82
|
+
"Invalid JSON file": "Ungültige JSON-Datei",
|
|
83
|
+
"JSON appears here after export…": "JSON erscheint hier nach Export…",
|
|
84
|
+
"Last cycle": "Letzter Zyklus",
|
|
85
|
+
"Last cycle not confidently detected. Please confirm or correct.": "Letzter Zyklus nicht sicher erkannt. Bitte bestätigen oder korrigieren.",
|
|
86
|
+
"Learned on": "Gelernt am",
|
|
87
|
+
"Live status": "Live-Status",
|
|
88
|
+
"Loading…": "Lade…",
|
|
89
|
+
"Min. interval (min)": "Min. Abstand (min)",
|
|
90
|
+
"Near-done dev. %": "Fast-fertig Abw. %",
|
|
91
|
+
"Near-done dev. min": "Fast-fertig Abw. min",
|
|
92
|
+
"Near-done from (%)": "Fast-fertig ab (%)",
|
|
93
|
+
"New name": "Neuer Name",
|
|
94
|
+
"No anti-crease pattern saved yet.": "Noch kein Anti-Knitter Muster gespeichert.",
|
|
95
|
+
"No cycle recorded yet.": "Noch kein Zyklus aufgezeichnet.",
|
|
96
|
+
"No cycles recorded yet.": "Noch keine Zyklen aufgezeichnet.",
|
|
97
|
+
"No cycles with curve data available": "Keine Zyklen mit Kurvendaten verfügbar",
|
|
98
|
+
"No device selected": "Kein Gerät ausgewählt",
|
|
99
|
+
"No devices configured.": "Keine Geräte konfiguriert.",
|
|
100
|
+
"No programs created yet.": "Noch keine Programme angelegt.",
|
|
101
|
+
"No suggestions available": "Keine Empfehlungen verfügbar",
|
|
102
|
+
"No trace available": "Keine Trace verfügbar",
|
|
103
|
+
"No trace data": "Keine Trace-Daten",
|
|
104
|
+
"Off": "Aus",
|
|
105
|
+
"Off delay": "Ausschaltverzögerung",
|
|
106
|
+
"Open": "Offen",
|
|
107
|
+
"Paused": "Pausiert",
|
|
108
|
+
"Placeholders:": "Platzhalter:",
|
|
109
|
+
"Please choose an adapter": "Bitte Adapter wählen",
|
|
110
|
+
"Please select a cycle": "Bitte einen Zyklus auswählen",
|
|
111
|
+
"Power curve": "Leistungskurve",
|
|
112
|
+
"Power-on threshold": "Einschalt-Schwelle",
|
|
113
|
+
"Profiles, cycles, and traces will be permanently deleted!": "Profile, Zyklen und Traces werden unwiderruflich gelöscht!",
|
|
114
|
+
"Program": "Programm",
|
|
115
|
+
"Program name": "Programmname",
|
|
116
|
+
"Program override": "Programm-Override",
|
|
117
|
+
"Progress": "Fortschritt",
|
|
118
|
+
"Really delete program \"": "Programm „",
|
|
119
|
+
"Really delete the saved anti-crease pattern?": "Gespeichertes Anti-Knitter-Muster wirklich löschen?",
|
|
120
|
+
"Really delete this cycle?": "Zyklus wirklich löschen?",
|
|
121
|
+
"Recipient": "Empfänger",
|
|
122
|
+
"Reference cycle": "Referenz-Zyklus",
|
|
123
|
+
"Renamed": "Umbenannt",
|
|
124
|
+
"Running ⚙️": "Läuft ⚙️",
|
|
125
|
+
"Save": "Speichern",
|
|
126
|
+
"Save as program": "Als Programm speichern",
|
|
127
|
+
"Saved programs": "Gespeicherte Programme",
|
|
128
|
+
"Split": "Teilen",
|
|
129
|
+
"Split!": "Geteilt!",
|
|
130
|
+
"Start": "Start",
|
|
131
|
+
"Start energy gate": "Start-Energie-Gate",
|
|
132
|
+
"Starting…": "Startet…",
|
|
133
|
+
"Status": "Status",
|
|
134
|
+
"Test message sent!": "Testnachricht gesendet!",
|
|
135
|
+
"Time remaining": "Restzeit",
|
|
136
|
+
"Trim": "Trimmen",
|
|
137
|
+
"Unknown": "Unbekannt",
|
|
138
|
+
"Which program was it actually?": "Welches Programm war das wirklich?",
|
|
139
|
+
"Wrong program": "Falsches Programm",
|
|
140
|
+
"confidence": "Konfidenz",
|
|
141
|
+
"cycles": "Zyklen",
|
|
142
|
+
"e.g. Cotton 60°": "z.B. Baumwolle 60°",
|
|
143
|
+
"e.g. name@example.com (blank = adapter default)": "z.B. name@example.com (leer = Adapter-Standard)",
|
|
144
|
+
"fields with >10% deviation only:": "nur Felder mit >10% Abweichung:",
|
|
145
|
+
"min lock period": "min Sperrzeit",
|
|
146
|
+
"– Choose adapter –": "– Adapter wählen –",
|
|
147
|
+
"– Choose cycle –": "– Zyklus wählen –",
|
|
148
|
+
"– No adapter found –": "– Kein Adapter gefunden –",
|
|
149
|
+
"– No adapter –": "– Kein Adapter –",
|
|
150
|
+
"– No cycle selected –": "– Kein Zyklus gewählt –",
|
|
151
|
+
"⏹ End cycle": "⏹ Zyklus beenden",
|
|
152
|
+
"⚠️ Review needed": "⚠️ Lernkontrolle erforderlich",
|
|
153
|
+
"✅ All cycles confirmed!": "✅ Alle Zyklen bestätigt!",
|
|
154
|
+
"✅ Done message": "✅ Fertig-Meldung",
|
|
155
|
+
"✅ Review": "✅ Lernkontrolle",
|
|
156
|
+
"✏️ Rename program": "✏️ Programm umbenennen",
|
|
157
|
+
"✓ Assign & learn": "✓ Zuweisen & Lernen",
|
|
158
|
+
"⬆ Import": "⬆ Import",
|
|
159
|
+
"⬇ Export": "⬇ Export",
|
|
160
|
+
"🌀 Anti-crease detection": "🌀 Anti-Knitter Erkennung",
|
|
161
|
+
"🌀 Save": "🌀 Speichern",
|
|
162
|
+
"🎮 Live control": "🎮 Live-Steuerung",
|
|
163
|
+
"🏷 Assign program": "🏷 Programm zuweisen",
|
|
164
|
+
"💡 Suggested settings": "💡 Empfohlene Einstellungen",
|
|
165
|
+
"💡 The adapter learns the real duration automatically after 2–3 cycles.": "💡 Der Adapter lernt die echte Dauer nach 2–3 Zyklen automatisch.",
|
|
166
|
+
"💾 Export": "💾 Export",
|
|
167
|
+
"💾 Save": "💾 Speichern",
|
|
168
|
+
"📊 Overview": "📊 Übersicht",
|
|
169
|
+
"🔄 Correct program": "🔄 Programm korrigieren",
|
|
170
|
+
"🔄 Update message": "🔄 Korrektur-Meldung",
|
|
171
|
+
"🔔 Notifications": "🔔 Benachrichtigungen",
|
|
172
|
+
"🔔 Test": "🔔 Test",
|
|
173
|
+
"🕐 Cycles": "🕐 Zyklen",
|
|
174
|
+
"🗂 Programs": "🗂 Programme",
|
|
175
|
+
"🗑 Delete": "🗑 Löschen",
|
|
176
|
+
"🟢 Start message": "🟢 Start-Meldung",
|
|
177
|
+
"🤖 Automatic": "🤖 Automatik",
|
|
178
|
+
"🧺 {device} running\n⏳ Determining time…": "🧺 {device} läuft\n⏳ Zeit wird ermittelt…",
|
|
179
|
+
"🧺 {device} update\n✅ Done at {endTime}\n📊 Program: {program}": "🧺 {device} Update\n✅ Fertig um {endTime} Uhr\n📊 Programm: {program}",
|
|
180
|
+
"🧺 {device} update\n✅ Done at {endTime}\n[↩️ Before: {prevTime}]\n📊 Program: {program}\n📈 Progress: {progress}%": "🧺 {device} Update\n✅ Fertig um {endTime} Uhr\n[↩️ Vorher: {prevTime}]\n📊 Programm: {program}\n📈 Fortschritt: {progress}%",
|
|
181
|
+
"🧺 {device} done!\n⏱️ Total runtime: {duration} min\n📊 Program: {program}\n⚡ Consumption: {energy} kWh": "🧺 {device} fertig!\n⏱️ Gesamtlaufzeit: {duration} min\n📊 Programm: {program}\n⚡ Verbrauch: {energy} kWh",
|
|
182
|
+
"Apply suggested value?": "Empfohlenen Wert übernehmen?",
|
|
183
|
+
"Ignore": "Ignorieren",
|
|
184
|
+
"Error saving": "Fehler beim Speichern",
|
|
185
|
+
"Setting saved! Restarting adapter…": "Einstellung gespeichert! Adapter wird neu gestartet…"
|
|
186
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Device name": "Device name",
|
|
3
|
+
"e.g. Washing machine": "e.g. Washing machine",
|
|
4
|
+
"Display name in the dashboard": "Display name in the dashboard",
|
|
5
|
+
"Device type": "Device type",
|
|
6
|
+
"🧺 Washing machine": "🧺 Washing machine",
|
|
7
|
+
"🍽️ Dishwasher": "🍽️ Dishwasher",
|
|
8
|
+
"♨️ Dryer": "♨️ Dryer",
|
|
9
|
+
"🔄 Washer-dryer": "🔄 Washer-dryer",
|
|
10
|
+
"⚙️ Other": "⚙️ Other",
|
|
11
|
+
"Power sensor (watt)": "Power sensor (watt)",
|
|
12
|
+
"ioBroker data point providing the current power draw in watts": "ioBroker data point providing the current power draw in watts",
|
|
13
|
+
"Detection thresholds": "Detection thresholds",
|
|
14
|
+
"Power-on threshold (W)": "Power-on threshold (W)",
|
|
15
|
+
"Power level from which the device is considered running. Recommended: 10W for all device types": "Power level from which the device is considered running. Recommended: 10W for all device types",
|
|
16
|
+
"Off delay (min)": "Off delay (min)",
|
|
17
|
+
"How long power must stay below the threshold before the cycle ends. Recommended: washing machine 5 min · dryer 8 min · dishwasher 8 min · washer-dryer 10 min": "How long power must stay below the threshold before the cycle ends. Recommended: washing machine 5 min · dryer 8 min · dishwasher 8 min · washer-dryer 10 min",
|
|
18
|
+
"Start energy gate (Wh)": "Start energy gate (Wh)",
|
|
19
|
+
"Minimum energy after start before the cycle is counted (prevents false starts). Recommended: washing machine 2 Wh · dryer 5 Wh · washer-dryer 5 Wh": "Minimum energy after start before the cycle is counted (prevents false starts). Recommended: washing machine 2 Wh · dryer 5 Wh · washer-dryer 5 Wh",
|
|
20
|
+
"Program detection": "Program detection",
|
|
21
|
+
"Duration tolerance (0.05–0.5)": "Duration tolerance (0.05–0.5)",
|
|
22
|
+
"How much the run time may deviate from the profile. 0.2 = ±20%": "How much the run time may deviate from the profile. 0.2 = ±20%",
|
|
23
|
+
"Matching interval (min)": "Matching interval (min)",
|
|
24
|
+
"How often the program is matched. Recommended: 5 min for all device types": "How often the program is matched. Recommended: 5 min for all device types",
|
|
25
|
+
"Match confirmations (count)": "Match confirmations (count)",
|
|
26
|
+
"How many times in a row the same program must be detected. 3 = reliable · 2 = faster": "How many times in a row the same program must be detected. 3 = reliable · 2 = faster",
|
|
27
|
+
"Auto-confirm from confidence (%)": "Auto-confirm from confidence (%)",
|
|
28
|
+
"From this confidence level the cycle is confirmed automatically. 0 = disabled · 85 = recommended": "From this confidence level the cycle is confirmed automatically. 0 = disabled · 85 = recommended",
|
|
29
|
+
"Instant adoption from confidence (%)": "Instant adoption from confidence (%)",
|
|
30
|
+
"During a running cycle: if the live preview repeatedly (2x) shows at least this confidence, the program is adopted immediately instead of waiting for the normal, slower detection.": "During a running cycle: if the live preview repeatedly (2x) shows at least this confidence, the program is adopted immediately instead of waiting for the normal, slower detection.",
|
|
31
|
+
"Program detection threshold (%)": "Program detection threshold (%)",
|
|
32
|
+
"From this confidence a program counts as detected (and is shown). Below it, it stays 'detecting...'. 55 = recommended": "From this confidence a program counts as detected (and is shown). Below it, it stays 'detecting...'. 55 = recommended",
|
|
33
|
+
"Notify also for probable program": "Notify also for probable program",
|
|
34
|
+
"Send a Telegram update as soon as a program is detected - even if confidence is below the auto-confirm threshold": "Send a Telegram update as soon as a program is detected - even if confidence is below the auto-confirm threshold",
|
|
35
|
+
"Dryer settings": "Dryer settings",
|
|
36
|
+
"Ignore anti-crease phase": "Ignore anti-crease phase",
|
|
37
|
+
"ON: cycle ends immediately at the beep, the anti-crease phase is ignored (simple, sufficient for most dryers). OFF: the adapter actively tries to detect when the cycle is really finished across the anti-crease phase (needs a saved reference pattern under 'Programs').": "ON: cycle ends immediately at the beep, the anti-crease phase is ignored (simple, sufficient for most dryers). OFF: the adapter actively tries to detect when the cycle is really finished across the anti-crease phase (needs a saved reference pattern under 'Programs').",
|
|
38
|
+
"+ Create": "+ Create",
|
|
39
|
+
"Adapter": "Adapter",
|
|
40
|
+
"All (broadcast)": "All (broadcast)",
|
|
41
|
+
"All cycles confirmed!": "All cycles confirmed!",
|
|
42
|
+
"All data deleted!": "All data deleted!",
|
|
43
|
+
"All devices": "All devices",
|
|
44
|
+
"Anti-crease pattern deleted": "Anti-crease pattern deleted",
|
|
45
|
+
"Anti-crease pattern saved!": "Anti-crease pattern saved!",
|
|
46
|
+
"Apply": "Apply",
|
|
47
|
+
"Assign program": "Assign program",
|
|
48
|
+
"Automatic": "Automatic",
|
|
49
|
+
"Back up configuration": "Back up configuration",
|
|
50
|
+
"Based on": "Based on",
|
|
51
|
+
"Cancel": "Cancel",
|
|
52
|
+
"Choose a recorded cycle as the anti-crease reference. The adapter will then automatically ignore this pattern after drying.": "Choose a recorded cycle as the anti-crease reference. The adapter will then automatically ignore this pattern after drying.",
|
|
53
|
+
"Choose a split point in the graph": "Choose a split point in the graph",
|
|
54
|
+
"Choose the program for this cycle:": "Choose the program for this cycle:",
|
|
55
|
+
"Confidence": "Confidence",
|
|
56
|
+
"Confirm or correct cycles marked with ❓. This automatically improves detection.": "Confirm or correct cycles marked with ❓. This automatically improves detection.",
|
|
57
|
+
"Confirmed": "Confirmed",
|
|
58
|
+
"Confirmed – adapter is learning!": "Confirmed – adapter is learning!",
|
|
59
|
+
"Consumption": "Consumption",
|
|
60
|
+
"Correct & learn": "Correct & learn",
|
|
61
|
+
"Correct – confirm": "Correct – confirm",
|
|
62
|
+
"Corrected – adapter is learning!": "Corrected – adapter is learning!",
|
|
63
|
+
"Create new program": "Create new program",
|
|
64
|
+
"Cycle deleted": "Cycle deleted",
|
|
65
|
+
"Cycle history": "Cycle history",
|
|
66
|
+
"Delete": "Delete",
|
|
67
|
+
"Delete all data for \"": "Delete all data for \"",
|
|
68
|
+
"Deleted": "Deleted",
|
|
69
|
+
"Detected as": "Detected as",
|
|
70
|
+
"Device": "Device",
|
|
71
|
+
"Device:": "Device:",
|
|
72
|
+
"Duration": "Duration",
|
|
73
|
+
"Duration (min)": "Duration (min)",
|
|
74
|
+
"Duration tolerance": "Duration tolerance",
|
|
75
|
+
"Elapsed time": "Elapsed time",
|
|
76
|
+
"Ending…": "Ending…",
|
|
77
|
+
"Error": "Error",
|
|
78
|
+
"Error loading": "Error loading",
|
|
79
|
+
"Export downloaded": "Export downloaded",
|
|
80
|
+
"Export failed": "Export failed",
|
|
81
|
+
"Go to review →": "Go to review →",
|
|
82
|
+
"Invalid JSON file": "Invalid JSON file",
|
|
83
|
+
"JSON appears here after export…": "JSON appears here after export…",
|
|
84
|
+
"Last cycle": "Last cycle",
|
|
85
|
+
"Last cycle not confidently detected. Please confirm or correct.": "Last cycle not confidently detected. Please confirm or correct.",
|
|
86
|
+
"Learned on": "Learned on",
|
|
87
|
+
"Live status": "Live status",
|
|
88
|
+
"Loading…": "Loading…",
|
|
89
|
+
"Min. interval (min)": "Min. interval (min)",
|
|
90
|
+
"Near-done dev. %": "Near-done dev. %",
|
|
91
|
+
"Near-done dev. min": "Near-done dev. min",
|
|
92
|
+
"Near-done from (%)": "Near-done from (%)",
|
|
93
|
+
"New name": "New name",
|
|
94
|
+
"No anti-crease pattern saved yet.": "No anti-crease pattern saved yet.",
|
|
95
|
+
"No cycle recorded yet.": "No cycle recorded yet.",
|
|
96
|
+
"No cycles recorded yet.": "No cycles recorded yet.",
|
|
97
|
+
"No cycles with curve data available": "No cycles with curve data available",
|
|
98
|
+
"No device selected": "No device selected",
|
|
99
|
+
"No devices configured.": "No devices configured.",
|
|
100
|
+
"No programs created yet.": "No programs created yet.",
|
|
101
|
+
"No suggestions available": "No suggestions available",
|
|
102
|
+
"No trace available": "No trace available",
|
|
103
|
+
"No trace data": "No trace data",
|
|
104
|
+
"Off": "Off",
|
|
105
|
+
"Off delay": "Off delay",
|
|
106
|
+
"Open": "Open",
|
|
107
|
+
"Paused": "Paused",
|
|
108
|
+
"Placeholders:": "Placeholders:",
|
|
109
|
+
"Please choose an adapter": "Please choose an adapter",
|
|
110
|
+
"Please select a cycle": "Please select a cycle",
|
|
111
|
+
"Power curve": "Power curve",
|
|
112
|
+
"Power-on threshold": "Power-on threshold",
|
|
113
|
+
"Profiles, cycles, and traces will be permanently deleted!": "Profiles, cycles, and traces will be permanently deleted!",
|
|
114
|
+
"Program": "Program",
|
|
115
|
+
"Program name": "Program name",
|
|
116
|
+
"Program override": "Program override",
|
|
117
|
+
"Progress": "Progress",
|
|
118
|
+
"Really delete program \"": "Really delete program \"",
|
|
119
|
+
"Really delete the saved anti-crease pattern?": "Really delete the saved anti-crease pattern?",
|
|
120
|
+
"Really delete this cycle?": "Really delete this cycle?",
|
|
121
|
+
"Recipient": "Recipient",
|
|
122
|
+
"Reference cycle": "Reference cycle",
|
|
123
|
+
"Renamed": "Renamed",
|
|
124
|
+
"Running ⚙️": "Running ⚙️",
|
|
125
|
+
"Save": "Save",
|
|
126
|
+
"Save as program": "Save as program",
|
|
127
|
+
"Saved programs": "Saved programs",
|
|
128
|
+
"Split": "Split",
|
|
129
|
+
"Split!": "Split!",
|
|
130
|
+
"Start": "Start",
|
|
131
|
+
"Start energy gate": "Start energy gate",
|
|
132
|
+
"Starting…": "Starting…",
|
|
133
|
+
"Status": "Status",
|
|
134
|
+
"Test message sent!": "Test message sent!",
|
|
135
|
+
"Time remaining": "Time remaining",
|
|
136
|
+
"Trim": "Trim",
|
|
137
|
+
"Unknown": "Unknown",
|
|
138
|
+
"Which program was it actually?": "Which program was it actually?",
|
|
139
|
+
"Wrong program": "Wrong program",
|
|
140
|
+
"confidence": "confidence",
|
|
141
|
+
"cycles": "cycles",
|
|
142
|
+
"e.g. Cotton 60°": "e.g. Cotton 60°",
|
|
143
|
+
"e.g. name@example.com (blank = adapter default)": "e.g. name@example.com (blank = adapter default)",
|
|
144
|
+
"fields with >10% deviation only:": "fields with >10% deviation only:",
|
|
145
|
+
"min lock period": "min lock period",
|
|
146
|
+
"– Choose adapter –": "– Choose adapter –",
|
|
147
|
+
"– Choose cycle –": "– Choose cycle –",
|
|
148
|
+
"– No adapter found –": "– No adapter found –",
|
|
149
|
+
"– No adapter –": "– No adapter –",
|
|
150
|
+
"– No cycle selected –": "– No cycle selected –",
|
|
151
|
+
"⏹ End cycle": "⏹ End cycle",
|
|
152
|
+
"⚠️ Review needed": "⚠️ Review needed",
|
|
153
|
+
"✅ All cycles confirmed!": "✅ All cycles confirmed!",
|
|
154
|
+
"✅ Done message": "✅ Done message",
|
|
155
|
+
"✅ Review": "✅ Review",
|
|
156
|
+
"✏️ Rename program": "✏️ Rename program",
|
|
157
|
+
"✓ Assign & learn": "✓ Assign & learn",
|
|
158
|
+
"⬆ Import": "⬆ Import",
|
|
159
|
+
"⬇ Export": "⬇ Export",
|
|
160
|
+
"🌀 Anti-crease detection": "🌀 Anti-crease detection",
|
|
161
|
+
"🌀 Save": "🌀 Save",
|
|
162
|
+
"🎮 Live control": "🎮 Live control",
|
|
163
|
+
"🏷 Assign program": "🏷 Assign program",
|
|
164
|
+
"💡 Suggested settings": "💡 Suggested settings",
|
|
165
|
+
"💡 The adapter learns the real duration automatically after 2–3 cycles.": "💡 The adapter learns the real duration automatically after 2–3 cycles.",
|
|
166
|
+
"💾 Export": "💾 Export",
|
|
167
|
+
"💾 Save": "💾 Save",
|
|
168
|
+
"📊 Overview": "📊 Overview",
|
|
169
|
+
"🔄 Correct program": "🔄 Correct program",
|
|
170
|
+
"🔄 Update message": "🔄 Update message",
|
|
171
|
+
"🔔 Notifications": "🔔 Notifications",
|
|
172
|
+
"🔔 Test": "🔔 Test",
|
|
173
|
+
"🕐 Cycles": "🕐 Cycles",
|
|
174
|
+
"🗂 Programs": "🗂 Programs",
|
|
175
|
+
"🗑 Delete": "🗑 Delete",
|
|
176
|
+
"🟢 Start message": "🟢 Start message",
|
|
177
|
+
"🤖 Automatic": "🤖 Automatic",
|
|
178
|
+
"🧺 {device} running\n⏳ Determining time…": "🧺 {device} running\n⏳ Determining time…",
|
|
179
|
+
"🧺 {device} update\n✅ Done at {endTime}\n📊 Program: {program}": "🧺 {device} update\n✅ Done at {endTime}\n📊 Program: {program}",
|
|
180
|
+
"🧺 {device} update\n✅ Done at {endTime}\n[↩️ Before: {prevTime}]\n📊 Program: {program}\n📈 Progress: {progress}%": "🧺 {device} update\n✅ Done at {endTime}\n[↩️ Before: {prevTime}]\n📊 Program: {program}\n📈 Progress: {progress}%",
|
|
181
|
+
"🧺 {device} done!\n⏱️ Total runtime: {duration} min\n📊 Program: {program}\n⚡ Consumption: {energy} kWh": "🧺 {device} done!\n⏱️ Total runtime: {duration} min\n📊 Program: {program}\n⚡ Consumption: {energy} kWh",
|
|
182
|
+
"Apply suggested value?": "Apply suggested value?",
|
|
183
|
+
"Ignore": "Ignore",
|
|
184
|
+
"Error saving": "Error saving",
|
|
185
|
+
"Setting saved! Restarting adapter…": "Setting saved! Restarting adapter…"
|
|
186
|
+
}
|