iobroker.alias-workbench 0.9.7 → 0.9.9
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 +51 -79
- package/admin/i18n/de.json +12 -588
- package/admin/i18n/en.json +12 -588
- package/admin/i18n/es.json +14 -0
- package/admin/i18n/fr.json +14 -0
- package/admin/i18n/it.json +14 -0
- package/admin/i18n/nl.json +14 -0
- package/admin/i18n/pl.json +14 -0
- package/admin/i18n/pt.json +14 -0
- package/admin/i18n/ru.json +14 -0
- package/admin/i18n/uk.json +14 -0
- package/admin/i18n/zh-cn.json +14 -0
- package/admin/js/detail.js +31 -6
- package/admin/js/erkennung.js +87 -0
- package/admin/js/musterwahl.js +30 -6
- package/admin/js/sprache.js +4 -2
- package/admin/js/vorlagenblatt.js +58 -17
- package/admin/jsonConfig.json +13 -157
- package/admin/sprachen/de.json +594 -0
- package/admin/sprachen/en.json +594 -0
- package/io-package.json +37 -102
- package/package.json +2 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Add missing icons to functions": "Compléter les icônes manquantes des fonctions",
|
|
3
|
+
"Add missing icons to rooms": "Compléter les icônes manquantes des pièces",
|
|
4
|
+
"Admin ships 62 function and 58 room templates, each with an icon. When the workbench creates an enumeration, it takes the icon from there. Existing enumerations keep whatever they have — unless you allow it to fill in what is missing. Nothing is ever written without the dry run showing it first.": "L'Admin fournit 62 modèles de fonction et 58 modèles de pièce, chacun avec une icône. Lorsque l'établi crée une énumération, il y prend l'icône. Les énumérations existantes conservent ce qu'elles ont — sauf si vous autorisez le complément de ce qui manque. Rien n'est jamais écrit sans que la simulation ne l'ait montré au préalable.",
|
|
5
|
+
"Also replace unusable icon entries": "Remplacer aussi les entrées d'icône inutilisables",
|
|
6
|
+
"Applies when a room has no icon at all and a template of the same name or ID exists.": "S'applique lorsqu'une pièce n'a aucune icône et qu'un modèle du même nom ou du même ID existe.",
|
|
7
|
+
"Icons for rooms and functions": "Icônes pour les pièces et les fonctions",
|
|
8
|
+
"Offer the Admin's room and function templates": "Proposer les modèles de pièce et de fonction de l'Admin",
|
|
9
|
+
"Same for functions. Enumerations mirrored from a HomeMatic CCU never carry an icon.": "Idem pour les fonctions. Les énumérations reprises d'une centrale HomeMatic ne portent jamais d'icône.",
|
|
10
|
+
"The Admin setup wizard leaves a bare name such as \"Playroom\" in the icon field, which no longer resolves to a picture and shows as a broken box. With this on, the workbench replaces it. It overwrites a field that is not empty — the dry run names it explicitly.": "L'assistant de configuration de l'Admin laisse dans le champ d'icône un simple nom tel que « Playroom », qui ne renvoie plus à aucune image et s'affiche comme un cadre cassé. Si cette option est activée, l'établi le remplace. Un champ non vide est alors écrasé — la simulation le signale explicitement.",
|
|
11
|
+
"The Alias Workbench has no running process — everything happens in the Admin tab. These settings control how it writes.": "L'Établi d'alias n'a aucun processus en cours — tout se passe dans l'onglet Admin. Ces réglages déterminent la manière dont il écrit.",
|
|
12
|
+
"The workbench reads them at runtime from the Admin's own bundle instead of keeping a copy that would age with every update. If that fails, the selection lists simply show what already exists — no error, just fewer entries.": "L'établi les lit à l'exécution depuis le bundle de l'Admin plutôt que de conserver une copie qui vieillirait à chaque mise à jour. En cas d'échec, les listes de sélection n'affichent que l'existant — pas d'erreur, simplement moins d'entrées.",
|
|
13
|
+
"Where the templates come from": "D'où viennent les modèles"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Add missing icons to functions": "Aggiungere le icone mancanti alle funzioni",
|
|
3
|
+
"Add missing icons to rooms": "Aggiungere le icone mancanti alle stanze",
|
|
4
|
+
"Admin ships 62 function and 58 room templates, each with an icon. When the workbench creates an enumeration, it takes the icon from there. Existing enumerations keep whatever they have — unless you allow it to fill in what is missing. Nothing is ever written without the dry run showing it first.": "L'Admin include 62 modelli di funzione e 58 di stanza, ciascuno con un’icona. Quando il banco di lavoro crea un’enumerazione, prende l’icona da lì. Le enumerazioni esistenti mantengono ciò che hanno, a meno che non si consenta di integrare ciò che manca. Nulla viene mai scritto senza che la simulazione lo mostri prima.",
|
|
5
|
+
"Also replace unusable icon entries": "Sostituire anche le voci di icona inutilizzabili",
|
|
6
|
+
"Applies when a room has no icon at all and a template of the same name or ID exists.": "Si applica quando una stanza non ha alcuna icona ed esiste un modello con lo stesso nome o ID.",
|
|
7
|
+
"Icons for rooms and functions": "Icone per stanze e funzioni",
|
|
8
|
+
"Offer the Admin's room and function templates": "Proporre i modelli di stanza e funzione dell’Admin",
|
|
9
|
+
"Same for functions. Enumerations mirrored from a HomeMatic CCU never carry an icon.": "Lo stesso vale per le funzioni. Le enumerazioni rispecchiate da una CCU HomeMatic non hanno mai un’icona.",
|
|
10
|
+
"The Admin setup wizard leaves a bare name such as \"Playroom\" in the icon field, which no longer resolves to a picture and shows as a broken box. With this on, the workbench replaces it. It overwrites a field that is not empty — the dry run names it explicitly.": "La procedura guidata di configurazione dell’Admin lascia nel campo icona un semplice nome come «Playroom», che non rimanda più ad alcuna immagine e appare come un riquadro rotto. Con questa opzione attiva, il banco di lavoro lo sostituisce. Viene così sovrascritto un campo non vuoto: la simulazione lo indica espressamente.",
|
|
11
|
+
"The Alias Workbench has no running process — everything happens in the Admin tab. These settings control how it writes.": "Il Banco di lavoro alias non ha alcun processo in esecuzione — tutto avviene nella scheda Admin. Queste impostazioni determinano come scrive.",
|
|
12
|
+
"The workbench reads them at runtime from the Admin's own bundle instead of keeping a copy that would age with every update. If that fails, the selection lists simply show what already exists — no error, just fewer entries.": "Il banco di lavoro li legge in fase di esecuzione dal bundle dell’Admin, anziché conservare una copia che invecchierebbe a ogni aggiornamento. Se ciò non riesce, gli elenchi di selezione mostrano solo ciò che esiste già: non è un errore, solo meno voci.",
|
|
13
|
+
"Where the templates come from": "Da dove provengono i modelli"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Add missing icons to functions": "Ontbrekende pictogrammen bij functies aanvullen",
|
|
3
|
+
"Add missing icons to rooms": "Ontbrekende pictogrammen bij ruimtes aanvullen",
|
|
4
|
+
"Admin ships 62 function and 58 room templates, each with an icon. When the workbench creates an enumeration, it takes the icon from there. Existing enumerations keep whatever they have — unless you allow it to fill in what is missing. Nothing is ever written without the dry run showing it first.": "Admin levert 62 functie- en 58 ruimtesjablonen, elk met een pictogram. Wanneer de werkbank een opsomming aanmaakt, neemt zij het pictogram daarvandaan. Bestaande opsommingen behouden wat ze hebben — tenzij u toestaat dat ontbrekende worden aangevuld. Er wordt nooit iets geschreven zonder dat de proefrun het eerst toont.",
|
|
5
|
+
"Also replace unusable icon entries": "Ook onbruikbare pictogramvermeldingen vervangen",
|
|
6
|
+
"Applies when a room has no icon at all and a template of the same name or ID exists.": "Geldt wanneer een ruimte helemaal geen pictogram heeft en er een sjabloon met dezelfde naam of ID bestaat.",
|
|
7
|
+
"Icons for rooms and functions": "Pictogrammen voor ruimtes en functies",
|
|
8
|
+
"Offer the Admin's room and function templates": "De ruimte- en functiesjablonen van Admin aanbieden",
|
|
9
|
+
"Same for functions. Enumerations mirrored from a HomeMatic CCU never carry an icon.": "Hetzelfde voor functies. Opsommingen die vanaf een HomeMatic-CCU worden gespiegeld, hebben nooit een pictogram.",
|
|
10
|
+
"The Admin setup wizard leaves a bare name such as \"Playroom\" in the icon field, which no longer resolves to a picture and shows as a broken box. With this on, the workbench replaces it. It overwrites a field that is not empty — the dry run names it explicitly.": "De installatiewizard van Admin laat in het pictogramveld een kale naam als \"Playroom\" achter, die niet langer naar een afbeelding verwijst en als een kapot kadertje verschijnt. Staat dit aan, dan vervangt de werkbank hem. Daarbij wordt een niet-leeg veld overschreven — de proefrun benoemt dat uitdrukkelijk.",
|
|
11
|
+
"The Alias Workbench has no running process — everything happens in the Admin tab. These settings control how it writes.": "De Alias-werkbank heeft geen draaiend proces — alles gebeurt in het Admin-tabblad. Deze instellingen bepalen hoe er geschreven wordt.",
|
|
12
|
+
"The workbench reads them at runtime from the Admin's own bundle instead of keeping a copy that would age with every update. If that fails, the selection lists simply show what already exists — no error, just fewer entries.": "De werkbank leest ze tijdens het uitvoeren uit de bundel van Admin zelf, in plaats van een kopie bij te houden die bij elke update veroudert. Mislukt dat, dan tonen de keuzelijsten alleen wat er al is — geen fout, alleen minder items.",
|
|
13
|
+
"Where the templates come from": "Waar de sjablonen vandaan komen"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Add missing icons to functions": "Uzupełniać brakujące ikony funkcji",
|
|
3
|
+
"Add missing icons to rooms": "Uzupełniać brakujące ikony pomieszczeń",
|
|
4
|
+
"Admin ships 62 function and 58 room templates, each with an icon. When the workbench creates an enumeration, it takes the icon from there. Existing enumerations keep whatever they have — unless you allow it to fill in what is missing. Nothing is ever written without the dry run showing it first.": "Admin dostarcza 62 szablony funkcji i 58 szablonów pomieszczeń, każdy z ikoną. Gdy warsztat tworzy wyliczenie, pobiera ikonę stamtąd. Istniejące wyliczenia zachowują to, co mają — chyba że pozwolisz uzupełnić braki. Nic nie jest zapisywane bez uprzedniego pokazania przez próbny przebieg.",
|
|
5
|
+
"Also replace unusable icon entries": "Zastępować także nieprzydatne wpisy ikon",
|
|
6
|
+
"Applies when a room has no icon at all and a template of the same name or ID exists.": "Działa, gdy pomieszczenie nie ma żadnej ikony, a istnieje szablon o tej samej nazwie lub ID.",
|
|
7
|
+
"Icons for rooms and functions": "Ikony dla pomieszczeń i funkcji",
|
|
8
|
+
"Offer the Admin's room and function templates": "Oferować szablony pomieszczeń i funkcji z Admina",
|
|
9
|
+
"Same for functions. Enumerations mirrored from a HomeMatic CCU never carry an icon.": "To samo dotyczy funkcji. Wyliczenia odwzorowane z centrali HomeMatic nigdy nie mają ikony.",
|
|
10
|
+
"The Admin setup wizard leaves a bare name such as \"Playroom\" in the icon field, which no longer resolves to a picture and shows as a broken box. With this on, the workbench replaces it. It overwrites a field that is not empty — the dry run names it explicitly.": "Kreator konfiguracji Admina pozostawia w polu ikony samą nazwę, np. „Playroom”, która nie prowadzi już do żadnego obrazka i wyświetla się jako uszkodzona ramka. Przy włączonej opcji warsztat ją zastępuje. Nadpisywane jest wtedy niepuste pole — próbny przebieg wskazuje to osobno.",
|
|
11
|
+
"The Alias Workbench has no running process — everything happens in the Admin tab. These settings control how it writes.": "Warsztat aliasów nie ma działającego procesu — wszystko dzieje się w zakładce Admina. Te ustawienia określają, jak zapisuje.",
|
|
12
|
+
"The workbench reads them at runtime from the Admin's own bundle instead of keeping a copy that would age with every update. If that fails, the selection lists simply show what already exists — no error, just fewer entries.": "Warsztat odczytuje je w czasie działania z własnego pakietu Admina, zamiast utrzymywać kopię, która starzałaby się z każdą aktualizacją. Jeśli się to nie powiedzie, listy wyboru pokazują tylko to, co już istnieje — to nie błąd, po prostu mniej pozycji.",
|
|
13
|
+
"Where the templates come from": "Skąd pochodzą szablony"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Add missing icons to functions": "Adicionar ícones em falta às funções",
|
|
3
|
+
"Add missing icons to rooms": "Adicionar ícones em falta às divisões",
|
|
4
|
+
"Admin ships 62 function and 58 room templates, each with an icon. When the workbench creates an enumeration, it takes the icon from there. Existing enumerations keep whatever they have — unless you allow it to fill in what is missing. Nothing is ever written without the dry run showing it first.": "O Admin inclui 62 modelos de função e 58 modelos de divisão, cada um com um ícone. Quando a bancada cria uma enumeração, retira o ícone daí. As enumerações existentes mantêm o que têm — a menos que permita preencher o que falta. Nada é escrito sem que a simulação o mostre primeiro.",
|
|
5
|
+
"Also replace unusable icon entries": "Substituir também entradas de ícone inutilizáveis",
|
|
6
|
+
"Applies when a room has no icon at all and a template of the same name or ID exists.": "Aplica-se quando uma divisão não tem qualquer ícone e existe um modelo com o mesmo nome ou ID.",
|
|
7
|
+
"Icons for rooms and functions": "Ícones para divisões e funções",
|
|
8
|
+
"Offer the Admin's room and function templates": "Oferecer os modelos de divisão e função do Admin",
|
|
9
|
+
"Same for functions. Enumerations mirrored from a HomeMatic CCU never carry an icon.": "O mesmo para as funções. As enumerações espelhadas de uma CCU HomeMatic nunca têm ícone.",
|
|
10
|
+
"The Admin setup wizard leaves a bare name such as \"Playroom\" in the icon field, which no longer resolves to a picture and shows as a broken box. With this on, the workbench replaces it. It overwrites a field that is not empty — the dry run names it explicitly.": "O assistente de configuração do Admin deixa no campo do ícone um nome simples como «Playroom», que já não corresponde a nenhuma imagem e aparece como uma caixa partida. Com esta opção ligada, a bancada substitui-o. Isso sobrescreve um campo que não está vazio — a simulação indica-o explicitamente.",
|
|
11
|
+
"The Alias Workbench has no running process — everything happens in the Admin tab. These settings control how it writes.": "A Bancada de Alias não tem processo em execução — tudo acontece no separador do Admin. Estas definições determinam como escreve.",
|
|
12
|
+
"The workbench reads them at runtime from the Admin's own bundle instead of keeping a copy that would age with every update. If that fails, the selection lists simply show what already exists — no error, just fewer entries.": "A bancada lê-os em tempo de execução a partir do próprio pacote do Admin, em vez de manter uma cópia que envelheceria a cada atualização. Se isso falhar, as listas de seleção mostram apenas o que já existe — não é um erro, apenas menos entradas.",
|
|
13
|
+
"Where the templates come from": "De onde vêm os modelos"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Add missing icons to functions": "Дополнять отсутствующие значки у функций",
|
|
3
|
+
"Add missing icons to rooms": "Дополнять отсутствующие значки у комнат",
|
|
4
|
+
"Admin ships 62 function and 58 room templates, each with an icon. When the workbench creates an enumeration, it takes the icon from there. Existing enumerations keep whatever they have — unless you allow it to fill in what is missing. Nothing is ever written without the dry run showing it first.": "Admin поставляется с 62 шаблонами функций и 58 шаблонами комнат, у каждого есть значок. Когда верстак создаёт перечисление, он берёт значок оттуда. Существующие перечисления сохраняют то, что у них есть, — если только вы не разрешите дополнить недостающее. Ничего не записывается без того, чтобы пробный прогон сначала это показал.",
|
|
5
|
+
"Also replace unusable icon entries": "Также заменять непригодные записи значков",
|
|
6
|
+
"Applies when a room has no icon at all and a template of the same name or ID exists.": "Действует, когда у комнаты вообще нет значка и существует шаблон с тем же именем или идентификатором.",
|
|
7
|
+
"Icons for rooms and functions": "Значки для комнат и функций",
|
|
8
|
+
"Offer the Admin's room and function templates": "Предлагать шаблоны комнат и функций из Admin",
|
|
9
|
+
"Same for functions. Enumerations mirrored from a HomeMatic CCU never carry an icon.": "То же для функций. Перечисления, зеркалируемые с центрального блока HomeMatic, никогда не содержат значка.",
|
|
10
|
+
"The Admin setup wizard leaves a bare name such as \"Playroom\" in the icon field, which no longer resolves to a picture and shows as a broken box. With this on, the workbench replaces it. It overwrites a field that is not empty — the dry run names it explicitly.": "Мастер настройки Admin оставляет в поле значка голое имя вроде «Playroom», которое больше не ведёт к изображению и отображается как сломанный прямоугольник. Если это включено, верстак заменяет его. При этом перезаписывается непустое поле — пробный прогон называет это отдельно.",
|
|
11
|
+
"The Alias Workbench has no running process — everything happens in the Admin tab. These settings control how it writes.": "У «Верстака алиасов» нет запущенного процесса — всё происходит во вкладке администратора. Эти настройки определяют, как он записывает.",
|
|
12
|
+
"The workbench reads them at runtime from the Admin's own bundle instead of keeping a copy that would age with every update. If that fails, the selection lists simply show what already exists — no error, just fewer entries.": "Верстак читает их во время выполнения из собственного бандла Admin, вместо того чтобы держать копию, устаревающую с каждым обновлением. Если это не удаётся, списки выбора показывают только то, что уже есть, — не ошибка, просто меньше вариантов.",
|
|
13
|
+
"Where the templates come from": "Откуда берутся шаблоны"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Add missing icons to functions": "Доповнювати відсутні значки функцій",
|
|
3
|
+
"Add missing icons to rooms": "Доповнювати відсутні значки кімнат",
|
|
4
|
+
"Admin ships 62 function and 58 room templates, each with an icon. When the workbench creates an enumeration, it takes the icon from there. Existing enumerations keep whatever they have — unless you allow it to fill in what is missing. Nothing is ever written without the dry run showing it first.": "Admin постачає 62 шаблони функцій і 58 шаблонів кімнат, кожен зі значком. Коли верстак створює перелік, він бере значок звідти. Наявні переліки зберігають те, що мають, — якщо ви не дозволите доповнити відсутнє. Нічого не записується без того, щоб пробний запуск спершу це показав.",
|
|
5
|
+
"Also replace unusable icon entries": "Також замінювати непридатні записи значків",
|
|
6
|
+
"Applies when a room has no icon at all and a template of the same name or ID exists.": "Діє, коли кімната взагалі не має значка й існує шаблон з такою самою назвою або ідентифікатором.",
|
|
7
|
+
"Icons for rooms and functions": "Значки для кімнат і функцій",
|
|
8
|
+
"Offer the Admin's room and function templates": "Пропонувати шаблони кімнат і функцій з Admin",
|
|
9
|
+
"Same for functions. Enumerations mirrored from a HomeMatic CCU never carry an icon.": "Те саме для функцій. Переліки, віддзеркалені з центрального блока HomeMatic, ніколи не містять значка.",
|
|
10
|
+
"The Admin setup wizard leaves a bare name such as \"Playroom\" in the icon field, which no longer resolves to a picture and shows as a broken box. With this on, the workbench replaces it. It overwrites a field that is not empty — the dry run names it explicitly.": "Майстер налаштування Admin залишає в полі значка саму лише назву на кшталт «Playroom», яка більше не веде до зображення й показується як зламаний прямокутник. Якщо цю опцію ввімкнено, верстак її замінює. При цьому перезаписується непорожнє поле — пробний запуск зазначає це окремо.",
|
|
11
|
+
"The Alias Workbench has no running process — everything happens in the Admin tab. These settings control how it writes.": "У «Верстака аліасів» немає запущеного процесу — усе відбувається у вкладці адміністратора. Ці налаштування визначають, як він записує.",
|
|
12
|
+
"The workbench reads them at runtime from the Admin's own bundle instead of keeping a copy that would age with every update. If that fails, the selection lists simply show what already exists — no error, just fewer entries.": "Верстак читає їх під час виконання з власного бандла Admin, замість того щоб тримати копію, яка старіє з кожним оновленням. Якщо це не вдається, списки вибору показують лише наявне — не помилка, просто менше записів.",
|
|
13
|
+
"Where the templates come from": "Звідки беруться шаблони"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Add missing icons to functions": "为功能补全缺失的图标",
|
|
3
|
+
"Add missing icons to rooms": "为房间补全缺失的图标",
|
|
4
|
+
"Admin ships 62 function and 58 room templates, each with an icon. When the workbench creates an enumeration, it takes the icon from there. Existing enumerations keep whatever they have — unless you allow it to fill in what is missing. Nothing is ever written without the dry run showing it first.": "Admin 自带 62 个功能模板和 58 个房间模板,每个都带有图标。工作台创建枚举时会从那里取用图标。已有的枚举保留原样——除非您允许补全缺失的部分。任何写入都会先由试运行展示。",
|
|
5
|
+
"Also replace unusable icon entries": "同时替换无效的图标条目",
|
|
6
|
+
"Applies when a room has no icon at all and a template of the same name or ID exists.": "仅当房间完全没有图标、且存在同名或同 ID 的模板时生效。",
|
|
7
|
+
"Icons for rooms and functions": "房间和功能的图标",
|
|
8
|
+
"Offer the Admin's room and function templates": "提供 Admin 的房间和功能模板",
|
|
9
|
+
"Same for functions. Enumerations mirrored from a HomeMatic CCU never carry an icon.": "功能同理。从 HomeMatic CCU 镜像而来的枚举从不带图标。",
|
|
10
|
+
"The Admin setup wizard leaves a bare name such as \"Playroom\" in the icon field, which no longer resolves to a picture and shows as a broken box. With this on, the workbench replaces it. It overwrites a field that is not empty — the dry run names it explicitly.": "Admin 的设置向导会在图标字段里留下诸如 \"Playroom\" 这样的裸名称,它已无法解析为图片,显示为一个破损的方框。开启此项后,工作台会将其替换。这会覆盖一个非空字段——试运行会明确指出这一点。",
|
|
11
|
+
"The Alias Workbench has no running process — everything happens in the Admin tab. These settings control how it writes.": "别名工作台没有运行中的进程——一切都在 Admin 选项卡中进行。这些设置决定它如何写入。",
|
|
12
|
+
"The workbench reads them at runtime from the Admin's own bundle instead of keeping a copy that would age with every update. If that fails, the selection lists simply show what already exists — no error, just fewer entries.": "工作台在运行时从 Admin 自身的打包文件中读取,而不是保留一份每次更新都会过时的副本。若读取失败,选择列表只显示已有内容——这不是错误,只是选项更少。",
|
|
13
|
+
"Where the templates come from": "模板来自何处"
|
|
14
|
+
}
|
package/admin/js/detail.js
CHANGED
|
@@ -5,7 +5,7 @@ import { socket } from './verbindung.js';
|
|
|
5
5
|
import { el } from './basis.js';
|
|
6
6
|
import { tr } from './sprache.js';
|
|
7
7
|
import { wertVon, jsonFelder, feldAusFormel, feldFormel, feldWert, jsonVon } from './werte.js';
|
|
8
|
-
import { musterVon, erkenneEntwurf,
|
|
8
|
+
import { musterVon, erkenneEntwurf, platzFuerRolle, typenFuerRolle } from './erkennung.js';
|
|
9
9
|
import { musterName } from './musternamen.js';
|
|
10
10
|
import { rollenFeld } from './rollenwahl.js';
|
|
11
11
|
import { opt , quellenAuswahl, vorlagenAbweichung, bestandsAbweichung } from './entwurf.js';
|
|
@@ -371,24 +371,47 @@ export function detailZeile(e, s, idx) {
|
|
|
371
371
|
muster: e.want,
|
|
372
372
|
belegtVon: belegtVon,
|
|
373
373
|
breite: '300px',
|
|
374
|
-
|
|
374
|
+
/* Die Rolle bestimmt den Platz, und der Platz bestimmt den Typ -
|
|
375
|
+
beides steht im selben Datensatz des type-detector. Wer eine
|
|
376
|
+
Rolle waehlt, bekommt deshalb den passenden Typ gleich mit.
|
|
377
|
+
Wer danach den Typ von Hand aendert, behaelt seine Wahl, bis er
|
|
378
|
+
die Rolle erneut wechselt. */
|
|
379
|
+
beiWahl: function (r) {
|
|
380
|
+
s.role = r;
|
|
381
|
+
/* Nur wo die Rolle im Muster genau einen Datentyp zulaesst, gibt
|
|
382
|
+
es etwas vorzugeben. Trifft sie mehrere Plaetze mit
|
|
383
|
+
verschiedenen Typen - wie die Fahrtrichtung boolean und number -
|
|
384
|
+
sind beide richtig, und die Wahl bleibt beim Nutzer. */
|
|
385
|
+
var moegliche = typenFuerRolle(e.want, r);
|
|
386
|
+
if (moegliche.length === 1 && s.typ !== moegliche[0]) { s.typ = moegliche[0]; }
|
|
387
|
+
neu();
|
|
388
|
+
}
|
|
375
389
|
}));
|
|
376
390
|
|
|
377
391
|
var must = e.want && musterVon(e.want);
|
|
378
392
|
if (must) {
|
|
379
|
-
var treffer =
|
|
380
|
-
|
|
381
|
-
if (!treffer && p.role && rolleTrifft(p.role, s.role)) { treffer = p; }
|
|
382
|
-
});
|
|
393
|
+
var treffer = platzFuerRolle(e.want, s.role, s.typ);
|
|
394
|
+
var erlaubt = typenFuerRolle(e.want, s.role);
|
|
383
395
|
var hin = el('div', 'sugg');
|
|
384
396
|
if (treffer) {
|
|
385
397
|
hin.appendChild(document.createTextNode(tr('pattern.fitsOn')));
|
|
386
398
|
hin.appendChild(el('b', null, String(treffer.role)));
|
|
387
399
|
hin.appendChild(document.createTextNode(tr('pattern.toSlot', treffer.name, musterName(e.want) || e.want)));
|
|
400
|
+
if (erlaubt.length) {
|
|
401
|
+
hin.appendChild(document.createTextNode(
|
|
402
|
+
tr('pattern.expectsType', erlaubt.join(tr('pattern.typeOr')))));
|
|
403
|
+
}
|
|
388
404
|
} else {
|
|
389
405
|
hin.textContent = tr('pattern.noPlaceLong', musterName(e.want) || e.want);
|
|
390
406
|
}
|
|
391
407
|
rb.appendChild(hin);
|
|
408
|
+
/* Passt der Typ nicht zum Platz, faellt der Punkt aus dem Muster -
|
|
409
|
+
lautlos, denn die Rolle stimmt ja. Genau das ist am 11.09.2026
|
|
410
|
+
an einem Tasmota-Stromzaehler passiert (I33). */
|
|
411
|
+
if (treffer && s.typ && erlaubt.length && erlaubt.indexOf(s.typ) === -1) {
|
|
412
|
+
rb.appendChild(el('div', 'aside w',
|
|
413
|
+
tr('pattern.typeMismatch', treffer.name, erlaubt.join(tr('pattern.typeOr')), s.typ)));
|
|
414
|
+
}
|
|
392
415
|
}
|
|
393
416
|
zeigeBeide(zeile(tr('detail.role'), rb), ['role']);
|
|
394
417
|
|
|
@@ -399,6 +422,8 @@ export function detailZeile(e, s, idx) {
|
|
|
399
422
|
['boolean', 'number', 'string', 'mixed'].forEach(function (t) { selT.appendChild(opt(t, t)); });
|
|
400
423
|
selT.value = s.typ || 'number';
|
|
401
424
|
selT.addEventListener('click', function (ev) { ev.stopPropagation(); });
|
|
425
|
+
/* Eine Aenderung von Hand bleibt stehen - bis die Rolle erneut
|
|
426
|
+
gewaehlt wird, dann gilt wieder der Typ des Platzes. */
|
|
402
427
|
selT.addEventListener('change', function () { s.typ = selT.value; neu(); });
|
|
403
428
|
var lT = el('label', 'fld');
|
|
404
429
|
lT.appendChild(el('span', null, tr('detail.type')));
|
package/admin/js/erkennung.js
CHANGED
|
@@ -201,6 +201,93 @@ export function musterVon(typ) {
|
|
|
201
201
|
return D.patterns[typ] || (TYP_ZU_MUSTER[typ] ? D.patterns[TYP_ZU_MUSTER[typ]] : null) || null;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
/* Welchen Platz trifft eine Rolle im gewaehlten Muster?
|
|
205
|
+
|
|
206
|
+
Gibt den ganzen Platz zurueck, nicht nur seinen Namen - denn er
|
|
207
|
+
traegt mehr als die Rolle: `type` sagt, welchen Datentyp der
|
|
208
|
+
type-detector dort erwartet. Am 11.09.2026 stand in einer eigenen
|
|
209
|
+
Vorlage `value.power.consumption` mit Typ `mixed`. Die Rolle war
|
|
210
|
+
richtig, der Platz CONSUMPTION verlangt aber `number` - der Punkt
|
|
211
|
+
fiel durch, kein Platz blieb belegt, und das ganze Geraet wurde
|
|
212
|
+
statt als `electricity` nur noch als `info` erkannt. Am Bildschirm
|
|
213
|
+
stand dazu nichts weiter als „passt nicht".
|
|
214
|
+
|
|
215
|
+
Dieselbe Suche stand vorher zweimal im Code (detail.js und
|
|
216
|
+
vorlagenblatt.js), beide Male ohne den Typ anzusehen. */
|
|
217
|
+
export function plaetzeFuerRolle(musterName, rolle) {
|
|
218
|
+
if (!rolle) { return []; }
|
|
219
|
+
var mu = musterName && musterVon(musterName);
|
|
220
|
+
if (!mu) { return []; }
|
|
221
|
+
return mu.states.filter(function (st) {
|
|
222
|
+
return st.role && rolleTrifft(st.role, rolle);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* Der Platz, den eine Rolle trifft - und zwar der, dessen Datentyp
|
|
227
|
+
auch passt.
|
|
228
|
+
|
|
229
|
+
Dieselbe Rolle kann mehrere Plaetze treffen: das blinds-Muster hat
|
|
230
|
+
DIRECTION (boolean, /^indicator\.direction$/) und daneben
|
|
231
|
+
DIRECTION_ENUM (number, /^(indicator|value)\.direction$/). Homematic
|
|
232
|
+
meldet die Fahrtrichtung als Zahl (0 steht, 1 faehrt auf, 2 faehrt
|
|
233
|
+
zu, 3 unbekannt), und der Detector legt sie richtig auf
|
|
234
|
+
DIRECTION_ENUM. Wer nur die Rolle vergleicht und den ersten Treffer
|
|
235
|
+
nimmt, landet auf DIRECTION und meldet einen Konflikt, den es nicht
|
|
236
|
+
gibt - genau das tat diese Funktion am 11.09.2026 einen halben Tag
|
|
237
|
+
lang, samt einer "begruendeten Ausnahme" im Test, die keine war. */
|
|
238
|
+
export function platzFuerRolle(musterName, rolle, typ) {
|
|
239
|
+
var alle = plaetzeFuerRolle(musterName, rolle);
|
|
240
|
+
if (!alle.length) { return null; }
|
|
241
|
+
if (typ) {
|
|
242
|
+
for (var i = 0; i < alle.length; i++) {
|
|
243
|
+
if (typPasstZuPlatz(alle[i], typ)) { return alle[i]; }
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return alle[0];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* Alle Datentypen, die eine Rolle in diesem Muster annehmen darf -
|
|
250
|
+
ueber alle Plaetze, die sie trifft. Bei der Fahrtrichtung sind das
|
|
251
|
+
boolean und number: beide Formen sind richtig, nur auf verschiedenen
|
|
252
|
+
Plaetzen. */
|
|
253
|
+
export function typenFuerRolle(musterName, rolle) {
|
|
254
|
+
var raus = [];
|
|
255
|
+
plaetzeFuerRolle(musterName, rolle).forEach(function (st) {
|
|
256
|
+
typenVomPlatz(st).forEach(function (t) {
|
|
257
|
+
if (raus.indexOf(t) === -1) { raus.push(t); }
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
return raus;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* Die Datentypen, die ein Platz zulaesst - als Liste.
|
|
264
|
+
|
|
265
|
+
Drei Faelle, gemessen am type-detector 6.0.1: 622 Plaetze nennen
|
|
266
|
+
genau einen Typ, 28 nennen mehrere (mediaPlayer/STATE etwa
|
|
267
|
+
["boolean","number"]), 82 nennen gar keinen - WORKING und ERROR
|
|
268
|
+
zum Beispiel. Wer `String(platz.type)` nimmt, macht aus den 28 den
|
|
269
|
+
Typ "boolean,number", und den gibt es nicht. */
|
|
270
|
+
export function typenVomPlatz(platz) {
|
|
271
|
+
if (!platz || !platz.type) { return []; }
|
|
272
|
+
return Array.isArray(platz.type) ? platz.type.slice() : [String(platz.type)];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* Der Typ, den ein Platz *vorgibt* - nur wenn er eindeutig ist. Wo ein
|
|
276
|
+
Platz mehrere zulaesst, gibt es nichts vorzugeben: dann ist jede der
|
|
277
|
+
erlaubten Formen richtig, und die Wahl bleibt beim Nutzer. */
|
|
278
|
+
export function typVomPlatz(platz) {
|
|
279
|
+
var t = typenVomPlatz(platz);
|
|
280
|
+
return t.length === 1 ? t[0] : '';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* Passt ein eingestellter Typ zu dem, was der Platz zulaesst? Ohne
|
|
284
|
+
Vorgabe passt jeder; ohne eingestellten Typ wird nicht geurteilt. */
|
|
285
|
+
export function typPasstZuPlatz(platz, typ) {
|
|
286
|
+
var t = typenVomPlatz(platz);
|
|
287
|
+
if (!t.length || !typ) { return true; }
|
|
288
|
+
return t.indexOf(String(typ)) > -1;
|
|
289
|
+
}
|
|
290
|
+
|
|
204
291
|
/* Welche Rolle faende im gewaehlten Muster einen Platz? */
|
|
205
292
|
export function plaetzeFuerRollen(musterName) {
|
|
206
293
|
var raus = {};
|
package/admin/js/musterwahl.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
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 } from './erkennung.js';
|
|
13
|
+
import { VORSCHAU, musterVon, erkenneEntwurf, platzFuerRolle, typenFuerRolle } from './erkennung.js';
|
|
14
14
|
import { anMusterAnpassen } from './vorlagen.js';
|
|
15
15
|
import { ratePlaetze, rateZurueck, rateAnzahl, rateMoeglich } from './vorschlagen.js';
|
|
16
16
|
import { zeichneErgebnis, entwurfAngefasst, knopfFrisch } from './ergebnis.js';
|
|
@@ -138,8 +138,25 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
138
138
|
if (!r.length) {
|
|
139
139
|
var fehlend = musterVon(m).states.filter(function (x) { return x.required; })
|
|
140
140
|
.map(function (x) { return x.name; });
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
if (fehlend.length) {
|
|
142
|
+
mark = '✕ ' + tr('pattern.missing', fehlend.join(', '));
|
|
143
|
+
} else {
|
|
144
|
+
/* Kein Pflichtplatz fehlt und trotzdem passt nichts - dann liegt
|
|
145
|
+
es an einer Zeile, die ihren Platz trifft, aber im falschen
|
|
146
|
+
Datentyp steht. Bis 11.09.2026 stand hier nur „passt nicht",
|
|
147
|
+
und genau dieser Fall (electricity hat keinen einzigen
|
|
148
|
+
Pflichtplatz) kostete Ricardo eine Stunde Suche: Rolle
|
|
149
|
+
value.power.consumption richtig, Typ mixed statt number, der
|
|
150
|
+
Punkt fiel lautlos aus dem Muster. */
|
|
151
|
+
mark = tr('pattern.doesNotFit');
|
|
152
|
+
(pruefE.states || []).some(function (st) {
|
|
153
|
+
var moegliche = typenFuerRolle(m, st.role);
|
|
154
|
+
if (!st.typ || !moegliche.length || moegliche.indexOf(st.typ) > -1) { return false; }
|
|
155
|
+
var pl = platzFuerRolle(m, st.role);
|
|
156
|
+
mark = tr('pattern.fitsNotType', pl.name, st.typ, moegliche.join(tr('pattern.typeOr')));
|
|
157
|
+
return true;
|
|
158
|
+
});
|
|
159
|
+
}
|
|
143
160
|
} else {
|
|
144
161
|
var g = r[0].states.filter(function (x) { return x.id; }).length;
|
|
145
162
|
mark = tr('pattern.slotsTaken', g, r[0].states.length);
|
|
@@ -281,9 +298,16 @@ export function baueMusterwahl(e, haupt, pflichtFehlt) {
|
|
|
281
298
|
Auswahlfeld. */
|
|
282
299
|
var mBeschriften = function () {
|
|
283
300
|
/* Im Feld der Beiname, der rohe Name im Tooltip - fuer beides
|
|
284
|
-
nebeneinander ist das Feld zu schmal.
|
|
285
|
-
|
|
286
|
-
|
|
301
|
+
nebeneinander ist das Feld zu schmal.
|
|
302
|
+
|
|
303
|
+
Die Marke nennt seit 11.09.2026 auch den Grund, wenn ein Muster
|
|
304
|
+
an einem falschen Datentyp scheitert („✕ CONSUMPTION: Typ mixed
|
|
305
|
+
statt number"). Das ist laenger als „passt nicht" und wird im
|
|
306
|
+
schmalen Feld abgeschnitten - deshalb steht sie zusaetzlich im
|
|
307
|
+
Tooltip, wo sie ganz lesbar ist. */
|
|
308
|
+
var marke = e.want ? markeFuer(e.want) : '';
|
|
309
|
+
sel.value = e.want ? ((musterName(e.want) || e.want) + ' ' + marke) : '';
|
|
310
|
+
sel.title = e.want ? (e.want + (marke ? ' ' + marke : '')) : '';
|
|
287
311
|
};
|
|
288
312
|
mBeschriften();
|
|
289
313
|
|
package/admin/js/sprache.js
CHANGED
|
@@ -11,7 +11,9 @@ import { $ } from './basis.js';
|
|
|
11
11
|
export var expertenVorgabe = false;
|
|
12
12
|
|
|
13
13
|
/* ================== Sprachen ==================
|
|
14
|
-
Woerterbuch als flache Schluessel-Text-Karte unter admin/
|
|
14
|
+
Woerterbuch als flache Schluessel-Text-Karte unter admin/sprachen/.
|
|
15
|
+
(Nicht admin/i18n/ - dort liegt das Woerterbuch der Einstellungsseite,
|
|
16
|
+
das der Admin selbst laedt.)
|
|
15
17
|
Neue Sprache = neue Datei, sonst nichts. Faellt eine Uebersetzung
|
|
16
18
|
aus, greift Englisch, danach der Schluessel selbst — so bleibt die
|
|
17
19
|
Oberflaeche bedienbar statt leer. */
|
|
@@ -38,7 +40,7 @@ export function ladeSprache(fertig) {
|
|
|
38
40
|
var vorgabe = (navigator.language || 'en').slice(0, 2).toLowerCase();
|
|
39
41
|
|
|
40
42
|
function hole(code, ziel, danach) {
|
|
41
|
-
fetch('./
|
|
43
|
+
fetch('./sprachen/' + code + '.json')
|
|
42
44
|
.then(function (r) { return r.ok ? r.json() : {}; })
|
|
43
45
|
.then(function (d) { Object.keys(d).forEach(function (k) { ziel[k] = d[k]; }); danach(); })
|
|
44
46
|
.catch(function () { danach(); });
|
|
@@ -9,7 +9,7 @@ import { D, $, el, kurz } from './basis.js';
|
|
|
9
9
|
import { tr, sprachtext, sprache } from './sprache.js';
|
|
10
10
|
import { katalogFehlt } from './katalog.js';
|
|
11
11
|
import { funktionsAuswahl, kennungZuFunktion } from './aufzaehlungen.js';
|
|
12
|
-
import { musterVon,
|
|
12
|
+
import { musterVon, platzFuerRolle, typenFuerRolle } from './erkennung.js';
|
|
13
13
|
import { musterZeile, musterName } from './musternamen.js';
|
|
14
14
|
import { ladeVorlagen, aendereVorlagen, setzeMeta, pruefeVorlage, hinweisTaugt, INSTANZ_ID } from './vorlagen.js';
|
|
15
15
|
import { kindZustaende, hatPunkt, feldAusFormel } from './werte.js';
|
|
@@ -283,9 +283,12 @@ export function zeichneVorlagenBlatt(host) {
|
|
|
283
283
|
var st = el('select', 'tx');
|
|
284
284
|
st.disabled = !eigen;
|
|
285
285
|
st.appendChild(opt('', tr('tpls.noType')));
|
|
286
|
+
/* Wie im Speichern-Dialog: der Wert ist der Typ, nicht der
|
|
287
|
+
Musterschluessel. musterwahl.js loest es seit laengerem so. */
|
|
286
288
|
(D ? Object.keys(D.patterns).sort() : []).forEach(function (m) {
|
|
287
|
-
var
|
|
288
|
-
|
|
289
|
+
var typ = D.patterns[m].type || m;
|
|
290
|
+
var o = opt(typ, musterZeile(m));
|
|
291
|
+
if (typ === v.geraetetyp) { o.selected = true; }
|
|
289
292
|
st.appendChild(o);
|
|
290
293
|
});
|
|
291
294
|
st.addEventListener('change', function () {
|
|
@@ -543,7 +546,7 @@ function dtFeld(beschriftung, element) {
|
|
|
543
546
|
|
|
544
547
|
/* Rollenauswahl samt Begruendung. geraetetyp darf leer sein — dann
|
|
545
548
|
entfaellt nur der Hinweis, welchen Platz die Rolle traefe. */
|
|
546
|
-
function rollenBlock(rolle, geraetetyp, setzen) {
|
|
549
|
+
function rollenBlock(rolle, geraetetyp, setzen, typJetzt, setzeTyp) {
|
|
547
550
|
var rb = el('div');
|
|
548
551
|
/* Dasselbe durchsuchbare Feld wie am Geraet - ein Aussehen fuer alle
|
|
549
552
|
Rollenwahlen. Ohne Belegt-Vermerk: in der Vorlage gibt es keinen
|
|
@@ -553,24 +556,38 @@ function rollenBlock(rolle, geraetetyp, setzen) {
|
|
|
553
556
|
muster: geraetetyp,
|
|
554
557
|
leerErlaubt: true,
|
|
555
558
|
breite: '300px',
|
|
556
|
-
|
|
559
|
+
/* Wie am Geraet: der Platz bringt seinen Datentyp mit, also wird er
|
|
560
|
+
beim Waehlen der Rolle gleich gesetzt. Eine Vorlage, deren Rolle
|
|
561
|
+
stimmt und deren Typ nicht, faellt sonst lautlos aus dem Muster. */
|
|
562
|
+
beiWahl: function (r) {
|
|
563
|
+
/* Wie am Geraet: nur ein eindeutiger Typ wird gesetzt. */
|
|
564
|
+
var moegliche = typenFuerRolle(geraetetyp, r);
|
|
565
|
+
if (moegliche.length === 1 && setzeTyp && typJetzt !== moegliche[0]) { setzeTyp(moegliche[0]); }
|
|
566
|
+
setzen(r);
|
|
567
|
+
}
|
|
557
568
|
}));
|
|
558
569
|
|
|
559
570
|
var must = geraetetyp && musterVon(geraetetyp);
|
|
560
571
|
if (must) {
|
|
561
|
-
var treffer =
|
|
562
|
-
|
|
563
|
-
if (!treffer && pp.role && rolleTrifft(pp.role, rolle)) { treffer = pp; }
|
|
564
|
-
});
|
|
572
|
+
var treffer = platzFuerRolle(geraetetyp, rolle, typJetzt);
|
|
573
|
+
var erlaubt = typenFuerRolle(geraetetyp, rolle);
|
|
565
574
|
var hin = el('div', 'sugg');
|
|
566
575
|
if (treffer) {
|
|
567
576
|
hin.appendChild(document.createTextNode(tr('pattern.fitsOn')));
|
|
568
577
|
hin.appendChild(el('b', null, String(treffer.role)));
|
|
569
578
|
hin.appendChild(document.createTextNode(tr('pattern.toSlot', treffer.name, musterName(geraetetyp) || geraetetyp)));
|
|
579
|
+
if (erlaubt.length) {
|
|
580
|
+
hin.appendChild(document.createTextNode(
|
|
581
|
+
tr('pattern.expectsType', erlaubt.join(tr('pattern.typeOr')))));
|
|
582
|
+
}
|
|
570
583
|
} else {
|
|
571
584
|
hin.textContent = tr('pattern.noPlaceLong', musterName(geraetetyp) || geraetetyp);
|
|
572
585
|
}
|
|
573
586
|
rb.appendChild(hin);
|
|
587
|
+
if (treffer && typJetzt && erlaubt.length && erlaubt.indexOf(typJetzt) === -1) {
|
|
588
|
+
rb.appendChild(el('div', 'aside w',
|
|
589
|
+
tr('pattern.typeMismatch', treffer.name, erlaubt.join(tr('pattern.typeOr')), typJetzt)));
|
|
590
|
+
}
|
|
574
591
|
}
|
|
575
592
|
return rb;
|
|
576
593
|
}
|
|
@@ -782,7 +799,7 @@ function vZeilenDetail(z, nr) {
|
|
|
782
799
|
|
|
783
800
|
dtZeile(d, tr('detail.role'), rollenBlock(z.rolle, v.geraetetyp, function (neu) {
|
|
784
801
|
setzeFeld('rolle', neu);
|
|
785
|
-
}));
|
|
802
|
+
}, z.typ, function (t) { setzeFeld('typ', t); }));
|
|
786
803
|
|
|
787
804
|
dtZeile(d, tr('detail.display'), anzeigeBlock(
|
|
788
805
|
function (was) {
|
|
@@ -1222,9 +1239,24 @@ export function vorlagenVorbereiten(e) {
|
|
|
1222
1239
|
|
|
1223
1240
|
var zeilen = [];
|
|
1224
1241
|
e.states.forEach(function (s) {
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1242
|
+
/* Eine Zeile braucht wenigstens ein Ziel - lesend oder schreibend.
|
|
1243
|
+
`STOP` am Rollladen hat nur ein Schreibziel: ein Tastendruck hat
|
|
1244
|
+
keinen Zustand zum Lesen. Bis 11.09.2026 stand hier `!s.srcR`,
|
|
1245
|
+
und solche Zeilen fielen beim Speichern lautlos weg. Dass das
|
|
1246
|
+
Anwenden diesen Fall kennt, steht seit dem 09.09.2026 in
|
|
1247
|
+
vorlagen.js - die Gegenrichtung war vergessen worden. */
|
|
1248
|
+
if (!s.n || (!s.srcR && !s.srcW)) { return; }
|
|
1249
|
+
var r = s.srcR ? relZu(s.srcR, e.kanal) : { p: '', abs: false };
|
|
1250
|
+
/* Das Schreibziel gehoert in die Vorlage, auch wenn es derselbe
|
|
1251
|
+
Punkt ist wie der gelesene. Bis 11.09.2026 stand hier zusaetzlich
|
|
1252
|
+
`s.srcW !== s.srcR`, und genau das trifft auf jeden Aktor zu, der
|
|
1253
|
+
seinen eigenen Zustand fuehrt: Rollladen, Dimmer, Thermostat
|
|
1254
|
+
schreiben auf denselben Punkt, den sie lesen (1.LEVEL). Beim
|
|
1255
|
+
Speichern verschwand ihr Schreibweg - der Alias zeigte die
|
|
1256
|
+
Position an und liess sich nicht mehr verstellen. Aufgefallen
|
|
1257
|
+
bei Tasmota nie, weil dort tele.STATE gelesen und cmnd.POWER
|
|
1258
|
+
geschrieben wird. */
|
|
1259
|
+
var w = s.srcW ? relZu(s.srcW, e.kanal) : null;
|
|
1228
1260
|
var zv = null;
|
|
1229
1261
|
if (quelle && s.ausVorlage) {
|
|
1230
1262
|
(quelle.zustaende || []).forEach(function (z) { if (z.name === s.ausVorlage) { zv = z; } });
|
|
@@ -1348,9 +1380,11 @@ export function baueVorlage(z) {
|
|
|
1348
1380
|
name: r.name,
|
|
1349
1381
|
rolle: s.role || undefined,
|
|
1350
1382
|
typ: s.typ || undefined,
|
|
1351
|
-
einheit: s.unit || undefined
|
|
1352
|
-
lesen: zPfad(r, k, false, z.zeilen)
|
|
1383
|
+
einheit: s.unit || undefined
|
|
1353
1384
|
};
|
|
1385
|
+
/* Ohne Lesequelle kein `lesen` - sonst stuende dort ein leerer
|
|
1386
|
+
Pfad, und `wendeAn` suchte einen Punkt namens "". */
|
|
1387
|
+
if (r.lesenRoh) { zu.lesen = zPfad(r, k, false, z.zeilen); }
|
|
1354
1388
|
if (r.lesenAbs) { zu.absolut = true; }
|
|
1355
1389
|
if (r.schreibenRoh) { zu.schreiben = zPfad(r, k, true, z.zeilen); }
|
|
1356
1390
|
if (f) { zu.feld = f; } else if (s.f) { zu.leseformel = s.f; }
|
|
@@ -1696,9 +1730,16 @@ export function zeichneVorlagenDialog() {
|
|
|
1696
1730
|
lt.appendChild(el('span', 'feldlabel', tr('tpls.deviceType')));
|
|
1697
1731
|
var st = el('select', 'tx');
|
|
1698
1732
|
st.appendChild(opt('', tr('tpls.noType')));
|
|
1733
|
+
/* Der Wert ist der Geraetetyp, nicht der Musterschluessel - drei
|
|
1734
|
+
Muster tragen einen anderen Namen als ihr Typ: blinds meldet
|
|
1735
|
+
"blind", mediaPlayer meldet "media", levelSlider meldet "slider".
|
|
1736
|
+
Die Vorlagen fuehren den Typ. Bis 11.09.2026 stand hier der
|
|
1737
|
+
Schluessel, und an jedem Rollladen zeigte der Dialog
|
|
1738
|
+
"- keiner -", obwohl "blind" gesetzt war. */
|
|
1699
1739
|
(D ? Object.keys(D.patterns).sort() : []).forEach(function (m) {
|
|
1700
|
-
var
|
|
1701
|
-
|
|
1740
|
+
var typ = D.patterns[m].type || m;
|
|
1741
|
+
var o = opt(typ, musterZeile(m));
|
|
1742
|
+
if (typ === k.geraetetyp) { o.selected = true; }
|
|
1702
1743
|
st.appendChild(o);
|
|
1703
1744
|
});
|
|
1704
1745
|
st.addEventListener('change', function () { k.geraetetyp = st.value; zeichneVorlagenDialog(); });
|