iobroker.alias-workbench 0.9.7 → 0.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +40 -78
  2. package/io-package.json +16 -81
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -189,11 +189,6 @@ Open the ioBroker admin, go to **Adapters**, look for **Alias Workbench** and
189
189
  create an instance. Then reload the admin and pick **Alias Workbench** in the
190
190
  left menu.
191
191
 
192
- The adapter has not been accepted into the ioBroker repository yet, so it does
193
- not show up in that list for the moment. Until it does, install it from npm:
194
- under **Adapters** press **install from custom URL** (the octocat button), tab
195
- **From npm**, and enter `iobroker.alias-workbench`.
196
-
197
192
  ## Why the tree shows devices that do not exist
198
193
 
199
194
  With MQTT, ioBroker only creates objects for the datapoints themselves. A topic
@@ -567,82 +562,49 @@ imported, and that both language files carry the same keys.
567
562
 
568
563
  ## Changelog
569
564
 
565
+ ### 0.9.8
566
+ * The changelog only lists versions that actually exist on npm. The entries 0.9.1 to 0.9.6 were local intermediate steps and were never published; their content is now summarised under 0.9.7. Found by the repochecker (E2004, E1032)
567
+ * The README no longer explains installation via “install from custom URL” — in the official repository that goes through the adapter list (E6013)
568
+ * `dependabot.yml` gets a seven-day cooldown for npm packages: what appears today is proposed a week later. If a compromised release is pulled within that time, it never arrives here (E8915). And `@types/node` stays on its major version — the types must match the Node release the adapter runs on (E8917)
569
+
570
570
  ### 0.9.7
571
- This version was measured on the **production system** — 24,786 objects, 140 aliases. None of it shows on the test system with 2,731 objects.
572
-
573
- * The search box no longer blocks. The tree was rebuilt completely on **every** keystroke: a measured **236 ms per keystroke, 1.9 seconds for eight**. It now draws once, 180 ms after the last keystroke — typing stays responsive. Plus three savings in the tree itself: collapsed nodes are no longer built as DOM at all (previously every subtree was created and immediately thrown away), the question “can this be expanded?” is answered once per row instead of on every sort comparison, and an `Intl.Collator` replaces `localeCompare` with an options object. **The whole tree: 263 → 67 ms.**
574
- * A redraw no longer costs half a second. `kindZustaende`, `aliasFuer` and their neighbours walked the sorted index **linearly** — 24,786 comparisons for ten hits, some twenty times per redraw, and with live values that is every 700 ms. The list is sorted and the range sits together: a binary search finds it in fifteen steps. Plus a reverse map source → alias built once per index state. **Drawing a source 15.8 → 1.6 ms, an alias with 50 points 51.9 → 14.2 ms.** Proven equal: 3,025 devices and all 727 alias points checked against the old versions, zero differences
575
- * A read formula can no longer freeze the tab for good. Formulas from `common.alias.read` and from templates run as JavaScript in the admin — on every redraw, per row, unasked. That is no new privilege escalation (whoever may write the formula already has it running in the js-controller), but it is an execution site without limits: `try/catch` does not catch an endless loop. Results are now remembered per formula and raw value — 2000 evaluations in 0.6 ms — and whatever once took longer than 250 ms does not run again; the row says why
576
- * The object counter in the header no longer gets stuck. Four places set the index directly instead of calling `indexNeu()`, so the short-name map kept deleted ids and `hatPunkt` returned hits on points that no longer existed
577
- * A full detector run per redraw is gone. Its result travelled through two intermediate steps into a parameter nobody reads. Also removed: `e.andere` and the dead symbols `bestandsWert` and `anzeigeText`
578
- * The write-source rule lives in one place instead of five. It was spelled out identically three times in `entwurf.js` and twice in `zuordnung.js` — and the comments at two of those sites each document a bug that came from exactly that
579
- * **Correction to 0.9.6:** adapter and instance roots were meant to become unselectable there — but the check used `_tiefe`, which is the height of the subtree **below** a node, not its position in the tree. On the test system that excluded 131 nodes, exactly one of them rightly: the other 130 were branches such as `…Decklenlicht_RGB.cmnd` and folders such as `iot.0.smart`, whose data points sit directly below. Selectable nodes dropped from 449 to 320. The position is checked now; `mqtt-client` and `mqtt-client.0` stay locked, everything else is back
580
-
581
- ### 0.9.6
582
- **Display and flow**
583
- * “All data points” keeps the output and the manual choice. On a multi-output template at output 2 the rows of output 1 came back while the target still read `…Ausgang_2`; and if automatic matching had found nothing and you picked the template by hand, the click dropped you into raw mode with the choice gone
584
- * “Differs from the alias” now also shows in alias mode. The marker was handed the target, which is never set there — you are already standing on the alias. So it never appeared exactly where it says the most
585
- * Switching sources quickly no longer fetches the wrong value. The callback stored the value under whatever source was selected when it arrived — and since only missing values are fetched, it stayed that way
586
- * The source jump list never appears twice. It hangs off the page body so it survives an automatic redraw; the button is a different one afterwards, and the second click laid a second list over the first
587
- * A room is suggested even when it is the last segment. With a flat adapter such as `sonoff.0.Wohnzimmer` the search over the source path never ran at all
588
- * Object names follow the admin language. There were two readers for the same question, one fixed on German before English — so on an English admin, objects, rooms and functions showed up in German. And the name match now looks at every language: “Light” in the system failed to find the function “Licht” and created a duplicate beside it
571
+ *Versions 0.9.1 to 0.9.6 were local intermediate steps and were never
572
+ published — their changes are part of 0.9.7.*
573
+
574
+ Seven packages from a code review — 45 fixes between 0.9.0 and this release. The intermediate steps 0.9.1 to 0.9.6 stayed local and were never published; they are summarised here.
575
+
576
+ **Data loss and failure paths**
577
+ * An enumeration error now stops a move. Previously the old alias was deleted anyway — and afterwards it was gone while the new one sat in no enumeration at all
578
+ * A partial failure while deleting no longer turns the retry button into a prop: only what really went is dropped
579
+ * Orphaned points are deleted on the second attempt too
580
+ * A load error on the enumerations leaves the previous state standing instead of emptying it — and while they are unknown, nothing is written. Before, one hiccup could drop an alias out of every room and function
581
+ * A load error on your own templates is reported instead of swallowed; otherwise the next save would have replaced an existing template with version 1
582
+
583
+ **Connection and display**
584
+ * The tab works again after a dropped connection. The admin's WebSocket fires `connect` once per page lifetime and `reconnect` afterwards — nobody listened, and neither object nor state changes arrived
585
+ * Template mode no longer rebuilds itself every second, and where the selection goes, its subscriptions go too
586
+ * “Differs from the alias” now also shows in alias mode — where it says the most
587
+ * Switching sources quickly no longer fetches the wrong value; the source jump list never appears twice
588
+ * Object names follow the admin language; the function match looks at every language and no longer creates a duplicate
589
+
590
+ **Templates**
591
+ * A broken name hint no longer takes down the whole source view — including the nested form `(a+)+` where the expression engine stalls
592
+ * The formula of a fallback source survives updating, an unknown device type no longer throws
593
+ * Importing checks more than id and states; a hand-typed id no longer replaces someone else's template
594
+ * The `%N%` placeholder only hits the output number now, not every trailing digit
595
+ * The blind gets its STOP: a button press has no state to read, and that case was unknown to template application — **not a single** blind alias ever had one
596
+ * ON_TIME finds its slot (four templates carried the wrong role)
589
597
 
590
598
  **MQTT and Tasmota**
