iobroker.alias-workbench 0.9.11 → 0.9.12

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.
@@ -52,21 +52,6 @@ export function berechnePlaetze(e, haupt) {
52
52
  ? steuerKanaele(S.current) : [];
53
53
  }
54
54
 
55
- /* Welche Punkte aus den gemeinsamen Kanaelen haben hier, auf der
56
- Geraeteebene, einen Platz gefunden? Diese Liste bekommen die
57
- Kanal-Entwuerfe mit — dort erkennt der Detektor sie nicht. */
58
- if (e.kanalGeraete && e.kanalGeraete.length > 1) {
59
- var eigenerKanal = {};
60
- e.kanalGeraete.forEach(function (k) { eigenerKanal[k.id] = 1; });
61
- e.gemeinsamMitPlatz = {};
62
- e.states.forEach(function (st) {
63
- if (!st.srcR || !platzVon[st.n]) { return; }
64
- var elt = st.srcR.slice(0, st.srcR.lastIndexOf('.'));
65
- if (elt.indexOf(S.current + '.') === 0 && !eigenerKanal[elt]) {
66
- e.gemeinsamMitPlatz[st.srcR] = platzVon[st.n];
67
- }
68
- });
69
- }
70
55
 
71
56
  /* Vorbelegung eines Rohentwurfs: angehakt ist, was im erkannten Muster
72
57
  einen Platz findet.
@@ -265,6 +250,11 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
265
250
  (Ricardo, 26.08.2026). „Freie Plaetze vorschlagen" bleibt oben - er
266
251
  gehoert zur Erkennung, nicht zur Auswahl. */
267
252
  var chipzeile = el('div', 'chipzeile');
