iobroker.alias-workbench 0.11.0 → 0.12.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 +19 -7
- package/admin/css/werkbank.css +73 -0
- package/admin/i18n/de.json +65 -0
- package/admin/i18n/en.json +65 -0
- package/admin/i18n/es.json +65 -0
- package/admin/i18n/fr.json +65 -0
- package/admin/i18n/it.json +65 -0
- package/admin/i18n/nl.json +65 -0
- package/admin/i18n/pl.json +65 -0
- package/admin/i18n/pt.json +65 -0
- package/admin/i18n/ru.json +65 -0
- package/admin/i18n/uk.json +65 -0
- package/admin/i18n/zh-cn.json +65 -0
- package/admin/js/attrappe.js +749 -0
- package/admin/js/baum.js +52 -5
- package/admin/js/entwurf.js +133 -6
- package/admin/js/ergebnis.js +77 -2
- package/admin/js/quellentausch.js +823 -16
- package/admin/js/sprache.js +4 -0
- package/admin/js/zustand.js +28 -0
- package/admin/tab.html +24 -0
- package/io-package.json +14 -14
- package/package.json +2 -2
package/admin/js/baum.js
CHANGED
|
@@ -8,9 +8,10 @@ import { S } from './zustand.js';
|
|
|
8
8
|
import { $, el } from './basis.js';
|
|
9
9
|
import { tr, txt, expertenVorgabe } from './sprache.js';
|
|
10
10
|
import './enums.js';
|
|
11
|
-
import { mitNachfrage, aboLoesen } from './entwurf.js';
|
|
11
|
+
import { mitNachfrage, aboLoesen, zweigUmschalten, zweigPfade, waehle } from './entwurf.js';
|
|
12
12
|
import { zeichneErgebnis } from './ergebnis.js';
|
|
13
13
|
import { zeichneVorlagenListe } from './vorlagenblatt.js';
|
|
14
|
+
import { zeigeMenue } from './attrappe.js';
|
|
14
15
|
|
|
15
16
|
var KLAPP_SCHLUESSEL = 'alias-workbench.baum';
|
|
16
17
|
|
|
@@ -205,6 +206,17 @@ export function zeichneBaum() {
|
|
|
205
206
|
}
|
|
206
207
|
}
|
|
207
208
|
|
|
209
|
+
/* Warum ein Strg-Klick nicht angekommen ist.
|
|
210
|
+
|
|
211
|
+
„schon drin" und „der letzte" brauchen keine Worte - da passiert
|
|
212
|
+
sichtbar nichts, und das versteht sich. „Aus einer anderen Instanz"
|
|
213
|
+
braucht sie: sonst klickt jemand dreimal und haelt es fuer kaputt. */
|
|
214
|
+
function meldeZweig(grund) {
|
|
215
|
+
if (grund !== 'fremd') { return; }
|
|
216
|
+
S.zweigMeldung = tr('tree.branchForeign');
|
|
217
|
+
zeichneErgebnis();
|
|
218
|
+
}
|
|
219
|
+
|
|
208
220
|
/* Waehlbar ist alles, unter dem irgendwo Zustaende liegen — nicht nur
|
|
209
221
|
direkt darunter. MQTT legt fuer Zwischenebenen gar keine Objekte an:
|
|
210
222
|
unter …SmartHome.Karbonator existieren nur tele.LWT, tele.SENSOR und
|
|
@@ -391,8 +403,14 @@ function renderKinder(knoten, filter, tiefe) {
|
|
|
391
403
|
|
|
392
404
|
var li = el('li');
|
|
393
405
|
var waehlbar = istWaehlbar(k);
|
|
406
|
+
/* Bei einer Mehrfachauswahl ist JEDER gewaehlte Zweig markiert, und
|
|
407
|
+
der gemeinsame Elternknoten schwaecher - sonst sieht man nicht,
|
|
408
|
+
worauf der Entwurf steht. Denselben Mangel hatte das
|
|
409
|
+
Attrappen-Menue (Ricardo, 12.10.2026). */
|
|
410
|
+
var gewaehlt = zweigPfade().indexOf(k.id) !== -1;
|
|
411
|
+
var istEltern = !!(S.zweige && S.zweige.length) && k.id === S.current;
|
|
394
412
|
var d = el('div', 'node' + (waehlbar ? ' pick' : ' grp') + (leer ? ' leer' : '') +
|
|
395
|
-
(
|
|
413
|
+
(gewaehlt ? ' sel' : '') + (istEltern ? ' selEltern' : ''));
|
|
396
414
|
|
|
397
415
|
var hatKinder = kinderPassen;
|
|
398
416
|
var auf = aufJetzt;
|
|
@@ -439,6 +457,11 @@ function renderKinder(knoten, filter, tiefe) {
|
|
|
439
457
|
d.appendChild(el('span', 'cnt', k._zust + ''));
|
|
440
458
|
}
|
|
441
459
|
|
|
460
|
+
/* Rechtsklick auf JEDE Zeile, nicht nur auf waehlbare: ausgeben
|
|
461
|
+
laesst sich auch ein Geraet oder ein Ordner, und gerade der ist
|
|
462
|
+
beim Nachbauen der interessante Knoten. */
|
|
463
|
+
d.addEventListener('contextmenu', function (e) { zeigeMenue(e, k.id, d); });
|
|
464
|
+
|
|
442
465
|
if (waehlbar) {
|
|
443
466
|
d.tabIndex = 0;
|
|
444
467
|
d.setAttribute('role', 'button');
|
|
@@ -452,10 +475,34 @@ function renderKinder(knoten, filter, tiefe) {
|
|
|
452
475
|
dazu, und die stehen nicht in den Zeilen. Geschrieben wird
|
|
453
476
|
dadurch nichts — es geht nur darum, dass niemand etwas verliert,
|
|
454
477
|
ohne gefragt zu werden. */
|
|
455
|
-
|
|
456
|
-
|
|
478
|
+
/* Ein gewoehnlicher Klick waehlt EINEN Knoten - auch dann, wenn es
|
|
479
|
+
derselbe ist, auf dem gerade eine Mehrfachauswahl steht. Wer den
|
|
480
|
+
Elternknoten anklickt, will ihn ganz. */
|
|
481
|
+
var go = function () {
|
|
482
|
+
mitNachfrage(k.id, function () { S.zweige = null; waehle(k.id); });
|
|
483
|
+
};
|
|
484
|
+
/* Strg-Klick nimmt einen Zweig dazu oder heraus, statt die Auswahl
|
|
485
|
+
zu ersetzen. Strg und nicht Umschalt: Umschalt heisst ueberall
|
|
486
|
+
„Bereich von…bis", gewollt sind einzelne Zweige. Auf dem Mac
|
|
487
|
+
dieselbe Taste wie sonst dort (Cmd).
|
|
488
|
+
|
|
489
|
+
Wer keine Tastatur hat oder nicht weiss, dass es das gibt,
|
|
490
|
+
findet dasselbe im Rechtsklickmenue. */
|
|
491
|
+
var dazu = function () {
|
|
492
|
+
mitNachfrage(k.id, function () {
|
|
493
|
+
var grund = zweigUmschalten(k.id);
|
|
494
|
+
if (grund) { meldeZweig(grund); }
|
|
495
|
+
});
|
|
496
|
+
};
|
|
497
|
+
d.addEventListener('click', function (e) {
|
|
498
|
+
if (e.ctrlKey || e.metaKey) { e.preventDefault(); dazu(); return; }
|
|
499
|
+
go();
|
|
500
|
+
});
|
|
457
501
|
d.addEventListener('keydown', function (e) {
|
|
458
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
502
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
503
|
+
e.preventDefault();
|
|
504
|
+
if (e.ctrlKey || e.metaKey) { dazu(); } else { go(); }
|
|
505
|
+
}
|
|
459
506
|
});
|
|
460
507
|
}
|
|
461
508
|
li.appendChild(d);
|
package/admin/js/entwurf.js
CHANGED
|
@@ -8,7 +8,7 @@ import { $ } from './basis.js';
|
|
|
8
8
|
import { txt, tr } from './sprache.js';
|
|
9
9
|
import './enums.js';
|
|
10
10
|
import { zusatzName, setzeModus, zeichneBaum, merkeKlappstand } from './baum.js';
|
|
11
|
-
import { kindZustaende, geraetePunkte, aliasQuellen, holeWerte,
|
|
11
|
+
import { kindZustaende, geraetePunkte, aliasQuellen, holeWerte, istZerlegt,
|
|
12
12
|
mitVorspann, schreibQuelle, zeileAusAlias, statesText, statesGleich, istTaster as istTasterObjekt
|
|
13
13
|
} from './werte.js';
|
|
14
14
|
import { erkenneEntwurf } from './erkennung.js';
|
|
@@ -77,10 +77,56 @@ export function baueEntwurf(kanal) {
|
|
|
77
77
|
relativer Name kommt von dort. Sonst hiesse die Zeile
|
|
78
78
|
`tele_Weihnachten_aussen_STATE` statt `tele_STATE`, und derselbe
|
|
79
79
|
Tasmota ergaebe je nach FullTopic einen anderen Alias. */
|
|
80
|
-
geraetePunkte(kanal)
|
|
80
|
+
var punkte = geraetePunkte(kanal);
|
|
81
|
+
/* Mehrere Zweige als ein Geraet: nur die gewaehlten. Gefiltert wird
|
|
82
|
+
NACH `geraetePunkte`, nicht davor - dessen Ergebnis liegt je Knoten
|
|
83
|
+
im Zwischenspeicher, und die Auswahl ist fluechtig. */
|
|
84
|
+
var mehrzweig = false;
|
|
85
|
+
if (S.zweige && S.zweige.length && kanal === S.current) {
|
|
86
|
+
mehrzweig = true;
|
|
87
|
+
punkte = punkte.filter(function (p) {
|
|
88
|
+
return S.zweige.some(function (z) { return p.rel === z || p.rel.indexOf(z + '.') === 0; });
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/* Kurze Namen, wo sie eindeutig sind.
|
|
92
|
+
|
|
93
|
+
Aus `OnOffPlugInUnit-1.SET` soll `SET` werden - sonst hiesse der
|
|
94
|
+
Alias-Punkt `OnOffPlugInUnit-1_SET`, und die Zeile traegt den Namen
|
|
95
|
+
eines Endpoints, den ausser dem Adapter niemand kennt. Gekuerzt wird
|
|
96
|
+
nur, wenn das letzte Glied unter den GEWAEHLTEN Zweigen genau einmal
|
|
97
|
+
vorkommt; sonst bliebe nicht unterscheidbar, welcher Zweig gemeint
|
|
98
|
+
ist.
|
|
99
|
+
|
|
100
|
+
Nicht bei einem zerlegten Geraet (Tasmota): dort ist der Zweig
|
|
101
|
+
bedeutungstragend. `cmnd.POWER` und `stat.POWER` kuerzten sich
|
|
102
|
+
ohnehin nicht, weil `POWER` zweimal vorkommt - aber `tele.SENSOR`
|
|
103
|
+
waere eindeutig und wuerde zu `SENSOR`. Das haette jeden
|
|
104
|
+
bestehenden MQTT-Alias gebrochen.
|
|
105
|
+
|
|
106
|
+
Dasselbe gilt, wenn jemand die Sparten eines Tasmota ausdruecklich
|
|
107
|
+
zusammenklickt (`…Steckdose.stat` + `…Steckdose.tele`). Dort heisst
|
|
108
|
+
der Zweig `cmnd`, `stat` oder `tele`, und die Vorlagen adressieren
|
|
109
|
+
genau so (`stat.POWER`). Gekuerzt faende keine von ihnen mehr ihr
|
|
110
|
+
Ziel. */
|
|
111
|
+
var kurz = {};
|
|
112
|
+
var sparte = (S.zweige || []).some(function (zg) {
|
|
113
|
+
return SPARTEN.indexOf(zg.split('.').pop()) !== -1;
|
|
114
|
+
});
|
|
115
|
+
if (mehrzweig && !sparte && !istZerlegt(kanal)) {
|
|
116
|
+
var zaehler = {};
|
|
117
|
+
punkte.forEach(function (p) {
|
|
118
|
+
var k = p.rel.split('.').pop();
|
|
119
|
+
zaehler[k] = (zaehler[k] || 0) + 1;
|
|
120
|
+
});
|
|
121
|
+
punkte.forEach(function (p) {
|
|
122
|
+
var k = p.rel.split('.').pop();
|
|
123
|
+
if (zaehler[k] === 1 && k !== p.rel) { kurz[p.rel] = k; }
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
punkte.forEach(function (p) {
|
|
81
127
|
var id = p.id;
|
|
82
128
|
var o = S.objects[id], c = o.common || {}, a = c.alias || {}, q = aliasQuellen(o);
|
|
83
|
-
var kurzName = p.rel;
|
|
129
|
+
var kurzName = kurz[p.rel] || p.rel;
|
|
84
130
|
/* Ein Knopfdruck hat keinen Zustand — sonst hat auch ein
|
|
85
131
|
nur-schreibender Punkt einen.
|
|
86
132
|
|
|
@@ -980,7 +1026,85 @@ export function aboErgaenzen(quellen) {
|
|
|
980
1026
|
zeigeAbozahl();
|
|
981
1027
|
}
|
|
982
1028
|
|
|
983
|
-
|
|
1029
|
+
/* Die gewaehlten Zweige als volle Kennungen - eine Liste, auch wenn es
|
|
1030
|
+
nur einer ist. */
|
|
1031
|
+
export function zweigPfade() {
|
|
1032
|
+
if (!S.current) { return []; }
|
|
1033
|
+
if (!S.zweige || !S.zweige.length) { return [S.current]; }
|
|
1034
|
+
return S.zweige.map(function (z) { return S.current + '.' + z; });
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/* Der laengste gemeinsame Elternknoten mehrerer Kennungen - auf
|
|
1038
|
+
Punktgrenzen, nicht auf Zeichen. */
|
|
1039
|
+
function gemeinsamerEltern(ids) {
|
|
1040
|
+
var teile = ids[0].split('.');
|
|
1041
|
+
for (var i = 1; i < ids.length; i++) {
|
|
1042
|
+
var t2 = ids[i].split('.');
|
|
1043
|
+
var n = 0;
|
|
1044
|
+
while (n < teile.length && n < t2.length && teile[n] === t2[n]) { n++; }
|
|
1045
|
+
teile = teile.slice(0, n);
|
|
1046
|
+
}
|
|
1047
|
+
return teile.join('.');
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
/* Einen Zweig dazunehmen oder herausnehmen.
|
|
1051
|
+
|
|
1052
|
+
Gedacht fuer Geraete, die ueber Geschwisterzweige verteilt liegen
|
|
1053
|
+
(Matter, siehe `S.zweige`). Der gemeinsame Elternknoten wird zur
|
|
1054
|
+
Auswahl, die angeklickten Zweige zu `S.zweige`.
|
|
1055
|
+
|
|
1056
|
+
Gibt einen Grund zurueck, wenn es nicht geht - dann hat sich nichts
|
|
1057
|
+
geaendert. */
|
|
1058
|
+
export function zweigUmschalten(id) {
|
|
1059
|
+
if (!S.current) { return 'leer'; }
|
|
1060
|
+
var pfade = zweigPfade();
|
|
1061
|
+
var drin = pfade.indexOf(id);
|
|
1062
|
+
if (drin !== -1) {
|
|
1063
|
+
/* Der letzte laesst sich nicht abwaehlen - sonst stuende rechts
|
|
1064
|
+
nichts mehr, und der Klick saehe aus wie ein Fehler. */
|
|
1065
|
+
if (pfade.length < 2) { return 'letzter'; }
|
|
1066
|
+
pfade.splice(drin, 1);
|
|
1067
|
+
} else {
|
|
1068
|
+
/* Ein Zweig, der einen anderen enthaelt (oder in ihm liegt), ist
|
|
1069
|
+
kein zweiter Zweig - sonst zaehlten dieselben Punkte doppelt. */
|
|
1070
|
+
var verschachtelt = pfade.some(function (p) {
|
|
1071
|
+
return p === id || id.indexOf(p + '.') === 0 || p.indexOf(id + '.') === 0;
|
|
1072
|
+
});
|
|
1073
|
+
if (verschachtelt) { return 'verschachtelt'; }
|
|
1074
|
+
pfade.push(id);
|
|
1075
|
+
}
|
|
1076
|
+
var eltern = gemeinsamerEltern(pfade);
|
|
1077
|
+
/* Nie ueber die Instanz hinaus. Zwei Zweige aus verschiedenen
|
|
1078
|
+
Adaptern haetten gar keinen gemeinsamen Elternknoten, und zwei
|
|
1079
|
+
Instanzen desselben Adapters nur den Adapternamen - in beiden
|
|
1080
|
+
Faellen stuende die Werkbank auf einem Knoten, der kein Ort ist.
|
|
1081
|
+
Ein Geraet liegt in einer Instanz; das ist keine kuenstliche
|
|
1082
|
+
Schranke, sondern die Lage. */
|
|
1083
|
+
if (!eltern || eltern.split('.').length < 2) { return 'fremd'; }
|
|
1084
|
+
var zweige = pfade.map(function (p) { return p.slice(eltern.length + 1); })
|
|
1085
|
+
.filter(function (z) { return z; });
|
|
1086
|
+
/* Steht ein gewaehlter Pfad selbst auf dem Elternknoten, ist „alles"
|
|
1087
|
+
gemeint - dann ist es wieder eine gewoehnliche Auswahl. */
|
|
1088
|
+
S.zweige = (zweige.length === pfade.length && zweige.length > 1) ? zweige.sort() : null;
|
|
1089
|
+
waehle(eltern, null, true);
|
|
1090
|
+
return '';
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
export function waehle(id, fertig, zweigeBehalten) {
|
|
1094
|
+
/* Ein ANDERER Knoten hebt die Mehrfachauswahl auf, derselbe nicht.
|
|
1095
|
+
|
|
1096
|
+
`waehle(S.current)` heisst an drei Stellen „bau den Entwurf neu" -
|
|
1097
|
+
nach dem Nachladen der Objekte (`objekte.js`), nach einer Aenderung
|
|
1098
|
+
am Bestand (`ergebnis.js`) und nach dem Schreiben (`schreiben.js`).
|
|
1099
|
+
Eine Regel, die hier bei JEDEM Aufruf aufraeumt, loescht die
|
|
1100
|
+
Auswahl beim naechsten Objektereignis aus dem Admin - gemessen
|
|
1101
|
+
13.10.2026 in AA3, wo ein neu angelegter Datenpunkt sie mitnahm.
|
|
1102
|
+
|
|
1103
|
+
Dass ein gewoehnlicher KLICK auf den Elternknoten „alles" bedeutet,
|
|
1104
|
+
entscheidet der Klick selbst (`baum.js`), nicht diese Funktion.
|
|
1105
|
+
`zweigeBehalten` setzt nur `zweigUmschalten`, das den Knoten
|
|
1106
|
+
absichtlich wechselt. */
|
|
1107
|
+
if (!zweigeBehalten && id !== S.current) { S.zweige = null; }
|
|
984
1108
|
/* Wer links etwas anderes anklickt, will es rechts sehen - auch wenn
|
|
985
1109
|
der Fokus noch in einem Feld der rechten Seite steht. `tipptGerade`
|
|
986
1110
|
haelt das Neuzeichnen zurueck, damit ein eintreffender Messwert
|
|
@@ -1042,8 +1166,11 @@ export function waehle(id, fertig) {
|
|
|
1042
1166
|
Zeilen mit neuen Quellen dazukommen. Eine Liste, damit beim
|
|
1043
1167
|
naechsten Wechsel `aboLoesen` alles abmeldet. */
|
|
1044
1168
|
aboLoesen();
|
|
1045
|
-
|
|
1046
|
-
|
|
1169
|
+
/* Bei mehreren Zweigen nur diese, nicht den ganzen Elternknoten. Der
|
|
1170
|
+
traegt oft mehr, als zum Geraet gehoert - bei Matter den Kanal
|
|
1171
|
+
`info` mit der Verbindungsmeldung, anderswo gleich mehrere Geraete. */
|
|
1172
|
+
S.abo = zweigPfade().map(function (p) { return p + '.*'; });
|
|
1173
|
+
S.abo.forEach(function (m) { socket.emit('subscribe', m); });
|
|
1047
1174
|
if (id.indexOf('alias.') === 0) {
|
|
1048
1175
|
var ausAlias = [];
|
|
1049
1176
|
kindZustaende(id).forEach(function (kid) {
|
package/admin/js/ergebnis.js
CHANGED
|
@@ -37,7 +37,9 @@ import {
|
|
|
37
37
|
bestandVorrang,
|
|
38
38
|
kanalGruppen,
|
|
39
39
|
aufteilBehaelter,
|
|
40
|
-
rohEntwurf
|
|
40
|
+
rohEntwurf,
|
|
41
|
+
zweigPfade,
|
|
42
|
+
zweigUmschalten
|
|
41
43
|
} from './entwurf.js';
|
|
42
44
|
import { setzeEnums, setzeZiel, unterschiede } from './zuordnung.js';
|
|
43
45
|
import './detail.js';
|
|
@@ -55,7 +57,7 @@ import {
|
|
|
55
57
|
} from './schreiben.js';
|
|
56
58
|
|
|
57
59
|
import { mqttKarte, mqttSchreiben } from './mqtt.js';
|
|
58
|
-
import { kindZustaende, direkteZustaende } from './werte.js';
|
|
60
|
+
import { kindZustaende, direkteZustaende, mitVorspann } from './werte.js';
|
|
59
61
|
import './aufzaehlungen.js';
|
|
60
62
|
import { erkenneEntwurf } from './erkennung.js';
|
|
61
63
|
import { zusatzName } from './baum.js';
|
|
@@ -308,6 +310,57 @@ var warumAuf = false;
|
|
|
308
310
|
/* Der Kopf: was links angeklickt wurde - Name, Kennung, Bestand
|
|
309
311
|
und der Sprungknopf zum Gegenstueck. Nicht, was daraus werden
|
|
310
312
|
soll: das sagt die Zielzeile darunter. */
|
|
313
|
+
/* Geschwisterzweige mit eigenen Datenpunkten, die noch nicht zur
|
|
314
|
+
Auswahl gehoeren.
|
|
315
|
+
|
|
316
|
+
Gemeint sind Geraete, die ein Adapter auf mehrere Zweige verteilt -
|
|
317
|
+
Matter legt den Schalter in `OnOffPlugInUnit-1` und die Messwerte in
|
|
318
|
+
`ElectricalSensor-2`. Angeboten wird das nur, nie ausgefuehrt.
|
|
319
|
+
|
|
320
|
+
Nicht angeboten wird es an einem Alias (dort gibt es nichts
|
|
321
|
+
zusammenzufassen) und nicht unter einer Instanzwurzel, wo die
|
|
322
|
+
„Nachbarn" schlicht alle anderen Geraete waeren. */
|
|
323
|
+
function nachbarZweige() {
|
|
324
|
+
if (!S.current || S.current.indexOf('alias.') === 0) { return []; }
|
|
325
|
+
var pfade = zweigPfade();
|
|
326
|
+
var eltern = (S.zweige && S.zweige.length)
|
|
327
|
+
? S.current
|
|
328
|
+
: S.current.slice(0, S.current.lastIndexOf('.'));
|
|
329
|
+
if (!eltern || eltern.split('.').length < 3) { return []; }
|
|
330
|
+
var vor = eltern + '.';
|
|
331
|
+
var kinder = {};
|
|
332
|
+
mitVorspann(vor).forEach(function (id) {
|
|
333
|
+
var rest = id.slice(vor.length);
|
|
334
|
+
var erst = rest.split('.')[0];
|
|
335
|
+
if (!erst) { return; }
|
|
336
|
+
if (S.objects[id] && S.objects[id].type === 'state') { kinder[vor + erst] = 1; }
|
|
337
|
+
});
|
|
338
|
+
return Object.keys(kinder).filter(function (k) {
|
|
339
|
+
return pfade.indexOf(k) === -1 &&
|
|
340
|
+
!pfade.some(function (p) { return k.indexOf(p + '.') === 0 || p.indexOf(k + '.') === 0; });
|
|
341
|
+
}).sort();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* Warum das ein Geraet sein koennte - wo es belegbar ist.
|
|
345
|
+
|
|
346
|
+
Matter schreibt an jeden Endpoint dieselbe `nodeId` und dieselbe
|
|
347
|
+
`statusStates.onlineId` (gemessen an matter.0.controller.2,
|
|
348
|
+
13.10.2026). Wo das zutrifft, ist es keine Vermutung. Wo nicht,
|
|
349
|
+
bleibt es ein nuechternes Angebot. */
|
|
350
|
+
function nachbarnGrund(nachbarn) {
|
|
351
|
+
var eigen = S.objects[zweigPfade()[0]] || {};
|
|
352
|
+
var kennung = function (o) {
|
|
353
|
+
var st = ((o.common || {}).statusStates || {}).onlineId || '';
|
|
354
|
+
var nid = (o.native || {}).nodeId;
|
|
355
|
+
return st + '|' + (nid === undefined ? '' : nid);
|
|
356
|
+
};
|
|
357
|
+
var meins = kennung(eigen);
|
|
358
|
+
var gleich = meins !== '|' && nachbarn.every(function (n) {
|
|
359
|
+
return kennung(S.objects[n] || {}) === meins;
|
|
360
|
+
});
|
|
361
|
+
return gleich ? tr('result.addNeighboursSame') : tr('result.addNeighboursHint');
|
|
362
|
+
}
|
|
363
|
+
|
|
311
364
|
function baueKopf() {
|
|
312
365
|
var obj = S.objects[S.current] || {};
|
|
313
366
|
var alleZust = kindZustaende(S.current);
|
|
@@ -322,6 +375,18 @@ var warumAuf = false;
|
|
|
322
375
|
oben steht, nicht unter den Bestandszaehler. */
|
|
323
376
|
var namensZeile = el('div', 'namzeile');
|
|
324
377
|
namensZeile.appendChild(el('div', 'id', kopfName || S.current.split('.').pop()));
|
|
378
|
+
/* Liegt das Geraet auf mehrere Geschwisterzweige verteilt, steht der
|
|
379
|
+
Weg dorthin hier - sichtbar. Strg-Klick im Baum tut dasselbe, aber
|
|
380
|
+
den findet nur, wer schon weiss, dass es ihn gibt. */
|
|
381
|
+
var nachbarn = nachbarZweige();
|
|
382
|
+
if (nachbarn.length) {
|
|
383
|
+
var nk = el('button', 'btn klein', tr('result.addNeighbours', nachbarn.length));
|
|
384
|
+
nk.title = nachbarnGrund(nachbarn);
|
|
385
|
+
nk.addEventListener('click', function () {
|
|
386
|
+
nachbarn.forEach(function (n) { zweigUmschalten(n); });
|
|
387
|
+
});
|
|
388
|
+
namensZeile.appendChild(nk);
|
|
389
|
+
}
|
|
325
390
|
links.appendChild(namensZeile);
|
|
326
391
|
links.appendChild(el('div', 'pfad', S.current));
|
|
327
392
|
|
|
@@ -1050,6 +1115,16 @@ var warumAuf = false;
|
|
|
1050
1115
|
var sg0 = $('#sperrgrund');
|
|
1051
1116
|
if (sg0) { sg0.hidden = true; sg0.textContent = ''; }
|
|
1052
1117
|
if (S.baumModus === 'vorlagen') { return zeichneVorlagenBlatt(host); }
|
|
1118
|
+
/* Eine Meldung aus dem Baum - einmal zeigen, dann weg. Sie steht
|
|
1119
|
+
ganz oben, weil sie auf einen Klick antwortet, der sonst wirkungslos
|
|
1120
|
+
aussieht. */
|
|
1121
|
+
if (S.zweigMeldung) {
|
|
1122
|
+
var zm = el('div', 'aside w');
|
|
1123
|
+
zm.style.borderLeftColor = 'var(--warn)';
|
|
1124
|
+
zm.textContent = S.zweigMeldung;
|
|
1125
|
+
host.appendChild(zm);
|
|
1126
|
+
S.zweigMeldung = '';
|
|
1127
|
+
}
|
|
1053
1128
|
var bck = $('#btn-checks');
|
|
1054
1129
|
if (bck) { bck.disabled = false; }
|
|
1055
1130
|
if (!S.current || !S.entwurf) { return zeichneLeer(host); }
|