591
- * An empty `custom` entry no longer takes anything down. `common.custom` can hold an entry whose value is `null` — ioBroker does not clean it up when an instance disappears. Reaching into it took the whole result view with it
592
- * `enabled: false` counts as switched off. The field did not appear in the reader at all: `{ enabled: false, publish: true }` counted as publishable although the instance does not serve that point
593
- * No more false “cannot publish” for ioBroker.mqtt and sonoff. Their objects carry the topic in `native` only; that was reported as a firm “no” instead of “unknown”, the chip was red, and “allow publishing” wrote the object back unchanged — a message that could not be cleared
594
- * “Answer received” only for a real answer. A `stat.RESULT` left retained from the day before yesterday was enough for the green feedback, even with the device switched off
595
- * `Vcc` and `Command` are not commands. `{"Command":"Unknown"}` — the reply to an unknown command — stood there as a missing command point, with a create button
596
- * Command names from foreign JSON no longer reach ids and topics unchecked. A key containing `#` would make a wildcard subscription, one containing `.` an extra level
597
-
598
- **Templates and devices**
599
- * The blind gets its STOP. A button press has no state to read, and that case was unknown to template application: without a read path the point dropped out — not a single blind alias ever had a STOP
600
- * ON_TIME finds its slot. Four templates carried the role `level.timer` while the slot requires `level.timer.off`, so the point ended up in the info device instead of the switching device
601
- * An explicit formula beats the field. Where a template gives both, the formula was discarded and a new one built from the field
602
-
603
- **Subscriptions and tree**
604
- * What is subscribed is what is read — not half the adapter. The patterns came from the display grouping: on a flat MQTT device that produced `mqtt-client.0.*` with over three hundred objects on a single alias. It is now the channels of the actual sources, branches of the same device folded into one pattern, and where even that is too wide, the sources one by one
605
- * Adapter and instance roots can no longer be selected. `mqtt-client.0` is not a device; selecting it would have subscribed the whole namespace
606
- * Dark admin themes are recognised. The detection knew four names; `blue` and `colored` fell through and landed on the system setting
607
- * A late answer to `system.config` still counts. After 2.5 seconds it carries on without one — the answer arriving later was discarded entirely, and without it every expert object was missing from the tree
608
-
609
- **Housekeeping**
610
- * The checks touch nothing again. One of them wrote an object from inside the drawing path
611
- * The delete dialog warns about channels of their own below the target. The hint spoke only of “data points below”
612
- * Four dead language keys removed — and the test now checks both directions, not just code → JSON
613
-
614
- ### 0.9.5
615
- * A broken name hint no longer takes down the whole source view. The text was evaluated as a regular expression unchecked, although neither the template sheet nor the save dialog validates it: after saving `Lampe (Bad`, template matching threw on **every** device selection, no caller caught it, and the right-hand side stayed empty — repairable only through the instance configuration by hand. An unusable expression now counts as “no match” and is flagged in red at the field. The same goes for the nested form `(a+)+`, where the expression engine stalls: a measured 3196 ms for one device name, now none
616
- * The formula of a fallback source survives updating a template. It was stored under `formel` while every reader looks for `leseformel` — so updating from a device silently dropped it. With `tasmota-steckdose` the consequence was that on devices without `stat.POWER` the boolean alias ended up on the raw JSON text of `tele.STATE` instead of on `POWER`
617
- * A device type this detector does not know no longer throws. The offered pattern list was filtered, the **selected** type was not — it comes from the template unchecked. An imported template naming a pattern from a newer type-detector made the pattern picker throw, and the draft was never drawn at all
618
- * Importing now checks more than id and states. `erkennung.erforderlich` as a string instead of a list made template matching throw on **every** device afterwards; a missing `name` threw as soon as the sheet opened. And “import and save” was on screen long before that — you could save a template that then made the tab unusable. `erkennung`, `erforderlich`/`verboten`, `inhalt`, `name`, the name hint and the device type are checked now; a single string that unambiguously means a list is turned into one rather than rejected
619
- * A hand-typed id no longer replaces someone else's template. Ids were only checked for collisions when switching modes, not after typing — and saving replaces without asking on a matching id, in “new” mode even with version 1. An own template at v7 silently became a different one at v1. The reason is now shown in red at the field and saving is blocked
620
- * The `%N%` placeholder only hits the output number now. Replacement went purely by trailing digit: on a multi-output device at output 2 the IP row from `tele.INFO2` became `tele.INFO%N%` — and at output 1 that same row reported a foreign output, with “drop the others” throwing it out. Only what actually carries the output becomes a placeholder now: what the template already held as `%N%`, the prefix from `kanalname`, and what appears more than once with the same number
621
-
622
- ### 0.9.4
623
- * The tab works again after a dropped connection. It does not load socket.io but the admin's WebSocket shim — and there `connect` fires exactly once per page lifetime, only `reconnect` afterwards. Nobody listened for that, and the shim renews no subscription on its own. After every outage — admin restart, network hiccup, standby — neither object nor state changes arrived, and the dot in the header stayed on “disconnected” although the connection had long been back. `reconnect` is now handled: the display goes back to “connected”, every subscription is renewed and the objects are re-read — anything could have changed while disconnected, and nobody was watching
624
- * The template mode no longer rebuilds itself every second. Selecting a device with live values and switching to the templates tab rebuilt the whole sheet every 700 ms, including a trial run across all candidates and all templates — the selection deliberately survives the mode switch, but there is no state list on the right any more
625
- * Where the selection goes, its subscriptions now go too. Unsubscribing only happened when selecting the next node; the four other paths — switching mode, collapsing a branch, leaving expert mode, deleting an alias — unsubscribed from nothing. A subscription then ran on a device no longer shown, and the header counter still claimed “one subscription”
626
- * Switching nodes while loading no longer leaves the caller hanging. The callback never arrived in that case: “running” stayed on the button forever, and the dry run meant to open after creating missing command points never opened. Twelve seconds of waiting on a SetOption59 query is ample opportunity for that
627
-
628
- ### 0.9.3
629
- * An error on the enumerations now stops the move. The first step — creating the new one — always aborted on error, “two rather than none”; the second did not: enumeration errors were collected and the old one was deleted anyway. Afterwards the old alias was gone and the new one sat in no enumeration at all, because the js-controller removes members itself on delete. The assignment was therefore lost outright, not merely orphaned. The same abort now applies one level down, and the button offers “Try again”
630
- * A partial failure while deleting no longer turns the retry button into a prop. If one delete failed, **all** ids were dropped from the internal store anyway, empty folders and enumerations were cleaned up and the delete target was set to null — which is exactly what `loescheAlias` starts with, so it bailed out immediately. Whatever stayed in the database was out of reach: the workbench considered it deleted. Only what really went is dropped now, the cleanup is skipped, the target stays — and the second click actually finishes the job
631
- * Orphaned points are deleted on the second attempt too. Their list was cleared after writing **always**, even after a failure; the retry button then wrote the objects but removed nothing, and the message no longer counted them either
632
- * A load error on your own templates is reported instead of swallowed. If the instance configuration answered with an error, that counted as “no own templates” — the warning chip in the header stayed away, although the timeout path one line above sets it correctly. The consequence was the dangerous part: the workbench considered taken ids free, and the next save would have replaced an existing template with version 1. The chip's tooltip now says so
633
-
634
- ### 0.9.2
635
- * Swapping the source no longer writes to the read source: if no new write target is found for a point with separate sources, a plain string was left in `alias.id` — and to the js-controller that means “read and write on the same id”. With Tasmota the command then went to the status topic instead of the command topic: the device does not switch and the feedback is falsified. Worse, the workbench guessed the write source by name and landed on `stat.POWER`, because that too contains “POWER”. A guessed write target now only counts if it is a different point from the read source, the object form is kept, and the row marks the missing match in red
636
- * Moving recognises two more targets as a collision: one that exists only as a tree node carrying data points — existing points of the same name were overwritten there — and one that sits below the alias itself: `alias.0.X` to `alias.0.X.Sub` took its own parent node along on the final delete
637
- * A rejected creation of a send point no longer counts as success. The silent path did not even accept the error and entered the object into its own store anyway; after that the guard no longer bit, and “Create now” wrote `alias.id.write` onto an id that never existed in the database — exactly the error the js-controller remembers for good
638
- * Channel names are cleaned into ids when “Create all” builds one channel per output. “Licht Bar, oben” produced an id with a space and a comma, “Küche.Decke” an extra level including an intermediate folder. And the js-controller does not reject that, it cleans silently — so the object would have appeared under a different id than the one shown. The display name is left untouched
639
- * A channel keeps its template link across an update, even when the template was deleted or renamed. `native` used to be replaced wholesale; template, version and device type only came back when a template happened to match. The role one line below had long been rescued, `native` had not
640
- * Hardened: the cleanup of separated sources no longer switches off a point that is itself part of the alias. Whether it happened depended on the order of `Object.keys` — it was not reachable through the interface, because none of the bundled templates puts a reporting row before the controlling one, but the consequence would have been a deleted data point
641
-
642
- ### 0.9.1
643
- * A load error on the enumerations can no longer overwrite one: until now a failed `getObjectView` set the store to empty and kept quiet about it. After that the workbench considered every enumeration absent, the catalogue kept offering them because the duplicate filter had nothing to check against, and on writing `setObject` replaced the existing object with a fresh one holding a single member — measured, a room lost three of its four members that way and was given the origin mark that makes it deletable later on. The previous state is now kept, no enumeration is touched, and both the field and the dry run say why room and function are not being written. The alias itself is still created, and a hiccup heals itself after three attempts
644
- * An enumeration deleted from outside is no longer resurrected: the subscription compared against `objects`, where enumerations never live — on deletion old and new value were therefore both empty and the branch that removes it from the store was never reached. The next alias using that room recreated it with all its old members, including the foreign ones
645
- * “Create all” now gives every channel its room and its function. The partial drafts carried neither, so not a single channel got an entry — the single route set it, the bulk route did not. A second object for the same enumeration was also discarded, so even then only the first channel would have made it in. And for a channel other than the one shown the assignment counted as empty: if its alias already sat in a room, the bulk route took it **out**. Every channel now keeps what it has, all others get what is set, and members are merged instead of discarded
599
+ * An empty `custom` entry no longer takes anything down, `enabled: false` counts as switched off
600
+ * No more false “cannot publish” for ioBroker.mqtt and sonoff — there, publishing capability is simply unknown, not denied
601
+ * “Answer received” only for a real answer; `Vcc` and `Command` are not commands
602
+
603
+ **Speed, measured on a production system with 24,786 objects**
604
+ * The search box no longer blocks: **236 ms per keystroke → 0**, the whole tree **263 → 67 ms**
605
+ * A redraw no longer costs half a second — binary search instead of linear scans: drawing a source **15.8 → 1.6 ms**, an alias with 50 points **51.9 → 14.2 ms**
606
+ * A read formula can no longer freeze the tab for good
607
+ * What is subscribed is what is read — before, a single alias could subscribe to half an adapter
646
608
 
647
609
  ### 0.9.0
648
610
  * The role list is complete again: the detector hands out the expressions of its slots as text WITH slashes (`/^indicator…$/`), not as a regular expression. Take the slashes for part of the expression and you find neither start nor end afterwards — 210 roles instead of 232, and `indicator.lowbat` of all things was missing, the role every Homematic device writes. In the role picker, no slot of the pattern was offered at all any more, only the line "show all roles"
