iobroker.alias-workbench 0.8.2 → 0.8.3

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 CHANGED
@@ -510,6 +510,17 @@ imported, and that both language files carry the same keys.
510
510
 
511
511
  ## Changelog
512
512
 
513
+ ### 0.8.3
514
+ * The dry run now shows enumerations as a comparison as well: the "before" column stayed empty for them, because enumerations live in their own store and the dry run only looked in the object store. Everything appeared as new, so it was impossible to see that eleven of twelve members were already there
515
+ * …and the interface no longer announces a creation where it changes: on such an alias the chip said "will be newly created", the button offered "create alias", the dry run was titled "what would come into being", the room and function were guessed instead of read, orphaned points went unnoticed and move/swap/remove did nothing. All of them asked whether the channel is an object instead of whether the alias exists
516
+ * An alias whose channel exists only as an id, not as an object — the usual result of adding points by hand in the admin — is now compared against the stored state at all. Before, the whole comparison bailed out there, and updating would have replaced captions with the bare point names and dropped roles, formulas and write direction along with them
517
+ * The same rule was missing a third time, for aliases where several points read from one and the same source datapoint — a blind, where OPEN, CLOSE, SET and pct all go to `level`. Only the first of them kept its write source; the others lost it, and updating would have made the blind unreachable through its alias
518
+ * Updating an existing alias no longer overwrites its caption with the bare row name, and no longer turns a read-only alias into a writable one: the function that takes the stored alias over into the draft was missing both rules its twin already had. The false "differs from the stored alias" mark that came with it is gone too
519
+ * A line that comes from the stored alias and reads from a source outside the selected node now gets its value: the values were fetched before that line even existed, so it claimed "source delivers nothing" while the alias was working fine. Only showed on aliases assembled from several adapters, and only until the node was clicked a second time
520
+
521
+ ### **WORK IN PROGRESS**
522
+ * A line that comes from the stored alias and reads from a source outside the selected node now gets its value: the values were fetched before that line even existed, so it claimed "source delivers nothing" while the alias was working fine. Only showed on aliases assembled from several adapters, and only until the node was clicked a second time
523
+
513
524
  ### 0.8.2
514
525
  * A source that already has an alias now says so when the target points elsewhere: "This source already has alias.0.… — that one stays where it is", with a button "move it instead …" that opens the move dialog prefilled. Nothing is forbidden — two aliases on one source remain possible, they are no longer silent
515
526
  * The same line appears in the dry run, right above what cannot be written
@@ -683,16 +683,18 @@ var warumAuf = false;
683
683
  var bTpl = $('#btn-tpl');
684
684
  if (bTpl) { bTpl.hidden = imAliasmodus; }
685
685
  tplKnopf(true);
686
- delKnopf(imAliasmodus && !!S.objects[zielId2] && zielId2.indexOf('alias.') === 0);
686
+ /* Siehe zielleiste: der Alias kann ohne eigenes Kanalobjekt bestehen. */
687
+ var zielDa = knotenDa(zielId2);
688
+ delKnopf(imAliasmodus && zielDa && zielId2.indexOf('alias.') === 0);
687
689
  if (bd) {
688
690
  bd.disabled = false;
689
691
  /* Bei mehreren Ausgaengen den Ausgang beim Namen nennen — „für den
690
692
  ausgewählten Ausgang" waere lang und sagt weniger. */
691
693
  bd.textContent = mehr
692
- ? (S.objects[zielId2] ? tr('write.updateNamed', e.zielName) : tr('write.createNamed', e.zielName))
694
+ ? (zielDa ? tr('write.updateNamed', e.zielName) : tr('write.createNamed', e.zielName))
693
695
  : mehrK
694
- ? (S.objects[zielId2] ? tr('write.updateAsOne') : tr('write.createAsOne'))
695
- : (S.objects[zielId2] ? tr('write.updateAlias') : tr('write.createAlias'));
696
+ ? (zielDa ? tr('write.updateAsOne') : tr('write.createAsOne'))
697
+ : (zielDa ? tr('write.updateAlias') : tr('write.createAlias'));
696
698
  bd.title = zielId2;
697
699
  }
