iobroker.laundrylens 0.4.21 → 0.4.22
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 +3 -0
- package/io-package.json +14 -14
- package/lib/cycleDetector.js +11 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,9 @@ This also works inside the conditional `[...]` blocks: `[🌡️ Outside: {state
|
|
|
132
132
|
|
|
133
133
|
### **WORK IN PROGRESS**
|
|
134
134
|
|
|
135
|
+
### 0.4.22 (2026-09-16)
|
|
136
|
+
- Fix: the per-device "Off delay" setting (`offDelayMin`) was silently ignored - `CycleDetector`'s config merge never translated it into the field the detector actually uses (`offDelay`, in seconds), so every device always used a hardcoded 5-minute default regardless of what was configured. Found via a real trace where a cycle stayed stuck as "running" long after power had genuinely dropped to ~0W. Note: this alone doesn't fully explain very long stalls (well over an hour) - if a cycle still gets stuck after this fix, please share the adapter log from around that time
|
|
137
|
+
|
|
135
138
|
### 0.4.21 (2026-09-08)
|
|
136
139
|
- Fix: translated all remaining German user-visible strings in the admin tab (toasts, table headers, confirm dialogs - about 35 instances, more than initially found by review) into the existing i18n system
|
|
137
140
|
- Fix: a cycle's `matchedProfile` could be stored server-side as literal German text ("Anti-Knitter") for anti-crease-tagged cycles, showing up untranslated in the `lastCycleProgram` data point and cycle history regardless of system language - now stored as a language-neutral marker and translated at display time
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "laundrylens",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.22",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.4.22": {
|
|
7
|
+
"en": "Fix: the per-device \"Off delay\" setting (offDelayMin) was silently ignored - CycleDetector's config merge never translated it into the field the detector actually uses (offDelay, in seconds), so every device always used a hardcoded 5-minute default regardless of what was configured. Found via a real trace where a cycle stayed stuck as \"running\" long after power had genuinely dropped to ~0W. Note: this alone doesn't fully explain very long stalls (well over an hour) - if a cycle still gets stuck after this fix, please share the adapter log from around that time so the remaining cause can be tracked down.",
|
|
8
|
+
"de": "Fix: Die Geräte-Einstellung „Off delay\" (offDelayMin) wurde stillschweigend ignoriert - beim Zusammenführen der Konfiguration im CycleDetector wurde sie nie in das tatsächlich verwendete Feld (offDelay, in Sekunden) übersetzt, wodurch jedes Gerät unabhängig von der Einstellung immer den fest codierten 5-Minuten-Standard genutzt hat. Gefunden über eine reale Aufzeichnung, bei der ein Zyklus lange als „läuft\" hängen blieb, obwohl die Leistung längst auf ~0W gefallen war. Hinweis: Das allein erklärt sehr lange Aussetzer (deutlich über eine Stunde) nicht vollständig - falls ein Zyklus nach diesem Fix weiterhin hängen bleibt, bitte das Adapter-Log aus diesem Zeitraum teilen, damit die verbleibende Ursache gefunden werden kann.",
|
|
9
|
+
"ru": "Исправление: настройка «Off delay» (offDelayMin) для устройства незаметно игнорировалась - при объединении конфигурации в CycleDetector она никогда не преобразовывалась в поле, которое реально используется (offDelay, в секундах), поэтому каждое устройство всегда использовало жёстко заданное значение по умолчанию в 5 минут независимо от настройки. Обнаружено благодаря реальной записи, где цикл долго оставался «запущенным», хотя мощность давно упала до ~0 Вт.",
|
|
10
|
+
"pt": "Correção: a configuração \"Off delay\" (offDelayMin) por dispositivo era silenciosamente ignorada - a fusão de configuração do CycleDetector nunca a traduzia para o campo realmente usado (offDelay, em segundos), então cada dispositivo sempre usava um padrão fixo de 5 minutos, independentemente do configurado. Encontrado através de um traço real onde um ciclo ficou preso como \"em execução\" muito depois da potência ter realmente caído para ~0W.",
|
|
11
|
+
"nl": "Fix: de instelling \"Off delay\" (offDelayMin) per apparaat werd stilzwijgend genegeerd - bij het samenvoegen van de configuratie in CycleDetector werd deze nooit vertaald naar het veld dat daadwerkelijk wordt gebruikt (offDelay, in seconden), waardoor elk apparaat altijd de vast ingestelde standaard van 5 minuten gebruikte, ongeacht de instelling. Gevonden via een echte trace waarbij een cyclus lang als \"actief\" bleef hangen terwijl het vermogen al naar ~0W was gedaald.",
|
|
12
|
+
"fr": "Correction : le réglage « Off delay » (offDelayMin) par appareil était silencieusement ignoré - la fusion de configuration de CycleDetector ne le traduisait jamais vers le champ réellement utilisé (offDelay, en secondes), donc chaque appareil utilisait toujours la valeur par défaut codée en dur de 5 minutes, quel que soit le réglage. Trouvé via une trace réelle où un cycle est resté bloqué en « en cours » bien après que la puissance soit réellement tombée à ~0W.",
|
|
13
|
+
"it": "Correzione: l'impostazione \"Off delay\" (offDelayMin) per dispositivo veniva silenziosamente ignorata - la fusione della configurazione in CycleDetector non la traduceva mai nel campo effettivamente usato (offDelay, in secondi), quindi ogni dispositivo usava sempre il valore predefinito fisso di 5 minuti, indipendentemente dall'impostazione. Trovato tramite una traccia reale in cui un ciclo è rimasto bloccato come \"in esecuzione\" molto dopo che la potenza era scesa a ~0W.",
|
|
14
|
+
"es": "Corrección: el ajuste \"Off delay\" (offDelayMin) por dispositivo se ignoraba silenciosamente - la fusión de configuración de CycleDetector nunca lo traducía al campo realmente utilizado (offDelay, en segundos), por lo que cada dispositivo siempre usaba el valor predeterminado fijo de 5 minutos, sin importar lo configurado. Encontrado mediante un registro real donde un ciclo quedó atascado como \"en ejecución\" mucho después de que la potencia realmente cayera a ~0W.",
|
|
15
|
+
"pl": "Poprawka: ustawienie \"Off delay\" (offDelayMin) dla urządzenia było po cichu ignorowane - łączenie konfiguracji w CycleDetector nigdy nie przekładało go na pole faktycznie używane (offDelay, w sekundach), więc każde urządzenie zawsze używało sztywno zakodowanej wartości domyślnej 5 minut, niezależnie od ustawienia. Znalezione dzięki rzeczywistemu zapisowi, w którym cykl długo pozostawał jako \"działający\", mimo że moc już dawno spadła do ~0W.",
|
|
16
|
+
"uk": "Виправлення: налаштування \"Off delay\" (offDelayMin) для пристрою непомітно ігнорувалося - під час об'єднання конфігурації в CycleDetector воно ніколи не перетворювалося на поле, яке дійсно використовується (offDelay, у секундах), тому кожен пристрій завжди використовував жорстко задане значення за замовчуванням 5 хвилин, незалежно від налаштування. Виявлено завдяки реальному запису, де цикл довго залишався \"запущеним\", хоча потужність давно впала до ~0 Вт.",
|
|
17
|
+
"zh-cn": "修复:每个设备的\"关闭延迟\"(offDelayMin)设置此前被静默忽略——CycleDetector 合并配置时从未将其转换为实际使用的字段(offDelay,单位为秒),导致每台设备始终使用硬编码的 5 分钟默认值,而与实际配置无关。此问题是通过一次真实记录发现的:某个周期在功率早已降至约 0W 之后,仍长时间卡在\"运行中\"状态。"
|
|
18
|
+
},
|
|
6
19
|
"0.4.21": {
|
|
7
20
|
"en": "Fix: translated all remaining German user-visible strings in the admin tab (toasts, table headers, confirm dialogs - about 35 instances, more than initially found by review) into the existing i18n system. Fix: a cycle's matchedProfile could be stored server-side as literal German text (\"Anti-Knitter\") for anti-crease-tagged cycles, showing up untranslated in the lastCycleProgram data point and cycle history regardless of system language - now stored as a language-neutral marker and translated at display time. Fix: two remaining hardcoded German date/time locales in the admin tab now use the configured language like everywhere else. Fix: added the full MIT license text to README.md (previously only the header/copyright line). Extended the English-only regression test to also cover the admin tab, closing the gap that let these issues go unnoticed.",
|
|
8
21
|
"de": "Fix: alle verbliebenen deutschen, für Nutzer sichtbaren Texte im Admin-Tab (Toasts, Tabellenüberschriften, Bestätigungsdialoge - ca. 35 Stellen, mehr als ursprünglich vom Review gefunden) ins bestehende i18n-System übersetzt. Fix: Der matchedProfile-Wert eines Zyklus konnte serverseitig als wörtlicher deutscher Text (\"Anti-Knitter\") für Anti-Knitter-markierte Zyklen gespeichert werden und erschien unübersetzt im lastCycleProgram-Datenpunkt sowie in der Zyklus-Historie, unabhängig von der Systemsprache - wird jetzt als sprachneutraler Marker gespeichert und erst bei der Anzeige übersetzt. Fix: zwei verbliebene fest codierte deutsche Datums-/Zeit-Gebietsschemata im Admin-Tab nutzen jetzt wie überall sonst die eingestellte Sprache. Fix: vollständigen MIT-Lizenztext zur README.md hinzugefügt (vorher nur Kopfzeile/Copyright-Zeile). Den Englisch-only-Regressionstest erweitert, damit er auch den Admin-Tab abdeckt und diese Lücke künftig auffällt.",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "Nowość: szablony wiadomości powiadomień obsługują teraz symbol zastępczy `{state:objectId}`, który podczas wysyłania podstawia bieżącą wartość dowolnego punktu danych ioBroker (np. temperatura na zewnątrz, cena prądu) - oprócz istniejących wbudowanych symboli zastępczych. Działa też wewnątrz bloków warunkowych `[...]`: blok ukrywa się, jeśli wskazany punkt danych jest pusty. Naprawiono też pozostałe niemieckie słowo (\"Fertig\") w temacie powiadomienia.",
|
|
81
94
|
"uk": "Новинка: шаблони повідомлень тепер підтримують заповнювач `{state:objectId}`, який під час надсилання підставляє поточне значення будь-якої точки даних ioBroker (наприклад, температуру зовні, ціну електроенергії) - на додаток до наявних вбудованих заповнювачів. Працює й усередині умовних блоків `[...]`: блок приховується, якщо вказана точка даних порожня. Також виправлено залишкове німецьке слово («Fertig») у темі сповіщення.",
|
|
82
95
|
"zh-cn": "新功能:通知消息模板现在支持 `{state:objectId}` 占位符,可在发送时解析任意 ioBroker 数据点的当前值(例如室外温度、电价)——在现有内置占位符之上新增。在条件性 `[...]` 块内同样有效:若引用的数据点为空,该块会自动隐藏。同时修复了通知主题行中残留的一个德文单词(\"Fertig\")。"
|
|
83
|
-
},
|
|
84
|
-
"0.4.15": {
|
|
85
|
-
"en": "Fixes from a full adapter review: the notification-language cache was module-level state, which could leak between two instances of this adapter sharing one process under compact mode - moved to an instance field. Two devices accidentally configured with the same power sensor now log a warning instead of one silently stopping updates. Cleaned up a small inconsistency in default-value handling for a few settings, and removed unused dead code.",
|
|
86
|
-
"de": "Fixes aus einem vollständigen Adapter-Review: Der Sprach-Cache für Benachrichtigungen war modulweiter State, der unter Compact-Mode zwischen zwei Instanzen dieses Adapters im selben Prozess hätte überlaufen können - jetzt ein Instanz-Feld. Zwei Geräte, die versehentlich denselben Stromsensor nutzen, loggen jetzt eine Warnung statt dass eines stillschweigend keine Updates mehr bekommt. Kleine Inkonsistenz bei Default-Werten einiger Einstellungen bereinigt, toten Code entfernt.",
|
|
87
|
-
"ru": "Исправления по итогам полного ревью адаптера: кэш языка уведомлений был состоянием уровня модуля, что могло привести к утечке между двумя инстанциями этого адаптера в одном процессе при compact-режиме - перенесено в поле инстанции. Два устройства, случайно настроенных на один датчик мощности, теперь логируют предупреждение вместо того, чтобы одно из них молча переставало получать обновления. Устранена небольшая несогласованность в обработке значений по умолчанию, удалён неиспользуемый код.",
|
|
88
|
-
"pt": "Correções de uma revisão completa do adaptador: o cache de idioma de notificação era estado em nível de módulo, podendo vazar entre duas instâncias deste adaptador compartilhando um processo em modo compact - movido para um campo da instância. Dois dispositivos configurados acidentalmente com o mesmo sensor de energia agora registram um aviso em vez de um parar silenciosamente de receber atualizações. Corrigida uma pequena inconsistência no tratamento de valores padrão e removido código morto.",
|
|
89
|
-
"nl": "Fixes uit een volledige adapterreview: de taalcache voor meldingen was module-brede state, die onder compact mode kon lekken tussen twee instanties van deze adapter in hetzelfde proces - nu een instantieveld. Twee apparaten die per ongeluk dezelfde stroomsensor gebruiken, loggen nu een waarschuwing in plaats van dat er één stilletjes geen updates meer krijgt. Kleine inconsistentie bij standaardwaarden opgelost, ongebruikte code verwijderd.",
|
|
90
|
-
"fr": "Corrections issues d'une revue complète de l'adaptateur : le cache de langue des notifications était un état au niveau du module, pouvant fuiter entre deux instances de cet adaptateur partageant un processus en mode compact - déplacé vers un champ d'instance. Deux appareils configurés par erreur avec le même capteur de puissance enregistrent désormais un avertissement au lieu que l'un cesse silencieusement de recevoir des mises à jour. Petite incohérence corrigée dans les valeurs par défaut, code mort supprimé.",
|
|
91
|
-
"it": "Correzioni da una revisione completa dell'adattatore: la cache della lingua delle notifiche era stato a livello di modulo, che poteva perdersi tra due istanze di questo adattatore che condividono un processo in modalità compact - spostata in un campo dell'istanza. Due dispositivi configurati per errore con lo stesso sensore di potenza ora registrano un avviso invece che uno smetta silenziosamente di ricevere aggiornamenti. Risolta una piccola incoerenza nei valori predefiniti, rimosso codice inutilizzato.",
|
|
92
|
-
"es": "Correcciones de una revisión completa del adaptador: la caché de idioma de notificaciones era estado a nivel de módulo, que podía filtrarse entre dos instancias de este adaptador que comparten un proceso en modo compact - movida a un campo de instancia. Dos dispositivos configurados accidentalmente con el mismo sensor de energía ahora registran una advertencia en lugar de que uno deje de recibir actualizaciones silenciosamente. Corregida una pequeña inconsistencia en los valores predeterminados, eliminado código muerto.",
|
|
93
|
-
"pl": "Poprawki z pełnego przeglądu adaptera: pamięć podręczna języka powiadomień była stanem na poziomie modułu, co mogło powodować wyciek między dwiema instancjami tego adaptera współdzielącymi jeden proces w trybie compact - przeniesiono do pola instancji. Dwa urządzenia przypadkowo skonfigurowane z tym samym czujnikiem mocy teraz logują ostrzeżenie zamiast tego, by jedno z nich po cichu przestało otrzymywać aktualizacje. Naprawiono drobną niespójność w wartościach domyślnych, usunięto martwy kod.",
|
|
94
|
-
"uk": "Виправлення за результатами повного огляду адаптера: кеш мови сповіщень був станом рівня модуля, що могло призвести до витоку між двома інстанціями цього адаптера в одному процесі в режимі compact - перенесено в поле інстанції. Два пристрої, випадково налаштовані на один датчик потужності, тепер логують попередження замість того, щоб один із них тихо переставав отримувати оновлення. Виправлено дрібну невідповідність у значеннях за замовчуванням, видалено невикористовуваний код.",
|
|
95
|
-
"zh-cn": "全面审查适配器后的修复:通知语言缓存原为模块级状态,在 compact 模式下共享同一进程的两个适配器实例之间可能发生泄漏——现已改为实例字段。两个设备如果意外配置了相同的功率传感器,现在会记录警告,而不是其中一个默默停止接收更新。修复了部分设置默认值处理中的小的不一致,移除了未使用的死代码。"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/lib/cycleDetector.js
CHANGED
|
@@ -49,6 +49,17 @@ class CycleDetector {
|
|
|
49
49
|
*/
|
|
50
50
|
constructor(config = {}, onStateChange = null, adapter = null) {
|
|
51
51
|
this.cfg = { ...DEFAULT_CONFIG, ...config };
|
|
52
|
+
// The admin UI's per-device "Off delay" setting is stored as
|
|
53
|
+
// offDelayMin (minutes) on the normalized device config, but this
|
|
54
|
+
// detector's own field is offDelay (seconds) - the naive object-spread
|
|
55
|
+
// merge above never matches those two different key names, so the
|
|
56
|
+
// configured value was silently ignored and every device always used
|
|
57
|
+
// DEFAULT_CONFIG's hardcoded 300s (5 min), regardless of what was set
|
|
58
|
+
// in the admin UI (or the 8/10 min device-type defaults main.js
|
|
59
|
+
// computes for offDelayMin). Translated explicitly here.
|
|
60
|
+
if (config.offDelayMin !== undefined && config.offDelayMin !== null) {
|
|
61
|
+
this.cfg.offDelay = config.offDelayMin * 60;
|
|
62
|
+
}
|
|
52
63
|
this.onStateChange = onStateChange;
|
|
53
64
|
this.adapter = adapter;
|
|
54
65
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.laundrylens",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.22",
|
|
4
4
|
"description": "ioBroker adapter that detects washing machine and dryer cycles via smart plug power measurement, matches them against learned programs and estimates remaining time",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "backfisch88",
|