package/io-package.json CHANGED
@@ -1,11 +1,24 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "alias-workbench",
4
- "version": "0.9.7",
4
+ "version": "0.9.8",
5
5
  "news": {
6
+ "0.9.8": {
7
+ "en": "* The changelog only lists versions that actually exist on npm. The entries 0.9.1 to 0.9.6 were local intermediate steps and were never published; their content is now summarised under 0.9.7. Found by the repochecker (E2004, E1032)\n* The README no longer explains installation via “install from custom URL” — in the official repository that goes through the adapter list (E6013)\n* `dependabot.yml` gets a seven-day cooldown for npm packages: what appears today is proposed a week later. If a compromised release is pulled within that time, it never arrives here (E8915). And `@types/node` stays on its major version — the types must match the Node release the adapter runs on (E8917)",
8
+ "de": "* Der Changelog nennt nur noch Fassungen, die es auf npm wirklich gibt. Die Einträge 0.9.1 bis 0.9.6 waren lokale Zwischenstände und wurden nie veröffentlicht; ihr Inhalt steht jetzt zusammengefasst bei 0.9.7. Gefunden vom Repochecker (E2004, E1032)\n* Die README erklärt die Installation nicht mehr über „aus eigener URL“ — im offiziellen Repository geht das über die Adapterliste (E6013)\n* `dependabot.yml` bekommt eine Abkühlzeit von sieben Tagen für npm-Pakete: Was heute erscheint, wird erst in einer Woche vorgeschlagen. Wird eine kompromittierte Fassung in dieser Zeit zurückgezogen, kommt sie hier nie an (E8915). Und `@types/node` bleibt bei seiner Hauptversion — die Typen müssen zu der Node-Fassung passen, unter der der Adapter läuft (E8917)",
9
+ "ru": "Приведение в порядок перед подачей в репозиторий ioBroker: в списке изменений остались только версии, действительно существующие на npm (0.9.1–0.9.6 были локальными промежуточными шагами, их содержимое собрано в 0.9.7), README больше не описывает установку по своей ссылке, а dependabot получил семидневную выдержку для npm-пакетов и запрет на смену мажорной версии @types/node.",
10
+ "pt": "Arrumação antes da submissão ao repositório ioBroker: o changelog só lista versões que existem mesmo no npm (0.9.1–0.9.6 eram passos intermédios locais, o seu conteúdo está reunido em 0.9.7), o README já não explica a instalação por URL própria, e o dependabot recebeu sete dias de arrefecimento para pacotes npm e a proibição de saltar a versão maior de @types/node.",
11
+ "nl": "Opruiming voor de aanmelding bij het ioBroker-repository: de changelog noemt alleen nog versies die echt op npm staan (0.9.1–0.9.6 waren lokale tussenstappen, hun inhoud staat samengevat bij 0.9.7), de README legt installatie via een eigen URL niet meer uit, en dependabot kreeg zeven dagen afkoeltijd voor npm-pakketten plus een verbod op majorsprongen van @types/node.",
12
+ "fr": "Rangement avant la soumission au dépôt ioBroker : le changelog ne cite plus que des versions qui existent vraiment sur npm (0.9.1–0.9.6 étaient des étapes locales, leur contenu est résumé sous 0.9.7), le README n'explique plus l'installation par URL personnalisée, et dependabot reçoit sept jours de refroidissement pour les paquets npm ainsi que l'interdiction de changer la version majeure de @types/node.",
13
+ "it": "Riordino prima della candidatura al repository ioBroker: il changelog elenca solo versioni che esistono davvero su npm (0.9.1-0.9.6 erano passi intermedi locali, il loro contenuto e riassunto sotto 0.9.7), il README non spiega piu l'installazione da URL propria, e dependabot riceve sette giorni di raffreddamento per i pacchetti npm e il divieto di saltare la versione maggiore di @types/node.",
14
+ "es": "Ordenacion antes de la solicitud al repositorio de ioBroker: el changelog solo menciona versiones que existen realmente en npm (0.9.1-0.9.6 eran pasos intermedios locales, su contenido esta resumido en 0.9.7), el README ya no explica la instalacion por URL propia, y dependabot recibe siete dias de enfriamiento para paquetes npm y la prohibicion de saltar la version mayor de @types/node.",
15
+ "pl": "Porzadki przed zgloszeniem do repozytorium ioBroker: changelog wymienia juz tylko wersje, ktore naprawde istnieja w npm (0.9.1-0.9.6 byly lokalnymi krokami posrednimi, ich tresc zebrano w 0.9.7), README nie opisuje juz instalacji z wlasnego adresu, a dependabot dostal siedmiodniowy okres wystudzenia dla pakietow npm oraz zakaz zmiany wersji glownej @types/node.",
16
+ "uk": "Впорядкування перед поданням до репозиторію ioBroker: у переліку змін лишилися тільки версії, які справді є на npm (0.9.1–0.9.6 були локальними проміжними кроками, їхній зміст зібрано в 0.9.7), README більше не описує встановлення за власним посиланням, а dependabot отримав семиденну витримку для npm-пакетів і заборону змінювати мажорну версію @types/node.",
17
+ "zh-cn": "提交到 ioBroker 仓库前的整理:更新日志只保留 npm 上真实存在的版本(0.9.1 至 0.9.6 只是本地中间状态,内容已归入 0.9.7),README 不再介绍通过自定义地址安装,dependabot 为 npm 包设置了七天冷却期,并禁止 @types/node 的主版本跳跃。"
18
+ },
6
19
  "0.9.7": {
7
- "en": "This version was measured on the **production system** — 24,786 objects, 140 aliases. None of it shows on the test system with 2,731 objects.\n\n* The search box no longer blocks. The tree was rebuilt completely on **every** keystroke: a measured **236 ms per keystroke, 1.9 seconds for eight**. It now draws once, 180 ms after the last keystroke — typing stays responsive. Plus three savings in the tree itself: collapsed nodes are no longer built as DOM at all (previously every subtree was created and immediately thrown away), the question “can this be expanded?” is answered once per row instead of on every sort comparison, and an `Intl.Collator` replaces `localeCompare` with an options object. **The whole tree: 263 → 67 ms.**\n* A redraw no longer costs half a second. `kindZustaende`, `aliasFuer` and their neighbours walked the sorted index **linearly** — 24,786 comparisons for ten hits, some twenty times per redraw, and with live values that is every 700 ms. The list is sorted and the range sits together: a binary search finds it in fifteen steps. Plus a reverse map source → alias built once per index state. **Drawing a source 15.8 → 1.6 ms, an alias with 50 points 51.9 → 14.2 ms.** Proven equal: 3,025 devices and all 727 alias points checked against the old versions, zero differences\n* A read formula can no longer freeze the tab for good. Formulas from `common.alias.read` and from templates run as JavaScript in the admin — on every redraw, per row, unasked. That is no new privilege escalation (whoever may write the formula already has it running in the js-controller), but it is an execution site without limits: `try/catch` does not catch an endless loop. Results are now remembered per formula and raw value — 2000 evaluations in 0.6 ms — and whatever once took longer than 250 ms does not run again; the row says why\n* The object counter in the header no longer gets stuck. Four places set the index directly instead of calling `indexNeu()`, so the short-name map kept deleted ids and `hatPunkt` returned hits on points that no longer existed\n* A full detector run per redraw is gone. Its result travelled through two intermediate steps into a parameter nobody reads. Also removed: `e.andere` and the dead symbols `bestandsWert` and `anzeigeText`\n* The write-source rule lives in one place instead of five. It was spelled out identically three times in `entwurf.js` and twice in `zuordnung.js` — and the comments at two of those sites each document a bug that came from exactly that\n* **Correction to 0.9.6:** adapter and instance roots were meant to become unselectable there — but the check used `_tiefe`, which is the height of the subtree **below** a node, not its position in the tree. On the test system that excluded 131 nodes, exactly one of them rightly: the other 130 were branches such as `…Decklenlicht_RGB.cmnd` and folders such as `iot.0.smart`, whose data points sit directly below. Selectable nodes dropped from 449 to 320. The position is checked now; `mqtt-client` and `mqtt-client.0` stay locked, everything else is back",
8
- "de": "Diese Version ist am **Produktivsystem** gemessen — 24.786 Objekte, 140 Aliase. Am Testsystem mit 2.731 Objekten fällt nichts davon auf.\n\n* Das Suchfeld blockiert nicht mehr. Der Baum wurde bei **jedem** Tastendruck komplett neu gebaut: gemessene **236 ms je Anschlag, acht Anschläge 1,9 Sekunden**. Jetzt wird 180 ms nach dem letzten Anschlag einmal gezeichnet — die Eingabe bleibt frei. Dazu drei Sparmaßnahmen im Baum selbst: zugeklappte Knoten werden gar nicht erst als DOM erzeugt (vorher entstand jeder Teilbaum und wurde gleich weggeworfen), die Frage „lässt sich das aufklappen?“ wird einmal je Zeile statt bei jedem Sortiervergleich beantwortet, und ein `Intl.Collator` ersetzt das `localeCompare` mit Optionsobjekt. **Der ganze Baum: 263 → 67 ms.**\n* Ein Neuzeichnen kostet keine halbe Sekunde mehr. `kindZustaende`, `aliasFuer` und ihre Nachbarn gingen den sortierten Gesamtindex **linear** durch — 24.786 Vergleiche für zehn Treffer, rund zwanzigmal je Neuzeichnen, bei laufenden Werten alle 700 ms. Die Liste ist sortiert, der gesuchte Bereich liegt am Stück: eine Binärsuche findet ihn in fünfzehn Schritten. Dazu eine Rückwärtskarte Quelle → Alias, die einmal je Indexstand entsteht. **Zeichnen einer Quelle 15,8 → 1,6 ms, eines Alias mit 50 Punkten 51,9 → 14,2 ms.** Nachgewiesen gleich: 3.025 Geräte und alle 727 Aliaspunkte gegen die alten Fassungen geprüft, null Abweichungen\n* Eine Leseformel kann den Reiter nicht mehr dauerhaft einfrieren. Formeln aus `common.alias.read` und aus Vorlagen laufen als JavaScript im Admin — bei jedem Zeichnen, je Zeile, ungefragt. Das ist keine neue Rechteausweitung (wer die Formel schreiben darf, hat sie schon im js-controller laufen), aber ein Ausführungsort ohne Grenzen: `try/catch` fängt keine Endlosschleife. Jetzt wird das Ergebnis je Formel und Rohwert gemerkt — 2000 Auswertungen in 0,6 ms —, und was einmal länger als 250 ms gebraucht hat, läuft nicht wieder; die Zeile sagt, warum\n* Der Objektzähler in der Kopfzeile bleibt nicht mehr stehen. An vier Stellen wurde der Index direkt gesetzt statt über `indexNeu()` — dadurch behielt die Kurznamen-Karte gelöschte Kennungen, und `hatPunkt` lieferte Treffer auf Punkte, die es nicht mehr gab\n* Ein voller Detektorlauf je Zeichnen ist weggefallen. Sein Ergebnis wurde über zwei Zwischenschritte in einen Parameter gereicht, den niemand liest. Ebenso gestrichen: `e.andere` und die toten Symbole `bestandsWert` und `anzeigeText`\n* Die Schreibquellenregel steht an einer Stelle statt an fünf. Sie war wörtlich gleich dreimal in `entwurf.js` und zweimal in `zuordnung.js` ausprogrammiert — und die Kommentare an zwei dieser Stellen dokumentieren je einen Fehler, der genau daraus entstanden ist\n* **Richtigstellung zu 0.9.6:** Dort sollten Adapter- und Instanzwurzeln unwählbar werden — geprüft wurde aber `_tiefe`, und das ist die Höhe des Teilbaums **unter** einem Knoten, nicht seine Stelle im Baum. Am Testsystem schloss das 131 Knoten aus, genau einen davon zu Recht: Die anderen 130 waren Sparten wie `…Decklenlicht_RGB.cmnd` und Ordner wie `iot.0.smart`, deren Datenpunkte direkt darunter liegen. Die wählbaren Knoten fielen von 449 auf 320. Jetzt wird die Stelle geprüft; `mqtt-client` und `mqtt-client.0` bleiben gesperrt, alles andere ist wieder da",
20
+ "en": "Seven packages from a code review — 45 fixes between 0.9.0 and this release. The intermediate steps 0.9.1 to 0.9.6 stayed local and were never published; they are summarised here.\n\n**Data loss and failure paths**\n* An enumeration error now stops a move. Previously the old alias was deleted anyway — and afterwards it was gone while the new one sat in no enumeration at all\n* A partial failure while deleting no longer turns the retry button into a prop: only what really went is dropped\n* Orphaned points are deleted on the second attempt too\n* A load error on the enumerations leaves the previous state standing instead of emptying it — and while they are unknown, nothing is written. Before, one hiccup could drop an alias out of every room and function\n* A load error on your own templates is reported instead of swallowed; otherwise the next save would have replaced an existing template with version 1\n\n**Connection and display**\n* The tab works again after a dropped connection. The admin's WebSocket fires `connect` once per page lifetime and `reconnect` afterwards — nobody listened, and neither object nor state changes arrived\n* Template mode no longer rebuilds itself every second, and where the selection goes, its subscriptions go too\n* “Differs from the alias” now also shows in alias mode — where it says the most\n* Switching sources quickly no longer fetches the wrong value; the source jump list never appears twice\n* Object names follow the admin language; the function match looks at every language and no longer creates a duplicate\n\n**Templates**\n* A broken name hint no longer takes down the whole source view — including the nested form `(a+)+` where the expression engine stalls\n* The formula of a fallback source survives updating, an unknown device type no longer throws\n* Importing checks more than id and states; a hand-typed id no longer replaces someone else's template\n* The `%N%` placeholder only hits the output number now, not every trailing digit\n* The blind gets its STOP: a button press has no state to read, and that case was unknown to template application — **not a single** blind alias ever had one\n* ON_TIME finds its slot (four templates carried the wrong role)\n\n**MQTT and Tasmota**\n* An empty `custom` entry no longer takes anything down, `enabled: false` counts as switched off\n* No more false “cannot publish” for ioBroker.mqtt and sonoff — there, publishing capability is simply unknown, not denied\n* “Answer received” only for a real answer; `Vcc` and `Command` are not commands\n\n**Speed, measured on a production system with 24,786 objects**\n* The search box no longer blocks: **236 ms per keystroke → 0**, the whole tree **263 → 67 ms**\n* A redraw no longer costs half a second — binary search instead of linear scans: drawing a source **15.8 → 1.6 ms**, an alias with 50 points **51.9 → 14.2 ms**\n* A read formula can no longer freeze the tab for good\n* What is subscribed is what is read — before, a single alias could subscribe to half an adapter",
21
+ "de": "Sieben Pakete aus einem Code-Review — 45 behobene Fehler zwischen 0.9.0 und dieser Fassung. Die Zwischenstände 0.9.1 bis 0.9.6 waren lokal und wurden nie veröffentlicht; hier stehen sie zusammengefasst.\n\n**Datenverlust und Fehlerpfade**\n* Ein Fehler an den Aufzählungen hält das Verlegen jetzt auf. Vorher lief das Löschen des alten Alias trotzdem — danach war er weg und der neue stand in keiner Aufzählung mehr\n* Ein Teilfehler beim Löschen macht den Wiederholen-Knopf nicht mehr zur Attrappe: Es wird nur ausgetragen, was wirklich weg ist\n* Verwaiste Punkte werden auch beim zweiten Anlauf gelöscht\n* Ein Ladefehler bei den Aufzählungen lässt den alten Stand stehen, statt ihn zu leeren — und solange sie unbekannt sind, wird nichts geschrieben. Vorher konnte ein Aussetzer beim Laden dazu führen, dass ein Alias aus allen Räumen und Funktionen fiel\n* Ein Ladefehler bei den eigenen Vorlagen wird gemeldet statt verschwiegen; vorher hätte das nächste Speichern eine vorhandene Vorlage mit Version 1 ersetzt\n\n**Verbindung und Anzeige**\n* Nach einem Verbindungsabbruch arbeitet der Reiter wieder. Der WebSocket des Admin feuert `connect` nur einmal pro Seitenleben, danach `reconnect` — das hörte niemand, und es kamen weder Objekt- noch Wertänderungen an\n* Der Vorlagenmodus baut sich nicht mehr im Sekundentakt neu auf, und wo die Auswahl fällt, fallen auch ihre Abos\n* „Weicht vom Alias ab“ erscheint jetzt auch im Aliasmodus — dort, wo die Marke am meisten sagt\n* Ein schneller Quellenwechsel holt keinen fremden Wert mehr, die Quellen-Sprungliste steht nie doppelt\n* Objektnamen folgen der Adminsprache; der Funktionsabgleich sieht alle Sprachfassungen an und legt keinen Doppelgänger mehr an\n\n**Vorlagen**\n* Ein kaputter Namenshinweis legt nicht mehr die ganze Quellenansicht lahm — samt der verschachtelten Form `(a+)+`, an der die Ausdrucks-Maschine hängenbleibt\n* Die Formel einer Ersatzquelle überlebt das Aktualisieren, ein unbekannter Gerätetyp wirft nicht mehr\n* Das Einlesen prüft mehr als Kennung und Zustände; eine von Hand eingetippte Kennung ersetzt keine fremde Vorlage mehr\n* Der Platzhalter `%N%` trifft nur noch die Ausgangsnummer, nicht jede Endziffer\n* Der Rollladen bekommt seinen STOP: Ein Tastendruck hat keinen Zustand zum Lesen, und diesen Fall kannte das Anwenden nicht — **kein einziger** Rollladen-Alias hatte je einen\n* ON_TIME findet seinen Platz (vier Vorlagen trugen die falsche Rolle)\n\n**MQTT und Tasmota**\n* Ein leerer `custom`-Eintrag legt nichts mehr lahm, `enabled: false` gilt als abgeschaltet\n* Kein falsches „kann nicht senden“ mehr bei ioBroker.mqtt und sonoff — dort ist die Sendefähigkeit schlicht unbekannt, nicht verneint\n* „Antwort erhalten“ nur noch bei einer echten Antwort; `Vcc` und `Command` sind keine Befehle\n\n**Tempo, am Produktivsystem mit 24.786 Objekten gemessen**\n* Das Suchfeld blockiert nicht mehr: **236 ms je Anschlag → 0**, der ganze Baum **263 → 67 ms**\n* Ein Neuzeichnen kostet keine halbe Sekunde mehr — Binärsuche statt linearer Scans: Zeichnen einer Quelle **15,8 → 1,6 ms**, eines Alias mit 50 Punkten **51,9 → 14,2 ms**\n* Eine Leseformel kann den Reiter nicht mehr dauerhaft einfrieren\n* Abonniert wird, was gelesen wird — vorher konnte ein einziger Alias den halben Adapter abonnieren",
9
22
  "ru": "Скорость на большой системе (измерено на боевой системе с 24 786 объектами): поле поиска больше не блокирует интерфейс (236 мс на нажатие → 0, дерево 263 → 67 мс), перерисовка ускорена за счёт бинарного поиска по отсортированному индексу и обратной карты источник → алиас (алиас 51,9 → 14,2 мс), формулы чтения кешируются и не могут больше намертво подвесить вкладку, счётчик объектов снова обновляется, лишний прогон детектора и пятикратно продублированное правило записи убраны.",
10
23
  "pt": "Desempenho num sistema grande (medido no sistema de produção com 24 786 objetos): o campo de pesquisa deixou de bloquear (236 ms por tecla → 0, árvore 263 → 67 ms), o redesenho acelera com pesquisa binária no índice ordenado e um mapa inverso fonte → alias (alias 51,9 → 14,2 ms), as fórmulas de leitura são memorizadas e já não podem congelar o separador, o contador de objetos volta a atualizar, e caíram uma passagem inútil do detetor e a regra de escrita repetida cinco vezes.",
11
24
  "nl": "Snelheid op een groot systeem (gemeten op het productiesysteem met 24.786 objecten): het zoekveld blokkeert niet meer (236 ms per toetsaanslag → 0, boom 263 → 67 ms), opnieuw tekenen gaat sneller door binair zoeken in de gesorteerde index en een omgekeerde kaart bron → alias (alias 51,9 → 14,2 ms), leesformules worden onthouden en kunnen het tabblad niet meer blijvend bevriezen, de objectteller loopt weer mee, en een overbodige detectorronde en de vijfvoudig uitgeschreven schrijfregel zijn verdwenen.",
@@ -16,84 +29,6 @@
16
29
  "uk": "Швидкодія на великій системі (виміряно на робочій системі з 24 786 об'єктами): поле пошуку більше не блокує (236 мс на натискання → 0, дерево 263 → 67 мс), перемальовування пришвидшено завдяки двійковому пошуку впорядкованим індексом і зворотній карті джерело → аліас (аліас 51,9 → 14,2 мс), формули читання кешуються й більше не можуть назавжди підвісити вкладку, лічильник об'єктів знову оновлюється, а зайвий прохід детектора та п'ятиразово продубльоване правило запису прибрано.",
17
30
  "zh-cn": "大型系统上的速度(在拥有 24.786 个对象的生产系统上实测):搜索框不再卡顿(每次按键 236 毫秒 → 0,整棵树 263 → 67 毫秒),重绘通过对有序索引的二分查找和“来源 → 别名”反向表加速(别名 51,9 → 14,2 毫秒),读取公式的结果会被缓存且不再能长久冻结标签页,对象计数重新同步,多余的一次检测器运行以及重复五遍的写入规则均已移除。"
18
31
  },
19
- "0.9.6": {
20
- "en": "**Display and flow**\n* “All data points” keeps the output and the manual choice. On a multi-output template at output 2 the rows of output 1 came back while the target still read `…Ausgang_2`; and if automatic matching had found nothing and you picked the template by hand, the click dropped you into raw mode with the choice gone\n* “Differs from the alias” now also shows in alias mode. The marker was handed the target, which is never set there — you are already standing on the alias. So it never appeared exactly where it says the most\n* Switching sources quickly no longer fetches the wrong value. The callback stored the value under whatever source was selected when it arrived — and since only missing values are fetched, it stayed that way\n* The source jump list never appears twice. It hangs off the page body so it survives an automatic redraw; the button is a different one afterwards, and the second click laid a second list over the first\n* A room is suggested even when it is the last segment. With a flat adapter such as `sonoff.0.Wohnzimmer` the search over the source path never ran at all\n* Object names follow the admin language. There were two readers for the same question, one fixed on German before English — so on an English admin, objects, rooms and functions showed up in German. And the name match now looks at every language: “Light” in the system failed to find the function “Licht” and created a duplicate beside it\n\n**MQTT and Tasmota**\n* An empty `custom` entry no longer takes anything down. `common.custom` can hold an entry whose value is `null` — ioBroker does not clean it up when an instance disappears. Reaching into it took the whole result view with it\n* `enabled: false` counts as switched off. The field did not appear in the reader at all: `{ enabled: false, publish: true }` counted as publishable although the instance does not serve that point\n* No more false “cannot publish” for ioBroker.mqtt and sonoff. Their objects carry the topic in `native` only; that was reported as a firm “no” instead of “unknown”, the chip was red, and “allow publishing” wrote the object back unchanged — a message that could not be cleared\n* “Answer received” only for a real answer. A `stat.RESULT` left retained from the day before yesterday was enough for the green feedback, even with the device switched off\n* `Vcc` and `Command` are not commands. `{\"Command\":\"Unknown\"}` — the reply to an unknown command — stood there as a missing command point, with a create button\n* Command names from foreign JSON no longer reach ids and topics unchecked. A key containing `#` would make a wildcard subscription, one containing `.` an extra level\n\n**Templates and devices**\n* The blind gets its STOP. A button press has no state to read, and that case was unknown to template application: without a read path the point dropped out — not a single blind alias ever had a STOP\n* ON_TIME finds its slot. Four templates carried the role `level.timer` while the slot requires `level.timer.off`, so the point ended up in the info device instead of the switching device\n* An explicit formula beats the field. Where a template gives both, the formula was discarded and a new one built from the field\n\n**Subscriptions and tree**\n* What is subscribed is what is read — not half the adapter. The patterns came from the display grouping: on a flat MQTT device that produced `mqtt-client.0.*` with over three hundred objects on a single alias. It is now the channels of the actual sources, branches of the same device folded into one pattern, and where even that is too wide, the sources one by one\n* Adapter and instance roots can no longer be selected. `mqtt-client.0` is not a device; selecting it would have subscribed the whole namespace\n* Dark admin themes are recognised. The detection knew four names; `blue` and `colored` fell through and landed on the system setting\n* A late answer to `system.config` still counts. After 2.5 seconds it carries on without one — the answer arriving later was discarded entirely, and without it every expert object was missing from the tree\n\n**Housekeeping**\n* The checks touch nothing again. One of them wrote an object from inside the drawing path\n* The delete dialog warns about channels of their own below the target. The hint spoke only of “data points below”\n* Four dead language keys removed — and the test now checks both directions, not just code → JSON",
21
- "de": "**Anzeige und Ablauf**\n* „Alle Datenpunkte“ hält Ausgang und Handwahl fest. An einer Mehrfachvorlage mit Ausgang 2 kamen die Zeilen von Ausgang 1 zurück, während das Ziel weiter `…Ausgang_2` hieß; und hatte die Automatik nichts gefunden und man die Vorlage von Hand gewählt, landete man nach dem Klick im Rohmodus — die Handwahl war weg\n* „Weicht vom Alias ab“ erscheint jetzt auch im Aliasmodus. Die Marke bekam das Ziel, und das ist dort nie gesetzt: Man steht ja schon auf dem Alias. Sie erschien also ausgerechnet dort nie, wo sie am meisten sagt\n* Ein schneller Quellenwechsel holt keinen fremden Wert mehr. Der Nachlade-Rückruf legte den Wert unter der Quelle ab, die beim Eintreffen eingestellt war — und da nur geholt wird, was noch fehlt, blieb es dabei\n* Die Quellen-Sprungliste steht nie doppelt. Sie hängt am Seitenkörper, damit sie ein automatisches Neuzeichnen überlebt; der Knopf ist danach aber ein anderer, und der zweite Klick legte eine zweite Liste über die erste\n* Ein Raum wird auch dann vorgeschlagen, wenn er das letzte Segment ist. Bei einem flachen Adapter wie `sonoff.0.Wohnzimmer` lief die Suche über den Quellenpfad kein einziges Mal\n* Objektnamen folgen der Adminsprache. Es gab zwei Leser für dieselbe Frage, einer nahm fest Deutsch vor Englisch — auf einem englischen Admin standen Objekte, Räume und Funktionen deshalb deutsch da. Und der Namensabgleich sieht jetzt alle Sprachfassungen an: „Light“ im Bestand fand die Funktion „Licht“ nicht und legte einen Doppelgänger daneben\n\n**MQTT und Tasmota**\n* Ein leerer `custom`-Eintrag legt nichts mehr lahm. `common.custom` kann einen Eintrag mit dem Wert `null` tragen — ioBroker räumt ihn nicht weg, wenn eine Instanz verschwindet. Der Zugriff darauf riss die ganze Ergebnisansicht mit\n* `enabled: false` gilt als abgeschaltet. Der Bezeichner kam im Leser gar nicht vor: Ein Eintrag `{ enabled: false, publish: true }` galt als sendefähig, obwohl die Instanz den Punkt nicht bedient\n* Kein falsches „kann nicht senden“ mehr bei ioBroker.mqtt und sonoff. Deren Objekte tragen das Thema nur in `native`; dafür stand fest „nein“ statt „unbekannt“, der Chip war rot, und der Knopf „senden erlauben“ schrieb das Objekt unverändert zurück — eine Meldung, die sich nicht abstellen ließ\n* „Antwort erhalten“ nur bei einer echten Antwort. Ein `stat.RESULT`, das retained von vorgestern dasteht, reichte für die grüne Rückmeldung, auch wenn das Gerät aus ist\n* `Vcc` und `Command` sind keine Befehle. `{\"Command\":\"Unknown\"}` — die Antwort auf einen unbekannten Befehl — stand als fehlender Sendepunkt da, mit Anlegen-Knopf\n* Befehlsnamen aus fremdem JSON kommen nicht mehr ungeprüft in Kennung und Thema. Ein Schlüssel mit `#` ergäbe ein Wildcard-Abo, einer mit `.` eine zusätzliche Ebene\n\n**Vorlagen und Geräte**\n* Der Rollladen bekommt seinen STOP. Ein Tastendruck hat keinen Zustand zum Lesen, und genau diesen Fall kannte das Anwenden nicht: Ohne Lesepfad fiel der Punkt heraus — kein einziger Rollladen-Alias hatte je einen STOP\n* ON_TIME findet seinen Platz. Vier Vorlagen führten die Rolle `level.timer`, der Platz verlangt `level.timer.off`; der Punkt landete deshalb im info-Gerät statt am Schaltgerät\n* Eine ausdrückliche Formel gewinnt gegen das Feld. Wo eine Vorlage beides angibt, wurde die Formel verworfen und aus dem Feld eine neue gebaut\n\n**Abos und Baum**\n* Abonniert wird, was gelesen wird — nicht der halbe Adapter. Die Muster kamen aus der Anzeige-Verteilung: Bei einem flachen MQTT-Gerät wurde daraus `mqtt-client.0.*` mit über dreihundert Objekten an einem einzigen Alias. Jetzt sind es die Kanäle der tatsächlichen Quellen, Sparten desselben Geräts zu einem Muster zusammengefasst, und wo auch das zu breit wäre, die Quellen einzeln\n* Adapter- und Instanzwurzeln sind nicht mehr wählbar. `mqtt-client.0` ist kein Gerät; die Auswahl hätte den ganzen Namensraum abonniert\n* Dunkle Admin-Themen werden erkannt. Die Erkennung kannte vier Namen; `blue` und `colored` fielen durch und landeten bei der Systemeinstellung\n* Eine späte Antwort auf `system.config` gilt trotzdem. Nach 2,5 Sekunden geht es ohne weiter — die Antwort danach wurde ganz verworfen, und ohne sie fehlten alle Expertenobjekte im Baum\n\n**Aufräumen**\n* Die Prüfungen fassen wieder nichts an. Eine von ihnen schrieb aus dem Zeichenpfad heraus ein Objekt\n* Der Löschdialog warnt vor eigenständigen Kanälen unterhalb des Ziels. Der Hinweistext sprach nur von „Datenpunkten darunter“\n* Vier tote Sprachschlüssel entfernt — und der Test prüft jetzt beide Richtungen, nicht nur Code → JSON",
22
- "ru": "Двадцать две ошибки в отображении, MQTT, шаблонах и подписках: «все точки данных» сохраняют выход и ручной выбор, метка «отличается от алиаса» снова видна в режиме алиасов, пустая запись custom больше ничего не ломает, enabled: false учитывается, ответ Tasmota засчитывается только настоящий, ролик получает свой STOP, ON_TIME находит своё место, подписка охватывает только читаемые источники, а не половину адаптера, корни адаптеров больше не выбираются, тёмные темы админки распознаются.",
23
- "pt": "Vinte e dois erros na apresentação, MQTT, modelos e subscrições: “todos os pontos de dados” mantêm a saída e a escolha manual, a marca “difere do alias” volta a aparecer no modo alias, uma entrada custom vazia já não derruba nada, enabled: false é respeitado, só uma resposta verdadeira do Tasmota conta, o estore recebe o seu STOP, ON_TIME encontra o seu lugar, subscreve-se o que se lê e não meio adaptador, as raízes de adaptador deixam de ser selecionáveis e os temas escuros do admin são reconhecidos.",
24
- "nl": "Tweeëntwintig fouten in weergave, MQTT, sjablonen en abonnementen: “alle datapunten” behouden uitgang en handmatige keuze, de markering “wijkt af van de alias” verschijnt weer in aliasmodus, een lege custom-vermelding legt niets meer plat, enabled: false telt, alleen een echt antwoord van Tasmota telt, het rolluik krijgt zijn STOP, ON_TIME vindt zijn plek, er wordt geabonneerd op wat gelezen wordt in plaats van op een halve adapter, adapterwortels zijn niet meer selecteerbaar en donkere adminthema's worden herkend.",
25
- "fr": "Vingt-deux erreurs dans l'affichage, MQTT, les modèles et les abonnements : « tous les points de données » conservent la sortie et le choix manuel, la marque « diffère de l'alias » réapparaît en mode alias, une entrée custom vide ne casse plus rien, enabled: false est pris en compte, seule une vraie réponse Tasmota compte, le volet reçoit son STOP, ON_TIME trouve sa place, on s'abonne à ce qu'on lit et non à la moitié d'un adaptateur, les racines d'adaptateur ne sont plus sélectionnables et les thèmes sombres de l'admin sont reconnus.",
26
- "it": "Ventidue errori in visualizzazione, MQTT, modelli e sottoscrizioni: «tutti i punti dati» mantengono uscita e scelta manuale, il segno «differisce dall'alias» torna a comparire in modalita alias, una voce custom vuota non blocca piu nulla, enabled: false viene rispettato, conta solo una vera risposta Tasmota, la tapparella ottiene il suo STOP, ON_TIME trova il suo posto, si sottoscrive cio che si legge e non mezzo adattatore, le radici degli adattatori non sono piu selezionabili e i temi scuri dell'admin vengono riconosciuti.",
27
- "es": "Veintidos errores en la presentacion, MQTT, plantillas y suscripciones: «todos los puntos de datos» conservan la salida y la eleccion manual, la marca «difiere del alias» vuelve a aparecer en modo alias, una entrada custom vacia ya no tumba nada, enabled: false cuenta, solo una respuesta real de Tasmota cuenta, la persiana recibe su STOP, ON_TIME encuentra su sitio, se suscribe lo que se lee y no medio adaptador, las raices de adaptador ya no son seleccionables y los temas oscuros del admin se reconocen.",
28
- "pl": "Dwadziescia dwa bledy w wyswietlaniu, MQTT, szablonach i subskrypcjach: 'wszystkie punkty danych' zachowuja wyjscie i wybor reczny, znacznik 'rozni sie od aliasu' znow pojawia sie w trybie aliasow, pusty wpis custom niczego juz nie wywraca, enabled: false jest respektowane, liczy sie tylko prawdziwa odpowiedz Tasmoty, roleta dostaje swoj STOP, ON_TIME znajduje swoje miejsce, subskrybowane jest to, co czytane, a nie pol adaptera, korzenie adapterow nie sa juz wybieralne, a ciemne motywy admina sa rozpoznawane.",
29
- "uk": "Двадцять дві помилки у відображенні, MQTT, шаблонах і підписках: «усі точки даних» зберігають вихід і ручний вибір, позначка «відрізняється від аліаса» знову видима в режимі аліасів, порожній запис custom більше нічого не ламає, enabled: false враховується, зараховується лише справжня відповідь Tasmota, ролета отримує свій STOP, ON_TIME знаходить своє місце, підписка охоплює лише те, що читається, а не пів адаптера, корені адаптерів більше не вибираються, а темні теми адміна розпізнаються.",
30
- "zh-cn": "修复了显示、MQTT、模板与订阅中的二十二个问题:“所有数据点”保留输出与手动选择,“与别名不符”标记在别名模式下重新出现,空的 custom 条目不再导致崩溃,enabled: false 生效,只有真实的 Tasmota 应答才算数,卷帘获得它的 STOP,ON_TIME 找到对应槽位,订阅范围只覆盖真正读取的来源而非半个适配器,适配器根节点不再可选,深色管理主题也能被识别。"
31
- },
32
- "0.9.5": {
33
- "en": "* A broken name hint no longer takes down the whole source view. The text was evaluated as a regular expression unchecked, although neither the template sheet nor the save dialog validates it: after saving `Lampe (Bad`, template matching threw on **every** device selection, no caller caught it, and the right-hand side stayed empty — repairable only through the instance configuration by hand. An unusable expression now counts as “no match” and is flagged in red at the field. The same goes for the nested form `(a+)+`, where the expression engine stalls: a measured 3196 ms for one device name, now none\n* The formula of a fallback source survives updating a template. It was stored under `formel` while every reader looks for `leseformel` — so updating from a device silently dropped it. With `tasmota-steckdose` the consequence was that on devices without `stat.POWER` the boolean alias ended up on the raw JSON text of `tele.STATE` instead of on `POWER`\n* A device type this detector does not know no longer throws. The offered pattern list was filtered, the **selected** type was not — it comes from the template unchecked. An imported template naming a pattern from a newer type-detector made the pattern picker throw, and the draft was never drawn at all\n* Importing now checks more than id and states. `erkennung.erforderlich` as a string instead of a list made template matching throw on **every** device afterwards; a missing `name` threw as soon as the sheet opened. And “import and save” was on screen long before that — you could save a template that then made the tab unusable. `erkennung`, `erforderlich`/`verboten`, `inhalt`, `name`, the name hint and the device type are checked now; a single string that unambiguously means a list is turned into one rather than rejected\n* A hand-typed id no longer replaces someone else's template. Ids were only checked for collisions when switching modes, not after typing — and saving replaces without asking on a matching id, in “new” mode even with version 1. An own template at v7 silently became a different one at v1. The reason is now shown in red at the field and saving is blocked\n* The `%N%` placeholder only hits the output number now. Replacement went purely by trailing digit: on a multi-output device at output 2 the IP row from `tele.INFO2` became `tele.INFO%N%` — and at output 1 that same row reported a foreign output, with “drop the others” throwing it out. Only what actually carries the output becomes a placeholder now: what the template already held as `%N%`, the prefix from `kanalname`, and what appears more than once with the same number",
34
- "de": "* Ein kaputter Namenshinweis legt nicht mehr die ganze Quellenansicht lahm. Der Text wurde ungeprüft als regulärer Ausdruck ausgewertet, obwohl ihn weder das Vorlagenblatt noch der Speichern-Dialog prüft: Nach dem Speichern von `Lampe (Bad` warf die Vorlagenprüfung bei **jeder** Geräteauswahl, kein Aufrufer fing das, und die rechte Seite blieb leer — zu reparieren nur noch über die Instanzkonfiguration von Hand. Jetzt zählt ein unbrauchbarer Ausdruck als „trifft nicht“ und wird im Feld rot gemeldet. Dasselbe gilt für die verschachtelte Form `(a+)+`, an der die Ausdrucks-Maschine hängenbleibt: gemessene 3196 ms für einen Gerätenamen, jetzt keine\n* Die Formel einer Ersatzquelle überlebt das Aktualisieren einer Vorlage. Sie wurde unter `formel` abgelegt, gelesen wird aber `leseformel` — beim Aktualisieren aus einem Gerät ging sie damit still verloren. Folge bei `tasmota-steckdose`: An Geräten ohne `stat.POWER` landete der boolesche Alias danach auf dem rohen JSON-Text von `tele.STATE` statt auf `POWER`\n* Ein Gerätetyp, den dieser Detector nicht kennt, wirft nicht mehr. Die angebotene Musterliste war gefiltert, der **gewählte** Typ nicht — er kommt ungeprüft aus der Vorlage. Eine eingelesene Vorlage mit dem Musternamen eines neueren type-detector ließ die Musterwahl werfen, und der Entwurf wurde gar nicht erst gezeichnet\n* Das Einlesen prüft jetzt mehr als Kennung und Zustände. `erkennung.erforderlich` als Text statt als Liste ließ die Vorlagenprüfung danach an **jedem** Gerät werfen; ein fehlendes `name` warf schon beim Öffnen im Blatt. Und „Einlesen und speichern“ stand zu diesem Zeitpunkt längst da — man konnte eine Vorlage speichern, die den Reiter danach unbrauchbar machte. Geprüft werden jetzt `erkennung`, `erforderlich`/`verboten`, `inhalt`, `name`, der Namenshinweis und der Gerätetyp; ein einzelner Text, der eindeutig eine Liste meint, wird zu einer gemacht statt abgewiesen\n* Eine von Hand eingetippte Kennung ersetzt keine fremde Vorlage mehr. Auf freie Kennungen wurde nur beim Umschalten geprüft, nicht nach der Handeingabe — und gespeichert wird bei gleicher Kennung ohne Rückfrage, im Modus „neu“ sogar mit Version 1. Aus einer eigenen Vorlage v7 wurde so still eine ganz andere v1. Jetzt steht der Grund rot am Feld und das Speichern ist gesperrt\n* Der Platzhalter `%N%` trifft nur noch die Ausgangsnummer. Ersetzt wurde rein nach Endziffer: An einem Mehrfachgerät mit Ausgang 2 wurde damit auch die IP-Zeile aus `tele.INFO2` zu `tele.INFO%N%` — und an Ausgang 1 meldete dieselbe Zeile einen fremden Ausgang, „Andere weglassen“ warf sie hinaus. Zum Platzhalter wird jetzt nur, was den Ausgang trägt: was die Vorlage im Original schon mit `%N%` führte, der Vorspann aus `kanalname` und was mit derselben Nummer mehrfach vorkommt",
35
- "ru": "Шесть ошибок в логике шаблонов: неверная подсказка по имени больше не выводит из строя весь просмотр источников (включая вложенную форму (a+)+), формула запасного источника переживает обновление шаблона, неизвестный тип устройства не вызывает исключения, импорт проверяет больше, чем идентификатор и состояния, вручную введённый идентификатор не заменяет чужой шаблон, а подстановка %N% затрагивает только номер выхода.",
36
- "pt": "Seis erros na lógica de modelos: uma dica de nome inválida já não inutiliza toda a vista de fontes (incluindo a forma aninhada (a+)+), a fórmula de uma fonte alternativa sobrevive à atualização do modelo, um tipo de dispositivo desconhecido já não lança erro, a importação verifica mais do que id e estados, um id escrito à mão não substitui um modelo alheio, e o marcador %N% só atinge o número da saída.",
37
- "nl": "Zes fouten in de sjabloonlogica: een kapotte naamhint legt niet langer de hele bronweergave plat (ook de geneste vorm (a+)+), de formule van een reservebron overleeft het bijwerken van een sjabloon, een onbekend apparaattype gooit geen fout meer, het inlezen controleert meer dan id en toestanden, een met de hand ingetypte id vervangt geen andermans sjabloon, en de plaatshouder %N% raakt alleen het uitgangsnummer.",
38
- "fr": "Six erreurs dans la logique des modèles : un indice de nom invalide ne paralyse plus toute la vue des sources (y compris la forme imbriquée (a+)+), la formule d'une source de repli survit à la mise à jour d'un modèle, un type d'appareil inconnu ne lève plus d'erreur, l'import vérifie plus que l'identifiant et les états, un identifiant saisi à la main ne remplace plus le modèle d'un autre, et le marqueur %N% ne touche que le numéro de sortie.",
39
- "it": "Sei errori nella logica dei modelli: un suggerimento di nome rotto non blocca piu l'intera vista delle sorgenti (compresa la forma annidata (a+)+), la formula di una sorgente di riserva sopravvive all'aggiornamento del modello, un tipo di dispositivo sconosciuto non solleva piu eccezioni, l'importazione controlla piu di id e stati, un id digitato a mano non sostituisce il modello altrui, e il segnaposto %N% colpisce solo il numero dell'uscita.",
40
- "es": "Seis errores en la logica de plantillas: una pista de nombre rota ya no inutiliza toda la vista de fuentes (incluida la forma anidada (a+)+), la formula de una fuente alternativa sobrevive a la actualizacion de la plantilla, un tipo de dispositivo desconocido ya no lanza error, la importacion comprueba mas que el id y los estados, un id escrito a mano no reemplaza la plantilla de otro, y el marcador %N% solo afecta al numero de salida.",
41
- "pl": "Szesc bledow w logice szablonow: zepsuta wskazowka nazwy nie unieruchamia juz calego widoku zrodel (takze forma zagniezdzona (a+)+), formula zrodla zapasowego przetrwa aktualizacje szablonu, nieznany typ urzadzenia nie rzuca juz wyjatku, wczytywanie sprawdza wiecej niz identyfikator i stany, recznie wpisany identyfikator nie zastepuje cudzego szablonu, a symbol %N% dotyczy tylko numeru wyjscia.",
42
- "uk": "Шість помилок у логіці шаблонів: зіпсована підказка імені більше не виводить з ладу весь перегляд джерел (зокрема вкладена форма (a+)+), формула запасного джерела переживає оновлення шаблону, невідомий тип пристрою більше не кидає виняток, зчитування перевіряє більше, ніж ідентифікатор і стани, введений вручну ідентифікатор не замінює чужий шаблон, а підстановка %N% стосується лише номера виходу.",
43
- "zh-cn": "修复了模板逻辑中的六个问题:错误的名称提示不再让整个源视图瘫痪(包括嵌套形式 (a+)+),备用来源的公式在更新模板时不再丢失,未知的设备类型不再抛出异常,导入时的检查不再只看标识和数据点,手工输入的标识不会覆盖他人的模板,占位符 %N% 只作用于输出编号。"
44
- },
45
- "0.9.4": {
46
- "en": "* The tab works again after a dropped connection. It does not load socket.io but the admin's WebSocket shim — and there `connect` fires exactly once per page lifetime, only `reconnect` afterwards. Nobody listened for that, and the shim renews no subscription on its own. After every outage — admin restart, network hiccup, standby — neither object nor state changes arrived, and the dot in the header stayed on “disconnected” although the connection had long been back. `reconnect` is now handled: the display goes back to “connected”, every subscription is renewed and the objects are re-read — anything could have changed while disconnected, and nobody was watching\n* The template mode no longer rebuilds itself every second. Selecting a device with live values and switching to the templates tab rebuilt the whole sheet every 700 ms, including a trial run across all candidates and all templates — the selection deliberately survives the mode switch, but there is no state list on the right any more\n* Where the selection goes, its subscriptions now go too. Unsubscribing only happened when selecting the next node; the four other paths — switching mode, collapsing a branch, leaving expert mode, deleting an alias — unsubscribed from nothing. A subscription then ran on a device no longer shown, and the header counter still claimed “one subscription”\n* Switching nodes while loading no longer leaves the caller hanging. The callback never arrived in that case: “running” stayed on the button forever, and the dry run meant to open after creating missing command points never opened. Twelve seconds of waiting on a SetOption59 query is ample opportunity for that",
47
- "de": "* Nach einem Verbindungsabbruch arbeitet der Reiter wieder. Er lädt nicht socket.io, sondern den WebSocket-Shim des Admin — und dort feuert `connect` genau einmal pro Seitenleben, danach nur noch `reconnect`. Das hörte niemand, und der Shim erneuert von sich aus kein einziges Abo. Nach jedem Aussetzer — Admin-Neustart, Netzwerkhänger, Standby — kamen weder Objekt- noch Wertänderungen an, und der Punkt in der Kopfzeile blieb auf „getrennt“ stehen, obwohl die Verbindung längst wieder stand. Jetzt wird `reconnect` gehört: die Anzeige geht auf „verbunden“, alle Abos werden erneuert und der Bestand neu gelesen — während der Trennung kann sich alles geändert haben, und mitbekommen hat es niemand\n* Der Vorlagenmodus baut sich nicht mehr im Sekundentakt neu auf. Wer ein Gerät mit laufenden Werten gewählt hatte und in den Vorlagen-Tab wechselte, baute dort alle 700 ms das ganze Blatt neu, samt Probelauf über alle Kandidaten und alle Vorlagen — die Auswahl bleibt beim Moduswechsel absichtlich stehen, aber rechts steht dann gar keine Zustandsliste mehr\n* Wo die Auswahl fällt, fallen jetzt auch ihre Abos. Abgemeldet wurde nur beim Auswählen des nächsten Knotens; die vier anderen Wege — Moduswechsel, Zweig zuklappen, Expertenmodus abschalten, Alias löschen — meldeten nichts ab. Danach lief ein Abo auf ein Gerät, das rechts gar nicht mehr stand, und der Zähler in der Kopfzeile behauptete weiter „ein Abo“\n* Ein Knotenwechsel während des Ladens lässt den Aufrufer nicht mehr hängen. Der Rückruf kam in diesem Fall nie: „läuft“ blieb für immer am Knopf stehen, und der Trockenlauf, der nach dem Anlegen fehlender Sendepunkte aufgehen soll, ging nie auf. Zwölf Sekunden Wartezeit bei einer SetOption59-Abfrage sind reichlich Gelegenheit dafür",
48
- "ru": "Соединение и подписки: после разрыва связи вкладка снова работает (обрабатывается reconnect, подписки возобновляются, объекты перечитываются), режим шаблонов больше не перестраивается каждую секунду, подписки снимаются везде, где снимается выбор, а смена узла во время загрузки больше не оставляет вызывающего в подвешенном состоянии.",
49
- "pt": "Ligação e subscrições: após uma quebra de ligação o separador volta a funcionar (reconnect é tratado, as subscrições são renovadas, os objetos relidos), o modo de modelos já não se reconstrói a cada segundo, as subscrições caem onde cai a seleção, e mudar de nó durante o carregamento já não deixa quem chamou à espera.",
50
- "nl": "Verbinding en abonnementen: na een verbroken verbinding werkt het tabblad weer (reconnect wordt afgehandeld, abonnementen worden vernieuwd, objecten opnieuw gelezen), de sjabloonmodus bouwt zich niet meer elke seconde opnieuw op, abonnementen vervallen waar de selectie vervalt, en van knooppunt wisselen tijdens het laden laat de aanroeper niet meer hangen.",
51
- "fr": "Connexion et abonnements : après une coupure, l'onglet fonctionne de nouveau (reconnect est traité, les abonnements sont renouvelés, les objets relus), le mode modèles ne se reconstruit plus chaque seconde, les abonnements tombent là où tombe la sélection, et changer de nœud pendant le chargement ne laisse plus l'appelant en attente.",
52
- "it": "Connessione e sottoscrizioni: dopo un'interruzione la scheda funziona di nuovo (reconnect viene gestito, le sottoscrizioni rinnovate, gli oggetti riletti), la modalita modelli non si ricostruisce piu ogni secondo, le sottoscrizioni cadono dove cade la selezione, e cambiare nodo durante il caricamento non lascia piu appeso il chiamante.",
53
- "es": "Conexion y suscripciones: tras una caida la pestana vuelve a funcionar (se atiende reconnect, se renuevan las suscripciones, se releen los objetos), el modo de plantillas ya no se reconstruye cada segundo, las suscripciones caen donde cae la seleccion, y cambiar de nodo durante la carga ya no deja colgado a quien llama.",
54
- "pl": "Polaczenie i subskrypcje: po zerwaniu polaczenia karta znow dziala (reconnect jest obslugiwany, subskrypcje odnawiane, obiekty wczytywane ponownie), tryb szablonow nie przebudowuje sie juz co sekunde, subskrypcje znikaja tam gdzie znika wybor, a zmiana wezla podczas ladowania nie zostawia juz wywolujacego w zawieszeniu.",
55
- "uk": "З'єднання та підписки: після розриву вкладка знову працює (reconnect обробляється, підписки поновлюються, об'єкти перечитуються), режим шаблонів більше не перебудовується щосекунди, підписки знімаються там, де знімається вибір, а зміна вузла під час завантаження більше не залишає того, хто викликав, у підвішеному стані.",
56
- "zh-cn": "连接与订阅:断线后标签页恢复工作(处理 reconnect、重新订阅、重新读取对象),模板模式不再每秒重建,选择取消时订阅一并取消,加载期间切换节点不再让调用方永远等待。"
57
- },
58
- "0.9.3": {
59
- "en": "* An error on the enumerations now stops the move. The first step — creating the new one — always aborted on error, “two rather than none”; the second did not: enumeration errors were collected and the old one was deleted anyway. Afterwards the old alias was gone and the new one sat in no enumeration at all, because the js-controller removes members itself on delete. The assignment was therefore lost outright, not merely orphaned. The same abort now applies one level down, and the button offers “Try again”\n* A partial failure while deleting no longer turns the retry button into a prop. If one delete failed, **all** ids were dropped from the internal store anyway, empty folders and enumerations were cleaned up and the delete target was set to null — which is exactly what `loescheAlias` starts with, so it bailed out immediately. Whatever stayed in the database was out of reach: the workbench considered it deleted. Only what really went is dropped now, the cleanup is skipped, the target stays — and the second click actually finishes the job\n* Orphaned points are deleted on the second attempt too. Their list was cleared after writing **always**, even after a failure; the retry button then wrote the objects but removed nothing, and the message no longer counted them either\n* A load error on your own templates is reported instead of swallowed. If the instance configuration answered with an error, that counted as “no own templates” — the warning chip in the header stayed away, although the timeout path one line above sets it correctly. The consequence was the dangerous part: the workbench considered taken ids free, and the next save would have replaced an existing template with version 1. The chip's tooltip now says so",
60
- "de": "* Ein Fehler an den Aufzählungen hält das Verlegen jetzt auf. Der erste Schritt — das Neue anlegen — brach bei einem Fehler schon immer ab, „besser zwei als keiner“; der zweite nicht: Die Aufzählungs-Fehler wurden gesammelt und das Löschen des Alten lief trotzdem. Danach war der alte Alias weg und der neue stand in keiner Aufzählung mehr, denn beim Löschen trägt der js-controller selbst aus. Die Zuordnung war damit ganz verloren, nicht nur verwaist. Jetzt gilt derselbe Abbruch wie eine Stufe darüber, und der Knopf bietet „Noch einmal versuchen“ an\n* Ein Teilfehler beim Löschen macht den Wiederholen-Knopf nicht mehr zur Attrappe. Schlug eins der Löschen fehl, fielen trotzdem **alle** Kennungen aus dem eigenen Bestand, leere Ordner und Aufzählungen wurden geräumt und das Löschziel auf null gesetzt — und genau damit begann `loescheAlias` und stieg sofort wieder aus. Was in der Datenbank stehenblieb, war über die Werkbank nicht mehr zu greifen: sie hielt es für gelöscht. Jetzt wird nur ausgetragen, was wirklich weg ist, das Aufräumen unterbleibt, das Ziel bleibt stehen — und der zweite Klick räumt tatsächlich auf\n* Verwaiste Punkte werden auch beim zweiten Anlauf gelöscht. Ihre Liste wurde nach dem Schreiben **immer** geleert, auch nach einem Fehlschlag; der Wiederholen-Knopf schrieb dann zwar die Objekte, entfernte aber nichts mehr, und die Meldung zählte es auch nicht mehr mit\n* Ein Ladefehler bei den eigenen Vorlagen wird gemeldet statt verschwiegen. Antwortete die Instanzkonfiguration mit einem Fehler, galt das als „keine eigenen Vorlagen“ — der Warnchip in der Kopfzeile blieb aus, obwohl der Timeout-Pfad eine Zeile darüber ihn richtig setzt. Gefährlich war die Folge: Die Werkbank hielt vergebene Kennungen für frei, und das nächste Speichern hätte eine vorhandene Vorlage mit Version 1 ersetzt. Der Hinweis am Chip sagt das jetzt auch",
61
- "ru": "Четыре ошибки на путях сбоя: ошибка перечисления теперь останавливает перемещение, частичный сбой при удалении больше не делает кнопку повтора бутафорией, осиротевшие точки удаляются и со второй попытки, а сбой загрузки собственных шаблонов сообщается вместо замалчивания.",
62
- "pt": "Quatro erros nos caminhos de falha: um erro de enumeração interrompe agora a mudança de lugar, uma falha parcial ao apagar já não torna o botão de repetição um adereço, os pontos órfãos são apagados também na segunda tentativa, e uma falha ao carregar os próprios modelos é comunicada em vez de silenciada.",
63
- "nl": "Vier fouten in de foutpaden: een opsommingsfout stopt nu het verplaatsen, een gedeeltelijke fout bij verwijderen maakt de herhaalknop niet langer tot een rekwisiet, verweesde punten worden ook bij de tweede poging verwijderd, en een laadfout bij eigen sjablonen wordt gemeld in plaats van verzwegen.",
64
- "fr": "Quatre erreurs sur les chemins d'échec : une erreur d'énumération arrête désormais le déplacement, un échec partiel lors de la suppression ne rend plus le bouton de reprise décoratif, les points orphelins sont supprimés aussi au second essai, et une erreur de chargement des modèles propres est signalée au lieu d'être tue.",
65
- "it": "Quattro errori nei percorsi di errore: un errore sulle enumerazioni ferma ora lo spostamento, un fallimento parziale nella cancellazione non rende più finto il pulsante di ripetizione, i punti orfani vengono eliminati anche al secondo tentativo, e un errore di caricamento dei modelli propri viene segnalato invece che taciuto.",
66
- "es": "Cuatro errores en las rutas de fallo: un error de enumeración detiene ahora el traslado, un fallo parcial al borrar ya no convierte el botón de reintento en un adorno, los puntos huérfanos se borran también en el segundo intento, y un fallo al cargar las plantillas propias se informa en vez de silenciarse.",
67
- "pl": "Cztery błędy na ścieżkach awarii: błąd wyliczenia zatrzymuje teraz przenoszenie, częściowa awaria przy usuwaniu nie czyni już przycisku ponowienia atrapą, osierocone punkty są usuwane także za drugim razem, a błąd wczytywania własnych szablonów jest zgłaszany zamiast przemilczany.",
68
- "uk": "Чотири помилки на шляхах збою: помилка переліку тепер зупиняє переміщення, часткова невдача під час видалення більше не робить кнопку повтору бутафорією, осиротілі точки видаляються й з другої спроби, а збій завантаження власних шаблонів повідомляється, а не замовчується.",
69
- "zh-cn": "修复了四个错误路径上的问题:枚举出错时不再继续移动,删除部分失败不再让重试按钮成为摆设,孤立的数据点在第二次尝试时也会被删除,加载自有模板失败会给出提示而非默默略过。"
70
- },
71
- "0.9.2": {
72
- "en": "* Swapping the source no longer writes to the read source: if no new write target is found for a point with separate sources, a plain string was left in `alias.id` — and to the js-controller that means “read and write on the same id”. With Tasmota the command then went to the status topic instead of the command topic: the device does not switch and the feedback is falsified. Worse, the workbench guessed the write source by name and landed on `stat.POWER`, because that too contains “POWER”. A guessed write target now only counts if it is a different point from the read source, the object form is kept, and the row marks the missing match in red\n* Moving recognises two more targets as a collision: one that exists only as a tree node carrying data points — existing points of the same name were overwritten there — and one that sits below the alias itself: `alias.0.X` to `alias.0.X.Sub` took its own parent node along on the final delete\n* A rejected creation of a send point no longer counts as success. The silent path did not even accept the error and entered the object into its own store anyway; after that the guard no longer bit, and “Create now” wrote `alias.id.write` onto an id that never existed in the database — exactly the error the js-controller remembers for good\n* Channel names are cleaned into ids when “Create all” builds one channel per output. “Licht Bar, oben” produced an id with a space and a comma, “Küche.Decke” an extra level including an intermediate folder. And the js-controller does not reject that, it cleans silently — so the object would have appeared under a different id than the one shown. The display name is left untouched\n* A channel keeps its template link across an update, even when the template was deleted or renamed. `native` used to be replaced wholesale; template, version and device type only came back when a template happened to match. The role one line below had long been rescued, `native` had not\n* Hardened: the cleanup of separated sources no longer switches off a point that is itself part of the alias. Whether it happened depended on the order of `Object.keys` — it was not reachable through the interface, because none of the bundled templates puts a reporting row before the controlling one, but the consequence would have been a deleted data point",
73
- "de": "* Der Quellentausch schreibt nicht mehr auf die Lesequelle: Findet er für einen Punkt mit getrennten Quellen kein neues Schreibziel, blieb bisher eine blosse Zeichenkette in `alias.id` stehen — und die heisst für den js-controller „lesen und schreiben auf dieselbe Kennung“. Bei Tasmota ging der Befehl damit ins Status-Thema statt ins Befehls-Thema: das Gerät schaltet nicht, die Rückmeldung ist verfälscht. Verschärfend riet die Werkbank die Schreibquelle nach dem Namen und landete dabei auf `stat.POWER`, weil dort auch „POWER“ steht. Jetzt zählt ein geratenes Schreibziel nur, wenn es ein anderer Punkt ist als die Lesequelle, die Objektform bleibt erhalten, und die Zeile weist den fehlenden Treffer rot aus\n* Verlegen erkennt zwei Ziele mehr als Kollision: eines, das nur als Baumknoten mit Datenpunkten besteht — dort wurden vorhandene Punkte gleichen Namens überschrieben —, und eines, das unter dem Alias selbst liegt: `alias.0.X` nach `alias.0.X.Sub` nahm beim abschliessenden Löschen den eigenen Elternknoten mit\n* Ein abgelehntes Anlegen eines Sendepunkts gilt nicht mehr als Erfolg. Der stille Weg nahm den Fehler nicht einmal entgegen und trug das Objekt trotzdem in den eigenen Bestand ein; danach griff die Sperre nicht mehr, und „Jetzt anlegen“ schrieb `alias.id.write` auf eine Kennung, die es in der Datenbank nie gab — genau der Fehler, den der js-controller sich dauerhaft merkt\n* Kanalnamen werden zur Kennung gesäubert, wenn „Alle erzeugen“ je Ausgang einen Kanal anlegt. „Licht Bar, oben“ ergab eine Kennung mit Leerzeichen und Komma, „Küche.Decke“ eine zusätzliche Ebene samt Zwischenordner. Und der js-controller lehnt so etwas nicht ab, er säubert still — das Objekt wäre also unter einer anderen Kennung entstanden als angezeigt. Der Anzeigename bleibt davon unberührt\n* Die Vorlagenverknüpfung eines Kanals überlebt ein Aktualisieren, auch wenn die Vorlage gelöscht oder umbenannt wurde. `native` wurde bisher vollständig ersetzt; Vorlage, Version und Gerätetyp kamen nur zurück, wenn gerade eine Vorlage griff. Die Rolle wurde eine Zeile weiter unten längst gerettet, `native` nicht\n* Gehärtet: die Bereinigung getrennter Quellen schaltet keinen Punkt mehr ab, der selbst im Alias steht. Ob das passierte, hing an der Reihenfolge von `Object.keys` — über die Oberfläche war es nicht auslösbar, weil keine der mitgelieferten Vorlagen eine Melderzeile vor die Stellzeile setzt, aber die Folge wäre ein gelöschter Datenpunkt gewesen",
74
- "ru": "Шесть ошибок, приводивших к тихой записи неверных данных: замена источника больше не пишет в источник чтения, перемещение распознаёт вложенные и бесобъектные цели, отклонённое создание точки отправки больше не считается успехом, имена каналов очищаются до идентификаторов, а связь канала с шаблоном переживает обновление.",
75
- "pt": "Seis erros que faziam escrever silenciosamente o valor errado: a troca de origem já não escreve na origem de leitura, mover reconhece destinos aninhados e sem objeto, a criação recusada de um ponto de envio já não conta como êxito, os nomes de canal são limpos para identificadores e a ligação ao modelo sobrevive a uma atualização.",
76
- "nl": "Zes fouten die stilzwijgend het verkeerde wegschreven: het wisselen van bron schrijft niet meer naar de leesbron, verplaatsen herkent geneste en objectloze doelen, een geweigerd aanmaken van een verzendpunt geldt niet meer als succes, kanaalnamen worden tot identificatie opgeschoond en de sjabloonkoppeling overleeft een bijwerking.",
77
- "fr": "Six erreurs qui écrivaient silencieusement la mauvaise chose : le changement de source n'écrit plus sur la source de lecture, le déplacement reconnaît les cibles imbriquées et sans objet, une création refusée de point d'envoi ne compte plus comme réussite, les noms de canaux sont nettoyés en identifiants et le lien au modèle survit à une mise à jour.",
78
- "it": "Sei errori che scrivevano in silenzio la cosa sbagliata: lo scambio della sorgente non scrive più sulla sorgente di lettura, lo spostamento riconosce destinazioni annidate e prive di oggetto, una creazione rifiutata di un punto di invio non conta più come successo, i nomi dei canali vengono ripuliti in identificatori e il legame al modello sopravvive a un aggiornamento.",
79
- "es": "Seis errores que escribían en silencio lo incorrecto: el cambio de origen ya no escribe sobre el origen de lectura, mover reconoce destinos anidados y sin objeto, una creación rechazada de un punto de envío ya no cuenta como éxito, los nombres de canal se limpian a identificadores y el vínculo con la plantilla sobrevive a una actualización.",
80
- "pl": "Sześć błędów, które po cichu zapisywały nie to: zmiana źródła nie zapisuje już do źródła odczytu, przenoszenie rozpoznaje cele zagnieżdżone i bez obiektu, odrzucone utworzenie punktu wysyłki nie liczy się już jako sukces, nazwy kanałów są oczyszczane do identyfikatorów, a powiązanie z szablonem przetrwa aktualizację.",
81
- "uk": "Шість помилок, що тихо записували не те: заміна джерела більше не пише в джерело читання, переміщення розпізнає вкладені та безоб'єктні цілі, відхилене створення точки надсилання більше не вважається успіхом, назви каналів очищаються до ідентифікаторів, а зв'язок із шаблоном переживає оновлення.",
82
- "zh-cn": "修复了六个会悄悄写错的错误:更换来源不再写入读取来源,移动会识别嵌套目标和无对象目标,被拒绝的发送点创建不再算作成功,通道名称会清理为标识符,模板关联也能在更新后保留。"
83
- },
84
- "0.9.1": {
85
- "en": "* A load error on the enumerations can no longer overwrite one: until now a failed `getObjectView` set the store to empty and kept quiet about it. After that the workbench considered every enumeration absent, the catalogue kept offering them because the duplicate filter had nothing to check against, and on writing `setObject` replaced the existing object with a fresh one holding a single member — measured, a room lost three of its four members that way and was given the origin mark that makes it deletable later on. The previous state is now kept, no enumeration is touched, and both the field and the dry run say why room and function are not being written. The alias itself is still created, and a hiccup heals itself after three attempts\n* An enumeration deleted from outside is no longer resurrected: the subscription compared against `objects`, where enumerations never live — on deletion old and new value were therefore both empty and the branch that removes it from the store was never reached. The next alias using that room recreated it with all its old members, including the foreign ones\n* “Create all” now gives every channel its room and its function. The partial drafts carried neither, so not a single channel got an entry — the single route set it, the bulk route did not. A second object for the same enumeration was also discarded, so even then only the first channel would have made it in. And for a channel other than the one shown the assignment counted as empty: if its alias already sat in a room, the bulk route took it **out**. Every channel now keeps what it has, all others get what is set, and members are merged instead of discarded",
86
- "de": "* Ein Ladefehler der Aufzählungen kann keine mehr überschreiben: Bisher setzte ein fehlgeschlagenes `getObjectView` den Vorrat auf leer und verschwieg es. Danach hielt die Werkbank jede Aufzählung für nicht vorhanden, der Katalog bot sie weiter an, weil der Dublettenfilter gegen nichts prüfte, und beim Schreiben ersetzte `setObject` das vorhandene Objekt durch ein frisches mit einem einzigen Mitglied — gemessen verlor ein Raum dabei drei von vier Mitgliedern und bekam obendrein die Herkunftsmarke, die ihn später löschbar macht. Jetzt bleibt der alte Stand stehen, es wird keine Aufzählung angefasst, und Feld wie Trockenlauf sagen, warum Raum und Funktion gerade nicht geschrieben werden. Der Alias selbst entsteht weiterhin, und ein Aussetzer heilt sich nach drei Versuchen selbst\n* Eine von außen gelöschte Aufzählung wird nicht mehr wiederbelebt: Das Abo verglich gegen `objects`, wo Aufzählungen nie liegen — beim Löschen waren alter und neuer Wert deshalb beide leer, und der Zweig, der sie aus dem Vorrat nimmt, wurde nie erreicht. Der nächste Alias mit diesem Raum legte sie samt aller alten Mitglieder wieder an, auch der fremden\n* „Alle erzeugen“ gibt jedem Kanal seinen Raum und seine Funktion. Die Teil-Entwürfe trugen keinen von beiden, also entstand für keinen einzigen Kanal ein Eintrag — der Einzelweg setzte ihn, der Sammelweg nicht. Ein zweites Objekt derselben Aufzählung wurde zudem verworfen, sodass selbst dann nur der erste Kanal hineingekommen wäre. Und für einen fremden Ausgang galt die Zuordnung als leer: Stand sein Alias schon in einem Raum, trug ihn der Sammelweg dort **aus**. Jetzt behält jeder Kanal, was er hat, alle übrigen bekommen das Eingestellte, und die Mitglieder werden vereinigt statt verworfen",
87
- "ru": "Исправлены три ошибки в перечислениях: сбой загрузки больше не может перезаписать существующее перечисление, удалённое извне перечисление больше не воскресает, а «Создать все» теперь задаёт комнату и функцию каждому каналу, не отнимая их у чужих выходов.",
88
- "pt": "Três erros nas enumerações corrigidos: uma falha de carregamento já não pode sobrescrever uma existente, uma enumeração apagada externamente já não ressuscita, e «Criar todos» atribui agora sala e função a cada canal sem as retirar a saídas alheias.",
89
- "nl": "Drie fouten in de opsommingen verholpen: een laadfout kan een bestaande niet meer overschrijven, een van buitenaf verwijderde opsomming herrijst niet meer, en «Alle aanmaken» geeft nu elk kanaal zijn ruimte en functie zonder ze van andere uitgangen af te nemen.",
90
- "fr": "Trois erreurs sur les énumérations corrigées : une erreur de chargement ne peut plus en écraser une existante, une énumération supprimée de l'extérieur ne ressuscite plus, et « Tout créer » attribue désormais pièce et fonction à chaque canal sans les retirer aux autres sorties.",
91
- "it": "Corretti tre errori sulle enumerazioni: un errore di caricamento non può più sovrascriverne una esistente, un'enumerazione eliminata dall'esterno non risorge più e «Crea tutti» assegna ora stanza e funzione a ogni canale senza toglierle alle altre uscite.",
92
- "es": "Tres errores en las enumeraciones corregidos: un fallo de carga ya no puede sobrescribir una existente, una enumeración borrada desde fuera ya no resucita, y «Crear todos» asigna ahora habitación y función a cada canal sin quitárselas a otras salidas.",
93
- "pl": "Naprawiono trzy błędy w wyliczeniach: błąd wczytywania nie może już nadpisać istniejącego, wyliczenie usunięte z zewnątrz już nie zmartwychwstaje, a «Utwórz wszystkie» nadaje teraz każdemu kanałowi pokój i funkcję, nie odbierając ich innym wyjściom.",
94
- "uk": "Виправлено три помилки в переліках: збій завантаження більше не може перезаписати наявний, видалений ззовні перелік більше не воскресає, а «Створити всі» тепер задає кімнату й функцію кожному каналу, не забираючи їх у чужих виходів.",
95
- "zh-cn": "修复了枚举中的三个错误:加载失败不再会覆盖已有枚举,从外部删除的枚举不再复活,「全部创建」现在会为每个通道设置房间和功能,且不会夺走其他输出的归属。"
96
- },
97
32
  "0.9.0": {
98
33
  "en": "Several sources behind one alias are now visible: a chip names their count, every row its origin, and the way back leads from each source to the alias. The fields “reads from” and “writes to” show the full id, the pattern names now come from the admin, and values keep running in the alias view. A complete run on the production system brought four findings: the role list was half empty because the detector delivers its slot expressions as text with slashes — 210 roles instead of 232, and BRIGHTNESS without a role in six patterns; and a point the template lists under a different name now keeps its role and its caption at the source.",
99
34
  "de": "Mehrere Quellen an einem Alias werden sichtbar: ein Chip nennt ihre Zahl, jede Zeile ihre Herkunft, und der Rückweg führt von jeder Quelle zum Alias. Die Felder „liest aus“ und „schreibt auf“ zeigen die volle Kennung, die Musternamen kommen jetzt aus dem Admin, und am Alias laufen die Werte mit. Der komplette Durchlauf am Produktivsystem brachte vier Befunde: Die Rollenliste war halb leer, weil der Detektor seine Platzausdrücke als Text mit Schrägstrichen liefert — 210 statt 232 Rollen, und BRIGHTNESS ohne Rolle in sechs Mustern; und ein Punkt, den die Vorlage unter anderem Namen führt, behält an der Quelle jetzt seine Rolle und seine Beschriftung.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.alias-workbench",
3
- "version": "0.9.7",
3
+ "version": "0.9.8",
4
4
  "description": "Creates aliases the comfortable way — devices that vis, Alexa and the device adapter understand. Templates do the work: shipped ones for HomeMatic and Tasmota, your own for everything else. Live values while you build, dry run before anything is written.",
5
5
  "author": {
6
6
  "name": "Ricardo Hipp",