253
+ /* „Vorlage" nur, wo eine in Kraft ist. Der Knopf holt die Haken der
254
+ Vorlage zurueck - ohne Vorlage holt er nichts und behauptet doch,
255
+ es gaebe etwas zu holen (Ricardo, 17.09.2026, zusammen mit der
256
+ Marke „weicht von der Vorlage ab"). */
257
+ var mitVorlage = !!(e.vorschlag && e.vorlage);
268
258
  (amAlias ? [] :
269
259
  [[tr('list.tpl'), function () {
270
260
  /* Die Haken, die die Vorlage vorgibt. Gibt es keinen Vorlagenwert
@@ -293,7 +283,9 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
293
283
  });
294
284
  }
295
285
  e.states.forEach(function (s) { s.on = !!drin[s.n]; });
296
- }, tr('list.onlyPatternHint')]]).forEach(function (pr) {
286
+ }, tr('list.onlyPatternHint')]])
287
+ .filter(function (pr) { return mitVorlage || pr[0] !== tr('list.tpl'); })
288
+ .forEach(function (pr) {
297
289
  var b = el('button', null, pr[0]);
298
290
  if (pr[2]) { b.title = pr[2]; }
299
291
  b.addEventListener('click', function () {
@@ -372,6 +364,31 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
372
364
  gerechnet: die Zeilenschleife braucht es, die Legende darunter
373
365
  ebenso, und beide sollen dieselbe Antwort geben. */
374
366
  var kipptAnTyp = typKonflikte(e.states, e.want).filter(function (x) { return x.pflicht; })[0] || null;
367
+ /* Gekippt ist es aber nur, wenn der genannte Platz auch wirklich leer
368
+ geblieben ist. Sonst hat eine ANDERE Zeile ihn besetzt, das Muster
369
+ greift, und der Konflikt betrifft nur diese eine Zeile.
370
+
371
+ `typKonflikte` fragt je Zeile „deine Rolle taugt fuer einen Platz,
372
+ dein Typ aber nicht" — es sieht nicht nach, wer den Platz am Ende
373
+ bekommen hat. Gemessen am 17.09.2026 an `hm-rpc.2.NEQ1660737` nach
374
+ „keine Vorlage": `0_AES_KEY` traegt (von hm-rpc selbst) die Rolle
375
+ `state` und den Typ `number`. `state` ist beim Licht-Platz SET
376
+ zugelassen, `number` nicht — also meldete die Legende „Das
377
+ Licht-Muster greift gerade nicht: SET verlangt boolean, eingestellt
378
+ ist number. Deshalb hat keine Zeile einen Platz." Dabei ist die
379
+ SET-Zeile `switch.light`/`boolean` und einwandfrei, das Muster greift
380
+ (SET, WORKING, UNREACH, LOWBAT, RSSI besetzt), und fuenf Zeilen haben
381
+ sehr wohl einen Platz. Die Meldung nannte den PLATZ und nie die
382
+ Zeile, um die es ging (Ricardo).
383
+
384
+ Fuer I34 aendert das nichts: dort ist SET selbst der Konflikt
385
+ (`mixed` statt `boolean`), der Platz bleibt leer, und die Legende
386
+ benennt weiter die Ursache. */
387
+ if (kipptAnTyp && Object.keys(platzVon).some(function (n) {
388
+ return platzVon[n] === kipptAnTyp.platz;
389
+ })) {
390
+ kipptAnTyp = null;
391
+ }
375
392
 
376
393
  /* --- Zustandsliste --- */
377
394
  e.states.forEach(function (s, i) {
@@ -425,7 +442,7 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
425
442
  var cb = document.createElement('input');
426
443
  cb.type = 'checkbox';
427
444
  cb.checked = s.on;
428
- cb.setAttribute('aria-label', s.n + ' anlegen');
445
+ cb.setAttribute('aria-label', tr('list.createAria', s.n));
429
446
  cb.addEventListener('click', function (ev) { ev.stopPropagation(); });
430
447
  cb.addEventListener('change', function () {
431
448
  s.on = cb.checked; entwurfAngefasst(); zeichneErgebnis();
@@ -22,7 +22,7 @@
22
22
  "check.duplicateSome": "zeigen auf dasselbe: {0}",
23
23
  "check.feedback": "Rückmeldung kommt sofort",
24
24
  "check.feedbackFast": "sofort, SetOption59 ist an",
25
- "check.feedbackFine": "alle in Ordnung",
25
+ "check.feedbackNone": "betrifft keine Zeile — alle lesen aus stat/…",
26
26
  "check.feedbackSlow": "verzögert: {0}",
27
27
  "check.feedbackUnknown": "ungeprüft: {0}",
28
28
  "check.formulaYields": "Leseformel liefert etwas",
@@ -39,7 +39,7 @@
39
39
  "check.sourceHasValue": "Quelle hat einen Wert",
40
40
  "check.targetCan": "Ziel kann, was verlangt wird",
41
41
  "check.targetCanFine": "alle in Ordnung",
42
- "check.targetNoRead": "{0}: die Lesequelle meldet nichts",
42
+ "check.targetNoRead": "{0}: die Lesequelle ändert sich nie",
43
43
  "check.targetNoWrite": "{0}: das Ziel ist nicht beschreibbar",
44
44
  "check.targetVoidFormula": "{0}: Schreibformel läuft ins Leere, das Ziel ist {1}",
45
45
  "check.title": "Prüfungen — laufen immer mit, fassen nichts an",
@@ -92,7 +92,7 @@
92
92
  "detail.rawValue": "Rohwert",
93
93
  "detail.readsFrom": "liest aus",
94
94
  "detail.removePoint": "Diesen Punkt entfernen",
95
- "detail.reportsNothing": "meldet nichts",
95
+ "detail.reportsNothing": "ändert sich nie",
96
96
  "detail.role": "Rolle",
97
97
  "detail.sameAsRead": "— dieselbe wie lesen —",
98
98
  "detail.separateHint": "getrennt — der Schalter zeigt den Zustand, nicht den Befehl",
@@ -100,7 +100,7 @@
100
100
  "detail.stateSays": "Zustand sagt {0}",
101
101
  "detail.takeFromAlias": "Diesen einen Wert aus dem gespeicherten Alias zurückholen",
102
102
  "detail.takeOne": "Diesen einen Wert aus der Vorlage übernehmen",
103
- "detail.targetNoRead": "Die Lesequelle trägt read: false — sie meldet nie einen Wert. Bei einem Tastendruck ist das richtig so: er hat keinen Zustand. Dann gehört hier gar keine Lesequelle hin.",
103
+ "detail.targetNoRead": "Die Lesequelle trägt read: false — dort kommt nie eine Aktualisierung an. Ein Wert kann trotzdem darin stehen; es ist der, den zuletzt jemand hineingeschrieben hat, oft der Anfangswert des Adapters. Der Alias zeigt dann für immer diesen einen Wert. Bei einem Tastendruck ist das richtig so: er hat keinen Zustand. Dann gehört hier gar keine Lesequelle hin.",
104
104
  "detail.targetNoWrite": "Der Zielpunkt trägt write: false — sein Adapter reicht nichts ans Gerät weiter. ioBroker legt den Wert trotzdem ab, passieren wird aber nichts.",
105
105
  "detail.targetTypeHint": "Der Typ des Zielpunktes ist {0}. Er entscheidet, was von der Schreibformel ankommt: mixed und string nehmen Text, boolean und number rechnen ihn zurück.",
106
106
  "detail.targetTypeVoid": "Das Ziel ist {0} und nimmt keinen Text. Die Schreibformel liefert aber Text — der js-controller rechnet ihn beim Schreiben wieder auf {0} zurück, die Formel bleibt also wirkungslos. Geschaltet wird trotzdem.",
@@ -276,7 +276,8 @@
276
276
  "mq.instantChecking": "frage nach",
277
277
  "mq.instantEnable": "Einschalten",
278
278
  "mq.instantEnabling": "schalte ein",
279
- "mq.instantHintOff": "Ohne SetOption59 zeigt ein Alias, der aus tele/STATE liest, nach dem Schalten minutenlang den alten Wert. Einschalten ist eine dauerhafte Einstellung am Gerät — sie schaltet nichts und ändert nur, wie oft das Gerät meldet.",
279
+ "mq.instantHintOff": "Ohne SetOption59 meldet das Gerät nur im Telemetrietakt. {0} liest aus tele/… und zeigt nach dem Schalten so lange den alten Wert. Einschalten ist eine dauerhafte Einstellung am Gerät — sie schaltet nichts und ändert nur, wie oft gemeldet wird.",
280
+ "mq.instantHintOffTakt": "Ohne SetOption59 meldet das Gerät nur alle {1} Sekunden. {0} liest aus tele/… und zeigt nach dem Schalten bis dahin den alten Wert. Einschalten ist eine dauerhafte Einstellung am Gerät — sie schaltet nichts und ändert nur, wie oft gemeldet wird.",
280
281
  "mq.instantHintOn": "SetOption59 ist gesetzt: das Gerät meldet jede Änderung sofort, nicht erst mit der nächsten Telemetrie. Gemessen wurden drei Sekunden.",
281
282
  "mq.instantHintUnknown": "Das Gerät wurde danach noch nicht gefragt. „Nachfragen\" schickt eine leere Abfrage an SetOption59 — sie ändert nichts.",
282
283
  "mq.instantOff": "aus",
@@ -328,7 +329,7 @@
328
329
  "pattern.usualOnly": "nur die üblichen",
329
330
  "pattern.viaRole": "Rolle {0}",
330
331
  "result.allAnyway": "Trotzdem alle ",
331
- "result.channelsHint": "Dieses Gerät hat {0} Kanäle, die für sich ein Gerät ergeben. Unten kannst du wählen: ein Alias für alles, oder einer je Kanal.",
332
+ "result.channelsHint": "Dieses Gerät hat {0} Kanäle. Unten kannst du wählen: alles flach in einem Alias, oder die Struktur der Quelle übernehmen — ein Ordner für das Gerät, darunter je Kanal einer.",
332
333
  "result.extraSwitches": "Mit dabei: {0} Punkte aus weiteren Kanälen, für die das {1}-Muster keinen Platz hat. Sie werden angelegt, gelten aber nicht als Schalter oder Rückmeldung des Geräts. Für getrennte Bedienung unten „je Kanal ein Gerät\" wählen.",
333
334
  "result.header": "Was der type-detector daraus macht",
334
335
  "result.newlyCreated": "wird neu angelegt",
@@ -428,10 +429,10 @@
428
429
  "tpl.showProposal": "Vorschlag zeigen",
429
430
  "tpl.showProposalHelp": "Zurück zu dem, was die Vorlage für dieses Gerät vorschlägt.",
430
431
  "tpl.skippedEmpty": "„{0}“ hätte die höhere Punktzahl, baut an diesem Gerät aber keine einzige Zeile — übergangen",
431
- "tpl.skippedHead": "Weggelassen, weil die Quelle fehlt: {0}",
432
+ "tpl.skippedHead": "{0} weggelassen, weil die Quelle fehlt",
433
+ "tpl.skippedChip": "{0} ohne Quelle",
432
434
  "tpl.skippedNowhere": "{0}: weder in {1}",
433
435
  "tpl.skippedSource": "{0}: {1} fehlt",
434
- "tpl.switch": "— Vorlage wechseln —",
435
436
  "tpl.whyNone": "Warum keine Vorlage greift",
436
437
  "tpl.whyThis": "Warum diese Vorlage",
437
438
  "tpl.withoutField": "{0} ohne {1}",
@@ -610,7 +611,7 @@
610
611
  "write.createAll": "Alle {0} erzeugen …",
611
612
  "write.createAsOne": "als ein Gerät erzeugen …",
612
613
  "write.createNamed": "{0} erzeugen …",
613
- "write.createPerChannel": "je Kanal ein Gerät, {0} Stück …",
614
+ "write.createPerChannel": "Unterordner je Kanal, {0} Stück …",
614
615
  "write.createSendPoints": "Die {0} fehlenden Sendepunkte anlegen",
615
616
  "write.deselected": "abgewählt",
616
617
  "write.diffNew": "danach",
@@ -654,5 +655,7 @@
654
655
  "write.willKeep": "bleiben stehen: {0}",
655
656
  "write.willRemove": "entfernt: {0}",
656
657
  "write.writeSourceMissing": "{0}: den Sendepunkt {1} gibt es noch nicht",
657
- "write.writing": "schreibe …"
658
+ "write.writing": "schreibe …",
659
+ "detail.typeNumber": "Zahl",
660
+ "list.createAria": "{0} anlegen"
658
661
  }
@@ -22,7 +22,7 @@
22
22
  "check.duplicateSome": "point at the same thing: {0}",
23
23
  "check.feedback": "feedback arrives at once",
24
24
  "check.feedbackFast": "at once, SetOption59 is on",
25
- "check.feedbackFine": "all fine",
25
+ "check.feedbackNone": "no row affected — all read from stat/…",
26
26
  "check.feedbackSlow": "delayed: {0}",
27
27
  "check.feedbackUnknown": "unchecked: {0}",
28
28
  "check.formulaYields": "read formula yields something",
@@ -39,7 +39,7 @@
39
39
  "check.sourceHasValue": "source has a value",
40
40
  "check.targetCan": "target can do what is asked",
41
41
  "check.targetCanFine": "all fine",
42
- "check.targetNoRead": "{0}: the read source reports nothing",
42
+ "check.targetNoRead": "{0}: the read source never changes",
43
43
  "check.targetNoWrite": "{0}: the target is not writable",
44
44
  "check.targetVoidFormula": "{0}: write formula runs into nothing, the target is {1}",
45
45
  "check.title": "Checks — always running, never touching anything",
@@ -92,7 +92,7 @@
92
92
  "detail.rawValue": "Raw value",
93
93
  "detail.readsFrom": "reads from",
94
94
  "detail.removePoint": "Remove this point",
95
- "detail.reportsNothing": "reports nothing",
95
+ "detail.reportsNothing": "never changes",
96
96
  "detail.role": "Role",
97
97
  "detail.sameAsRead": "— same as read —",
98
98
  "detail.separateHint": "separate — the switch shows the state, not the command",
@@ -100,7 +100,7 @@
100
100
  "detail.stateSays": "state says {0}",
101
101
  "detail.takeFromAlias": "Take this one value back from the stored alias",
102
102
  "detail.takeOne": "Take this one value from the template",
103
- "detail.targetNoRead": "The read source carries read: false — it never reports a value. For a button press that is correct: it has no state. Then no read source belongs here at all.",
103
+ "detail.targetNoRead": "The read source carries read: false — no update ever arrives there. A value may still sit in it: the one somebody wrote last, often the adapter's initial value. The alias will then show that one value forever. For a button press that is correct: it has no state. Then no read source belongs here at all.",
104
104
  "detail.targetNoWrite": "The target point carries write: false — its adapter passes nothing on to the device. ioBroker stores the value anyway, but nothing will happen.",
105
105
  "detail.targetTypeHint": "The target point is of type {0}. It decides what survives of the write formula: mixed and string take text, boolean and number convert it back.",
106
106
  "detail.targetTypeVoid": "The target is {0} and takes no text. The write formula does produce text — the js-controller converts it back to {0} on write, so the formula has no effect. Switching still works.",
@@ -276,7 +276,8 @@
276
276
  "mq.instantChecking": "asking",
277
277
  "mq.instantEnable": "Enable",
278
278
  "mq.instantEnabling": "enabling",
279
- "mq.instantHintOff": "Without SetOption59 an alias reading from tele/STATE shows the old value for minutes after switching. Enabling is a persistent setting on the device — it switches nothing and only changes how often the device reports.",
279
+ "mq.instantHintOff": "Without SetOption59 the device only reports on its telemetry cycle. {0} reads from tele/… and keeps showing the old value after switching until then. Enabling it is a permanent device setting — it switches nothing and only changes how often the device reports.",
280
+ "mq.instantHintOffTakt": "Without SetOption59 the device only reports every {1} seconds. {0} reads from tele/… and keeps showing the old value after switching until then. Enabling it is a permanent device setting — it switches nothing and only changes how often the device reports.",
280
281
  "mq.instantHintOn": "SetOption59 is set: the device reports every change at once, not only with the next telemetry. Measured at three seconds.",
281
282
  "mq.instantHintUnknown": "The device has not been asked yet. \"Ask\" sends an empty query to SetOption59 — it changes nothing.",
282
283
  "mq.instantOff": "off",
@@ -328,7 +329,7 @@
328
329
  "pattern.usualOnly": "the usual ones only",
329
330
  "pattern.viaRole": "role {0}",
330
331
  "result.allAnyway": "All anyway ",
331
- "result.channelsHint": "This device has {0} channels that make sense on their own. Choose below: one alias for all of it, or one per channel.",
332
+ "result.channelsHint": "This device has {0} channels. Choose below: everything flat in one alias, or mirror the structure of the source — a folder for the device, one channel each below it.",
332
333
  "result.extraSwitches": "Included: {0} points from other channels that the {1} pattern has no slot for. They are created, but do not count as the device’s switch or feedback. For separate control, use \"one device per channel\" below.",
333
334
  "result.header": "What the type-detector makes of it",
334
335
  "result.newlyCreated": "will be created",
@@ -428,10 +429,10 @@
428
429
  "tpl.showProposal": "show proposal",
429
430
  "tpl.showProposalHelp": "Back to what the template proposes for this device.",
430
431
  "tpl.skippedEmpty": "\"{0}\" would score higher but builds not a single row on this device — skipped",
431
- "tpl.skippedHead": "Left out because the source is missing: {0}",
432
+ "tpl.skippedHead": "{0} left out because the source is missing",
433
+ "tpl.skippedChip": "{0} without source",
432
434
  "tpl.skippedNowhere": "{0}: neither in {1}",
433
435
  "tpl.skippedSource": "{0}: {1} missing",
434
- "tpl.switch": "— switch template —",
435
436
  "tpl.whyNone": "Why no template applies",
436
437
  "tpl.whyThis": "Why this template",
437
438
  "tpl.withoutField": "{0} without {1}",
@@ -610,7 +611,7 @@
610
611
  "write.createAll": "Create all {0} …",
611
612
  "write.createAsOne": "create as one device …",
612
613
  "write.createNamed": "Create {0} …",
613
- "write.createPerChannel": "one device per channel, {0} of them …",
614
+ "write.createPerChannel": "one sub-folder per channel, {0} of them …",
614
615
  "write.createSendPoints": "Create the {0} missing send datapoints",
615
616
  "write.deselected": "deselected",
616
617
  "write.diffNew": "after",
@@ -654,5 +655,7 @@
654
655
  "write.willKeep": "kept: {0}",
655
656
  "write.willRemove": "removed: {0}",
656
657
  "write.writeSourceMissing": "{0}: the send datapoint {1} does not exist yet",
657
- "write.writing": "writing …"
658
+ "write.writing": "writing …",
659
+ "detail.typeNumber": "number",
660
+ "list.createAria": "create {0}"
658
661
  }
package/admin/tab.html CHANGED
@@ -1,8 +1,8 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <title>Alias-Werkbank</title>
5
+ <title>Alias Workbench</title>
6
6
  <script src="../../socket.io/socket.io.js"></script>
7
7
  <script src="./detector.js"></script>
8
8
  <script>
@@ -46,43 +46,43 @@
46
46
  <body>
47
47
 
48
48
  <header class="top">
49
- <h1>Alias-Werkbank</h1>
49
+ <h1>Alias Workbench</h1>
50
50
  <span class="meta" id="meta"></span>
51
51
  <span class="sp"></span>
52
- <span class="conn off" id="conn">verbinde …</span>
52
+ <span class="conn off" id="conn">connecting …</span>
53
53
  </header>
54
54
 
55
55
  <div class="split">
56
56
  <div class="pickpane">
57
57
  <div class="panehead modusleiste">
58
58
  <span class="umschalter breit">
59
- <button id="m-quellen" class="an">Alias anlegen</button><button id="m-aliase">Alias bearbeiten</button><button id="m-vorlagen">Vorlagen</button>
59
+ <button id="m-quellen" class="an">Create alias</button><button id="m-aliase">Edit alias</button><button id="m-vorlagen">Templates</button>
60
60
  </span>
61
61
  </div>
62
62
  <div class="panehead">
63
- <input class="search" id="q" type="search" placeholder="filtern …" aria-label="Objekte filtern">
63
+ <input class="search" id="q" type="search" placeholder="filter …" aria-label="Filter objects">
64
64
  <button class="klapp" id="btn-auf" type="button"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2m0 12H4V8h16z"/></svg></button>
65
65
  <button class="klapp" id="btn-zu" type="button"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8z"/></svg></button>
66
- <button class="btn schmal" id="btn-einlesen" hidden>Einlesen &hellip;</button>
66
+ <button class="btn schmal" id="btn-einlesen" hidden>Import &hellip;</button>
67
67
  <input type="file" id="datei-einlesen" accept=".json,application/json" hidden>
68
68
  </div>
69
- <div class="scroll"><div class="tree" id="tree"><div class="empty">lade Objekte …</div></div></div>
69
+ <div class="scroll"><div class="tree" id="tree"><div class="empty">loading objects …</div></div></div>
70
70
  </div>
71
71
 
72
72
  <div class="respane">
73
- <div class="panehead"><span class="lbl">Was der type-detector daraus macht</span></div>
73
+ <div class="panehead"><span class="lbl">What the type-detector makes of it</span></div>
74
74
  <div class="resscroll"><div class="resinner" id="res">
75
75
  <div class="empty"></div>
76
76
  </div></div>
77
77
  <div class="footbar">
78
- <button class="btn primary" id="btn-dry" disabled>Alias erzeugen &hellip;</button>
79
- <button class="btn primary" id="btn-dry-alle" hidden>Alle erzeugen &hellip;</button>
80
- <button class="btn" id="btn-tpl" disabled>Als Vorlage speichern &hellip;</button>
78
+ <button class="btn primary" id="btn-dry" disabled>Create alias &hellip;</button>
79
+ <button class="btn primary" id="btn-dry-alle" hidden>Create all &hellip;</button>
80
+ <button class="btn" id="btn-tpl" disabled>Save as template &hellip;</button>
81
81
  <span class="sperrgrund" id="sperrgrund" hidden></span>
82
- <button class="btn" id="btn-move" hidden>Verlegen &hellip;</button>
83
- <button class="btn" id="btn-swap" hidden>Quelle tauschen &hellip;</button>
84
- <button class="btn" id="btn-del" hidden>Alias entfernen &hellip;</button>
85
- <button class="btn" id="btn-checks">Pr&uuml;fungen <span id="checkchip"></span></button>
82
+ <button class="btn" id="btn-move" hidden>Move &hellip;</button>
83
+ <button class="btn" id="btn-swap" hidden>Swap source &hellip;</button>
84
+ <button class="btn" id="btn-del" hidden>Remove alias &hellip;</button>
85
+ <button class="btn" id="btn-checks">Checks <span id="checkchip"></span></button>
86
86
  <span class="sp" style="flex:1"></span>
87
87
  </div>
88
88
  </div>
@@ -90,90 +90,90 @@
90
90
 
91
91
  <script type="module" src="./js/start.js"></script>
92
92
  <dialog id="dlg-dry" style="max-width:760px;">
93
- <h3 id="dry-titel">Alias erzeugen &mdash; das w&uuml;rde entstehen</h3>
93
+ <h3 id="dry-titel">Create alias &mdash; this is what would appear</h3>
94
94
  <div class="dbody" id="dry-body"></div>
95
95
  <div class="dfoot">
96
- <button class="btn" data-close>Schlie&szlig;en</button>
97
- <button class="btn primary" id="btn-dry-write">Jetzt anlegen</button>
96
+ <button class="btn" data-close>Close</button>
97
+ <button class="btn primary" id="btn-dry-write">Create now</button>
98
98
  </div>
99
99
  </dialog>
100
100
 
101
101
  <dialog id="dlg-del" style="max-width:640px;">
102
- <h3 id="del-titel">Alias entfernen</h3>
102
+ <h3 id="del-titel">Remove alias</h3>
103
103
  <div class="dbody" id="del-body"></div>
104
104
  <div class="dfoot">
105
- <button class="btn" data-close>Schlie&szlig;en</button>
106
- <button class="btn primary" id="btn-del-go">Endg&uuml;ltig entfernen</button>
105
+ <button class="btn" data-close>Close</button>
106
+ <button class="btn primary" id="btn-del-go">Remove for good</button>
107
107
  </div>
108
108
  </dialog>
109
109
 
110
110
  <dialog id="dlg-move" style="max-width:760px;">
111
- <h3 id="move-titel">Alias verlegen</h3>
111
+ <h3 id="move-titel">Move alias</h3>
112
112
  <div class="dbody" id="move-body"></div>
113
113
  <div class="dfoot">
114
- <button class="btn" data-close>Schlie&szlig;en</button>
115
- <button class="btn primary" id="btn-move-go">Jetzt verlegen</button>
114
+ <button class="btn" data-close>Close</button>
115
+ <button class="btn primary" id="btn-move-go">Move now</button>
116
116
  </div>
117
117
  </dialog>
118
118
 
119
119
  <dialog id="dlg-tpl" style="max-width:820px;">
120
- <h3 id="tpl-titel">Als Vorlage speichern</h3>
120
+ <h3 id="tpl-titel">Save as template</h3>
121
121
  <div class="dbody" id="tpl-body"></div>
122
122
  <div class="dfoot">
123
- <button class="btn" data-close>Schlie&szlig;en</button>
124
- <button class="btn primary" id="btn-tpl-save">Speichern</button>
123
+ <button class="btn" data-close>Close</button>
124
+ <button class="btn primary" id="btn-tpl-save">Save</button>
125
125
  </div>
126
126
  </dialog>
127
127
 
128
128
  <dialog id="dlg-mqtt" style="max-width:820px;">
129
- <h3 id="mqtt-titel">Sendepunkte anlegen</h3>
129
+ <h3 id="mqtt-titel">Create send points</h3>
130
130
  <div class="dbody" id="mqtt-body"></div>
131
131
  <div class="dfoot">
132
- <button class="btn" data-close>Schlie&szlig;en</button>
133
- <button class="btn primary" id="btn-mqtt-write">Anlegen</button>
132
+ <button class="btn" data-close>Close</button>
133
+ <button class="btn primary" id="btn-mqtt-write">Create</button>
134
134
  </div>
135
135
  </dialog>
136
136
 
137
137
  <dialog id="dlg-info" style="max-width:600px;">
138
- <h3 id="info-titel">Geh&ouml;rt nicht zum Muster</h3>
138
+ <h3 id="info-titel">Not part of the pattern</h3>
139
139
  <div class="dbody" id="info-body"></div>
140
140
  <div class="dfoot">
141
- <button class="btn primary" data-close>Schlie&szlig;en</button>
141
+ <button class="btn primary" data-close>Close</button>
142
142
  </div>
143
143
  </dialog>
144
144
 
145
145
  <dialog id="dlg-guess" style="max-width:560px;">
146
- <h3 id="guess-titel">Freie Pl&auml;tze trotz Vorlage?</h3>
146
+ <h3 id="guess-titel">Suggest free slots despite a template?</h3>
147
147
  <div class="dbody" id="guess-body"></div>
148
148
  <div class="dfoot">
149
- <button class="btn" data-close>Schlie&szlig;en</button>
150
- <button class="btn primary" id="btn-guess-go">Trotzdem vorschlagen</button>
149
+ <button class="btn" data-close>Close</button>
150
+ <button class="btn primary" id="btn-guess-go">Suggest anyway</button>
151
151
  </div>
152
152
  </dialog>
153
153
 
154
154
  <dialog id="dlg-swap" style="max-width:880px;width:calc(100% - 32px);">
155
- <h3 id="swap-titel">Quelle tauschen</h3>
155
+ <h3 id="swap-titel">Swap source</h3>
156
156
  <div class="dbody" id="swap-body"></div>
157
157
  <div class="dfoot">
158
- <button class="btn" data-close>Schlie&szlig;en</button>
159
- <button class="btn primary" id="btn-swap-go">Jetzt tauschen</button>
158
+ <button class="btn" data-close>Close</button>
159
+ <button class="btn primary" id="btn-swap-go">Swap now</button>
160
160
  </div>
161
161
  </dialog>
162
162
 
163
163
  <dialog id="dlg-checks">
164
- <h3>Pr&uuml;fungen &mdash; laufen immer mit, fassen nichts an</h3>
164
+ <h3>Checks &mdash; always running, never touching anything</h3>
165
165
  <div class="dbody"><ul class="checks" id="checklist"></ul></div>
166
- <div class="dfoot"><button class="btn" data-close>Schlie&szlig;en</button></div>
166
+ <div class="dfoot"><button class="btn" data-close>Close</button></div>
167
167
  </dialog>
168
168
 
169
169
  <!-- Wer im Baum weiterklickt, verlor bis zum 06.09.2026 seine Aenderungen
170
170
  ohne ein Wort (Ricardo). Der Text wird zur Laufzeit gesetzt. -->
171
171
  <dialog id="dlg-leave">
172
- <h3 id="leave-titel">Ungespeicherte &Auml;nderungen</h3>
172
+ <h3 id="leave-titel">Unsaved changes</h3>
173
173
  <div class="dbody"><p id="leave-body"></p></div>
174
174
  <div class="dfoot">
175
- <button class="btn" id="btn-leave-stay">Hierbleiben</button>
176
- <button class="btn primary" id="btn-leave-go">Verwerfen und wechseln</button>
175
+ <button class="btn" id="btn-leave-stay">Stay here</button>
176
+ <button class="btn primary" id="btn-leave-go">Discard and switch</button>
177
177
  </div>
178
178
  </dialog>
179
179
 
@@ -32,6 +32,7 @@
32
32
  {
33
33
  "name": "CONSUMPTION",
34
34
  "rolle": "value.power.consumption",
35
+ "_rolle": "value.power.consumption is struck through in the ioBroker state roles list, but @iobroker/type-detector 6.0.x recognises CONSUMPTION only with exactly this role (typePatterns.js, pattern 'consumption', defaultRole 'value.power.consumption'). With value.energy.consumed the point would drop out of the detected device, and vis, Alexa and the device manager would no longer show the consumption. Kept on purpose until the type-detector moves to the new role.",
35
36
  "typ": "number",
36
37
  "einheit": "kWh",
37
38
  "lesen": "tele.SENSOR",
@@ -54,6 +54,7 @@
54
54
  {
55
55
  "name": "CONSUMPTION",
56
56
  "rolle": "value.power.consumption",
57
+ "_rolle": "value.power.consumption is struck through in the ioBroker state roles list, but @iobroker/type-detector 6.0.x recognises CONSUMPTION only with exactly this role (typePatterns.js, pattern 'consumption', defaultRole 'value.power.consumption'). With value.energy.consumed the point would drop out of the detected device, and vis, Alexa and the device manager would no longer show the consumption. Kept on purpose until the type-detector moves to the new role.",
57
58
  "typ": "number",
58
59
  "einheit": "kWh",
59
60
  "lesen": "tele.SENSOR",
@@ -62,6 +62,7 @@
62
62
  {
63
63
  "name": "CONSUMPTION",
64
64
  "rolle": "value.power.consumption",
65
+ "_rolle": "value.power.consumption is struck through in the ioBroker state roles list, but @iobroker/type-detector 6.0.x recognises CONSUMPTION only with exactly this role (typePatterns.js, pattern 'consumption', defaultRole 'value.power.consumption'). With value.energy.consumed the point would drop out of the detected device, and vis, Alexa and the device manager would no longer show the consumption. Kept on purpose until the type-detector moves to the new role.",
65
66
  "typ": "number",
66
67
  "einheit": "kWh",
67
68
  "lesen": "tele.SENSOR",
@@ -55,6 +55,7 @@
55
55
  {
56
56
  "name": "CONSUMPTION",
57
57
  "rolle": "value.power.consumption",
58
+ "_rolle": "value.power.consumption is struck through in the ioBroker state roles list, but @iobroker/type-detector 6.0.x recognises CONSUMPTION only with exactly this role (typePatterns.js, pattern 'consumption', defaultRole 'value.power.consumption'). With value.energy.consumed the point would drop out of the detected device, and vis, Alexa and the device manager would no longer show the consumption. Kept on purpose until the type-detector moves to the new role.",
58
59
  "typ": "number",
59
60
  "einheit": "kWh",
60
61
  "lesen": "tele.SENSOR",