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/mqtt.js
CHANGED
|
@@ -48,9 +48,24 @@ export function mqttEinstellung(id) {
|
|
|
48
48
|
publish: true }` galt als sendefaehig, obwohl die Instanz diesen
|
|
49
49
|
Punkt nicht bedient. Fehlt das Feld, gilt der Eintrag als an — so
|
|
50
50
|
legt der Admin es an, wenn man die Verknuepfung setzt. */
|
|
51
|
+
var aus = null;
|
|
51
52
|
Object.keys(cu).forEach(function (x) {
|
|
52
|
-
if (
|
|
53
|
+
if (!/^mqtt/.test(x) || !cu[x]) { return; }
|
|
54
|
+
if (cu[x].enabled !== false) { if (!k) { k = x; } }
|
|
55
|
+
else if (!aus) { aus = x; }
|
|
53
56
|
});
|
|
57
|
+
/* Eine abgeschaltete Verknuepfung ist eine Auskunft, kein Nichtwissen.
|
|
58
|
+
|
|
59
|
+
Steht das Thema zusaetzlich in `native` — bei mqtt-client der
|
|
60
|
+
Normalfall —, fiel der Punkt vorher in den Zweig darunter und galt
|
|
61
|
+
als „Thema da, Senden unbekannt"; die Karte zeigte dafuer gruen
|
|
62
|
+
„angelegt, sendet", obwohl die Instanz ihn nicht bedient (Ricardo,
|
|
63
|
+
20.09.2026; Lauf vom 19.09.2026, H13). Wer den Schalter ausdruecklich
|
|
64
|
+
auf aus gestellt hat, bekommt das jetzt gesagt. */
|
|
65
|
+
if (!k && aus) {
|
|
66
|
+
return { instanz: aus, topic: cu[aus].topic || (o.native || {}).topic || '',
|
|
67
|
+
publish: false, abgeschaltet: true, roh: cu[aus] };
|
|
68
|
+
}
|
|
54
69
|
if (!k) {
|
|
55
70
|
/* Manche Objekte tragen das Thema nur in native — ioBroker.mqtt und
|
|
56
71
|
sonoff tun das. Fuer sie ist `publish` schlicht UNBEKANNT, nicht
|
|
@@ -149,6 +164,38 @@ export function befehlsWissen(name) {
|
|
|
149
164
|
return null;
|
|
150
165
|
}
|
|
151
166
|
|
|
167
|
+
/* Welche Zeilen haengen ueberhaupt am Telemetrietakt?
|
|
168
|
+
|
|
169
|
+
Betroffen ist nur die eine Bauform: aus `tele/...` lesen und nach
|
|
170
|
+
`cmnd/...` schreiben. Wer aus `stat/POWER1` liest, bekommt die Antwort
|
|
171
|
+
bei jedem Befehl sofort — SetOption59 aendert daran nichts.
|
|
172
|
+
|
|
173
|
+
Ricardos Steckdosenleiste hat keine einzige solche Zeile: seine Aliase
|
|
174
|
+
lesen alle aus `stat.POWERn`. Trotzdem stand der SetOption59-Block an
|
|
175
|
+
der Karte und die Pruefung meldete "alle in Ordnung", als waere etwas
|
|
176
|
+
geprueft worden. Beides ist jetzt an diese Frage gebunden
|
|
177
|
+
(Ricardo, 16.09.2026). */
|
|
178
|
+
export function telegesteuert(e) {
|
|
179
|
+
if (!e || !e.states) { return []; }
|
|
180
|
+
return e.states.filter(function (x) {
|
|
181
|
+
if (!x.on || !x.srcW || !x.srcR) { return false; }
|
|
182
|
+
return /\.tele\./.test(x.srcR) && /\.cmnd\./.test(x.srcW);
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* Wie oft meldet das Geraet von sich aus? Steht in tele/STATE.
|
|
187
|
+
|
|
188
|
+
Ohne diese Zahl stand im Hinweis "minutenlang" — das unterstellt die
|
|
189
|
+
Tasmota-Vorgabe von 300 Sekunden. An Ricardos Leiste sind es zehn
|
|
190
|
+
(gemessen 16.09.2026: tele/STATE im Zehnsekundentakt). Wer eine Zahl
|
|
191
|
+
nennt, soll die richtige nennen. */
|
|
192
|
+
export function telePeriode(kanal) {
|
|
193
|
+
var id = hatPunkt(kanal, 'tele.STATE');
|
|
194
|
+
var j = id ? jsonVon(id) : null;
|
|
195
|
+
var n = j && Number(j.TelePeriod);
|
|
196
|
+
return (n && isFinite(n)) ? n : null;
|
|
197
|
+
}
|
|
198
|
+
|
|
152
199
|
/* Meldet das Geraet Aenderungen sofort? Das haengt an SetOption59.
|
|
153
200
|
|
|
154
201
|
Die Bitmaske aus StatusLOG zu entziffern waere moeglich, ist aber
|
|
@@ -229,16 +276,20 @@ export function mqttLage(kanal) {
|
|
|
229
276
|
var g = mqttGeraet(kanal);
|
|
230
277
|
if (!g) { return null; }
|
|
231
278
|
var b = tasmotaBefehle(kanal);
|
|
232
|
-
var fehlen = [], stumm = [], da = [];
|
|
279
|
+
var fehlen = [], stumm = [], da = [], unklar = [];
|
|
233
280
|
if (b) {
|
|
234
281
|
b.befehle.forEach(function (x) {
|
|
235
282
|
var id = hatPunkt(kanal, 'cmnd.' + x.name);
|
|
236
283
|
if (!id) { fehlen.push(x); return; }
|
|
237
284
|
var m = mqttEinstellung(id);
|
|
238
|
-
/* `publish === null` heisst unbekannt (Thema nur in `native
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
285
|
+
/* `publish === null` heisst unbekannt (Thema nur in `native`, ohne
|
|
286
|
+
Verknuepfung — ioBroker.mqtt und sonoff). Frueher kam so ein
|
|
287
|
+
Punkt zu den vorhandenen und stand gruen als „angelegt, sendet"
|
|
288
|
+
da; behauptet ist damit mehr, als die Werkbank weiss. Er steht
|
|
289
|
+
jetzt eigens (Ricardo, 20.09.2026). */
|
|
290
|
+
if (m && m.publish === false) { stumm.push({ name: x.name, id: id }); }
|
|
291
|
+
else if (m && m.publish === null) { unklar.push(x.name); }
|
|
292
|
+
else { da.push(x.name); }
|
|
242
293
|
});
|
|
243
294
|
}
|
|
244
295
|
/* Auch cmnd-Punkte, die es schon gibt, ohne dass sie im Zustand
|
|
@@ -251,8 +302,9 @@ export function mqttLage(kanal) {
|
|
|
251
302
|
if (da.indexOf(name) > -1) { return; }
|
|
252
303
|
var m = mqttEinstellung(id);
|
|
253
304
|
if (m && m.publish === false) { stumm.push({ name: name, id: id }); }
|
|
305
|
+
else if (m && m.publish === null && unklar.indexOf(name) === -1) { unklar.push(name); }
|
|
254
306
|
});
|
|
255
|
-
return { geraet: g, befehle: b, fehlen: fehlen, stumm: stumm, da: da,
|
|
307
|
+
return { geraet: g, befehle: b, fehlen: fehlen, stumm: stumm, da: da, unklar: unklar,
|
|
256
308
|
sofort: sofortRueckmeldung(kanal) };
|
|
257
309
|
}
|
|
258
310
|
|
|
@@ -281,7 +333,12 @@ export function mqttKarte(host, kanal) {
|
|
|
281
333
|
ch.appendChild(th);
|
|
282
334
|
if (l.fehlen.length) { ch.appendChild(el('span', 'chip warn', tr('mq.missing', l.fehlen.length))); }
|
|
283
335
|
if (l.stumm.length) { ch.appendChild(el('span', 'chip bad', tr('mq.mute', l.stumm.length))); }
|
|
284
|
-
|
|
336
|
+
/* Nur warnen, wo es jemanden trifft: Ohne eine Zeile, die aus tele
|
|
337
|
+
liest und nach cmnd schreibt, ist SetOption59 folgenlos. */
|
|
338
|
+
var telZ = telegesteuert(S.entwurf);
|
|
339
|
+
if (l.sofort === false && telZ.length) {
|
|
340
|
+
ch.appendChild(el('span', 'chip warn', tr('mq.instantOffShort')));
|
|
341
|
+
}
|
|
285
342
|
ch.insertBefore(klappZeichen(mqttAuf), ch.firstChild);
|
|
286
343
|
ch.classList.add('klappbar');
|
|
287
344
|
ch.addEventListener('click', function () { mqttAuf = !mqttAuf; zeichneErgebnis(); });
|
|
@@ -309,7 +366,11 @@ export function mqttKarte(host, kanal) {
|
|
|
309
366
|
sah die Zahlen, aber nicht, welcher Befehl welcher Fall ist. */
|
|
310
367
|
var zustand = {};
|
|
311
368
|
l.fehlen.forEach(function (x) { zustand[x.name] = 'fehlt'; });
|
|
312
|
-
l.stumm.forEach(function (x) {
|
|
369
|
+
l.stumm.forEach(function (x) {
|
|
370
|
+
var m = mqttEinstellung(x.id);
|
|
371
|
+
zustand[x.name] = (m && m.abgeschaltet) ? 'aus' : 'stumm';
|
|
372
|
+
});
|
|
373
|
+
(l.unklar || []).forEach(function (n) { zustand[n] = 'unklar'; });
|
|
313
374
|
l.da.forEach(function (n) { zustand[n] = 'da'; });
|
|
314
375
|
|
|
315
376
|
var reihen = l.befehle.befehle.map(function (x) { return x.name; });
|
|
@@ -342,6 +403,8 @@ export function mqttKarte(host, kanal) {
|
|
|
342
403
|
var c = el('span', 'mchip');
|
|
343
404
|
if (z === 'fehlt') { c.appendChild(el('span', 'chip warn', tr('mq.stMissing'))); }
|
|
344
405
|
else if (z === 'stumm') { c.appendChild(el('span', 'chip bad', tr('mq.stMute'))); }
|
|
406
|
+
else if (z === 'aus') { c.appendChild(el('span', 'chip bad', tr('mq.stOff'))); }
|
|
407
|
+
else if (z === 'unklar') { c.appendChild(el('span', 'chip mut', tr('mq.stUnknown'))); }
|
|
345
408
|
else { c.appendChild(el('span', 'chip ok', tr('mq.stFine'))); }
|
|
346
409
|
r.appendChild(c);
|
|
347
410
|
|
|
@@ -352,7 +415,7 @@ export function mqttKarte(host, kanal) {
|
|
|
352
415
|
var bn = el('button', 'btn schmal', tr('mq.rowCreate'));
|
|
353
416
|
bn.addEventListener('click', function () { mqttEinzeln(kanal, n, 'neu', bn); });
|
|
354
417
|
h.appendChild(bn);
|
|
355
|
-
} else if (z === 'stumm') {
|
|
418
|
+
} else if (z === 'stumm' || z === 'aus') {
|
|
356
419
|
var bs2 = el('button', 'btn schmal', tr('mq.rowAllow'));
|
|
357
420
|
bs2.addEventListener('click', function () { mqttEinzeln(kanal, n, 'frei', bs2); });
|
|
358
421
|
h.appendChild(bs2);
|
|
@@ -379,57 +442,14 @@ export function mqttKarte(host, kanal) {
|
|
|
379
442
|
}
|
|
380
443
|
b.appendChild(leiste);
|
|
381
444
|
|
|
382
|
-
/* Sofortige Rueckmeldung — Zustand und, wenn noetig, der Schalter.
|
|
383
|
-
var sk = el('div');
|
|
384
|
-
sk.style.marginTop = '11px';
|
|
385
|
-
sk.style.paddingTop = '10px';
|
|
386
|
-
sk.style.borderTop = '1px solid var(--line)';
|
|
387
|
-
var sz = el('div');
|
|
388
|
-
sz.style.fontSize = '11.5px';
|
|
389
|
-
sz.appendChild(el('b', null, tr('mq.instant') + ' '));
|
|
390
|
-
if (l.sofort === true) {
|
|
391
|
-
sz.appendChild(el('span', 'chip ok', tr('mq.instantOn')));
|
|
392
|
-
} else if (l.sofort === false) {
|
|
393
|
-
sz.appendChild(el('span', 'chip warn', tr('mq.instantOff')));
|
|
394
|
-
} else {
|
|
395
|
-
sz.appendChild(el('span', 'chip mut', tr('mq.instantUnknown')));
|
|
396
|
-
}
|
|
397
|
-
sk.appendChild(sz);
|
|
398
|
-
if (so59Stumm[kanal] && l.sofort === null) {
|
|
399
|
-
var st59 = el('div', 'hint');
|
|
400
|
-
st59.style.marginTop = '4px';
|
|
401
|
-
st59.style.color = 'var(--warn)';
|
|
402
|
-
st59.textContent = tr('mq.askNoAnswer');
|
|
403
|
-
sk.appendChild(st59);
|
|
404
|
-
}
|
|
445
|
+
/* Sofortige Rueckmeldung — Zustand und, wenn noetig, der Schalter.
|
|
405
446
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
if (
|
|
412
|
-
/* Beide gleich gross - schmal neben normal las sich wie zwei
|
|
413
|
-
verschiedene Schriften (Ricardo, 25.08.2026). */
|
|
414
|
-
var lauf = so59Laeuft[kanal];
|
|
415
|
-
var bp = el('button', 'btn schmal' + (lauf === 'pruefen' ? ' laedt' : ''),
|
|
416
|
-
lauf === 'pruefen' ? tr('mq.instantChecking') : tr('mq.instantCheck'));
|
|
417
|
-
bp.addEventListener('click', function () { so59(kanal, bp, ''); });
|
|
418
|
-
sl.appendChild(bp);
|
|
419
|
-
var be = el('button', 'btn schmal' + (lauf === 'einschalten' ? ' laedt' : ''),
|
|
420
|
-
lauf === 'einschalten' ? tr('mq.instantEnabling') : tr('mq.instantEnable'));
|
|
421
|
-
be.addEventListener('click', function () { so59(kanal, be, '1'); });
|
|
422
|
-
sl.appendChild(be);
|
|
423
|
-
if (lauf) { bp.disabled = true; be.disabled = true; }
|
|
424
|
-
}
|
|
425
|
-
sk.appendChild(sl);
|
|
426
|
-
var hinweis = l.sofort === true ? tr('mq.instantHintOn')
|
|
427
|
-
: (l.sofort === false ? tr('mq.instantHintOff') : tr('mq.instantHintUnknown'));
|
|
428
|
-
/* Woher der Befund stammt, gehoert dazu — sonst weiss niemand, ob er
|
|
429
|
-
von eben ist oder von vorgestern. */
|
|
430
|
-
var alter = (l.sofort === null) ? '' : so59Alter(kanal);
|
|
431
|
-
sk.appendChild(el('div', 'hint', hinweis + (alter ? ' · ' + alter : '')));
|
|
432
|
-
b.appendChild(sk);
|
|
447
|
+
Nur, wenn ueberhaupt eine Zeile am Telemetrietakt haengt. An einem
|
|
448
|
+
Geraet, dessen Aliase alle aus `stat/...` lesen, ist SetOption59
|
|
449
|
+
folgenlos, und ein Block darueber ist bloss Betrieb. */
|
|
450
|
+
/* Frueher stand hier ein vorzeitiges `return` — es haengte die Karte
|
|
451
|
+
an, bevor `b` in ihr steckte, und aufgeklappt blieb sie leer. */
|
|
452
|
+
if (telZ.length) { so59Kasten(b, kanal, l, telZ); }
|
|
433
453
|
|
|
434
454
|
/* Nachfragen liefert dasselbe wie tele/STATE — gemessen, Feld fuer
|
|
435
455
|
Feld. Der Knopf erscheint deshalb nur, wenn es etwas zu holen gibt:
|
|
@@ -474,6 +494,75 @@ export function mqttKarte(host, kanal) {
|
|
|
474
494
|
host.appendChild(k);
|
|
475
495
|
}
|
|
476
496
|
|
|
497
|
+
/* Der Block zur sofortigen Rueckmeldung (SetOption59) — nur gerufen,
|
|
498
|
+
wenn eine Zeile am Telemetrietakt haengt. */
|
|
499
|
+
function so59Kasten(b, kanal, l, telZ) {
|
|
500
|
+
|
|
501
|
+
var sk = el('div');
|
|
502
|
+
sk.style.marginTop = '11px';
|
|
503
|
+
sk.style.paddingTop = '10px';
|
|
504
|
+
sk.style.borderTop = '1px solid var(--line)';
|
|
505
|
+
var sz = el('div');
|
|
506
|
+
sz.style.fontSize = '11.5px';
|
|
507
|
+
sz.appendChild(el('b', null, tr('mq.instant') + ' '));
|
|
508
|
+
if (l.sofort === true) {
|
|
509
|
+
sz.appendChild(el('span', 'chip ok', tr('mq.instantOn')));
|
|
510
|
+
} else if (l.sofort === false) {
|
|
511
|
+
sz.appendChild(el('span', 'chip warn', tr('mq.instantOff')));
|
|
512
|
+
} else {
|
|
513
|
+
sz.appendChild(el('span', 'chip mut', tr('mq.instantUnknown')));
|
|
514
|
+
}
|
|
515
|
+
sk.appendChild(sz);
|
|
516
|
+
/* Auch wenn noch ein alter Wert dasteht: die Frage eben blieb
|
|
517
|
+
unbeantwortet, und das gehoert gesagt. */
|
|
518
|
+
if (so59Stumm[kanal]) {
|
|
519
|
+
var st59 = el('div', 'hint');
|
|
520
|
+
st59.style.marginTop = '4px';
|
|
521
|
+
st59.style.color = 'var(--warn)';
|
|
522
|
+
st59.textContent = tr('mq.askNoAnswer');
|
|
523
|
+
sk.appendChild(st59);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
var sl = el('div');
|
|
527
|
+
sl.style.marginTop = '7px';
|
|
528
|
+
sl.style.display = 'flex';
|
|
529
|
+
sl.style.gap = '8px';
|
|
530
|
+
sl.style.flexWrap = 'wrap';
|
|
531
|
+
/* „Nachfragen" steht immer da. Ein „eingeschaltet" kann von
|
|
532
|
+
vorgestern stammen — ein liegengebliebenes `stat.RESULT` —, und
|
|
533
|
+
ohne den Knopf liess es sich nicht nachpruefen (H15).
|
|
534
|
+
„Einschalten" nur, wo es noch nicht an ist oder die Frage eben
|
|
535
|
+
unbeantwortet blieb. Beide gleich gross - schmal neben normal las
|
|
536
|
+
sich wie zwei verschiedene Schriften (Ricardo, 25.08.2026). */
|
|
537
|
+
var lauf = so59Laeuft[kanal];
|
|
538
|
+
var bp = el('button', 'btn schmal' + (lauf === 'pruefen' ? ' laedt' : ''),
|
|
539
|
+
lauf === 'pruefen' ? tr('mq.instantChecking') : tr('mq.instantCheck'));
|
|
540
|
+
bp.addEventListener('click', function () { so59(kanal, bp, ''); });
|
|
541
|
+
sl.appendChild(bp);
|
|
542
|
+
if (lauf) { bp.disabled = true; }
|
|
543
|
+
if (l.sofort !== true || so59Stumm[kanal]) {
|
|
544
|
+
var be = el('button', 'btn schmal' + (lauf === 'einschalten' ? ' laedt' : ''),
|
|
545
|
+
lauf === 'einschalten' ? tr('mq.instantEnabling') : tr('mq.instantEnable'));
|
|
546
|
+
be.addEventListener('click', function () { so59(kanal, be, '1'); });
|
|
547
|
+
sl.appendChild(be);
|
|
548
|
+
if (lauf) { be.disabled = true; }
|
|
549
|
+
}
|
|
550
|
+
sk.appendChild(sl);
|
|
551
|
+
/* Der Hinweis nennt die betroffenen Zeilen und den wirklichen Takt,
|
|
552
|
+
statt pauschal "minutenlang" zu behaupten. */
|
|
553
|
+
var telNamen = telZ.map(function (x) { return x.n; }).join(', ');
|
|
554
|
+
var takt = telePeriode(kanal);
|
|
555
|
+
var hinweis = l.sofort === true ? tr('mq.instantHintOn')
|
|
556
|
+
: (l.sofort === false
|
|
557
|
+
? (takt ? tr('mq.instantHintOffTakt', telNamen, takt) : tr('mq.instantHintOff', telNamen))
|
|
558
|
+
: tr('mq.instantHintUnknown'));
|
|
559
|
+
/* Woher der Befund stammt, gehoert dazu — sonst weiss niemand, ob er
|
|
560
|
+
von eben ist oder von vorgestern. */
|
|
561
|
+
var alter = (l.sofort === null) ? '' : so59Alter(kanal);
|
|
562
|
+
sk.appendChild(el('div', 'hint', hinweis + (alter ? ' · ' + alter : '')));
|
|
563
|
+
b.appendChild(sk);
|
|
564
|
+
}
|
|
565
|
+
|
|
477
566
|
var mqttStand = null;
|
|
478
567
|
var mqttAuswahl = {};
|
|
479
568
|
/* Bleibt ueber das Neuzeichnen hinweg stehen — sonst klappte die Karte
|
|
@@ -522,6 +611,13 @@ function so59(kanal, knopf, wert) {
|
|
|
522
611
|
if (!g) { return; }
|
|
523
612
|
so59Laeuft[kanal] = wert ? 'einschalten' : 'pruefen';
|
|
524
613
|
delete so59Stumm[kanal];
|
|
614
|
+
/* Wie alt ist die letzte Antwort JETZT? Gewertet wird nur, was nach
|
|
615
|
+
dem Senden kam — wie beim Abfrageweg. Vorher reichte ein
|
|
616
|
+
`stat.RESULT` von vorgestern mit `SetOption59` darin fuer
|
|
617
|
+
„eingeschaltet · gerade gefragt", auch wenn das Geraet gar nicht
|
|
618
|
+
antwortete (H15, gemessen 17.09.2026). */
|
|
619
|
+
var rid = hatPunkt(kanal, 'stat.RESULT');
|
|
620
|
+
var vorTs = (rid && S.werte[rid]) ? (S.werte[rid].ts || 0) : 0;
|
|
525
621
|
/* Sofort neu zeichnen: erst damit sperren sich BEIDE Knoepfe und die
|
|
526
622
|
alte Antwortzeile verschwindet - vorher passierte das erst mit dem
|
|
527
623
|
naechsten Nachzieher, Sekunden spaeter (Ricardo, 25.08.2026). */
|
|
@@ -544,7 +640,13 @@ function so59(kanal, knopf, wert) {
|
|
|
544
640
|
setTimeout(function () {
|
|
545
641
|
holeZweig(kanal + '.', function () {
|
|
546
642
|
delete so59Laeuft[kanal];
|
|
547
|
-
|
|
643
|
+
var rid2 = hatPunkt(kanal, 'stat.RESULT');
|
|
644
|
+
var jetzt = (rid2 && S.werte[rid2]) ? (S.werte[rid2].ts || 0) : 0;
|
|
645
|
+
/* Nichts Neues: nicht merken — sonst stuende der alte
|
|
646
|
+
Wert mit frischer Uhrzeit da. */
|
|
647
|
+
so59Stumm[kanal] = jetzt > vorTs
|
|
648
|
+
? (sofortRueckmeldung(kanal, true) === null)
|
|
649
|
+
: true;
|
|
548
650
|
zeichneErgebnis();
|
|
549
651
|
});
|
|
550
652
|
}, 4000);
|
|
@@ -706,7 +808,7 @@ function mqttPunktBauen(kanal, name, was) {
|
|
|
706
808
|
if (!alt0) { return null; }
|
|
707
809
|
obj = JSON.parse(JSON.stringify(alt0));
|
|
708
810
|
var cu0 = obj.common.custom || {};
|
|
709
|
-
Object.keys(cu0).forEach(function (i) { if (/^mqtt/.test(i) && cu0[i]) { cu0[i].publish = true; } });
|
|
811
|
+
Object.keys(cu0).forEach(function (i) { if (/^mqtt/.test(i) && cu0[i]) { cu0[i].publish = true; cu0[i].enabled = true; } });
|
|
710
812
|
obj.common.custom = cu0;
|
|
711
813
|
} else {
|
|
712
814
|
var w0 = befehlsWissen(name) || {};
|
|
@@ -740,7 +842,7 @@ export function mqttEinzeln(kanal, name, was, knopf) {
|
|
|
740
842
|
if (!alt) { return; }
|
|
741
843
|
obj = JSON.parse(JSON.stringify(alt));
|
|
742
844
|
var cu = obj.common.custom || {};
|
|
743
|
-
Object.keys(cu).forEach(function (i) { if (/^mqtt/.test(i) && cu[i]) { cu[i].publish = true; } });
|
|
845
|
+
Object.keys(cu).forEach(function (i) { if (/^mqtt/.test(i) && cu[i]) { cu[i].publish = true; cu[i].enabled = true; } });
|
|
744
846
|
obj.common.custom = cu;
|
|
745
847
|
} else {
|
|
746
848
|
var w = befehlsWissen(name) || {};
|
|
@@ -912,10 +1014,18 @@ function mqttZuSchreiben() {
|
|
|
912
1014
|
if (!mqttAuswahl['neu:' + x.name]) { return; }
|
|
913
1015
|
var w = befehlsWissen(x.name) || {};
|
|
914
1016
|
var thema = mqttThema(l.geraet, 'cmnd', x.name);
|
|
1017
|
+
/* Derselbe Typ wie auf dem Einzelweg — `punktTyp`, nicht `w.typ`.
|
|
1018
|
+
|
|
1019
|
+
Die Regel „Schreibformel heisst mixed" stand seit dem 15.09.2026 in
|
|
1020
|
+
`punktTyp` und wurde in `mqttPunktBauen` benutzt; hier blieb die
|
|
1021
|
+
alte Fassung stehen. Wer den Sammeldialog nahm, bekam `POWER`,
|
|
1022
|
+
`Fade` und `LedTable` als `boolean` statt `mixed` — der
|
|
1023
|
+
js-controller rechnete den Formelwert auf den Zieltyp zurueck, und
|
|
1024
|
+
auf der Leitung stand `true` statt `ON` (H18, gemessen 20.09.2026). */
|
|
915
1025
|
var common = {
|
|
916
1026
|
name: x.name,
|
|
917
1027
|
role: w.rolle || 'state',
|
|
918
|
-
type: w
|
|
1028
|
+
type: punktTyp(w),
|
|
919
1029
|
read: true, write: true,
|
|
920
1030
|
desc: tr('mq.createdBy'),
|
|
921
1031
|
custom: mqttCustom(l.geraet, thema)
|
|
@@ -930,7 +1040,7 @@ function mqttZuSchreiben() {
|
|
|
930
1040
|
if (!alt) { return; }
|
|
931
1041
|
var kopie = JSON.parse(JSON.stringify(alt));
|
|
932
1042
|
var cu = kopie.common.custom || {};
|
|
933
|
-
Object.keys(cu).forEach(function (i) { if (/^mqtt/.test(i) && cu[i]) { cu[i].publish = true; } });
|
|
1043
|
+
Object.keys(cu).forEach(function (i) { if (/^mqtt/.test(i) && cu[i]) { cu[i].publish = true; cu[i].enabled = true; } });
|
|
934
1044
|
kopie.common.custom = cu;
|
|
935
1045
|
raus.push({ id: x.id, obj: kopie, neu: false });
|
|
936
1046
|
});
|
package/admin/js/musterwahl.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Muster (passt / n von m belegt) und der Knopf, der freie Plaetze
|
|
3
3
|
vorschlaegt. Gebaut wird beides hier, eingehaengt woanders: der Block
|
|
4
4
|
je nach Ansicht im Vorlagenkasten oder in der Leiste ueber der Liste,
|
|
5
|
-
der Knopf immer in der Leiste.
|
|
5
|
+
der Knopf mit ihm (seit 19.09.2026; vorher immer in der Leiste).
|
|
6
6
|
|
|
7
7
|
Herausgeloest aus zeichneErgebnis - der Abschnitt hing an `e`, dem
|
|
8
8
|
Erkennungsergebnis und sonst an nichts. */
|
|
@@ -10,11 +10,84 @@
|
|
|
10
10
|
import { S } from './zustand.js';
|
|
11
11
|
import { D, el, $ } from './basis.js';
|
|
12
12
|
import { tr, sprachtext } from './sprache.js';
|
|
13
|
-
import { VORSCHAU, musterVon, erkenneEntwurf, platzFuerRolle, typenFuerRolle, typKonflikte } from './erkennung.js';
|
|
13
|
+
import { VORSCHAU, musterVon, erkenneEntwurf, platzFuerRolle, typenFuerRolle, typKonflikte, fehlendePflicht } from './erkennung.js';
|
|
14
14
|
import { anMusterAnpassen } from './vorlagen.js';
|
|
15
15
|
import { ratePlaetze, rateAnzahl } from './vorschlagen.js';
|
|
16
16
|
import { zeichneErgebnis, entwurfAngefasst, knopfFrisch } from './ergebnis.js';
|
|
17
17
|
import { musterName, musterZeile } from './musternamen.js';
|
|
18
|
+
import { nurWasInsMusterPasst } from './zustandsliste.js';
|
|
19
|
+
import { kindZustaende } from './werte.js';
|
|
20
|
+
|
|
21
|
+
/* Musterwechsel ohne Vorlage: die Haken folgen dem neuen Muster (C54).
|
|
22
|
+
|
|
23
|
+
Vorher lief die Vorbelegung nur einmal, beim Aufbau des Entwurfs; wer
|
|
24
|
+
danach das Muster wechselte, behielt die Haken des alten. Jetzt gilt
|
|
25
|
+
dieselbe Regel wie beim Aufbau — angehakt ist, was im gewaehlten
|
|
26
|
+
Muster einen Platz hat —, dazu jede Zeile, an der schon etwas von Hand
|
|
27
|
+
eingestellt wurde (Ricardo, 19.09.2026).
|
|
28
|
+
|
|
29
|
+
Nicht mit Vorlage: die bestimmt selbst, was an ist. Nicht an einem
|
|
30
|
+
Alias, den es schon gibt: dort ist jeder Haken eine getroffene
|
|
31
|
+
Entscheidung, abwaehlen hiesse loeschen — dieselben Ausnahmen wie bei
|
|
32
|
+
der Vorbelegung in `berechnePlaetze`. */
|
|
33
|
+
function hakenNachMuster(e) {
|
|
34
|
+
if (e.vorlage) { return; }
|
|
35
|
+
if (S.current && S.current.indexOf('alias.') === 0) { return; }
|
|
36
|
+
if (e.ziel && kindZustaende(e.ziel).length > 0) { return; }
|
|
37
|
+
/* Greift das neue Muster gar nicht — auch nicht mit allen Zeilen an —,
|
|
38
|
+
gibt es nichts, dem die Haken folgen koennten. Vorher fielen dann
|
|
39
|
+
alle bis auf die geaenderten: an der Klimaanlage verschwanden mit
|
|
40
|
+
dem Wechsel auf airCondition (MODE noch nicht da) ausgerechnet
|
|
41
|
+
Sollwert und Schalter, und nach dem Raten fehlte der Sollwert, den
|
|
42
|
+
das Muster verlangt (U13, 19.09.2026). Die Haken bleiben also, wie
|
|
43
|
+
sie sind; das Raten kann darauf aufbauen. */
|
|
44
|
+
var probe = JSON.parse(JSON.stringify({ kanal: e.kanal, states: e.states }));
|
|
45
|
+
probe.states.forEach(function (s) { s.on = true; });
|
|
46
|
+
if (!erkenneEntwurf(probe, e.want).length) { return; }
|
|
47
|
+
nurWasInsMusterPasst(e, true);
|
|
48
|
+
/* Wie beim Aufbau: der Schalter jedes weiteren Kanals kommt mit, damit
|
|
49
|
+
„als ein Geraet" keinen Ausgang heimlich verliert. */
|
|
50
|
+
(e.kanalGeraete || []).forEach(function (k) {
|
|
51
|
+
if (k.typ === 'info') { return; } /* Wartungskanal: kein Ausgang */
|
|
52
|
+
(k.pflicht || []).forEach(function (pid) {
|
|
53
|
+
var kurz = pid.slice(S.current.length + 1).replace(/\./g, '_');
|
|
54
|
+
e.states.forEach(function (st) { if (st.n === kurz) { st.on = true; } });
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* Die Meldung, wenn der Vorschlag nichts belegt hat - Begruendung dazu
|
|
60
|
+
in `baueMusterwahl`. Auf Modulebene, seit auch die Legende vorschlagen
|
|
61
|
+
kann (19.09.2026). */
|
|
62
|
+
function plaetzeText(frei) {
|
|
63
|
+
var kurz = frei.slice(0, 6).join(', ');
|
|
64
|
+
return frei.length > 6 ? tr('guess.slotsMore', kurz, frei.length - 6) : kurz;
|
|
65
|
+
}
|
|
66
|
+
function meldungZu(p) {
|
|
67
|
+
if (p.anzahl > 0) { return null; }
|
|
68
|
+
var satz = p.grund === 'voll' ? tr('guess.noneFull')
|
|
69
|
+
: p.grund === 'vergeben' ? tr('guess.noneUsed', plaetzeText(p.frei))
|
|
70
|
+
: p.grund === 'keinTreffer' ? tr('guess.noneFit', plaetzeText(p.frei))
|
|
71
|
+
: null;
|
|
72
|
+
/* Der Zusatz zur Handentscheidung (U15): Steht ein Platz nur deshalb
|
|
73
|
+
leer, weil die Zeile dazu von Hand entschieden ist, muss genau das
|
|
74
|
+
dastehen - sonst sieht es aus wie ein Fehler des Ratens. */
|
|
75
|
+
/* Mit Namen und in der richtigen Zahl — „1 Zeilen sind …" sagte weder
|
|
76
|
+
richtig Deutsch noch welche (Ricardo, 19.09.2026). */
|
|
77
|
+
if (satz && p.handWeg) {
|
|
78
|
+
var hn = (p.handNamen || []).slice(0, 4).join(', ') +
|
|
79
|
+
((p.handNamen || []).length > 4 ? ' …' : '');
|
|
80
|
+
satz += ' ' + (p.handWeg === 1 ? tr('guess.noneHandOne', hn) : tr('guess.noneHand', p.handWeg, hn));
|
|
81
|
+
}
|
|
82
|
+
return satz;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Vorschlagen und die Meldung dazu in einem Schritt. Gebraucht vom
|
|
86
|
+
Knopf, vom Pfeil hinter „… wuerde evtl. besser passen" und von der
|
|
87
|
+
orangen Legende, wenn das Muster erst nach dem Vorschlag greift. */
|
|
88
|
+
export function rateUndMelde(e) {
|
|
89
|
+
e.rateMeldung = meldungZu(ratePlaetze(e));
|
|
90
|
+
}
|
|
18
91
|
|
|
19
92
|
export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
20
93
|
var vw = el('div', 'verdictwrap' + (haupt && !pflichtFehlt.length ? '' : ' bad'));
|
|
@@ -49,9 +122,13 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
49
122
|
als `thermostat` erkannt, man wechselt also gar nichts, und ohne
|
|
50
123
|
Knopf bliebe es dabei.
|
|
51
124
|
|
|
52
|
-
Er wird hier gebaut, weil er zum Muster gehoert
|
|
53
|
-
|
|
54
|
-
|
|
125
|
+
Er wird hier gebaut, weil er zum Muster gehoert. Seit 19.09.2026
|
|
126
|
+
haengt er im blauen Vorlagenkasten, gleich hinter dem Musterfeld -
|
|
127
|
+
dort, wo die Erkennung steht, zu der er gehoert. Vorher stand er in
|
|
128
|
+
der Leiste ueber der Liste, und den Knopf, der den ganzen Bestand
|
|
129
|
+
des Geraets laedt, fand man im Kasten; beide standen am jeweils
|
|
130
|
+
falschen Ort (Ricardo). Nur im Aliasmodus, wo es keinen Kasten gibt,
|
|
131
|
+
bleibt er in der Leiste. */
|
|
55
132
|
/* Der Trockenlauf, der beides beantwortet: ob der Knopf etwas
|
|
56
133
|
anzubieten haette, und - wenn nicht - warum nicht. Frueher lief er
|
|
57
134
|
zweimal (einmal fuer `rateMoeglich`, einmal fuer den Klick); einmal
|
|
@@ -66,22 +143,6 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
66
143
|
Gezeigt wird sie, solange keine Vermutung offen ist: dann fuehrt die
|
|
67
144
|
blaue Leiste das Wort, und zwei Meldungen uebereinander widersprechen
|
|
68
145
|
sich nur. */
|
|
69
|
-
function plaetzeText(frei) {
|
|
70
|
-
var kurz = frei.slice(0, 6).join(', ');
|
|
71
|
-
return frei.length > 6 ? tr('guess.slotsMore', kurz, frei.length - 6) : kurz;
|
|
72
|
-
}
|
|
73
|
-
function meldungZu(p) {
|
|
74
|
-
if (p.anzahl > 0) { return null; }
|
|
75
|
-
var satz = p.grund === 'voll' ? tr('guess.noneFull')
|
|
76
|
-
: p.grund === 'vergeben' ? tr('guess.noneUsed', plaetzeText(p.frei))
|
|
77
|
-
: p.grund === 'keinTreffer' ? tr('guess.noneFit', plaetzeText(p.frei))
|
|
78
|
-
: null;
|
|
79
|
-
/* Der Zusatz zur Handentscheidung (U15): Steht ein Platz nur deshalb
|
|
80
|
-
leer, weil die Zeile dazu von Hand entschieden ist, muss genau das
|
|
81
|
-
dastehen - sonst sieht es aus wie ein Fehler des Ratens. */
|
|
82
|
-
if (satz && p.handWeg) { satz += ' ' + tr('guess.noneHand', p.handWeg); }
|
|
83
|
-
return satz;
|
|
84
|
-
}
|
|
85
146
|
/* Ungefragt gezeigt wird sie nur, wo sie etwas erklaert: dass kein
|
|
86
147
|
Knopf dasteht, obwohl Plaetze frei sind. Der Fall „alle Plaetze
|
|
87
148
|
besetzt" bleibt stumm - er sagt „alles gut, nichts zu tun", und das
|
|
@@ -131,7 +192,7 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
131
192
|
tr('guess.button'));
|
|
132
193
|
rateKnopf.title = beilaeufig ? tr('guess.tplHint') : tr('guess.hint');
|
|
133
194
|
var rateLos = function () {
|
|
134
|
-
|
|
195
|
+
rateUndMelde(e);
|
|
135
196
|
entwurfAngefasst();
|
|
136
197
|
S.openRow = null;
|
|
137
198
|
zeichneErgebnis();
|
|
@@ -178,8 +239,15 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
178
239
|
}
|
|
179
240
|
var r = erkenneEntwurf(pruefE, m), mark;
|
|
180
241
|
if (!r.length) {
|
|
181
|
-
|
|
182
|
-
|
|
242
|
+
/* Genannt wird, was wirklich fehlt — nicht jeder Pflichtplatz. An
|
|
243
|
+
der Klimaanlage stand „✕ MODE fehlt" neben einem bestaetigten
|
|
244
|
+
MODE; gefehlt hat der Sollwert (U13, 19.09.2026). Findet die
|
|
245
|
+
Grobpruefung nichts, bleibt die alte Auskunft. */
|
|
246
|
+
var fehlend = fehlendePflicht(pruefE.states, m);
|
|
247
|
+
if (!fehlend.length) {
|
|
248
|
+
fehlend = musterVon(m).states.filter(function (x) { return x.required; })
|
|
249
|
+
.map(function (x) { return x.name; });
|
|
250
|
+
}
|
|
183
251
|
/* Ein Pflichtplatz kann auch deshalb leer sein, weil die Zeile
|
|
184
252
|
dafuer im falschen Datentyp steht - die Rolle stimmt, der Typ
|
|
185
253
|
nicht, und der Punkt faellt aus dem Muster. „SET fehlt" ist dann
|
|
@@ -211,7 +279,14 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
211
279
|
}
|
|
212
280
|
} else {
|
|
213
281
|
var g = r[0].states.filter(function (x) { return x.id; }).length;
|
|
214
|
-
|
|
282
|
+
/* Ein Platz, der mehrfach vergeben wird (`multiple`, bei `info` das
|
|
283
|
+
ACTUAL), bekommt je Punkt einen Eintrag — die Gesamtzahl wuchs mit
|
|
284
|
+
jedem Haken, und „24/31“ klang, als fehlten sieben. Wo es keine
|
|
285
|
+
Hoechstzahl gibt, steht auch keine: nur die Zahl der Punkte
|
|
286
|
+
(Ricardo, 19.09.2026). Betrifft info, mediaPlayer, weatherForecast. */
|
|
287
|
+
var mehrfach = r[0].states.some(function (x) { return x.multiple; });
|
|
288
|
+
mark = mehrfach ? tr('pattern.pointsTaken', g)
|
|
289
|
+
: tr('pattern.slotsTaken', g, r[0].states.length);
|
|
215
290
|
/* Hier stand frueher „(Rollen werden angepasst)" hinter der
|
|
216
291
|
Belegung. Der Vermerk erschien an jeder Zeile ausser der gerade
|
|
217
292
|
gewaehlten — an einem Fensterkontakt also an sieben von acht.
|
|
@@ -316,6 +391,7 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
316
391
|
} else {
|
|
317
392
|
e.want = neuTyp;
|
|
318
393
|
}
|
|
394
|
+
hakenNachMuster(e);
|
|
319
395
|
S.openRow = null;
|
|
320
396
|
/* Kein Fokus zurueck ins Feld: der Fokus oeffnete die Liste sofort
|
|
321
397
|
wieder, und nach der Wahl stand sie erneut offen — man musste
|
|
@@ -475,7 +551,8 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
475
551
|
/* Beim Vorschlag entscheidet nicht das Muster, sondern die
|
|
476
552
|
Rollen, die das Auswaehlen setzt - genau wie in `mWaehlen`. */
|
|
477
553
|
if (e.vorschlag && !e.roh) { anMusterAnpassen(e, bestes); } else { e.want = bestes; }
|
|
478
|
-
|
|
554
|
+
hakenNachMuster(e);
|
|
555
|
+
rateUndMelde(e);
|
|
479
556
|
entwurfAngefasst();
|
|
480
557
|
S.openRow = null;
|
|
481
558
|
zeichneErgebnis();
|
package/admin/js/objekte.js
CHANGED
|
@@ -151,12 +151,26 @@ export function horcheAufObjekte() {
|
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
/* Nur die vier Arten, aus denen der Baum besteht.
|
|
155
|
+
|
|
156
|
+
Beim Laden holt `ladeObjekte` gezielt `ARTEN`, beim Nachziehen
|
|
157
|
+
wurde dagegen alles aufgenommen: eine geaenderte Instanz, ein
|
|
158
|
+
Adapter-Update, `system.config` nach dem Umstellen der Sprache.
|
|
159
|
+
Der Zaehler in der Kopfzeile ging dadurch von 3145 auf 3146, und
|
|
160
|
+
mit jeder Stunde offenem Reiter wurden es mehr (A4, 17.09.2026).
|
|
161
|
+
Wechselt ein Objekt seine Art, faellt es hier ebenfalls heraus. */
|
|
162
|
+
if (obj && ARTEN.indexOf(obj.type) === -1) {
|
|
163
|
+
if (S.objects[id] === undefined) { return; }
|
|
164
|
+
obj = null;
|
|
165
|
+
}
|
|
166
|
+
|
|
154
167
|
/* Alles Uebrige: nur was zaehlt, nicht jeder Schreibvorgang. */
|
|
155
168
|
var vorher = kern(S.objects[id]);
|
|
156
169
|
if (vorher === nachher) { return; }
|
|
157
170
|
|
|
158
171
|
var gabEs = S.objects[id] !== undefined;
|
|
159
172
|
if (obj) { S.objects[id] = obj; } else { delete S.objects[id]; }
|
|
173
|
+
S.objektStand++;
|
|
160
174
|
if (gabEs !== (S.objects[id] !== undefined)) { nachziehBaum = true; }
|
|
161
175
|
|
|
162
176
|
var betrifft = S.current && (id === S.current || id.indexOf(S.current + '.') === 0);
|
|
@@ -201,6 +215,7 @@ export function horcheAufObjekte() {
|
|
|
201
215
|
export function uebernimmObjekt(id, o) {
|
|
202
216
|
var gabEs = S.objects[id] !== undefined;
|
|
203
217
|
if (o) { S.objects[id] = o; } else { delete S.objects[id]; }
|
|
218
|
+
S.objektStand++;
|
|
204
219
|
return gabEs !== (S.objects[id] !== undefined);
|
|
205
220
|
}
|
|
206
221
|
|
|
@@ -237,6 +252,7 @@ export function kaputteAliaseNeu() {
|
|
|
237
252
|
}
|
|
238
253
|
|
|
239
254
|
export function indexNeu() {
|
|
255
|
+
S.objektStand++;
|
|
240
256
|
S.keysSorted = Object.keys(S.objects).sort();
|
|
241
257
|
S.kleinIndex = {};
|
|
242
258
|
kaputteAliaseNeu();
|
package/admin/js/pruefungen.js
CHANGED
|
@@ -5,7 +5,7 @@ import { $, el } from './basis.js';
|
|
|
5
5
|
import { tr } from './sprache.js';
|
|
6
6
|
import { wertVon, zielKann } from './werte.js';
|
|
7
7
|
import './erkennung.js';
|
|
8
|
-
import { sofortRueckmeldung, mqttEinstellung } from './mqtt.js';
|
|
8
|
+
import { sofortRueckmeldung, mqttEinstellung, telegesteuert } from './mqtt.js';
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
/* Kommt die Rueckmeldung sofort oder erst mit der naechsten Telemetrie?
|
|
@@ -21,11 +21,14 @@ import { sofortRueckmeldung, mqttEinstellung } from './mqtt.js';
|
|
|
21
21
|
da, tele/STATE kam erst nach der naechsten Telemetrie — bei
|
|
22
22
|
TelePeriod 300 also bis zu fuenf Minuten spaeter. */
|
|
23
23
|
export function pruefungRueckmeldung(e) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
/* Dieselbe Frage wie die MQTT-Karte, damit beide nicht auseinander
|
|
25
|
+
laufen (Ricardo, 16.09.2026). */
|
|
26
|
+
var lahm = telegesteuert(e);
|
|
27
|
+
/* Kein Haken, sondern ein Punkt: Hier wurde nichts geprueft, weil es
|
|
28
|
+
nichts zu pruefen gab. „alle in Ordnung" las sich, als haette die
|
|
29
|
+
Werkbank etwas nachgesehen - an Ricardos Steckdosenleiste lesen alle
|
|
30
|
+
Zeilen aus stat/..., SetOption59 ist dort folgenlos. */
|
|
31
|
+
if (!lahm.length) { return { s: 'mut', t: tr('check.feedback'), d: tr('check.feedbackNone') }; }
|
|
29
32
|
/* Nur warnen, wenn es wirklich langsam ist. Mit SetOption59 meldet
|
|
30
33
|
das Geraet jede Aenderung sofort — dann ist die Bauform zwar
|
|
31
34
|
dieselbe, aber kein Problem. Gemessen: drei Sekunden. */
|
|
@@ -113,8 +116,7 @@ export function pruefungZielKann(e) {
|
|
|
113
116
|
if (!treffer.length) { return { s: 'ok', t: tr('check.targetCan'), d: tr('check.targetCanFine') }; }
|
|
114
117
|
var text = treffer.map(function (x) {
|
|
115
118
|
if (x.art === 'formelBlind') { return tr('check.targetVoidFormula', x.n, x.typ); }
|
|
116
|
-
|
|
117
|
-
return tr('check.targetNoRead', x.n);
|
|
119
|
+
return tr('check.targetNoWrite', x.n);
|
|
118
120
|
}).join(', ');
|
|
119
121
|
return { s: 'warn', t: tr('check.targetCan'), d: text };
|
|
120
122
|
}
|