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/werte.js
CHANGED
|
@@ -42,7 +42,7 @@ export function jsonVon(id) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export function feldWert(obj, pfad) {
|
|
45
|
-
var t = pfad
|
|
45
|
+
var t = pfadTeile(pfad);
|
|
46
46
|
var x = obj;
|
|
47
47
|
for (var i = 0; i < t.length; i++) {
|
|
48
48
|
if (x === null || x === undefined || typeof x !== 'object') { return undefined; }
|
|
@@ -171,7 +171,11 @@ export function zeileAusAlias(o, zeilenname) {
|
|
|
171
171
|
aber als Lesequelle gilt sie nicht: sonst zeigte „Alias bearbeiten"
|
|
172
172
|
eine Quelle, die „Alias anlegen" nie eingetragen hat, und beim
|
|
173
173
|
naechsten Aktualisieren kippte `read` still auf `true` zurueck. */
|
|
174
|
-
|
|
174
|
+
/* Seit 19.09.2026 auch beim Taster: `read: false` am Alias haengt an
|
|
175
|
+
der Rolle, nicht an einer fehlenden Lesequelle (`knopfZeile`). Ein
|
|
176
|
+
alter Taster-Alias mit einfacher `alias.id` liest also aus seinem
|
|
177
|
+
Schreibziel - genau das, was ioBroker mit ihm ohnehin tut. */
|
|
178
|
+
srcR: q.read || '',
|
|
175
179
|
srcW: schreibQuelle(o),
|
|
176
180
|
f: (typeof a.read === 'string') ? a.read : '',
|
|
177
181
|
fw: (typeof a.write === 'string') ? a.write : '',
|
|
@@ -285,7 +289,7 @@ export function auswerten(formel, roh) {
|
|
|
285
289
|
var gedauert = performance.now() - t0;
|
|
286
290
|
if (gedauert > GEDULD_MS) {
|
|
287
291
|
formelGesperrt[formel] = Math.round(gedauert);
|
|
288
|
-
console.warn('[alias-workbench]
|
|
292
|
+
console.warn('[alias-workbench] Formula blocked after ' + Math.round(gedauert) + ' ms: ' + formel);
|
|
289
293
|
return { ok: false, txt: tr('detail.formulaTooSlow', Math.round(gedauert)), fehler: true };
|
|
290
294
|
}
|
|
291
295
|
if (sch !== null) {
|
|
@@ -375,6 +379,49 @@ var FELDTEIL = "\\??\\.(?:[A-Za-z_$][\\w$]*|\\[(?:'(?:[^'\\\\]|\\\\.)*'|\"(?:[^\
|
|
|
375
379
|
var FELDPFAD = new RegExp('^JSON\\.parse\\(val\\)((?:' + FELDTEIL + ')+)(?:\\s*\\?\\?\\s*null)?$');
|
|
376
380
|
var FELDSTUECK = new RegExp(FELDTEIL, 'g');
|
|
377
381
|
|
|
382
|
+
/* Der Feldpfad als Text und zurueck (X12, 19.09.2026).
|
|
383
|
+
|
|
384
|
+
Gewoehnlich sind die Stuecke durch Punkte getrennt: `ENERGY.Power`,
|
|
385
|
+
`service.storage./dev/shm.free`. Das bleibt zeichengleich - so stehen
|
|
386
|
+
die Pfade in gespeicherten Vorlagen, und die sollen weiter gelten.
|
|
387
|
+
Nur ein Schluessel, der SELBST einen Punkt enthaelt, steht in Klammern
|
|
388
|
+
ohne Punkt davor: `cpu_usages['frigate.full_system'].cpu`. Vorher
|
|
389
|
+
wurde er an jedem Punkt zerteilt, die Formel suchte
|
|
390
|
+
`?.frigate?.full_system` und ergab null. Frigate hat so einen
|
|
391
|
+
Schluessel in `stats`. Ein Stueck, das mit `[` anfaengt, kommt aus
|
|
392
|
+
demselben Grund in Klammern. */
|
|
393
|
+
export function pfadAus(teile) {
|
|
394
|
+
var raus = '';
|
|
395
|
+
teile.forEach(function (t, n) {
|
|
396
|
+
t = String(t);
|
|
397
|
+
if (t.indexOf('.') > -1 || t.charAt(0) === '[') {
|
|
398
|
+
raus += "['" + t.replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "']";
|
|
399
|
+
} else {
|
|
400
|
+
raus += (n ? '.' : '') + t;
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
return raus;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export function pfadTeile(pfad) {
|
|
407
|
+
var s = String(pfad || ''), teile = [], i = 0;
|
|
408
|
+
while (i < s.length) {
|
|
409
|
+
if (s.charAt(i) === '.') { i++; continue; }
|
|
410
|
+
if (s.slice(i, i + 2) === "['") {
|
|
411
|
+
var j = i + 2, t = '';
|
|
412
|
+
while (j < s.length && !(s.charAt(j) === "'" && s.charAt(j + 1) === ']')) {
|
|
413
|
+
if (s.charAt(j) === '\\' && j + 1 < s.length) { j++; }
|
|
414
|
+
t += s.charAt(j); j++;
|
|
415
|
+
}
|
|
416
|
+
teile.push(t); i = j + 2; continue;
|
|
417
|
+
}
|
|
418
|
+
var k = i;
|
|
419
|
+
while (k < s.length && s.charAt(k) !== '.' && s.slice(k, k + 2) !== "['") { k++; }
|
|
420
|
+
teile.push(s.slice(i, k)); i = k;
|
|
421
|
+
}
|
|
422
|
+
return teile;
|
|
423
|
+
}
|
|
424
|
+
|
|
378
425
|
export function feldAusFormel(f) {
|
|
379
426
|
var m = FELDPFAD.exec(f || '');
|
|
380
427
|
if (!m) { return ''; }
|
|
@@ -386,21 +433,19 @@ export function feldAusFormel(f) {
|
|
|
386
433
|
if (s.charAt(0) === '[') {
|
|
387
434
|
/* Nur die Fluchtzeichen zurueckdrehen, die feldSegment setzt. */
|
|
388
435
|
s = s.slice(2, -2).replace(/\\(.)/g, '$1');
|
|
389
|
-
/* Ein Punkt im Schluessel selbst laesst sich im Pfadformat von
|
|
390
|
-
`jsonFelder` nicht wieder auseinanderhalten — dann lieber
|
|
391
|
-
„eigene Formel" zeigen als einen Pfad, der nicht zurueckfuehrt. */
|
|
392
|
-
if (s.indexOf('.') > -1) { return ''; }
|
|
393
436
|
}
|
|
394
437
|
teile.push(s);
|
|
395
438
|
}
|
|
396
|
-
|
|
439
|
+
/* Ein Punkt im Schluessel selbst kommt seit X12 in Klammern zurueck
|
|
440
|
+
(`pfadAus`); vorher hiess das hier „eigene Formel". */
|
|
441
|
+
return pfadAus(teile);
|
|
397
442
|
}
|
|
398
443
|
|
|
399
444
|
/* Der abgesicherte Zugriff auf ein JSON-Feld. An einer Stelle, damit die
|
|
400
445
|
Vorlagen-Abkuerzung und die Feldauswahl im Detail dasselbe bauen. */
|
|
401
446
|
export function feldFormel(feld) {
|
|
402
447
|
if (!feld) { return ''; }
|
|
403
|
-
return 'JSON.parse(val)' +
|
|
448
|
+
return 'JSON.parse(val)' + pfadTeile(feld).map(feldSegment).join('') + ' ?? null';
|
|
404
449
|
}
|
|
405
450
|
|
|
406
451
|
/* ---- Feldpfade: Ende ---- */
|
|
@@ -412,18 +457,49 @@ export function jsonFelder(id) {
|
|
|
412
457
|
try { o = JSON.parse(st.val); } catch { return null; }
|
|
413
458
|
if (!o || typeof o !== 'object') { return null; }
|
|
414
459
|
var raus = [];
|
|
415
|
-
(function geh(x,
|
|
460
|
+
(function geh(x, weg, tiefe) {
|
|
416
461
|
if (tiefe > 3) { return; }
|
|
417
462
|
Object.keys(x).forEach(function (k) {
|
|
418
|
-
var
|
|
419
|
-
if (x[k] && typeof x[k] === 'object' && !Array.isArray(x[k])) { geh(x[k],
|
|
420
|
-
else { raus.push(
|
|
463
|
+
var w = weg.concat([k]);
|
|
464
|
+
if (x[k] && typeof x[k] === 'object' && !Array.isArray(x[k])) { geh(x[k], w, tiefe + 1); }
|
|
465
|
+
else { raus.push(pfadAus(w)); }
|
|
421
466
|
});
|
|
422
|
-
})(o,
|
|
467
|
+
})(o, [], 0);
|
|
423
468
|
return raus;
|
|
424
469
|
}
|
|
425
470
|
|
|
426
471
|
|
|
472
|
+
/* Ist das Objekt ein Taster - ein Punkt ohne Zustand?
|
|
473
|
+
|
|
474
|
+
`read: false` allein reicht nicht (siehe `zielKann`). Dazu muss er
|
|
475
|
+
schreibbar sein und sich als Tastendruck ausweisen: Homematic ueber
|
|
476
|
+
`native.TYPE: ACTION`, alle anderen ueber eine Rolle `button…`. Die
|
|
477
|
+
eine Stelle fuer diese Frage - der Entwurf fragt sie auch. */
|
|
478
|
+
export function istTaster(o) {
|
|
479
|
+
var c = (o && o.common) || {};
|
|
480
|
+
var nat = (o && o.native) || {};
|
|
481
|
+
return c.read === false && !!c.write &&
|
|
482
|
+
(nat.TYPE === 'ACTION' || /^button/.test(String(c.role || '')));
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/* Wird der Alias-Datenpunkt ein Knopf?
|
|
486
|
+
|
|
487
|
+
Die eine Regel fuer `common.read` am Alias (Ricardo, 19.09.2026): Rolle
|
|
488
|
+
`button…` UND ein Schreibziel -> Knopf, `read: false`. Alles andere
|
|
489
|
+
`read: true`. So steht es in der Rollenliste von ioBroker: „Buttons
|
|
490
|
+
(booleans, write-only) … common.write=true, common.read=false"; der
|
|
491
|
+
Tastensensor (`button.press`, `button.long` ohne Schreiben) liest.
|
|
492
|
+
|
|
493
|
+
Nicht aus der Quelle abgeleitet: deren `read` setzt jeder Adapter
|
|
494
|
+
anders. hm-rpc schreibt `read: false` an `BOOST_MODE`, einen Schalter,
|
|
495
|
+
der seinen Zustand meldet - uebernommen, zeichneten vis, Alexa und
|
|
496
|
+
matter den Boost als Knopf. Und nicht aus einer fehlenden Lesequelle:
|
|
497
|
+
gemessen am Testsystem liest ein Alias mit `read: false` trotzdem aus
|
|
498
|
+
seiner Lesequelle, jeder Druck kommt an. */
|
|
499
|
+
export function knopfZeile(s) {
|
|
500
|
+
return !!(s && s.srcW && /^button/.test(String(s.role || '')));
|
|
501
|
+
}
|
|
502
|
+
|
|
427
503
|
/* ---- Was das Ziel kann ---------------------------------------------
|
|
428
504
|
|
|
429
505
|
Die Werkbank schreibt auf fremde Punkte und liest aus fremden Punkten.
|
|
@@ -440,8 +516,15 @@ export function jsonFelder(id) {
|
|
|
440
516
|
Schreibvorgang trotzdem durch — gemessen —, der Adapter
|
|
441
517
|
dahinter reicht ihn aber nicht ans Geraet weiter.
|
|
442
518
|
Ein stiller Blindgaenger.
|
|
443
|
-
|
|
444
|
-
|
|
519
|
+
Bis 19.09.2026 stand an dritter Stelle `meldetNichts`: jede Lesequelle
|
|
520
|
+
mit `read: false` bekam die Marke „aendert sich nie". Gemessen am
|
|
521
|
+
Produktivsystem traf das 1371 Punkte, 620 davon keine Taster, und 76
|
|
522
|
+
dieser 620 hatten ihren Wert in den letzten 30 Tagen geaendert -
|
|
523
|
+
`BOOST_MODE` an den Heizungen etwa. hm-rpc setzt `read: false`, sobald
|
|
524
|
+
der Wert nicht *abfragbar* ist (OPERATIONS ohne Bit 1); gemeldet wird er
|
|
525
|
+
trotzdem. Aus dem Feld allein laesst sich nicht ablesen, ob ein Punkt
|
|
526
|
+
lebt, und wer der Marke folgte, nahm eine funktionierende Lesequelle
|
|
527
|
+
heraus (Ricardo).
|
|
445
528
|
|
|
446
529
|
Gibt eine Liste zurueck, nicht ein Urteil — wer sie anzeigt, entscheidet
|
|
447
530
|
ueber die Schaerfe. */
|
|
@@ -463,10 +546,5 @@ export function zielKann(s) {
|
|
|
463
546
|
}
|
|
464
547
|
}
|
|
465
548
|
|
|
466
|
-
if (s.srcR) {
|
|
467
|
-
var r = S.objects[s.srcR];
|
|
468
|
-
var rc = (r && r.common) || null;
|
|
469
|
-
if (rc && rc.read === false) { raus.push({ art: 'meldetNichts', punkt: s.srcR }); }
|
|
470
|
-
}
|
|
471
549
|
return raus;
|
|
472
550
|
}
|
package/admin/js/zielleiste.js
CHANGED
|
@@ -11,7 +11,7 @@ import { el } from './basis.js';
|
|
|
11
11
|
import { tr } from './sprache.js';
|
|
12
12
|
import { enumListe } from './aufzaehlungen.js';
|
|
13
13
|
import { enumZeile, setzeZiel } from './zuordnung.js';
|
|
14
|
-
import { aliasFuer, ordnerUnterAlias, kennungtauglich, knotenDa } from './entwurf.js';
|
|
14
|
+
import { aliasFuer, ausgangsQuellen, ordnerUnterAlias, kennungtauglich, knotenDa } from './entwurf.js';
|
|
15
15
|
import { zeichneErgebnis, entwurfAngefasst, angebotFrisch } from './ergebnis.js';
|
|
16
16
|
import { zeigeVerlegen } from './schreiben.js';
|
|
17
17
|
|
|
@@ -381,7 +381,13 @@ export function baueZielleiste(host, e) {
|
|
|
381
381
|
irrt sie hier, irrt sie dort ebenso. Und der Hinweis haelt
|
|
382
382
|
niemanden auf. */
|
|
383
383
|
var zwilling = null;
|
|
384
|
-
|
|
384
|
+
/* Dieselbe Frage wie die Vorbelegung, also auch dieselbe Antwort:
|
|
385
|
+
am Mehrfachgeraet der Alias DIESES Ausgangs. Sonst nennt der
|
|
386
|
+
Hinweis einen anderen Alias als den, dessen Stand oben in der
|
|
387
|
+
Liste steht - zwei Aussagen auf einem Bildschirm, die sich
|
|
388
|
+
widersprechen (C13). */
|
|
389
|
+
var vorhAlias = aliasFuer(e.kanal, ausgangsQuellen(e)) ||
|
|
390
|
+
((e.instanz === null || e.instanz === undefined) ? aliasFuer(e.kanal) : null);
|
|
385
391
|
if (vorhAlias && S.objects[vorhAlias] && vorhAlias !== e.ziel) {
|
|
386
392
|
var zw = el('div', 'uebernahme zwilling');
|
|
387
393
|
zw.appendChild(el('span', 'zq', tr('target.twinExists', vorhAlias)));
|
package/admin/js/zuordnung.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { S } from './zustand.js';
|
|
5
5
|
import { el } from './basis.js';
|
|
6
6
|
import { tr, txt } from './sprache.js';
|
|
7
|
-
import { enums, enumsUnbekannt } from './enums.js';
|
|
7
|
+
import { enums, enumsUnbekannt, beiEnumsGeladen } from './enums.js';
|
|
8
8
|
import {
|
|
9
9
|
enumListe,
|
|
10
10
|
enumsVon,
|
|
@@ -16,7 +16,8 @@ import { enumVorlagen, katalogFehlt, ikonCache, ikonErlaubt, ikonNachtrag,
|
|
|
16
16
|
ikonTaugt, vorlageZu, holeIkon } from './katalog.js';
|
|
17
17
|
import { kindZustaende, aliasQuellen, holeEinzelne,
|
|
18
18
|
zeileAusAlias } from './werte.js';
|
|
19
|
-
import { aliasFuer, zielId, knotenDa
|
|
19
|
+
import { aliasFuer, ausgangsQuellen, zielId, knotenDa,
|
|
20
|
+
aboErgaenzen, quellenVonEntwurf } from './entwurf.js';
|
|
20
21
|
import { zeichneErgebnis, entwurfAngefasst, angebotFrisch } from './ergebnis.js';
|
|
21
22
|
|
|
22
23
|
|
|
@@ -237,6 +238,15 @@ export function enumZeile(host, e) {
|
|
|
237
238
|
ex.title = tr('enums.clear');
|
|
238
239
|
ex.setAttribute('aria-label', tr('enums.clear'));
|
|
239
240
|
ex.hidden = !ei.value;
|
|
241
|
+
/* Aufzaehlungen nicht geladen: dann wird Raum und Funktion nicht
|
|
242
|
+
geschrieben, also laesst sich hier auch nichts waehlen. Vorher
|
|
243
|
+
stand das nur im Trockenlauf, und die Felder sahen aus wie immer
|
|
244
|
+
(P8, 19.09.2026). */
|
|
245
|
+
if (enumsUnbekannt()) {
|
|
246
|
+
ei.disabled = true;
|
|
247
|
+
ex.disabled = true;
|
|
248
|
+
ei.title = tr('enums.unknown');
|
|
249
|
+
}
|
|
240
250
|
ex.addEventListener('mousedown', function (ev) {
|
|
241
251
|
ev.preventDefault();
|
|
242
252
|
e[spec.feld] = '';
|
|
@@ -269,7 +279,7 @@ export function enumZeile(host, e) {
|
|
|
269
279
|
if (spec.art === 'rooms' && e.zuletzt === 'raum' && e.ziel && !aliasFuer(e.kanal)) {
|
|
270
280
|
var ro2 = enumAlsOrdner(e.raum);
|
|
271
281
|
if (ro2 && e.zielOrdner !== 'alias.0.' + ro2) {
|
|
272
|
-
var oz = el('div', 'uebernahme' +
|
|
282
|
+
var oz = el('div', 'uebernahme raumangebot' +
|
|
273
283
|
(angebotFrisch('raum:' + ro2) ? ' frisch' : ''));
|
|
274
284
|
oz.appendChild(el('span', 'zq', tr('enums.alsoFolder', ro2)));
|
|
275
285
|
var ob = el('button', 'btn mini wichtig', tr('target.yes'));
|
|
@@ -340,15 +350,7 @@ export function enumZeile(host, e) {
|
|
|
340
350
|
: (x.anzahl ? tr('enums.members', x.anzahl) : tr('enums.unused'))));
|
|
341
351
|
z.addEventListener('mousedown', function (ev) {
|
|
342
352
|
ev.preventDefault();
|
|
343
|
-
|
|
344
|
-
e[spec.her] = 'hand';
|
|
345
|
-
if (spec.art === 'rooms') { e.zuletzt = 'raum'; }
|
|
346
|
-
/* Das Icon jetzt holen, nicht erst beim Schreiben: dort ist
|
|
347
|
-
kein Warten mehr moeglich, der Objektbau laeuft synchron. */
|
|
348
|
-
if (x.vorlage && x.vorlage.icon) { holeIkon(spec.art, x.vorlage.icon); }
|
|
349
|
-
entwurfAngefasst();
|
|
350
|
-
zu();
|
|
351
|
-
zeichneErgebnis();
|
|
353
|
+
nimm(x);
|
|
352
354
|
});
|
|
353
355
|
el2.appendChild(z);
|
|
354
356
|
});
|
|
@@ -365,6 +367,23 @@ export function enumZeile(host, e) {
|
|
|
365
367
|
el2.hidden = false;
|
|
366
368
|
};
|
|
367
369
|
|
|
370
|
+
/* Einen Eintrag der Liste uebernehmen — fuer Mausklick und Enter
|
|
371
|
+
dieselbe Stelle. Bis 19.09.2026 waren es zwei, und der Enter-Weg
|
|
372
|
+
vergass zweierlei: `e.zuletzt`, an dem das Angebot „Den Alias auch
|
|
373
|
+
unter … ablegen?“ haengt, und das Bild einer neuen Aufzaehlung aus
|
|
374
|
+
den Vorlagen des Admin (Lauf vom 19.09.2026, S3). */
|
|
375
|
+
function nimm(x) {
|
|
376
|
+
e[spec.feld] = x.id;
|
|
377
|
+
e[spec.her] = 'hand';
|
|
378
|
+
if (spec.art === 'rooms') { e.zuletzt = 'raum'; }
|
|
379
|
+
/* Das Icon jetzt holen, nicht erst beim Schreiben: dort ist
|
|
380
|
+
kein Warten mehr moeglich, der Objektbau laeuft synchron. */
|
|
381
|
+
if (x.vorlage && x.vorlage.icon) { holeIkon(spec.art, x.vorlage.icon); }
|
|
382
|
+
entwurfAngefasst();
|
|
383
|
+
zu();
|
|
384
|
+
zeichneErgebnis();
|
|
385
|
+
}
|
|
386
|
+
|
|
368
387
|
ei.addEventListener('focus', function () { ei.value = ''; mMark = -1; malen(); });
|
|
369
388
|
ei.addEventListener('input', function () { mMark = -1; malen(); });
|
|
370
389
|
ei.addEventListener('blur', function () {
|
|
@@ -386,18 +405,23 @@ export function enumZeile(host, e) {
|
|
|
386
405
|
}
|
|
387
406
|
if (ev.key === 'Enter' && !el2.hidden && mListe.length) {
|
|
388
407
|
ev.preventDefault();
|
|
389
|
-
|
|
390
|
-
e[spec.her] = 'hand';
|
|
391
|
-
entwurfAngefasst();
|
|
392
|
-
zu();
|
|
393
|
-
zeichneErgebnis();
|
|
408
|
+
nimm(mListe[mMark >= 0 ? mMark : 0]);
|
|
394
409
|
}
|
|
395
410
|
});
|
|
396
411
|
});
|
|
397
412
|
if (enumAngebot) { ebar.appendChild(enumAngebot); }
|
|
398
413
|
host.appendChild(ebar);
|
|
414
|
+
if (enumsUnbekannt()) {
|
|
415
|
+
var eh = el('div', 'aside w', tr('enums.notLoadedField'));
|
|
416
|
+
eh.style.margin = '4px 0 8px';
|
|
417
|
+
host.appendChild(eh);
|
|
418
|
+
}
|
|
399
419
|
}
|
|
400
420
|
|
|
421
|
+
/* Klappt ein Nachversuch, verschwindet der Hinweis von selbst - sonst
|
|
422
|
+
stuende er bis zum naechsten Klick da, obwohl alles wieder geht. */
|
|
423
|
+
beiEnumsGeladen(function () { if (S.current) { zeichneErgebnis(); } });
|
|
424
|
+
|
|
401
425
|
/* Welcher Raum, welche Funktion - und woher.
|
|
402
426
|
|
|
403
427
|
Gibt es den Alias schon, gilt, was dort steht: seine Zuordnung ist eine
|
|
@@ -475,18 +499,35 @@ export function setzeZiel(e) {
|
|
|
475
499
|
/* Mehrere Ausgaenge: das Geraet wird zum Ordner, jeder Ausgang
|
|
476
500
|
ein Kanal darin. Ein folder darueber, kein device — sonst
|
|
477
501
|
rutscht die Erkennung hoch und macht aus dreien wieder eins. */
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
502
|
+
/* Gibt es den Alias fuer GENAU DIESEN Ausgang, ist er das Ziel —
|
|
503
|
+
mit seinem eigenen Namen, nicht mit dem der Ausgangsnummer.
|
|
504
|
+
|
|
505
|
+
Hier stand: „Wie der einzelne Ausgang heisst, kann die Werkbank
|
|
506
|
+
nicht wissen." Das galt, solange sie nur nach dem GERAET fragen
|
|
507
|
+
konnte. Seit `ausgangsQuellen` weiss sie es: Ricardos `RF1000`
|
|
508
|
+
liest aus `stat.POWER1` und ist damit Ausgang 1. Vorher schlug
|
|
509
|
+
die Zielzeile `…Steckdosenleiste.POWER1` vor — eine Kennung, die
|
|
510
|
+
es gar nicht gibt —, meldete „wird neu angelegt" und haette beim
|
|
511
|
+
Klick einen zweiten Alias neben `RF1000` gesetzt (C13,
|
|
512
|
+
16.09.2026). */
|
|
513
|
+
var vorhAus = aliasFuer(S.current, ausgangsQuellen(e));
|
|
514
|
+
if (vorhAus) {
|
|
515
|
+
var ta = vorhAus.split('.');
|
|
516
|
+
e.zielName = ta.pop();
|
|
517
|
+
e.zielOrdner = ta.join('.');
|
|
486
518
|
} else {
|
|
487
|
-
|
|
519
|
+
if (vorhanden) {
|
|
520
|
+
/* Kein Alias fuer diesen Ausgang, aber einer am Geraet: der gibt
|
|
521
|
+
wenigstens den Ordner vor. Der Name kommt aus der
|
|
522
|
+
Ausgangsnummer — hier entsteht wirklich etwas Neues. */
|
|
523
|
+
var tm = vorhanden.split('.');
|
|
524
|
+
tm.pop();
|
|
525
|
+
e.zielOrdner = tm.join('.');
|
|
526
|
+
} else {
|
|
527
|
+
e.zielOrdner = zt0.join('.') + '.' + geraet;
|
|
528
|
+
}
|
|
529
|
+
e.zielName = ausgangName(e, e.instanz);
|
|
488
530
|
}
|
|
489
|
-
e.zielName = ausgangName(e, e.instanz);
|
|
490
531
|
} else if (vorhanden) {
|
|
491
532
|
var te = vorhanden.split('.');
|
|
492
533
|
e.zielName = te.pop();
|
|
@@ -583,7 +624,10 @@ export function uebernehmeBestand(e) {
|
|
|
583
624
|
function vomAliasUebernehmen(z, o) {
|
|
584
625
|
var c = o.common || {}, q2 = aliasQuellen(o);
|
|
585
626
|
var ist = zeileAusAlias(o, z.n);
|
|
586
|
-
|
|
627
|
+
/* Dieselbe Frage wie in `bestandVorrang`: ohne Vorlage gibt es keinen
|
|
628
|
+
Vorlagenwert. Sonst verglich die Zeile gegen den Rohentwurf und
|
|
629
|
+
nannte das „weicht von der Vorlage ab" (17.09.2026). */
|
|
630
|
+
if (!z.vorlagenWert && e.vorschlag && e.vorlage) {
|
|
587
631
|
z.vorlagenWert = {
|
|
588
632
|
on: z.on, role: z.role, typ: z.typ, unit: z.unit, caption: z.caption,
|
|
589
633
|
f: z.f, fw: z.fw, srcR: z.srcR, srcW: z.srcW, states: z.states
|
|
@@ -768,6 +812,13 @@ export function uebernehmeBestand(e) {
|
|
|
768
812
|
});
|
|
769
813
|
}
|
|
770
814
|
}
|
|
815
|
+
/* Geholt ist nur der erste Wert - mitlaufen tut er erst mit einem Abo.
|
|
816
|
+
Die Zeilen aus dem Alias lesen oft aus einem anderen Knoten als dem
|
|
817
|
+
angeklickten (J9, 18.09.2026: `Stromzaehler` zeigte drei Zeilen „aus
|
|
818
|
+
Solar.Netz" stundenlang auf dem Stand vom Anklicken). Ergaenzt wird
|
|
819
|
+
nur, was noch nicht laeuft; bei jedem Zeichnen zu rufen kostet also
|
|
820
|
+
nichts. */
|
|
821
|
+
if (S.entwurf === e && e.kanal === S.current) { aboErgaenzen(quellenVonEntwurf(e)); }
|
|
771
822
|
}
|
|
772
823
|
|
|
773
824
|
export function unterschiede(e) {
|
package/admin/js/zustand.js
CHANGED
|
@@ -14,6 +14,11 @@ export var S = {
|
|
|
14
14
|
objects: {},
|
|
15
15
|
keysSorted: [],
|
|
16
16
|
kleinIndex: {},
|
|
17
|
+
/* Zaehlt jede Aenderung an S.objects. Wer sich etwas aus den Objekten
|
|
18
|
+
merkt (die Karte Quelle -> Alias in entwurf.js), vergleicht hiermit
|
|
19
|
+
statt mit der Zahl der Schluessel — beim Verlegen verschwinden genau
|
|
20
|
+
so viele, wie dazukommen (T22). */
|
|
21
|
+
objektStand: 0,
|
|
17
22
|
/* Alias-Kanal -> Zahl der Punkte, deren Quelle es nicht (mehr) gibt.
|
|
18
23
|
Einmal beim Laden gerechnet; der Baum schlaegt nur nach. */
|
|
19
24
|
aliasKaputt: {},
|
|
@@ -44,7 +49,6 @@ export var S = {
|
|
|
44
49
|
loeschListe: [],
|
|
45
50
|
loeschZiel: null,
|
|
46
51
|
loeschAlleAusgaenge: false,
|
|
47
|
-
verlegeZiel: null,
|
|
48
52
|
/* Einmal registrierter Schliesser fuer die Quellenauswahl am
|
|
49
53
|
Sprungknopf - siehe ergebnis.js. */
|
|
50
54
|
sprungZuhoerer: false,
|