iobroker.alias-workbench 0.10.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 +58 -98
- package/admin/css/werkbank.css +88 -0
- package/admin/i18n/de.json +766 -1
- package/admin/i18n/en.json +766 -1
- package/admin/i18n/es.json +766 -1
- package/admin/i18n/fr.json +766 -1
- package/admin/i18n/it.json +766 -1
- package/admin/i18n/nl.json +766 -1
- package/admin/i18n/pl.json +766 -1
- package/admin/i18n/pt.json +766 -1
- package/admin/i18n/ru.json +766 -1
- package/admin/i18n/uk.json +766 -1
- package/admin/i18n/zh-cn.json +766 -1
- package/admin/js/ablage.js +118 -0
- package/admin/js/attrappe.js +749 -0
- package/admin/js/baum.js +52 -5
- package/admin/js/detail.js +64 -3
- package/admin/js/entwurf.js +246 -31
- package/admin/js/ergebnis.js +77 -2
- package/admin/js/katalog.js +235 -40
- package/admin/js/mqtt.js +297 -27
- package/admin/js/musternamen.js +70 -26
- package/admin/js/objekte.js +2 -0
- package/admin/js/quellentausch.js +823 -16
- package/admin/js/schreiben.js +3 -2
- package/admin/js/sprache.js +11 -8
- package/admin/js/vorlagen.js +8 -3
- package/admin/js/vorlagenblatt.js +228 -64
- package/admin/js/werte.js +294 -5
- package/admin/js/zielleiste.js +19 -10
- package/admin/js/zuordnung.js +8 -7
- package/admin/js/zustand.js +32 -0
- package/admin/js/zustandsliste.js +9 -2
- package/admin/tab.html +24 -0
- package/admin/vorlagen/hm-dimmer.json +32 -8
- package/admin/vorlagen/hm-fensterkontakt-hm.json +20 -5
- package/admin/vorlagen/hm-fensterkontakt-hmip.json +28 -7
- package/admin/vorlagen/hm-heizgruppe.json +38 -11
- package/admin/vorlagen/hm-heizkoerper.json +42 -12
- package/admin/vorlagen/hm-rollladen.json +28 -7
- package/admin/vorlagen/hm-schaltaktor-lampe.json +24 -6
- package/admin/vorlagen/hm-schaltaktor-mehrfach.json +32 -8
- package/admin/vorlagen/hm-schaltaktor-steckdose.json +24 -6
- package/admin/vorlagen/hm-temperatur-feuchte.json +8 -2
- package/admin/vorlagen/hm-wandthermostat.json +36 -9
- package/admin/vorlagen/messpunkt.json +40 -10
- package/admin/vorlagen/tasmota-lampe.json +48 -12
- package/admin/vorlagen/tasmota-mehrfach.json +40 -10
- package/admin/vorlagen/tasmota-rgb.json +36 -9
- package/admin/vorlagen/tasmota-steckdose.json +56 -14
- package/io-package.json +41 -28
- package/package.json +3 -3
- package/admin/sprachen/de.json +0 -685
- package/admin/sprachen/en.json +0 -685
package/admin/js/katalog.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { holeText } from './basis.js';
|
|
2
|
-
import {
|
|
1
|
+
import { el, holeText } from './basis.js';
|
|
2
|
+
import { leseAblage, ergaenzeAblage, stempelAus } from './ablage.js';
|
|
3
|
+
import { tr, txt, alleTexte } from './sprache.js';
|
|
3
4
|
import { einst } from './einstellungen.js';
|
|
4
5
|
import './enums.js';
|
|
5
6
|
|
|
@@ -12,9 +13,11 @@ import './enums.js';
|
|
|
12
13
|
aus dem Bundle, in dem sie ohnehin liegen. Wir laufen in derselben
|
|
13
14
|
Herkunft wie der Admin, `fetch` genuegt.
|
|
14
15
|
|
|
15
|
-
Der Weg
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
Der Weg haengt am Bauwerkzeug des Admin, und das wechselt: bis 7.8.23
|
|
17
|
+
lagen die Listen als JSON.parse mit Rueckstrichen in einem „Enums"-
|
|
18
|
+
Chunk, seit 8.0.x als gewoehnliches JavaScript in einem Riesenmodul.
|
|
19
|
+
Beide Bauarten werden gelesen, das Ergebnis liegt danach im
|
|
20
|
+
Dateibereich. Bricht trotzdem etwas, bleiben die Listen leer
|
|
18
21
|
und das Feld zeigt nur den Bestand - wie vorher. Kein Fehler, keine
|
|
19
22
|
Meldung, nur weniger Auswahl. Deshalb faengt hier alles ab, was
|
|
20
23
|
schiefgehen kann, ohne ein Wort zu verlieren. */
|
|
@@ -123,47 +126,239 @@ function ordneListenZu(text) {
|
|
|
123
126
|
return enumVorlagen.rooms.length && enumVorlagen.functions.length;
|
|
124
127
|
}
|
|
125
128
|
|
|
129
|
+
/* ---------------- Die zweite Bauart: alles in einem Riesenmodul ----------------
|
|
130
|
+
|
|
131
|
+
Admin 8.0.14 hat sein Bündel auf „Module Federation" umgestellt. Der
|
|
132
|
+
Inhalt ist derselbe geblieben — gemessen am 07.10.2026: dieselben 58
|
|
133
|
+
Räume und 62 Funktionen, Kennung für Kennung identisch, dieselben 120
|
|
134
|
+
Bilder —, aber er steckt jetzt in **einer** Datei von 7,9 MB statt in
|
|
135
|
+
vielen kleinen. Zwei Dinge haben uns daran gehindert, ihn zu finden:
|
|
136
|
+
|
|
137
|
+
* Die Zeile `if (t.length > 3000000) return false;` übersprang genau
|
|
138
|
+
diese Datei. Unter 7.8.23 lag der Katalog in einem Bündel von
|
|
139
|
+
2 843 653 Bytes — fünf Prozent unter der Grenze. Es hat nie sicher
|
|
140
|
+
funktioniert, es ist bloß nie angestoßen.
|
|
141
|
+
* Die Listen stehen nicht mehr als JSON-Text in Rückstrichen, sondern
|
|
142
|
+
als gewöhnliches JavaScript: Schlüssel ohne Anführungszeichen,
|
|
143
|
+
Zeichenketten in Rückstrichen. `JSON.parse` greift da nicht.
|
|
144
|
+
|
|
145
|
+
Darum liest die Werkbank jetzt beide Bauarten. Und weil 7,9 MB bei
|
|
146
|
+
jedem Öffnen des Reiters unzumutbar wären, wird das Ergebnis im
|
|
147
|
+
Dateibereich des Adapters abgelegt und erst wieder geholt, wenn der
|
|
148
|
+
Admin seine Bündel neu schreibt. */
|
|
149
|
+
|
|
150
|
+
/* Eine Liste der Form `[{_id:`x`,name:{…},icon:`y.svg`}]`.
|
|
151
|
+
|
|
152
|
+
Kein `eval` und kein `new Function`: beides hieße, fremden Text
|
|
153
|
+
auszuführen, und der Gewinn wäre keiner. Die Einträge haben eine feste
|
|
154
|
+
Form, und in Namen kommen keine Rückstriche vor. */
|
|
155
|
+
function eintraegeAus(roh) {
|
|
156
|
+
var raus = [];
|
|
157
|
+
var re = /\{_id:`([^`]*)`,name:\{([\s\S]*?)\},icon:`([^`]*)`\}/g, m;
|
|
158
|
+
while ((m = re.exec(roh))) {
|
|
159
|
+
var name = {}, p = /(?:([A-Za-z0-9_$]+)|"([^"]+)"):`([^`]*)`/g, n;
|
|
160
|
+
while ((n = p.exec(m[2]))) { name[n[1] || n[2]] = n[3]; }
|
|
161
|
+
raus.push({ _id: m[1], name: name, icon: m[3].replace(/\.svg$/, '') });
|
|
162
|
+
}
|
|
163
|
+
return raus;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* Von `pos` an die eckige Klammer ausbalancieren. */
|
|
167
|
+
function klammerAb(text, pos) {
|
|
168
|
+
var tiefe = 0;
|
|
169
|
+
for (var j = pos; j < text.length; j += 1) {
|
|
170
|
+
if (text[j] === '[') { tiefe += 1; }
|
|
171
|
+
else if (text[j] === ']') { tiefe -= 1; if (!tiefe) { return text.slice(pos, j + 1); } }
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Die Bildkarte zu einer Liste: `{Anteroom:`PHN2…`, "Alarm Systems":`…`}`.
|
|
177
|
+
|
|
178
|
+
Gesucht wird über einen Bildnamen aus der Liste selbst — der
|
|
179
|
+
Variablenname wechselt bei jedem Bau des Admin, der Name „Storeroom"
|
|
180
|
+
nicht. Rückwärts bis zur öffnenden Klammer zu laufen ist hier sicher:
|
|
181
|
+
base64 enthält keine geschweiften Klammern. */
|
|
182
|
+
function ikonKarte(text, probe) {
|
|
183
|
+
var stelle = text.indexOf(probe + ':`');
|
|
184
|
+
if (stelle === -1) { stelle = text.indexOf('"' + probe + '":`'); }
|
|
185
|
+
if (stelle === -1) { return null; }
|
|
186
|
+
var auf = text.lastIndexOf('{', stelle);
|
|
187
|
+
if (auf === -1) { return null; }
|
|
188
|
+
var tiefe = 0, zu = -1;
|
|
189
|
+
for (var j = auf; j < text.length; j += 1) {
|
|
190
|
+
if (text[j] === '{') { tiefe += 1; }
|
|
191
|
+
else if (text[j] === '}') { tiefe -= 1; if (!tiefe) { zu = j; break; } }
|
|
192
|
+
}
|
|
193
|
+
if (zu === -1) { return null; }
|
|
194
|
+
var roh = text.slice(auf, zu + 1), karte = {};
|
|
195
|
+
var re = /(?:([A-Za-z0-9_$]+)|"([^"]+)"):`([A-Za-z0-9+/=]{40,})`/g, m;
|
|
196
|
+
while ((m = re.exec(roh))) { karte[m[1] || m[2]] = m[3]; }
|
|
197
|
+
return Object.keys(karte).length ? karte : null;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* Beide Listen und beide Bildkarten aus dem Riesenmodul. */
|
|
201
|
+
function ausRiesenmodul(text) {
|
|
202
|
+
var gefunden = { rooms: null, functions: null };
|
|
203
|
+
var pos = 0;
|
|
204
|
+
for (;;) {
|
|
205
|
+
var i = text.indexOf('[{_id:`', pos);
|
|
206
|
+
if (i === -1) { break; }
|
|
207
|
+
pos = i + 7;
|
|
208
|
+
var roh = klammerAb(text, i);
|
|
209
|
+
if (!roh) { continue; }
|
|
210
|
+
var liste = eintraegeAus(roh);
|
|
211
|
+
if (liste.length < 20) { continue; }
|
|
212
|
+
if (!gefunden.rooms && istListe(liste, RAUM_MARKE)) { gefunden.rooms = liste; }
|
|
213
|
+
else if (!gefunden.functions && istListe(liste, FUNK_MARKE)) { gefunden.functions = liste; }
|
|
214
|
+
if (gefunden.rooms && gefunden.functions) { break; }
|
|
215
|
+
}
|
|
216
|
+
if (!gefunden.rooms || !gefunden.functions) { return null; }
|
|
217
|
+
return {
|
|
218
|
+
rooms: gefunden.rooms,
|
|
219
|
+
functions: gefunden.functions,
|
|
220
|
+
ikonen: {
|
|
221
|
+
rooms: ikonKarte(text, gefunden.rooms[0].icon) || {},
|
|
222
|
+
functions: ikonKarte(text, gefunden.functions[0].icon) || {}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* ---------------- Der Hinweis, solange geholt wird ----------------
|
|
228
|
+
|
|
229
|
+
7,9 MB dauern beim ersten Mal ein paar Sekunden. Ohne ein Wort dazu
|
|
230
|
+
wirkt das wie ein Hänger. Danach nie wieder, bis der Admin sich
|
|
231
|
+
ändert — und auch das gehört in den Hinweis, sonst fragt man sich
|
|
232
|
+
beim nächsten Mal, warum es plötzlich schnell geht. */
|
|
233
|
+
function laedtAn() {
|
|
234
|
+
if (document.getElementById('katalog-laedt')) { return; }
|
|
235
|
+
var k = el('div', 'katalog-laedt');
|
|
236
|
+
k.id = 'katalog-laedt';
|
|
237
|
+
k.appendChild(el('div', 'kl-kopf', tr('catalog.loadingTitle')));
|
|
238
|
+
k.appendChild(el('div', 'kl-text', tr('catalog.loadingText')));
|
|
239
|
+
document.body.appendChild(k);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function laedtAus() {
|
|
243
|
+
var k = document.getElementById('katalog-laedt');
|
|
244
|
+
if (k && k.parentNode) { k.parentNode.removeChild(k); }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* Was aus der Ablage oder frisch kam, in die Arbeitsvariablen. */
|
|
248
|
+
function uebernehmen(satz) {
|
|
249
|
+
enumVorlagen.rooms = satz.rooms || [];
|
|
250
|
+
enumVorlagen.functions = satz.functions || [];
|
|
251
|
+
if (satz.ikonDateien) {
|
|
252
|
+
enumIkonen.rooms = satz.ikonDateien.rooms || {};
|
|
253
|
+
enumIkonen.functions = satz.ikonDateien.functions || {};
|
|
254
|
+
}
|
|
255
|
+
/* Fertige Bilder gleich in den Vorrat — bei der zweiten Bauart liegen
|
|
256
|
+
sie im selben Modul und müssen nicht einzeln nachgeholt werden. */
|
|
257
|
+
['rooms', 'functions'].forEach(function (art) {
|
|
258
|
+
var karte = (satz.ikonen && satz.ikonen[art]) || {};
|
|
259
|
+
Object.keys(karte).forEach(function (name) {
|
|
260
|
+
ikonCache[art + ':' + name] = 'data:image/svg+xml;base64,' + karte[name];
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
126
265
|
export function ladeEnumVorlagen(nachher) {
|
|
127
266
|
if (vorlagenGeholt || !einst('vorlagenVomAdmin')) { return; }
|
|
128
267
|
vorlagenGeholt = true;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
268
|
+
|
|
269
|
+
var stempel = null;
|
|
270
|
+
|
|
271
|
+
function abschluss() {
|
|
272
|
+
laedtAus();
|
|
273
|
+
if (!enumVorlagen.rooms.length || !enumVorlagen.functions.length) {
|
|
274
|
+
katalogFehlt = true;
|
|
275
|
+
}
|
|
276
|
+
/* Der Aufrufer entscheidet, ob und was neu zu zeichnen ist -
|
|
277
|
+
dieses Modul kennt die Oberflaeche nicht. */
|
|
278
|
+
if (typeof nachher === 'function') { nachher(); }
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* Erste Bauart: der Enums-Chunk mit JSON.parse in Rueckstrichen. */
|
|
282
|
+
function ersterWeg() {
|
|
283
|
+
return holeText('/index.html').then(function (html) {
|
|
284
|
+
return sucheEnumChunk(html.match(/assets\/[A-Za-z0-9_\-.]+\.js/g) || [], {}, 0);
|
|
285
|
+
}).then(function (chunk) {
|
|
286
|
+
if (!chunk) { return false; }
|
|
287
|
+
return holeText('/assets/' + chunk).then(function (src) {
|
|
288
|
+
enumIkonen.functions = ikonMap(src, 'devices');
|
|
289
|
+
enumIkonen.rooms = ikonMap(src, 'rooms');
|
|
290
|
+
if (ordneListenZu(src)) { return true; }
|
|
291
|
+
|
|
292
|
+
/* Fehlt eine, liegt sie in einer der Dateien, die der Chunk
|
|
293
|
+
nennt. Kurze Namen zuerst: die Listen stecken in kleinen
|
|
294
|
+
Bausteinen. Ohne diese Nachsuche fand Admin 7.8.23 am
|
|
295
|
+
07.10.2026 nur die 62 Funktionen und keinen einzigen Raum —
|
|
296
|
+
die Raumliste liegt dort in einer eigenen Datei. */
|
|
297
|
+
var dateien = (src.match(/[A-Za-z0-9_.-]+-[A-Za-z0-9_-]{8}\.js/g) || [])
|
|
298
|
+
.filter(function (x, i, a) { return a.indexOf(x) === i; })
|
|
299
|
+
.sort(function (a, b) { return a.length - b.length; })
|
|
300
|
+
.slice(0, 60);
|
|
301
|
+
|
|
302
|
+
return dateien.reduce(function (kette, f) {
|
|
303
|
+
return kette.then(function (fertig) {
|
|
304
|
+
if (fertig) { return true; }
|
|
305
|
+
return holeText('/assets/' + f).then(function (t) {
|
|
306
|
+
return ordneListenZu(t);
|
|
307
|
+
})['catch'](function () { return false; });
|
|
308
|
+
});
|
|
309
|
+
}, Promise.resolve(false));
|
|
156
310
|
});
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
311
|
+
})['catch'](function () { return false; });
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* Zweite Bauart: das Riesenmodul. Groesse ist jetzt kein Ausschluss
|
|
315
|
+
mehr, aber die Reihenfolge bleibt: kleine Dateien zuerst, das
|
|
316
|
+
Riesenmodul zuletzt, und nach dem ersten Treffer ist Schluss. */
|
|
317
|
+
function zweiterWeg() {
|
|
318
|
+
return holeText('/index.html').then(function (html) {
|
|
319
|
+
var dateien = (html.match(/assets\/[A-Za-z0-9_\-.]+\.js/g) || [])
|
|
320
|
+
.filter(function (x, i, a) { return a.indexOf(x) === i; });
|
|
321
|
+
var geholt = 0, treffer = null;
|
|
322
|
+
return dateien.reduce(function (kette, f) {
|
|
323
|
+
return kette.then(function () {
|
|
324
|
+
if (treffer || geholt > 25000000) { return; }
|
|
325
|
+
return holeText('/' + f).then(function (t) {
|
|
326
|
+
geholt += t.length;
|
|
327
|
+
var satz = ausRiesenmodul(t);
|
|
328
|
+
if (satz) { treffer = satz; }
|
|
329
|
+
})['catch'](function () { });
|
|
330
|
+
});
|
|
331
|
+
}, Promise.resolve()).then(function () { return treffer; });
|
|
332
|
+
})['catch'](function () { return null; });
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
holeText('/index.html').then(function (html) {
|
|
336
|
+
stempel = stempelAus(html);
|
|
337
|
+
return leseAblage();
|
|
338
|
+
}).then(function (abgelegt) {
|
|
339
|
+
if (abgelegt && abgelegt.stempel === stempel &&
|
|
340
|
+
(abgelegt.rooms || []).length && (abgelegt.functions || []).length) {
|
|
341
|
+
uebernehmen(abgelegt);
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
/* Jetzt wird wirklich geholt - und erst jetzt sagen wir es. */
|
|
345
|
+
laedtAn();
|
|
346
|
+
return ersterWeg().then(function (ging) {
|
|
347
|
+
if (ging) {
|
|
348
|
+
return { rooms: enumVorlagen.rooms, functions: enumVorlagen.functions,
|
|
349
|
+
ikonDateien: { rooms: enumIkonen.rooms, functions: enumIkonen.functions } };
|
|
162
350
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
351
|
+
return zweiterWeg().then(function (satz) {
|
|
352
|
+
if (!satz) { return null; }
|
|
353
|
+
uebernehmen(satz);
|
|
354
|
+
return satz;
|
|
355
|
+
});
|
|
166
356
|
});
|
|
357
|
+
}).then(function (zumAblegen) {
|
|
358
|
+
if (!zumAblegen) { return null; }
|
|
359
|
+
return ergaenzeAblage(stempel, zumAblegen);
|
|
360
|
+
})['catch'](function () { /* still bleiben: der Bestand genuegt */ })
|
|
361
|
+
.then(abschluss);
|
|
167
362
|
}
|
|
168
363
|
|
|
169
364
|
/* Das Icon einer Vorlage. Es steht als fertige data-URI im Chunk - genau
|