iobroker.laundrylens 0.4.34 → 0.4.35
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 +4 -0
- package/io-package.json +14 -14
- package/main.js +21 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,10 @@ This also works inside the conditional `[...]` blocks: `[🌡️ Outside: {state
|
|
|
132
132
|
|
|
133
133
|
### **WORK IN PROGRESS**
|
|
134
134
|
|
|
135
|
+
### 0.4.35 (2026-10-03)
|
|
136
|
+
- Fix: reported live - `phaseText` could get stuck showing an earlier phase (e.g. "Aufheizen"/heating) while `phase` had correctly moved on (e.g. to "dryer_drying"). Root cause: `phase` was already written on every `_onTime()` tick (which fires frequently throughout a running cycle), but `phaseText` (the human-readable, localized, emoji-carrying label) was only ever written in `_onManagerState()` - which only runs on actual state transitions (off/starting/running/paused/ending), not on every phase change within a single long "running" period. Both data points now update together on every tick
|
|
137
|
+
- Covered by a new regression test (`tests/test_phase_text_tick_update.js`)
|
|
138
|
+
|
|
135
139
|
### 0.4.34 (2026-10-02)
|
|
136
140
|
- Fix: reported live with screenshots - `availablePrograms` could show `[]` for a device that clearly had saved programs visible in the admin tab's own "Programme" list, while a second device correctly showed all of its programs. Root cause: the data point (and `programOverride`'s dropdown states) was only ever written from five specific admin-tab actions (create/delete/rename a program, "clear all data") - never at startup, and never after a program got auto-learned from a confirmed cycle. A device whose programs were all auto-learned, with none of those five actions performed since the last restart, kept showing an empty list indefinitely even though `profileStore` had loaded the real programs from disk
|
|
137
141
|
- Fix: `needsFeedback` stayed `false` even with a cycle visibly pending confirmation in the admin tab's "Lernkontrolle" tab (complete with its own "1" badge). Root cause: the data point was declared in `io-package.json` but never actually written anywhere - the admin tab computes its own pending-cycle count entirely client-side (`updateFeedbackBadge()` in `tab_m.html`, counting cycles with `!confirmed`), so the data point itself never reflected it
|
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.35",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.4.35": {
|
|
7
|
+
"en": "Fix: phaseText could get stuck showing an earlier phase (e.g. \"Aufheizen\"/heating) while phase correctly moved on (e.g. to \"dryer_drying\") - phase was already updated on every tick, but phaseText (the human-readable, localized label) was only ever written at actual state transitions, not on every phase change within a single running cycle. Both now update together on every tick.",
|
|
8
|
+
"de": "Fix: phaseText konnte auf einer älteren Phase hängen bleiben (z. B. \"Aufheizen\"), während phase korrekt weiterlief (z. B. zu \"dryer_drying\") - phase wurde bereits bei jedem Tick aktualisiert, phaseText (das menschenlesbare, übersetzte Label) aber nur bei tatsächlichen Zustandsübergängen, nicht bei jedem Phasenwechsel innerhalb eines laufenden Zyklus. Beide werden jetzt gemeinsam bei jedem Tick aktualisiert.",
|
|
9
|
+
"ru": "Исправление: phaseText мог зависать на более ранней фазе (например, \"Aufheizen\"/нагрев), в то время как phase корректно переходил дальше (например, к \"dryer_drying\") - phase уже обновлялся при каждом тике, а phaseText (человекочитаемая, локализованная метка) записывался только при фактических переходах состояния, а не при каждой смене фазы внутри одного работающего цикла. Теперь оба обновляются вместе при каждом тике.",
|
|
10
|
+
"pt": "Correção: phaseText podia ficar preso mostrando uma fase anterior (ex. \"Aufheizen\"/aquecendo) enquanto phase avançava corretamente (ex. para \"dryer_drying\") - phase já era atualizado a cada tick, mas phaseText (o rótulo legível e localizado) só era escrito em transições de estado reais, não a cada mudança de fase dentro de um único ciclo em execução. Ambos agora são atualizados juntos a cada tick.",
|
|
11
|
+
"nl": "Fix: phaseText kon blijven hangen op een eerdere fase (bijv. \"Aufheizen\"/verwarmen) terwijl phase correct verderging (bijv. naar \"dryer_drying\") - phase werd al bij elke tick bijgewerkt, maar phaseText (het leesbare, gelokaliseerde label) werd alleen geschreven bij daadwerkelijke statusovergangen, niet bij elke fasewijziging binnen één lopende cyclus. Beide worden nu samen bij elke tick bijgewerkt.",
|
|
12
|
+
"fr": "Correction : phaseText pouvait rester bloqué sur une phase antérieure (ex. \"Aufheizen\"/chauffage) alors que phase progressait correctement (ex. vers \"dryer_drying\") - phase était déjà mis à jour à chaque tick, mais phaseText (l'étiquette lisible et localisée) n'était écrit qu'aux transitions d'état réelles, pas à chaque changement de phase au sein d'un même cycle en cours. Les deux sont désormais mis à jour ensemble à chaque tick.",
|
|
13
|
+
"it": "Correzione: phaseText poteva restare bloccato su una fase precedente (es. \"Aufheizen\"/riscaldamento) mentre phase avanzava correttamente (es. a \"dryer_drying\") - phase veniva già aggiornato a ogni tick, ma phaseText (l'etichetta leggibile e localizzata) veniva scritto solo alle transizioni di stato reali, non a ogni cambio di fase all'interno di un singolo ciclo in corso. Ora entrambi si aggiornano insieme a ogni tick.",
|
|
14
|
+
"es": "Corrección: phaseText podía quedarse atascado mostrando una fase anterior (p. ej. \"Aufheizen\"/calentando) mientras phase avanzaba correctamente (p. ej. a \"dryer_drying\") - phase ya se actualizaba en cada tick, pero phaseText (la etiqueta legible y localizada) solo se escribía en transiciones de estado reales, no en cada cambio de fase dentro de un mismo ciclo en ejecución. Ambos se actualizan ahora juntos en cada tick.",
|
|
15
|
+
"pl": "Poprawka: phaseText mógł utknąć na wcześniejszej fazie (np. \"Aufheizen\"/nagrzewanie), podczas gdy phase poprawnie szedł dalej (np. do \"dryer_drying\") - phase był już aktualizowany przy każdym tyknięciu, ale phaseText (czytelna, zlokalizowana etykieta) był zapisywany tylko przy faktycznych przejściach stanu, a nie przy każdej zmianie fazy w obrębie jednego trwającego cyklu. Oba są teraz aktualizowane razem przy każdym tyknięciu.",
|
|
16
|
+
"uk": "Виправлення: phaseText міг застрягати на попередній фазі (наприклад, \"Aufheizen\"/нагрівання), тоді як phase коректно просувався далі (наприклад, до \"dryer_drying\") - phase вже оновлювався при кожному тіку, а phaseText (зрозуміла, локалізована мітка) записувався лише при фактичних переходах стану, а не при кожній зміні фази в межах одного робочого циклу. Тепер обидва оновлюються разом при кожному тіку.",
|
|
17
|
+
"zh-cn": "修复:phaseText 可能会卡在较早的阶段(例如「Aufheizen」/加热),而 phase 却正确地推进(例如到「dryer_drying」)——phase 早已在每次心跳时更新,但 phaseText(人类可读的本地化标签)此前只在实际状态转换时才写入,而不是在单次运行周期内每次阶段变化时都写入。现在两者会在每次心跳时一起更新。"
|
|
18
|
+
},
|
|
6
19
|
"0.4.34": {
|
|
7
20
|
"en": "Fix: availablePrograms could show [] for a device that clearly had saved programs (visible in the admin tab's own Programme list) - it was only ever written from specific admin-tab actions (create/delete/rename a program, clear all data), never at startup or after a program got auto-learned from a confirmed cycle. Fix: needsFeedback stayed false even with a cycle visibly pending confirmation in the admin tab's Lernkontrolle tab - the data point was declared but never actually written anywhere; the admin tab computed its own pending-count entirely client-side. Both are now kept in sync at adapter startup, after every finished cycle, and (for needsFeedback) after a cycle is confirmed or corrected.",
|
|
8
21
|
"de": "Fix: availablePrograms konnte [] anzeigen, obwohl ein Gerät eindeutig gespeicherte Programme hatte (sichtbar in der Admin-Tab-eigenen Programme-Liste) - der Datenpunkt wurde nur von bestimmten Admin-Tab-Aktionen geschrieben (Programm anlegen/löschen/umbenennen, alle Daten löschen), nie beim Start oder nachdem ein Programm aus einem bestätigten Zyklus automatisch gelernt wurde. Fix: needsFeedback blieb auf false, obwohl im Lernkontrolle-Tab des Admin-Tabs sichtbar ein Zyklus auf Bestätigung wartete - der Datenpunkt war deklariert, wurde aber nirgends tatsächlich beschrieben; der Admin-Tab berechnete seine eigene Anzahl offener Zyklen komplett clientseitig. Beide werden jetzt beim Adapterstart, nach jedem beendeten Zyklus und (bei needsFeedback) nach einer Bestätigung/Korrektur eines Zyklus synchron gehalten.",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "Poprawki zaleznosci/higieny repozytorium zgloszone przez przeglad repozytorium ioBroker: zaktualizowano @iobroker/testing do aktualnego minimum (6.2.2). Adres e-mail autora typu noreply z GitHub (nieakceptowany przez checker przegladu) zastapiono prawdziwym adresem kontaktowym w package.json, io-package.json oraz w liniach praw autorskich README/LICENSE. Timery falszywego adaptera w jednym pliku testowym przebudowano tak, aby uzywaly tego samego wzorca aliasow natywnych setTimeout/setInterval, ktory jest juz uzywany wszedzie indziej w zestawie testow, dzieki czemu kontrola checkera dotyczaca golych wywolan timerow juz blednie tego nie zglasza (mock i tak jedynie przekazuje wywolanie do prawdziwego timera pod nazwa adapter.setTimeout - zachowanie sie nie zmienia).",
|
|
81
94
|
"uk": "Виправлення залежностей і гігієни репозиторію, виявлені під час перегляду репозиторію ioBroker: @iobroker/testing оновлено до поточного мінімуму (6.2.2). Адресу електронної пошти автора GitHub noreply (яку не приймає чекер перегляду) замінено на справжню контактну адресу в package.json, io-package.json та рядках авторських прав README/LICENSE. Таймери фіктивного адаптера в одному тестовому файлі переведено на той самий шаблон нативних псевдонімів setTimeout/setInterval, який уже використовується всюди в решті набору тестів, щоб перевірка чекера на використання простих таймерів більше не позначала це помилково (мок і так лише передає виклик до справжнього таймера під назвою adapter.setTimeout - поведінка не змінюється).",
|
|
82
95
|
"zh-cn": "根据 ioBroker 仓库审查报告修复的依赖/仓库卫生问题:将 @iobroker/testing 升级到当前要求的最低版本(6.2.2)。将审查检查器不接受的 GitHub noreply 作者邮箱,替换为 package.json、io-package.json 以及 README/LICENSE 版权行中的真实联系邮箱。将某测试文件中伪造适配器的计时器改为使用测试套件其余部分早已统一采用的原生 setTimeout/setInterval 别名写法,使检查器对「直接使用原生计时器」的检测不再误报该文件(该模拟函数本来就只是以 adapter.setTimeout 之名转发给真实计时器——行为未发生变化)。"
|
|
83
|
-
},
|
|
84
|
-
"0.4.27": {
|
|
85
|
-
"en": "Fix: the notification-target dropdown showed a hardcoded German placeholder (\"Alle (broadcast)\") for every notification adapter except Telegram/email, regardless of the configured system language - now uses the existing translation everywhere. Fix: a Telegram user's display name (which any user messaging the configured bot can set arbitrarily) was written into the admin tab's dropdown options without HTML-escaping - now escaped before being inserted into the page.",
|
|
86
|
-
"de": "Fix: Das Dropdown für das Benachrichtigungsziel zeigte bei jedem Benachrichtigungs-Adapter außer Telegram/E-Mail einen fest codierten deutschen Platzhalter (\"Alle (broadcast)\") an, unabhängig von der eingestellten Systemsprache - nutzt jetzt überall die vorhandene Übersetzung. Fix: Der Anzeigename eines Telegram-Nutzers (den jeder Nutzer, der dem konfigurierten Bot schreibt, beliebig setzen kann) wurde ohne HTML-Escaping in die Dropdown-Optionen des Admin-Tabs geschrieben - wird jetzt vor dem Einfügen escaped.",
|
|
87
|
-
"ru": "Исправление: выпадающий список цели уведомления показывал жёстко заданный немецкий текст-заполнитель (\"Alle (broadcast)\") для любого адаптера уведомлений, кроме Telegram/email, независимо от настроенного системного языка - теперь везде используется существующий перевод. Исправление: отображаемое имя пользователя Telegram (которое может произвольно задать любой пользователь, написавший настроенному боту) записывалось в опции выпадающего списка вкладки администратора без экранирования HTML - теперь экранируется перед вставкой.",
|
|
88
|
-
"pt": "Correção: o menu suspenso do destino da notificação mostrava um texto de espaço reservado alemão fixo (\"Alle (broadcast)\") para qualquer adaptador de notificação exceto Telegram/email, independentemente do idioma do sistema configurado - agora usa a tradução existente em todos os casos. Correção: o nome de exibição de um usuário do Telegram (que qualquer usuário que enviar mensagem ao bot configurado pode definir livremente) era escrito nas opções do menu suspenso da aba de administração sem escapar HTML - agora é escapado antes de ser inserido.",
|
|
89
|
-
"nl": "Fix: de vervolgkeuzelijst voor het notificatiedoel toonde een hardgecodeerde Duitse plaatshoudertekst (\"Alle (broadcast)\") voor elke notificatie-adapter behalve Telegram/e-mail, ongeacht de ingestelde systeemtaal - gebruikt nu overal de bestaande vertaling. Fix: de weergavenaam van een Telegram-gebruiker (die elke gebruiker die de geconfigureerde bot een bericht stuurt willekeurig kan instellen) werd zonder HTML-escaping in de dropdown-opties van het admin-tabblad geschreven - wordt nu geëscaped voordat het wordt ingevoegd.",
|
|
90
|
-
"fr": "Correction : le menu déroulant de la cible de notification affichait un texte de remplacement allemand codé en dur (\"Alle (broadcast)\") pour tout adaptateur de notification autre que Telegram/e-mail, quelle que soit la langue système configurée - utilise désormais la traduction existante partout. Correction : le nom d'affichage d'un utilisateur Telegram (que tout utilisateur écrivant au bot configuré peut définir arbitrairement) était écrit dans les options du menu déroulant de l'onglet admin sans échappement HTML - il est désormais échappé avant insertion.",
|
|
91
|
-
"it": "Correzione: il menu a tendina della destinazione di notifica mostrava un testo segnaposto tedesco fisso (\"Alle (broadcast)\") per qualsiasi adattatore di notifica tranne Telegram/email, indipendentemente dalla lingua di sistema configurata - ora usa ovunque la traduzione esistente. Correzione: il nome visualizzato di un utente Telegram (che qualsiasi utente che scrive al bot configurato può impostare arbitrariamente) veniva scritto nelle opzioni del menu a tendina della scheda admin senza escaping HTML - ora viene sottoposto a escaping prima dell'inserimento.",
|
|
92
|
-
"es": "Corrección: el menú desplegable del destino de notificación mostraba un texto de marcador de posición en alemán fijo (\"Alle (broadcast)\") para cualquier adaptador de notificación excepto Telegram/correo electrónico, sin importar el idioma del sistema configurado - ahora usa la traducción existente en todos los casos. Corrección: el nombre de visualización de un usuario de Telegram (que cualquier usuario que escriba al bot configurado puede establecer libremente) se escribía en las opciones del menú desplegable de la pestaña de administración sin escapar HTML - ahora se escapa antes de insertarse.",
|
|
93
|
-
"pl": "Poprawka: rozwijana lista celu powiadomienia pokazywała na sztywno zakodowany niemiecki tekst zastępczy (\"Alle (broadcast)\") dla każdego adaptera powiadomień poza Telegram/e-mail, niezależnie od skonfigurowanego języka systemu - teraz wszędzie używa istniejącego tłumaczenia. Poprawka: wyświetlana nazwa użytkownika Telegram (którą może dowolnie ustawić każdy użytkownik piszący do skonfigurowanego bota) była zapisywana w opcjach rozwijanej listy zakładki administratora bez ucieczki HTML - teraz jest escapowana przed wstawieniem.",
|
|
94
|
-
"uk": "Виправлення: спадний список цілі сповіщення показував жорстко закодований німецький текст-заповнювач (\"Alle (broadcast)\") для будь-якого адаптера сповіщень, крім Telegram/email, незалежно від налаштованої системної мови - тепер скрізь використовується наявний переклад. Виправлення: відображуване ім'я користувача Telegram (яке може довільно встановити будь-який користувач, що пише налаштованому боту) записувалося в опції спадного списку вкладки адміністратора без екранування HTML - тепер екранується перед вставкою.",
|
|
95
|
-
"zh-cn": "修复:通知目标下拉菜单在除 Telegram/邮件之外的所有通知适配器中都显示硬编码的德语占位文本(\"Alle (broadcast)\"),与所配置的系统语言无关——现在统一使用现有的翻译。修复:Telegram 用户的显示名称(任何给已配置的机器人发消息的用户都可以任意设置)此前未经 HTML 转义就被写入管理标签页的下拉选项——现在会在插入前进行转义处理。"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/main.js
CHANGED
|
@@ -1540,10 +1540,29 @@ class WashdataAdapter extends utils.Adapter {
|
|
|
1540
1540
|
if (mgrPh) {
|
|
1541
1541
|
const st = mgrPh.getStatus();
|
|
1542
1542
|
if (st && st.phase) {
|
|
1543
|
-
const
|
|
1543
|
+
const phaseKey = st.phase
|
|
1544
1544
|
.replace(/^[\u{1F300}-\u{1FFFF}\u{2600}-\u{27BF}]\s*/u, "")
|
|
1545
1545
|
.trim();
|
|
1546
|
-
this.setState(`${deviceId}.phase`,
|
|
1546
|
+
this.setState(`${deviceId}.phase`, phaseKey, true);
|
|
1547
|
+
// phaseText was only ever written in _onManagerState() - which
|
|
1548
|
+
// only fires on actual state transitions (off/starting/running/
|
|
1549
|
+
// paused/ending), not on every phase change within a single
|
|
1550
|
+
// long "running" period. phase (above) was already correctly
|
|
1551
|
+
// updated on every tick, which is exactly why it could show a
|
|
1552
|
+
// newer phase (e.g. "dryer_drying") while phaseText stayed
|
|
1553
|
+
// frozen on an older one from earlier in the same cycle (e.g.
|
|
1554
|
+
// "Aufheizen"/heating) - found live.
|
|
1555
|
+
const devCfgTime = this._getDeviceConfig().find(
|
|
1556
|
+
(d) => d.deviceId === deviceId,
|
|
1557
|
+
);
|
|
1558
|
+
const langTime =
|
|
1559
|
+
(this._deviceLangCache && this._deviceLangCache[deviceId]) || "en";
|
|
1560
|
+
const noEmojiTime = devCfgTime ? !!devCfgTime.noEmoji : false;
|
|
1561
|
+
this.setState(
|
|
1562
|
+
`${deviceId}.phaseText`,
|
|
1563
|
+
getPhaseText(phaseKey, langTime, noEmojiTime),
|
|
1564
|
+
true,
|
|
1565
|
+
);
|
|
1547
1566
|
}
|
|
1548
1567
|
}
|
|
1549
1568
|
// Only check update messages every 60s AND only when a program is really recognized
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.laundrylens",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.35",
|
|
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",
|