iobroker.alias-workbench 0.9.11 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -4
- package/admin/css/werkbank.css +50 -6
- package/admin/js/aufzaehlungen.js +24 -8
- package/admin/js/baum.js +13 -2
- package/admin/js/detail.js +310 -89
- package/admin/js/entwurf.js +443 -197
- package/admin/js/enums.js +9 -2
- package/admin/js/ergebnis.js +148 -28
- package/admin/js/erkennung.js +52 -0
- package/admin/js/mqtt.js +175 -65
- package/admin/js/musterwahl.js +103 -26
- package/admin/js/objekte.js +16 -0
- package/admin/js/pruefungen.js +10 -8
- package/admin/js/quellentausch.js +59 -12
- package/admin/js/schreiben.js +76 -43
- package/admin/js/vorlagen.js +28 -5
- package/admin/js/vorlagenblatt.js +49 -7
- package/admin/js/vorschlagen.js +60 -7
- package/admin/js/werte.js +99 -21
- package/admin/js/zielleiste.js +8 -2
- package/admin/js/zuordnung.js +79 -28
- package/admin/js/zustand.js +5 -1
- package/admin/js/zustandsliste.js +219 -42
- package/admin/sprachen/de.json +45 -18
- package/admin/sprachen/en.json +45 -18
- package/admin/tab.html +44 -44
- package/admin/vorlagen/hm-rollladen.json +3 -2
- package/admin/vorlagen/messpunkt.json +7 -2
- package/admin/vorlagen/tasmota-lampe.json +7 -2
- package/admin/vorlagen/tasmota-mehrfach.json +7 -2
- package/admin/vorlagen/tasmota-rgb.json +6 -2
- package/admin/vorlagen/tasmota-steckdose.json +7 -2
- package/io-package.json +38 -29
- package/package.json +1 -1
package/admin/js/enums.js
CHANGED
|
@@ -32,6 +32,11 @@ export function enumsUnbekannt() { return unbekannt; }
|
|
|
32
32
|
var versuch = 0;
|
|
33
33
|
var wiederTimer = null;
|
|
34
34
|
|
|
35
|
+
/* Wer wissen will, wann ein Nachversuch geklappt hat - die Felder fuer
|
|
36
|
+
Raum und Funktion zeichnen sich dann neu (P8). */
|
|
37
|
+
var geladenHoerer = [];
|
|
38
|
+
export function beiEnumsGeladen(fn) { geladenHoerer.push(fn); }
|
|
39
|
+
|
|
35
40
|
export function ladeEnums(danach) {
|
|
36
41
|
if (wiederTimer) { clearTimeout(wiederTimer); wiederTimer = null; }
|
|
37
42
|
socket.emit('getObjectView', 'system', 'enum',
|
|
@@ -40,8 +45,8 @@ export function ladeEnums(danach) {
|
|
|
40
45
|
/* Den alten Stand behalten. Er ist vielleicht veraltet, aber
|
|
41
46
|
veraltet ist naeher an der Wahrheit als leer. */
|
|
42
47
|
unbekannt = true;
|
|
43
|
-
console.warn('[alias-workbench]
|
|
44
|
-
(err || '
|
|
48
|
+
console.warn('[alias-workbench] Enumerations not loaded: ' +
|
|
49
|
+
(err || 'no answer'));
|
|
45
50
|
if (versuch < 3) {
|
|
46
51
|
versuch++;
|
|
47
52
|
wiederTimer = setTimeout(function () {
|
|
@@ -59,8 +64,10 @@ export function ladeEnums(danach) {
|
|
|
59
64
|
if (r.value && r.id) { frisch[r.id] = r.value; }
|
|
60
65
|
});
|
|
61
66
|
enums = frisch;
|
|
67
|
+
var warUnbekannt = unbekannt;
|
|
62
68
|
unbekannt = false;
|
|
63
69
|
versuch = 0;
|
|
70
|
+
if (warUnbekannt) { geladenHoerer.forEach(function (fn) { fn(); }); }
|
|
64
71
|
if (typeof danach === 'function') { danach(null); }
|
|
65
72
|
});
|
|
66
73
|
}
|
package/admin/js/ergebnis.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { S } from './zustand.js';
|
|
2
2
|
import './start.js';
|
|
3
3
|
import { socket } from './verbindung.js';
|
|
4
|
-
import { D, $, el
|
|
4
|
+
import { D, $, el } from './basis.js';
|
|
5
5
|
import { tr, sprachtext } from './sprache.js';
|
|
6
6
|
import './einstellungen.js';
|
|
7
7
|
import './enums.js';
|
|
@@ -27,13 +27,17 @@ import {
|
|
|
27
27
|
mitNachfrage,
|
|
28
28
|
geraeteDarunter,
|
|
29
29
|
aliasFuer,
|
|
30
|
+
ausgangsQuellen,
|
|
30
31
|
quellenVerteilung,
|
|
31
32
|
quelleHier,
|
|
32
33
|
tipptGerade,
|
|
33
34
|
opt,
|
|
34
35
|
vorlagenAbweichung,
|
|
35
36
|
vorlageAnwenden,
|
|
36
|
-
bestandVorrang
|
|
37
|
+
bestandVorrang,
|
|
38
|
+
kanalGruppen,
|
|
39
|
+
aufteilBehaelter,
|
|
40
|
+
rohEntwurf
|
|
37
41
|
} from './entwurf.js';
|
|
38
42
|
import { setzeEnums, setzeZiel, unterschiede } from './zuordnung.js';
|
|
39
43
|
import './detail.js';
|
|
@@ -354,6 +358,15 @@ var warumAuf = false;
|
|
|
354
358
|
if (!sprungZiel) {
|
|
355
359
|
var vermerkt = S.objects[S.current] && S.objects[S.current].native && S.objects[S.current].native.quelle;
|
|
356
360
|
if (vermerkt) { sub.appendChild(el('span', 'chip warn', tr('result.sourceGone', vermerkt))); }
|
|
361
|
+
/* Der Knopf bleibt sichtbar, aber gesperrt: verschwaende er, suchte
|
|
362
|
+
man ihn; klickbar sprang er frueher irgendwohin (D10). */
|
|
363
|
+
var wohin = vermerkt || (insLeere[0] && insLeere[0].srcR) || '';
|
|
364
|
+
if (wohin) {
|
|
365
|
+
sprung = el('button', 'btn schmal sprungknopf', tr('result.toSource') + ' →');
|
|
366
|
+
sprung.disabled = true;
|
|
367
|
+
sprung.title = tr('result.sourceGone', wohin);
|
|
368
|
+
namensZeile.appendChild(sprung);
|
|
369
|
+
}
|
|
357
370
|
}
|
|
358
371
|
} else {
|
|
359
372
|
sprungZiel = aliasFuer(S.current);
|
|
@@ -505,22 +518,34 @@ var warumAuf = false;
|
|
|
505
518
|
/* Der Vorlagenkasten: welche Vorlage gegriffen hat, warum, ihre
|
|
506
519
|
Wahl und Knoepfe. Nimmt die Musterwahl bei sich auf; ohne Kasten
|
|
507
520
|
bleibt sie im Kopf - bis die Leiste sie sich holt. */
|
|
508
|
-
|
|
521
|
+
/* Zurueck kommt, was noch keinen Platz hat: der Musterblock (ohne
|
|
522
|
+
Kasten) und der Knopf fuer die Leiste ueber der Liste. Im Kasten
|
|
523
|
+
sitzt seit 19.09.2026 „Freie Plaetze vorschlagen"; der Knopf, der
|
|
524
|
+
den ganzen Bestand des Geraets laedt, wandert dafuer in die Leiste -
|
|
525
|
+
er aendert die Liste, nicht die Erkennung (Ricardo). */
|
|
526
|
+
function baueVorlagenkasten(host, head, e, istQuelle, musterBlock, rateKnopf) {
|
|
527
|
+
var leistenKnopf = rateKnopf;
|
|
509
528
|
if (e.vorschlag || istQuelle) {
|
|
510
529
|
var sg = el('div', 'suggestbox');
|
|
511
530
|
if (!e.vorschlag) {
|
|
512
531
|
sg.style.borderColor = 'var(--line-strong)';
|
|
513
532
|
sg.style.background = 'var(--surface-2)';
|
|
514
533
|
}
|
|
515
|
-
var hd = el('div', 'hd'
|
|
534
|
+
var hd = el('div', 'hd');
|
|
535
|
+
/* Der Name steht in einer eigenen Spanne, damit er sich kuerzen
|
|
536
|
+
laesst. Die Kopfzeile bricht nicht mehr um: vorher nahm sich der
|
|
537
|
+
Hinweis rechts eine eigene Zeile, sobald Marken dazukamen und der
|
|
538
|
+
Name lang wurde („Homematic Rollladenaktor" + von Hand gewaehlt +
|
|
539
|
+
erzwungen). Jetzt weicht stattdessen der Name zurueck — vollstaendig
|
|
540
|
+
steht er im Tooltip und im Auswahlfeld darunter (Ricardo, 17.09.2026). */
|
|
541
|
+
var hdText = e.vorschlag
|
|
516
542
|
? tr('tpl.identifiedAs', e.tplName)
|
|
517
|
-
: tr('tpl.noneDetected')
|
|
543
|
+
: tr('tpl.noneDetected');
|
|
544
|
+
var hdName = el('span', 'tname', hdText);
|
|
545
|
+
hdName.title = hdText;
|
|
546
|
+
hd.appendChild(hdName);
|
|
518
547
|
if (e.vorlageVersion) {
|
|
519
|
-
var vv2 = el('span',
|
|
520
|
-
vv2.style.fontFamily = 'var(--mono)';
|
|
521
|
-
vv2.style.fontSize = '10.5px';
|
|
522
|
-
vv2.style.fontWeight = '400';
|
|
523
|
-
vv2.style.color = 'var(--ink-3)';
|
|
548
|
+
var vv2 = el('span', 'tid', ' · ' + e.vorlage + ' v' + e.vorlageVersion);
|
|
524
549
|
hd.appendChild(vv2);
|
|
525
550
|
}
|
|
526
551
|
if (e.vonHandGewaehlt) {
|
|
@@ -571,13 +596,22 @@ var warumAuf = false;
|
|
|
571
596
|
Breite, die eine Liste braucht. */
|
|
572
597
|
var warumKopf = null, warumLeib = null;
|
|
573
598
|
if (gruende.length || weggelassen.length) {
|
|
574
|
-
warumKopf = el('div', 'wkopf');
|
|
575
599
|
/* Ohne Vorlage waere „Warum diese Vorlage" die falsche Frage —
|
|
576
600
|
dann steht hier, warum keine greift. */
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
601
|
+
var warumText = tr(e.vorschlag ? 'tpl.whyThis' : 'tpl.whyNone');
|
|
602
|
+
warumKopf = el('div', 'wkopf' + (warumAuf ? ' auf' : ''));
|
|
603
|
+
/* Statt „Warum diese Vorlage +" nur ein Fragezeichen: der Satz
|
|
604
|
+
steht im Tooltip und spart die halbe Kopfzeile. Was weggelassen
|
|
605
|
+
wurde, bleibt als kurze Marke stehen — dass Punkte fehlen, soll
|
|
606
|
+
niemand erst suchen muessen (Ricardo, 17.09.2026). */
|
|
607
|
+
if (weggelassen.length) {
|
|
608
|
+
warumKopf.appendChild(el('span', 'chip mut',
|
|
609
|
+
tr('tpl.skippedChip', weggelassen.length)));
|
|
610
|
+
warumText = tr('tpl.skippedHead', weggelassen.length) + ' — ' + warumText;
|
|
611
|
+
}
|
|
612
|
+
warumKopf.appendChild(el('span', 'fragez', '?'));
|
|
613
|
+
warumKopf.title = warumText;
|
|
614
|
+
warumKopf.setAttribute('aria-label', warumText);
|
|
581
615
|
warumKopf.tabIndex = 0;
|
|
582
616
|
var um2 = function () { warumAuf = !warumAuf; zeichneErgebnis(); };
|
|
583
617
|
warumKopf.addEventListener('click', um2);
|
|
@@ -634,6 +668,25 @@ var warumAuf = false;
|
|
|
634
668
|
v2.zielOrdner = e.zielOrdner;
|
|
635
669
|
v2.zielName = ausgangName(v2, selA.value);
|
|
636
670
|
v2.ziel = v2.zielOrdner + '.' + v2.zielName;
|
|
671
|
+
/* Dieser Weg fragte bisher gar nicht nach dem Bestand -
|
|
672
|
+
deshalb sah derselbe Ausgang je nach Weg anders aus:
|
|
673
|
+
ueber den Baum kamen die Haken eines fremden Alias, hier
|
|
674
|
+
die Vorgaben der Vorlage. Jetzt stellen alle drei Wege
|
|
675
|
+
dieselbe Frage (C13, 16.09.2026).
|
|
676
|
+
|
|
677
|
+
Und die Zielzeile folgt derselben Antwort. Sie wird hier von
|
|
678
|
+
Hand zusammengesetzt und laeuft nicht durch `setzeZiel`;
|
|
679
|
+
ohne diese Zeilen zeigte sie beim Umschalten weiter auf
|
|
680
|
+
`…POWER2` und meldete „wird neu angelegt", waehrend
|
|
681
|
+
`SUNLU` daneben stand. */
|
|
682
|
+
var vorhA2 = aliasFuer(S.current, ausgangsQuellen(v2));
|
|
683
|
+
if (vorhA2) {
|
|
684
|
+
var t2 = vorhA2.split('.');
|
|
685
|
+
v2.zielName = t2.pop();
|
|
686
|
+
v2.zielOrdner = t2.join('.');
|
|
687
|
+
v2.ziel = vorhA2;
|
|
688
|
+
}
|
|
689
|
+
if (vorhA2 && S.objects[vorhA2]) { bestandVorrang(v2, vorhA2); }
|
|
637
690
|
S.entwurf = v2; S.openRow = null; zeichneErgebnis();
|
|
638
691
|
}
|
|
639
692
|
});
|
|
@@ -650,7 +703,10 @@ var warumAuf = false;
|
|
|
650
703
|
das Ausgangsfeld daneben blieb ungestylt in der Browserschrift. */
|
|
651
704
|
var selV = el('select', 'tx');
|
|
652
705
|
|
|
653
|
-
|
|
706
|
+
/* Greift eine Vorlage, ist der erste Eintrag kein Titel, sondern
|
|
707
|
+
eine Wahl: sie wieder loswerden. „— Vorlage wechseln —" stand
|
|
708
|
+
wie eine Handlung da, tat aber nichts (Ricardo, 17.09.2026). */
|
|
709
|
+
selV.appendChild(opt('', e.vorschlag ? tr('tpl.none') : tr('tpl.choose')));
|
|
654
710
|
S.VORLAGEN.forEach(function (v) {
|
|
655
711
|
var t = pruefeVorlage(v, S.current);
|
|
656
712
|
/* Auch nicht passende bleiben waehlbar — mit Grund daneben. Sonst
|
|
@@ -663,7 +719,35 @@ var warumAuf = false;
|
|
|
663
719
|
selV.appendChild(o);
|
|
664
720
|
});
|
|
665
721
|
selV.addEventListener('change', function () {
|
|
666
|
-
if (!selV.value) {
|
|
722
|
+
if (!selV.value) {
|
|
723
|
+
/* „keine Vorlage": den Rohentwurf nehmen. Ziel, Raum und
|
|
724
|
+
Funktion bleiben — die hat der Mensch eingestellt, nicht die
|
|
725
|
+
Vorlage. `angefasst` verhindert, dass der naechste
|
|
726
|
+
eintreffende Messwert die Vorlage wieder heranzieht. */
|
|
727
|
+
if (!e.vorschlag) { return; }
|
|
728
|
+
var r = rohEntwurf(S.current);
|
|
729
|
+
if (!r) { selV.value = e.vorlage || ''; return; }
|
|
730
|
+
r.ziel = e.ziel; r.zielOrdner = e.zielOrdner; r.zielName = e.zielName;
|
|
731
|
+
r.raum = e.raum; r.funktion = e.funktion;
|
|
732
|
+
r.raumHer = e.raumHer; r.funktionHer = e.funktionHer;
|
|
733
|
+
/* Der Ausgang wird NICHT uebernommen. Er ist keine Eigenschaft
|
|
734
|
+
des Geraets, sondern des `mehrfach`-Blocks der Vorlage:
|
|
735
|
+
`instanzenVon` gibt ohne ihn `[null]` zurueck. Wurde die
|
|
736
|
+
Vorlage abgewaehlt, gibt es keinen Platzhalter mehr und damit
|
|
737
|
+
nichts zu waehlen. Bis 17.09.2026 erbte der Rohentwurf die
|
|
738
|
+
Ausgaenge der alten Vorlage: der Kasten blieb stehen, und wer
|
|
739
|
+
ihn benutzte, holte die abgewaehlte Vorlage kommentarlos
|
|
740
|
+
zurueck — der Ausgang-Zweig ruft `vorschlag` mit leerem
|
|
741
|
+
`e.vorlage` und laesst neu erkennen (gemessen an
|
|
742
|
+
`hm.ZWEIKANAL`: nach dem Umschalten auf `Licht_Esstisch`
|
|
743
|
+
stand `hm-schaltaktor-mehrfach` wieder im Feld). Die beiden
|
|
744
|
+
Kanaele laufen ohne Vorlage ueber „Unterordner je Kanal". */
|
|
745
|
+
S.entwurf = r;
|
|
746
|
+
S.openRow = null;
|
|
747
|
+
entwurfAngefasst();
|
|
748
|
+
zeichneErgebnis();
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
667
751
|
var v = vorschlag(S.current, selV.value);
|
|
668
752
|
if (v) {
|
|
669
753
|
v.ziel = e.ziel;
|
|
@@ -691,7 +775,6 @@ var warumAuf = false;
|
|
|
691
775
|
der nur die vorgeschlagenen Zeilen ein- und ausblendet. Deshalb
|
|
692
776
|
steht das Geraet im Namen und der Rest im Hinweis. */
|
|
693
777
|
bRoh.title = e.roh ? tr('tpl.showProposalHelp') : tr('tpl.showAllPointsHelp');
|
|
694
|
-
if (!e.vorschlag) { bRoh.disabled = true; }
|
|
695
778
|
bRoh.addEventListener('click', function () {
|
|
696
779
|
var rohJetzt = !e.roh;
|
|
697
780
|
/* Dieselben zwei Schritte wie in `waehle`: die Vorlage, aus der der
|
|
@@ -751,7 +834,11 @@ var warumAuf = false;
|
|
|
751
834
|
neuE.zielName = e.zielName;
|
|
752
835
|
neuE.ordnerVonHand = e.ordnerVonHand;
|
|
753
836
|
if (fest) { neuE.vonHandGewaehlt = false; neuE.ausBestand = true; }
|
|
754
|
-
|
|
837
|
+
/* Wie beim ersten Aufbau: am Mehrfachgeraet zaehlt der Alias
|
|
838
|
+
DIESES Ausgangs (C13). */
|
|
839
|
+
var vorhW = aliasFuer(S.current, ausgangsQuellen(neuE)) ||
|
|
840
|
+
((neuE.instanz === null || neuE.instanz === undefined) ? vorh : null);
|
|
841
|
+
if (vorhW && S.objects[vorhW]) { bestandVorrang(neuE, vorhW); }
|
|
755
842
|
S.entwurf = neuE; S.openRow = null; zeichneErgebnis();
|
|
756
843
|
});
|
|
757
844
|
/* An der Quelle bleibt die Musterwahl im Vorlagenkasten, wo sie
|
|
@@ -782,8 +869,12 @@ var warumAuf = false;
|
|
|
782
869
|
knoepfe.appendChild(bTpl);
|
|
783
870
|
}
|
|
784
871
|
}
|
|
785
|
-
knoepfe.appendChild(
|
|
786
|
-
acts.appendChild(knoepfe);
|
|
872
|
+
if (rateKnopf) { knoepfe.appendChild(rateKnopf); }
|
|
873
|
+
if (knoepfe.childNodes.length) { acts.appendChild(knoepfe); }
|
|
874
|
+
/* Ohne Vorlagenvorschlag gibt es keinen Bestand, zu dem er
|
|
875
|
+
umschalten koennte - dann steht er gar nicht erst da, statt
|
|
876
|
+
ausgegraut in der Leiste. */
|
|
877
|
+
leistenKnopf = e.vorschlag ? bRoh : null;
|
|
787
878
|
sg.appendChild(acts);
|
|
788
879
|
host.appendChild(sg);
|
|
789
880
|
}
|
|
@@ -792,7 +883,7 @@ var warumAuf = false;
|
|
|
792
883
|
if (musterBlock) {
|
|
793
884
|
head.appendChild(musterBlock);
|
|
794
885
|
}
|
|
795
|
-
return musterBlock;
|
|
886
|
+
return { musterBlock: musterBlock, leistenKnopf: leistenKnopf };
|
|
796
887
|
}
|
|
797
888
|
|
|
798
889
|
/* Die Karte „Gehoert nicht zum <Muster>" stand hier bis zum
|
|
@@ -844,7 +935,22 @@ var warumAuf = false;
|
|
|
844
935
|
var bd = $('#btn-dry');
|
|
845
936
|
var ba = $('#btn-dry-alle');
|
|
846
937
|
var mehr = e.instanzen && e.instanzen.length > 1;
|
|
847
|
-
|
|
938
|
+
/* Welche Unterordner entstuenden — nach den Haken, dieselbe Rechnung
|
|
939
|
+
wie der Schreibweg (C51). */
|
|
940
|
+
var grp = mehr ? [] : kanalGruppen(e).filter(function (g) { return !g.eigen; });
|
|
941
|
+
/* Zwei Kanaele mit Haken genuegen — auch wenn einer davon der
|
|
942
|
+
Wartungskanal ist.
|
|
943
|
+
|
|
944
|
+
Zwischenzeitlich zaehlte `.0` hier nicht mit, damit der Knopf nicht
|
|
945
|
+
an jedem Fuehler steht. Das ergab aber eine Unstimmigkeit, die beim
|
|
946
|
+
Benutzen auffaellt: fuer den INHALT zaehlte der Kanal (er bekommt
|
|
947
|
+
seinen Ordner), fuer den ANLASS nicht — man hakt etwas an und
|
|
948
|
+
nichts passiert. Ricardo am 17.09.2026: „zählt ist ja eher ne
|
|
949
|
+
Expertenfunktion, da weiss man schon was man macht." Also eine
|
|
950
|
+
Regel statt zweier. */
|
|
951
|
+
var typVonK = {};
|
|
952
|
+
(e.kanalGeraete || []).forEach(function (k) { typVonK[k.id] = k.typ; });
|
|
953
|
+
var mehrK = !mehr && grp.length > 1;
|
|
848
954
|
/* Die Knoepfe gehoeren zum Modus, nicht nur zum Objekt: Im Modus
|
|
849
955
|
„Alias anlegen" wird angelegt, nicht verwaltet — Verlegen, Quelle
|
|
850
956
|
tauschen und Entfernen haben dort nichts zu suchen. Im Modus
|
|
@@ -891,13 +997,25 @@ var warumAuf = false;
|
|
|
891
997
|
return (e.zielOrdner || '') + '.' + nm;
|
|
892
998
|
}).join(String.fromCharCode(10));
|
|
893
999
|
} else if (mehrK) {
|
|
894
|
-
ba.textContent = tr('write.createPerChannel',
|
|
1000
|
+
ba.textContent = tr('write.createPerChannel', grp.length);
|
|
895
1001
|
/* Im Hinweis stehen die Namen, die entstehen wuerden — sonst
|
|
896
1002
|
klickt man auf eine Zahl und weiss nicht, was danach dasteht. */
|
|
897
|
-
|
|
1003
|
+
/* Dieselbe Rechnung wie der Schreibweg (schreiben.js, `ordner`):
|
|
1004
|
+
ein Behaelter fuer das Geraet, darunter je Kanal einer. Hier
|
|
1005
|
+
stand nur `zielOrdner` — also eine Ebene zu wenig. Am
|
|
1006
|
+
Geschirrspueler versprach der Hinweis `alias.0.Befehle`,
|
|
1007
|
+
entstanden waere `alias.0.Geschirrspueler.Befehle`; am
|
|
1008
|
+
Wohnzimmer_Dimmer las man `alias.0.1`, `alias.0.2`, `alias.0.3`
|
|
1009
|
+
— drei Aliase, nach blanken Kanalnummern benannt, direkt unter
|
|
1010
|
+
alias.0. Gefunden im Lauf vom 16.09.2026 (C15). */
|
|
1011
|
+
var ordnerK = aufteilBehaelter(e);
|
|
1012
|
+
ba.title = grp.map(function (g) {
|
|
898
1013
|
/* Die Kennung, nicht den Anzeigenamen - so heisst das Objekt
|
|
899
|
-
hinterher wirklich (G31).
|
|
900
|
-
|
|
1014
|
+
hinterher wirklich (G31). Dahinter, was hineinkommt: die
|
|
1015
|
+
Zahl der angehakten Zeilen — daran sieht man vor dem Klick,
|
|
1016
|
+
dass nichts Erfundenes dabei ist. */
|
|
1017
|
+
return ordnerK + '.' + (g.kennung || g.name)
|
|
1018
|
+
+ ' (' + g.zeilen.length + (typVonK[g.id] ? ', ' + typVonK[g.id] : '') + ')';
|
|
901
1019
|
}).join(String.fromCharCode(10));
|
|
902
1020
|
}
|
|
903
1021
|
ba.disabled = false;
|
|
@@ -967,7 +1085,9 @@ var warumAuf = false;
|
|
|
967
1085
|
|
|
968
1086
|
var istQuelle = baueZielleiste(host, e);
|
|
969
1087
|
|
|
970
|
-
|
|
1088
|
+
var kasten = baueVorlagenkasten(host, head, e, istQuelle, musterBlock, rateKnopf);
|
|
1089
|
+
musterBlock = kasten.musterBlock;
|
|
1090
|
+
rateKnopf = kasten.leistenKnopf;
|
|
971
1091
|
|
|
972
1092
|
/* Gleich unter die Erkennung: was hier fehlt, entscheidet mit
|
|
973
1093
|
darueber, ob eine Vorlage ueberhaupt greift. */
|
package/admin/js/erkennung.js
CHANGED
|
@@ -32,6 +32,11 @@ import { D } from './basis.js';
|
|
|
32
32
|
export function ausdruckText(r) {
|
|
33
33
|
if (!r) { return ''; }
|
|
34
34
|
if (r.source !== undefined) { return r.source; }
|
|
35
|
+
/* Ein Objekt ohne `source` ist kein Ausdruck. `ignoreRole` kommt im
|
|
36
|
+
Browser als leeres `{}` an; `String({})` gab „[object Object]", und
|
|
37
|
+
das ist eine Zeichenklasse, die jede Rolle mit einem „e" trifft —
|
|
38
|
+
jeder Sollwert der Klimaanlage galt als ausgenommen (19.09.2026). */
|
|
39
|
+
if (typeof r === 'object') { return ''; }
|
|
35
40
|
var q = String(r);
|
|
36
41
|
var m = /^\/(.*)\/[a-z]*$/.exec(q);
|
|
37
42
|
return m ? m[1] : q;
|
|
@@ -226,6 +231,13 @@ export function musterVon(typ) {
|
|
|
226
231
|
statt als `electricity` nur noch als `info` erkannt. Am Bildschirm
|
|
227
232
|
stand dazu nichts weiter als „passt nicht".
|
|
228
233
|
|
|
234
|
+
Zur Rolle selbst: `value.power.consumption` ist in der Rollenliste von
|
|
235
|
+
ioBroker durchgestrichen, der type-detector 6.0.x erkennt CONSUMPTION
|
|
236
|
+
aber NUR mit genau dieser Rolle (typePatterns.js, Muster `consumption`).
|
|
237
|
+
Die mitgelieferten Vorlagen behalten sie deshalb bewusst; jede traegt
|
|
238
|
+
den Grund im Feld `_rolle`. Role note for reviewers: the deprecated role
|
|
239
|
+
is kept on purpose because the type-detector requires it.
|
|
240
|
+
|
|
229
241
|
Dieselbe Suche stand vorher zweimal im Code (detail.js und
|
|
230
242
|
vorlagenblatt.js), beide Male ohne den Typ anzusehen. */
|
|
231
243
|
export function plaetzeFuerRolle(musterName, rolle) {
|
|
@@ -304,6 +316,46 @@ export function typKonflikte(states, musterName) {
|
|
|
304
316
|
return raus;
|
|
305
317
|
}
|
|
306
318
|
|
|
319
|
+
/* Welche Pflicht eines Musters der Entwurf wirklich nicht erfuellt.
|
|
320
|
+
|
|
321
|
+
Bis 19.09.2026 nannte das Musterfeld schlicht alle `required`-Plaetze:
|
|
322
|
+
an der Klimaanlage stand „✕ MODE fehlt", obwohl MODE angehakt und
|
|
323
|
+
bestaetigt war — gefehlt hat der Sollwert. Der steht im Muster nicht
|
|
324
|
+
als `required`, sondern als Gruppe (`requiredOneOf: 'setpoint'`):
|
|
325
|
+
einer aus SET und den beiden Doppel-Sollwerten muss da sein, und die
|
|
326
|
+
Gruppe kam in der Auskunft gar nicht vor (U13).
|
|
327
|
+
|
|
328
|
+
Geprueft wird grob, wie der Detektor: angehakte Zeile mit passender
|
|
329
|
+
Rolle, schreibbar wo der Platz es verlangt, im zugelassenen Typ.
|
|
330
|
+
Zurueck kommen Namen — eine Gruppe als „SET / SET_HEAT / …". Findet
|
|
331
|
+
die Grobpruefung nichts, gibt sie [] zurueck, und der Aufrufer faellt
|
|
332
|
+
auf die alte Auskunft zurueck. */
|
|
333
|
+
export function fehlendePflicht(states, musterName) {
|
|
334
|
+
var mu = musterName && musterVon(musterName);
|
|
335
|
+
if (!mu) { return []; }
|
|
336
|
+
function erfuellt(pl) {
|
|
337
|
+
return (states || []).some(function (s) {
|
|
338
|
+
if (!s.on || !s.role || !rolleTrifft(pl.role, s.role)) { return false; }
|
|
339
|
+
if (pl.ignoreRole && rolleTrifft(pl.ignoreRole, s.role)) { return false; }
|
|
340
|
+
if (pl.write === true && !(s.wr || s.srcW)) { return false; }
|
|
341
|
+
return typPasstZuPlatz(pl, s.typ);
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
var raus = [], gruppen = {};
|
|
345
|
+
mu.states.forEach(function (pl) {
|
|
346
|
+
if (pl.required && !erfuellt(pl)) { raus.push(pl.name); }
|
|
347
|
+
if (pl.requiredOneOf) {
|
|
348
|
+
var g = gruppen[pl.requiredOneOf] = gruppen[pl.requiredOneOf] || { namen: [], da: false };
|
|
349
|
+
if (g.namen.indexOf(pl.name) === -1) { g.namen.push(pl.name); }
|
|
350
|
+
if (erfuellt(pl)) { g.da = true; }
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
Object.keys(gruppen).forEach(function (k) {
|
|
354
|
+
if (!gruppen[k].da) { raus.push(gruppen[k].namen.join(' / ')); }
|
|
355
|
+
});
|
|
356
|
+
return raus;
|
|
357
|
+
}
|
|
358
|
+
|
|
307
359
|
/* Die Datentypen, die ein Platz zulaesst - als Liste.
|
|
308
360
|
|
|
309
361
|
Drei Faelle, gemessen am type-detector 6.0.1: 622 Plaetze nennen
|