698
700
  if (ba) {
@@ -23,7 +23,7 @@ import { tr, txt } from './sprache.js';
23
23
  import { socket } from './verbindung.js';
24
24
  import { aliasQuellen, kindZustaende } from './werte.js';
25
25
  import { holeZweig, indexNeu } from './objekte.js';
26
- import { waehle } from './entwurf.js';
26
+ import { waehle, knotenDa } from './entwurf.js';
27
27
  import { zeichneErgebnis } from './ergebnis.js';
28
28
 
29
29
  /* Die Punkte des Alias, die ueberhaupt eine Quelle haben. */
@@ -325,7 +325,7 @@ export function zeigeTausch() {
325
325
  /* Wie bei zeigeVerlegen und zeigeLoeschen: an der Quelle ist
326
326
  S.current die Quelle, gemeint ist das Ziel des Entwurfs (T1). */
327
327
  var ziel = (S.entwurf && (S.entwurf.ziel || S.entwurf.kanal)) || S.current;
328
- if (!ziel || ziel.indexOf('alias.') !== 0 || !S.objects[ziel]) { return; }
328
+ if (!ziel || ziel.indexOf('alias.') !== 0 || !knotenDa(ziel)) { return; }
329
329
  S.tauschZiel = ziel;
330
330
  S.tauschNeu = '';
331
331
  S.tauschWeg = {};
@@ -19,7 +19,8 @@ import {
19
19
  gemeinsameKanaele,
20
20
  kennungtauglich,
21
21
  entwurfFuer,
22
- aliasFuer
22
+ aliasFuer,
23
+ knotenDa
23
24
  } from './entwurf.js';
24
25
  import { zeichneErgebnis } from './ergebnis.js';
25
26
 
@@ -163,8 +164,22 @@ export function objektText(o, geordnet) {
163
164
  return JSON.stringify(geordnet ? ordne(k, '') : k, null, 2);
164
165
  }
165
166
 
167
+ /* Der gespeicherte Stand zu einer Kennung.
168
+
169
+ Aufzaehlungen liegen nicht in `S.objects` - die Werkbank haelt sie in
170
+ einem eigenen Vorrat, weil der Admin sie getrennt ausliefert. Der
171
+ Trockenlauf las trotzdem nur `S.objects`, und so blieb die Spalte
172
+ „bisher" bei jeder Aufzaehlung leer: verglichen wurde gegen nichts,
173
+ also stand rechts jede Zeile als neu da - auch die zehn Mitglieder,
174
+ die laengst drin waren (Ricardo, 08.09.2026). */
175
+ export function bestandsObjekt(id) {
176
+ if (S.objects[id]) { return S.objects[id]; }
177
+ if (String(id).indexOf('enum.') === 0 && enums[id]) { return enums[id]; }
178
+ return null;
179
+ }
180
+
166
181
  export function unveraendert(id, obj) {
167
- var alt = S.objects[id];
182
+ var alt = bestandsObjekt(id);
168
183
  if (!alt) { return false; }
169
184
  var putz = function (x) {
170
185
  var k = JSON.parse(JSON.stringify(x || {}));
@@ -301,7 +316,9 @@ export function baueObjekte(e) {
301
316
  das wird nicht ungefragt geloescht. */
302
317
  export function verwaiste(e) {
303
318
  var ziel = e.ziel || e.kanal;
304
- if (!S.objects[ziel]) { return []; }
319
+ /* Auch ohne Kanalobjekt kann darunter ein Alias liegen - dann gibt es
320
+ dort auch verwaiste Punkte zu finden. */
321
+ if (!knotenDa(ziel)) { return []; }
305
322
  var behalten = {};
306
323
  e.states.forEach(function (st) {
307
324
  if (st.on && st.n) { behalten[ziel + '.' + st.n] = 1; }
@@ -473,7 +490,8 @@ export function zeigeTrockenlauf(alleAusgaenge) {
473
490
  verspraeche er eine Wirkung, die er nicht hat. */
474
491
  var vergleichbar = liste.filter(function (x) { return !x.neu && !x.gleich; });
475
492
  var rohAnders = vergleichbar.some(function (x) {
476
- return objektText(S.objects[x.id], false) !== objektText(S.objects[x.id], true)
493
+ var b0 = bestandsObjekt(x.id);
494
+ return objektText(b0, false) !== objektText(b0, true)
477
495
  || objektText(x.obj, false) !== objektText(x.obj, true);
478
496
  });
479
497
  if (vergleichbar.length && rohAnders) {
@@ -672,7 +690,7 @@ export function zeigeTrockenlauf(alleAusgaenge) {
672
690
  var vgl = el('div', 'dvgl');
673
691
  vgl.appendChild(el('span', 'dkopf', tr('write.diffOld')));
674
692
  vgl.appendChild(el('span', 'dkopf', tr('write.diffNew')));
675
- zeilenVergleich(objektText(S.objects[x.id], !S.trockenRoh),
693
+ zeilenVergleich(objektText(bestandsObjekt(x.id), !S.trockenRoh),
676
694
  objektText(x.obj, !S.trockenRoh))
677
695
  .forEach(function (z) {
678
696
  vgl.appendChild(el('span', 'dz l ' + z.art, z.l === undefined ? '' : z.l));
@@ -693,7 +711,7 @@ export function zeigeTrockenlauf(alleAusgaenge) {
693
711
  var zt = $('#dry-titel');
694
712
  if (zt) {
695
713
  var zielName = S.entwurf.ziel || S.entwurf.kanal;
696
- zt.textContent = (S.objects[zielName] ? tr('write.dryTitleUpdate') : tr('write.dryTitleCreate')) +
714
+ zt.textContent = (knotenDa(zielName) ? tr('write.dryTitleUpdate') : tr('write.dryTitleCreate')) +
697
715
  (entwuerfe.length > 1 ? tr('write.dryOutputs', entwuerfe.length) : '');
698
716
  }
699
717
  /* Beim Oeffnen wieder herstellen: der Dialog wird wiederverwendet, und
@@ -729,7 +747,7 @@ function geschwisterVon(ziel) {
729
747
 
730
748
  export function zeigeLoeschen() {
731
749
  var ziel = (S.entwurf && (S.entwurf.ziel || S.entwurf.kanal)) || S.current;
732
- if (!ziel || ziel.indexOf('alias.') !== 0 || !S.objects[ziel]) { return; }
750
+ if (!ziel || ziel.indexOf('alias.') !== 0 || !knotenDa(ziel)) { return; }
733
751
  S.loeschZiel = ziel;
734
752
  S.loeschAlleAusgaenge = false;
735
753
  zeichneLoeschen();
package/admin/js/werte.js CHANGED
@@ -93,6 +93,26 @@ export function holeWerte(kanal, extraIds, fertig) {
93
93
  });
94
94
  }
95
95
 
96
+ /* Nur diese Kennungen, ohne den Rundumschlag ueber einen Kanal.
97
+
98
+ Gebraucht dort, wo Zeilen erst spaeter dazukommen und ihre Quelle
99
+ ausserhalb des angeklickten Knotens liegt - dann ist der Kanal
100
+ laengst abgefragt, und ein zweites `getForeignStates` darauf braechte
101
+ nichts als Last. */
102
+ export function holeEinzelne(ids, fertig) {
103
+ var eindeutig = {};
104
+ (ids || []).forEach(function (i) { if (i) { eindeutig[i] = 1; } });
105
+ var liste = Object.keys(eindeutig);
106
+ if (!liste.length) { if (typeof fertig === 'function') { fertig(false); } return; }
107
+ var offen = liste.length, etwas = false;
108
+ liste.forEach(function (id) {
109
+ socket.emit('getState', id, function (err, st) {
110
+ if (!err && st) { S.werte[id] = st; etwas = true; }
111
+ if (--offen <= 0 && typeof fertig === 'function') { fertig(etwas); }
112
+ });
113
+ });
114
+ }
115
+
96
116
  /* ================== Formel und Wert ================== */
97
117
  export function auswerten(formel, roh) {
98
118
  if (roh === undefined || roh === null) { return { ok: false, txt: tr('detail.noValue') }; }
@@ -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 } from './entwurf.js';
14
+ import { aliasFuer, ordnerUnterAlias, kennungtauglich, knotenDa } from './entwurf.js';
15
15
  import { zeichneErgebnis, entwurfAngefasst, angebotFrisch } from './ergebnis.js';
16
16
  import { zeigeVerlegen } from './schreiben.js';
17
17
 
@@ -303,7 +303,10 @@ export function baueZielleiste(host, e) {
303
303
  /* Beide Faelle, an einer Stelle. Vorher stand „wird neu angelegt"
304
304
  oben im Kopf und „gibt es schon" hier — zwei Formulierungen fuer
305
305
  dieselbe Auskunft, an zwei Orten. */
306
- var gibtsZiel = !!S.objects[e.ziel];
306
+ /* `knotenDa`, nicht `S.objects`: ein Alias, dessen Punkte von Hand
307
+ angelegt wurden, hat oft kein Kanalobjekt - der Chip meldete dort
308
+ „wird neu angelegt", obwohl geaendert wird (Ricardo, 08.09.2026). */
309
+ var gibtsZiel = knotenDa(e.ziel);
307
310
  var ch2 = el('span', 'chip ' + (gibtsZiel ? 'warn' : 'ok'),
308
311
  gibtsZiel ? tr('target.exists') : tr('result.newlyCreated'));
309
312
  ch2.style.marginLeft = '7px';
@@ -14,8 +14,8 @@ import {
14
14
  } from './aufzaehlungen.js';
15
15
  import { enumVorlagen, katalogFehlt, ikonCache, ikonErlaubt, ikonNachtrag,
16
16
  ikonTaugt, vorlageZu, holeIkon } from './katalog.js';
17
- import { kindZustaende, aliasQuellen } from './werte.js';
18
- import { aliasFuer, zielId } from './entwurf.js';
17
+ import { kindZustaende, aliasQuellen, holeEinzelne } from './werte.js';
18
+ import { aliasFuer, zielId, knotenDa } from './entwurf.js';
19
19
  import { zeichneErgebnis, entwurfAngefasst, angebotFrisch } from './ergebnis.js';
20
20
 
21
21
 
@@ -394,7 +394,11 @@ export function enumZeile(host, e) {
394
394
  export function setzeEnums(e) {
395
395
  if (e.raum !== undefined && e.funktion !== undefined) { return; }
396
396
  var ziel = e.ziel || e.kanal;
397
- var da = !!S.objects[ziel];
397
+ /* Gibt es den Alias, gelten SEINE Aufzaehlungen - auch wenn sein Kanal
398
+ kein eigenes Objekt hat. Sonst wurden Raum und Funktion geraten und
399
+ als „vorgeschlagen" angezeigt, obwohl beide laengst zugeordnet
400
+ waren (Ricardo, 08.09.2026). */
401
+ var da = knotenDa(ziel);
398
402
 
399
403
  if (e.raum === undefined) {
400
404
  var r = da ? (enumsVon(ziel, 'rooms')[0] || '') : '';
@@ -499,7 +503,21 @@ export function setzeZiel(e) {
499
503
  export function uebernehmeBestand(e) {
500
504
  if (!e.ziel || e.bestandGeprueft === e.ziel) { return; }
501
505
  e.bestandGeprueft = e.ziel;
502
- if (!S.objects[e.ziel]) { return; }
506
+ /* Gefragt ist, ob es unter dem Ziel schon einen Alias gibt - nicht, ob
507
+ das Ziel selbst ein Objekt ist. Das ist nicht dasselbe: wer seine
508
+ Punkte von Hand im Admin anlegt, bekommt `alias.0.X.Y.PUNKT`, ohne
509
+ dass `alias.0.X.Y` als Kanal entsteht. Der Baum zeigt so einen
510
+ Knoten trotzdem, weil er sich aus den Kennungen aufbaut - `knotenDa`
511
+ ist genau dafuer da.
512
+
513
+ Mit der alten Frage stieg der ganze Bestandsabgleich dort aus:
514
+ `alias.0.Bastelzimmer.Klima` und `alias.0.Solar.Einstellungen.Bilanz`
515
+ haben kein Kanalobjekt, und ein Aktualisieren haette ihre Namen
516
+ durch die blossen Punktnamen ersetzt - „Strompreis fuer die
517
+ Ersparnisrechnung" waere zu „Strompreis_ct_kWh" geworden. Rollen,
518
+ Formeln und Schreibrichtung waeren ebenso durchgefallen
519
+ (Ricardo, 08.09.2026). */
520
+ if (!knotenDa(e.ziel)) { return; }
503
521
  /* Im Aliasmodus ist der Entwurf schon der Bestand. */
504
522
  if (e.kanal === e.ziel) { return; }
505
523
 
@@ -533,9 +551,35 @@ export function uebernehmeBestand(e) {
533
551
  z.states = c.states || undefined;
534
552
  z.f = (typeof a.read === 'string') ? a.read : '';
535
553
  z.fw = (typeof a.write === 'string') ? a.write : '';
554
+ /* Die Beschriftung steht im Alias und gehoert dem Nutzer.
555
+
556
+ Sie fehlte hier als einzige - `bestandVorrang` holt sie laengst
557
+ (`s.caption = txt(c.name)`), diese Zwillingsfunktion nicht. Also
558
+ blieb `caption` leer, im aufgeklappten Feld stand nichts, und ein
559
+ „Alias aktualisieren" haette den Namen durch den blossen
560
+ Zeilennamen ersetzt: aus „Netzbezug (+) / Einspeisung (-)" waere
561
+ „Bezug" geworden (Ricardo, 07.09.2026, an alias.0.Solar.Netz).
562
+ Gleicht die Beschriftung dem Zeilennamen, bleibt sie leer - so
563
+ haelt es der Zweig darunter, der neue Zeilen anlegt, auch. */
564
+ var nm2 = txt(c.name);
565
+ z.caption = (nm2 && nm2 !== z.n) ? nm2 : '';
536
566
  if (q2.read) { z.srcR = q2.read; }
567
+ /* Und dieselbe Schreibregel wie im Bestandsvorrang.
568
+
569
+ Hier stand die Schreibquelle nur fuer das getrennte Paar; sonst
570
+ blieb stehen, was der Vorschlag aus der Quelle abgeleitet hatte.
571
+ Bei einem Nur-Lese-Alias auf einen beschreibbaren Punkt hiess das:
572
+ die Quelle sagt `write: true`, der Alias sagt `write: false` - und
573
+ die Werkbank meldete eine Abweichung, die sie selbst erzeugt hatte,
574
+ und haette den Alias beim Aktualisieren schreibbar gemacht.
575
+
576
+ Belegt ist das Schreiben durch `common.write` oder durch eine
577
+ hinterlegte Schreibformel; bei getrennten Quellen zaehlt, was in
578
+ `alias.id.write` steht. */
579
+ z.srcW = q2.einfach
580
+ ? ((c.write === true || typeof a.write === 'string') ? (q2.write || '') : '')
581
+ : (q2.write || '');
537
582
  if (q2.write && !q2.einfach && q2.write !== q2.read) {
538
- z.srcW = q2.write;
539
583
  /* Die Gegenzeile eines Paars ist keine eigene mehr - ihre Quelle
540
584
  steckt jetzt als Schreibquelle in dieser Zeile. */
541
585
  e.states.forEach(function (x) {
@@ -605,7 +649,22 @@ export function uebernehmeBestand(e) {
605
649
  role: c.role || '', typ: c.type || '', unit: c.unit || '',
606
650
  states: c.states || undefined,
607
651
  wr: !!c.write,
608
- srcR: q.read || '', srcW: q.einfach ? '' : (q.write || ''),
652
+ srcR: q.read || '',
653
+ /* Dieselbe Schreibregel wie oben und im Bestandsvorrang.
654
+
655
+ Hier stand `q.einfach ? '' : (q.write || '')` - bei schlichtem
656
+ `alias.id` also immer leer, ohne `common.write` ueberhaupt
657
+ anzusehen. Es trifft jeden Alias, bei dem MEHRERE Punkte auf
658
+ denselben Quellpunkt zeigen: die eine Vorschlagszeile bekommt
659
+ der erste von ihnen, alle weiteren landen hier. Am
660
+ `alias.0.Badezimmer.Rollladen` zeigen OPEN, CLOSE, SET und pct
661
+ alle auf `…Bad.level`; CLOSE lief oben durch und behielt seine
662
+ Schreibquelle, OPEN, SET und pct verloren sie - ein
663
+ Aktualisieren haette den Rollladen ueber den Alias unfahrbar
664
+ gemacht (Ricardo, 08.09.2026). */
665
+ srcW: q.einfach
666
+ ? ((c.write === true || typeof a.write === 'string') ? (q.write || '') : '')
667
+ : (q.write || ''),
609
668
  f: (typeof a.read === 'string') ? a.read : '',
610
669
  fw: (typeof a.write === 'string') ? a.write : '',
611
670
  caption: (nm && nm !== n) ? nm : '',
@@ -627,6 +686,38 @@ export function uebernehmeBestand(e) {
627
686
  e.bestandNachgezeichnet = true;
628
687
  setTimeout(function () { if (S.entwurf === e) { zeichneErgebnis(); } }, 0);
629
688
  }
689
+
690
+ /* Und die Werte zu den eben ergaenzten Zeilen nachholen.
691
+
692
+ `waehle` holt die Werte, bevor es diese Zeilen ueberhaupt gibt: es
693
+ fragt den angeklickten Kanal ab und die Quellen, die der Entwurf zu
694
+ dem Zeitpunkt kennt. Was hier dazukommt, steht nur im Alias - und
695
+ seine Quelle kann irgendwo liegen. Solange sie unter demselben
696
+ Knoten liegt, faellt nichts auf, weil `getForeignStates` sie
697
+ mitgenommen hat. Liegt sie woanders, blieb die Zeile ohne Wert und
698
+ behauptete „Quelle liefert nichts", obwohl der Alias einwandfrei
699
+ arbeitet.
700
+
701
+ Gefunden am 07.09.2026 (Ricardo) an `alias.0.Solar.Netz`: drei
702
+ Punkte aus `0_userdata`, zwei aus `mqtt-client`. Nach einem
703
+ Reiterwechsel und dem ersten Klick auf den Knoten standen genau die
704
+ beiden mqtt-Zeilen leer; ein zweiter Klick heilte es, weil der Wert
705
+ dann schon im Vorrat lag. Der Mitschnitt zeigte, dass nach der
706
+ mqtt-Kennung nie gefragt wurde.
707
+
708
+ Einmal je Entwurf, und nur, wenn wirklich etwas fehlt. */
709
+ if (!e.bestandWerte) {
710
+ var fehlen = [];
711
+ e.states.forEach(function (s) {
712
+ if (s.srcR && !S.werte[s.srcR] && fehlen.indexOf(s.srcR) === -1) { fehlen.push(s.srcR); }
713
+ });
714
+ if (fehlen.length) {
715
+ e.bestandWerte = true;
716
+ holeEinzelne(fehlen, function (etwas) {
717
+ if (etwas && S.entwurf === e) { zeichneErgebnis(); }
718
+ });
719
+ }
720
+ }
630
721
  }
631
722
 
632
723
  export function unterschiede(e) {
@@ -667,7 +758,7 @@ export function unterschiede(e) {
667
758
  Grundlinie — dann zaehlt, was sich gegenueber dem Gespeicherten
668
759
  aendert. Gibt es ihn noch nicht, ist es der Vorschlag der
669
760
  Vorlage. */
670
- var aliasDa = !!S.objects[zielBasis];
761
+ var aliasDa = knotenDa(zielBasis);
671
762
 
672
763
  e.states.forEach(function (s) {
673
764
  if (s.manuell) { raus.push({ n: s.n || '(ohne Namen)', was: tr('diff.newByHand') }); return; }
@@ -97,7 +97,7 @@ export function berechnePlaetze(e, haupt) {
97
97
  - und die Vorbelegung machte es sofort wieder zunichte: die neun
98
98
  uebernommenen Zeilen hatten im thermostat-Muster keinen Platz und
99
99
  wurden abgewaehlt, uebrig blieben zwei. */
100
- var bestandDa = e.ziel && S.objects[e.ziel] && kindZustaende(e.ziel).length > 0;
100
+ var bestandDa = !!(e.ziel && kindZustaende(e.ziel).length > 0);
101
101
  if (!e.vorbelegt && !e.vorlage && S.current.indexOf('alias.') !== 0) {
102
102
  e.vorbelegt = true;
103
103
  if (bestandDa) {
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "alias-workbench",
4
- "version": "0.8.2",
4
+ "version": "0.8.3",
5
5
  "news": {
6
+ "0.8.3": {
7
+ "en": "What is stored in an existing alias now holds: its caption stays, a read-only alias stays read-only, and that applies to every point, including several pointing at one and the same source. An alias whose channel exists only as an id is compared at all now, and the interface no longer announces a creation where it changes. The dry run shows enumerations as a comparison, and a line reading from another adapter gets its value on the first click.",
8
+ "de": "Was in einem vorhandenen Alias steht, gilt jetzt: die Beschriftung bleibt, ein Nur-Lese-Alias bleibt lesend, und das für jeden Punkt — auch wenn mehrere auf dieselbe Quelle zeigen. Ein Alias, dessen Kanal nur als Kennung besteht, wird überhaupt verglichen, und die Oberfläche kündigt kein Anlegen mehr an, wo sie ändert. Der Trockenlauf zeigt Aufzählungen im Vergleich, und eine Zeile aus einem anderen Adapter bekommt ihren Wert schon beim ersten Klick.",
9
+ "ru": "То, что записано в существующем алиасе, теперь имеет приоритет: подпись сохраняется, алиас только для чтения остаётся таким же, и это касается каждой точки — даже если несколько указывают на один источник. Алиас, канал которого существует лишь как идентификатор, теперь вообще сравнивается, а интерфейс больше не объявляет создание там, где он изменяет. Пробный прогон показывает перечисления в сравнении, а строка из другого адаптера получает значение уже при первом щелчке.",
10
+ "pt": "O que está guardado num alias existente passa a valer: a legenda mantém-se, um alias só de leitura continua só de leitura, e isso para cada ponto — mesmo quando vários apontam para a mesma fonte. Um alias cujo canal existe apenas como identificador passa a ser comparado, e a interface deixa de anunciar uma criação onde altera. A simulação mostra as enumerações em comparação, e uma linha de outro adaptador recebe o seu valor logo no primeiro clique.",
11
+ "nl": "Wat in een bestaande alias staat, geldt nu: het opschrift blijft, een alleen-lezen alias blijft alleen-lezen, en dat voor elk punt — ook als meerdere naar dezelfde bron wijzen. Een alias waarvan het kanaal alleen als id bestaat, wordt nu überhaupt vergeleken, en de interface kondigt geen aanmaak meer aan waar zij wijzigt. De proefronde toont opsommingen in vergelijking, en een regel uit een andere adapter krijgt zijn waarde al bij de eerste klik.",
12
+ "fr": "Ce qui figure dans un alias existant fait désormais foi : la légende reste, un alias en lecture seule le demeure, et cela pour chaque point — même lorsque plusieurs pointent vers la même source. Un alias dont le canal n’existe que comme identifiant est enfin comparé, et l’interface n’annonce plus une création là où elle modifie. La simulation montre les énumérations en comparaison, et une ligne provenant d’un autre adaptateur obtient sa valeur dès le premier clic.",
13
+ "it": "Quello che è memorizzato in un alias esistente ora vale: la didascalia resta, un alias di sola lettura rimane tale, e questo per ogni punto — anche quando più punti indicano la stessa sorgente. Un alias il cui canale esiste solo come identificatore viene finalmente confrontato, e l’interfaccia non annuncia più una creazione dove modifica. La prova a vuoto mostra le enumerazioni a confronto, e una riga che legge da un altro adattatore ottiene il suo valore già al primo clic.",
14
+ "es": "Lo que está guardado en un alias existente ahora manda: el rótulo se mantiene, un alias de solo lectura sigue siéndolo, y eso para cada punto — incluso cuando varios apuntan a la misma fuente. Un alias cuyo canal existe solo como identificador por fin se compara, y la interfaz ya no anuncia una creación donde modifica. La simulación muestra las enumeraciones en comparación, y una línea que lee de otro adaptador obtiene su valor ya en el primer clic.",
15
+ "pl": "To, co zapisano w istniejącym aliasie, teraz obowiązuje: podpis zostaje, alias tylko do odczytu pozostaje taki, i dotyczy to każdego punktu — także gdy kilka wskazuje to samo źródło. Alias, którego kanał istnieje wyłącznie jako identyfikator, jest wreszcie porównywany, a interfejs nie zapowiada już tworzenia tam, gdzie zmienia. Przebieg próbny pokazuje wyliczenia w porównaniu, a wiersz czytający z innego adaptera dostaje wartość już przy pierwszym kliknięciu.",
16
+ "uk": "Те, що записано в наявному аліасі, тепер має силу: підпис залишається, аліас лише для читання таким і лишається, і це для кожної точки — навіть коли кілька вказують на те саме джерело. Аліас, канал якого існує лише як ідентифікатор, нарешті порівнюється, а інтерфейс більше не оголошує створення там, де змінює. Пробний прогін показує переліки в порівнянні, а рядок з іншого адаптера отримує значення вже при першому кліку.",
17
+ "zh-cn": "现有别名中已保存的内容现在具有优先权:标题保留,只读别名仍为只读,并且对每个数据点都适用——即使多个点指向同一数据源。通道仅以标识符形式存在的别名现在也会被比对,界面不再在修改时宣告“新建”。试运行会以对比方式显示枚举,来自其他适配器的数据行在第一次点击时就能取到值。"
18
+ },
6
19
  "0.8.2": {
7
20
  "en": "A second alias on the same source is now announced instead of created silently — with a button to move the existing one instead. Switching to a template that finds nothing now works. Roles the workbench adapted are marked and can be taken back. Escape discards in every field of the target bar. New adapter icon.",
8
21
  "de": "Ein zweiter Alias auf dieselbe Quelle wird jetzt angesagt statt stillschweigend angelegt — daneben ein Knopf, der stattdessen den vorhandenen verlegt. Der Wechsel auf eine Vorlage, die nichts findet, greift jetzt. Angepasste Rollen sind markiert und lassen sich zurückholen. Escape verwirft in jedem Feld des Zielbalkens. Neues Adaptersymbol.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.alias-workbench",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "Creates aliases the comfortable way — devices that vis, Alexa and the device adapter understand. Templates do the work: shipped ones for HomeMatic and Tasmota, your own for everything else. Live values while you build, dry run before anything is written.",
5
5
  "author": {
6
6
  "name": "Ricardo Hipp",