From fc7efd47689d59228bb400d04fc770a463c871bb Mon Sep 17 00:00:00 2001 From: mokusone <14061880+mokusone@users.noreply.github.com> Date: Thu, 14 May 2026 11:40:28 +0200 Subject: [PATCH] feat(filter): add verbose filter logging option New `verboseFilterLog` boolean (default `false`). When enabled, the initial sync logs every excluded entity_id individually on INFO level. This is useful when iterating on exclude patterns or verifying that the filter catches the intended entities. The verbose output is intentionally limited to the first sync. Subsequent debouncedSync() calls only emit the aggregate count to avoid log spam during normal operation. Live `state_changed` events for filtered entities remain on DEBUG. Admin UI gets a checkbox below the patterns field; i18n keys added for all 11 supported languages. --- admin/i18n/de.json | 4 +++- admin/i18n/en.json | 4 +++- admin/i18n/es.json | 4 +++- admin/i18n/fr.json | 4 +++- admin/i18n/it.json | 4 +++- admin/i18n/nl.json | 4 +++- admin/i18n/pl.json | 4 +++- admin/i18n/pt.json | 4 +++- admin/i18n/ru.json | 4 +++- admin/i18n/uk.json | 4 +++- admin/i18n/zh-cn.json | 4 +++- admin/jsonConfig.json | 6 ++++++ io-package.json | 3 ++- src/main.ts | 14 ++++++++++++++ 14 files changed, 55 insertions(+), 12 deletions(-) diff --git a/admin/i18n/de.json b/admin/i18n/de.json index 33f7a2b..f0b008d 100644 --- a/admin/i18n/de.json +++ b/admin/i18n/de.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "Passwörter stimmen nicht überein!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "Filter-Patterns (eines pro Zeile)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob-Patterns mit * als Wildcard. Zeilen mit # sind Kommentare. Leer = Filter aus." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob-Patterns mit * als Wildcard. Zeilen mit # sind Kommentare. Leer = Filter aus.", + "Verbose filter logging": "Ausführliches Filter-Logging", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Wenn aktiv: jede ausgeschlossene entity_id wird beim initialen Adapter-Sync einzeln geloggt (benötigt Loglevel info oder debug)." } \ No newline at end of file diff --git a/admin/i18n/en.json b/admin/i18n/en.json index 2a3aede..307dd24 100644 --- a/admin/i18n/en.json +++ b/admin/i18n/en.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "Passwords missmatch!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "Exclude patterns (one per line)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.", + "Verbose filter logging": "Verbose filter logging", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug)." } \ No newline at end of file diff --git a/admin/i18n/es.json b/admin/i18n/es.json index 379fff8..712e053 100644 --- a/admin/i18n/es.json +++ b/admin/i18n/es.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "¡Las contraseñas no coinciden!", "Secure": "¿HTTPS?", "Exclude patterns (one per line)": "Patrones de exclusión (uno por línea)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Patrones glob, * como comodín. Las líneas que empiezan con # son comentarios. Vacío = filtro desactivado." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Patrones glob, * como comodín. Las líneas que empiezan con # son comentarios. Vacío = filtro desactivado.", + "Verbose filter logging": "Registro detallado del filtro", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Cuando está activado, cada entity_id excluido se registra individualmente durante la sincronización inicial del adaptador (requiere loglevel info o debug)." } \ No newline at end of file diff --git a/admin/i18n/fr.json b/admin/i18n/fr.json index 02f9bb9..9a042de 100644 --- a/admin/i18n/fr.json +++ b/admin/i18n/fr.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "Les mots de passe ne correspondent pas !", "Secure": "HTTPS ?", "Exclude patterns (one per line)": "Modèles d'exclusion (un par ligne)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Modèles glob, * comme joker. Les lignes commençant par # sont des commentaires. Vide = filtre désactivé." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Modèles glob, * comme joker. Les lignes commençant par # sont des commentaires. Vide = filtre désactivé.", + "Verbose filter logging": "Journalisation détaillée du filtre", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Lorsqu'activé, chaque entity_id exclu est journalisé individuellement pendant la synchronisation initiale de l'adaptateur (nécessite loglevel info ou debug)." } \ No newline at end of file diff --git a/admin/i18n/it.json b/admin/i18n/it.json index 58c43bd..d8c812b 100644 --- a/admin/i18n/it.json +++ b/admin/i18n/it.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "Le password non corrispondono!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "Pattern di esclusione (uno per riga)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Pattern glob, * come wildcard. Le righe che iniziano con # sono commenti. Vuoto = filtro disattivato." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Pattern glob, * come wildcard. Le righe che iniziano con # sono commenti. Vuoto = filtro disattivato.", + "Verbose filter logging": "Logging dettagliato del filtro", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Se attivato, registra ogni entity_id escluso individualmente durante la sincronizzazione iniziale dell'adattatore (richiede loglevel info o debug)." } \ No newline at end of file diff --git a/admin/i18n/nl.json b/admin/i18n/nl.json index b2c9f0c..8c69b91 100644 --- a/admin/i18n/nl.json +++ b/admin/i18n/nl.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "Wachtwoorden komen niet overeen!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "Uitsluitpatronen (één per regel)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob-patronen, * als wildcard. Regels die beginnen met # zijn commentaar. Leeg = filter uit." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob-patronen, * als wildcard. Regels die beginnen met # zijn commentaar. Leeg = filter uit.", + "Verbose filter logging": "Uitgebreide filterlogging", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Indien ingeschakeld, wordt elke uitgesloten entity_id afzonderlijk gelogd tijdens de initiële adapter-synchronisatie (vereist loglevel info of debug)." } \ No newline at end of file diff --git a/admin/i18n/pl.json b/admin/i18n/pl.json index 979d9e3..5c79d78 100644 --- a/admin/i18n/pl.json +++ b/admin/i18n/pl.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "Niezgodność haseł!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "Wzorce wykluczeń (jeden na linię)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Wzorce glob, * jako symbol wieloznaczny. Linie zaczynające się od # to komentarze. Puste = filtr wyłączony." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Wzorce glob, * jako symbol wieloznaczny. Linie zaczynające się od # to komentarze. Puste = filtr wyłączony.", + "Verbose filter logging": "Szczegółowe logowanie filtra", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Gdy włączone, każde wykluczone entity_id jest logowane osobno podczas początkowej synchronizacji adaptera (wymaga poziomu logowania info lub debug)." } \ No newline at end of file diff --git a/admin/i18n/pt.json b/admin/i18n/pt.json index 0ba7e37..8c67662 100644 --- a/admin/i18n/pt.json +++ b/admin/i18n/pt.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "As senhas não correspondem!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "Padrões de exclusão (um por linha)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Padrões glob, * como wildcard. Linhas começando com # são comentários. Vazio = filtro desligado." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Padrões glob, * como wildcard. Linhas começando com # são comentários. Vazio = filtro desligado.", + "Verbose filter logging": "Registro detalhado do filtro", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Quando ativado, cada entity_id excluído é registrado individualmente durante a sincronização inicial do adaptador (requer loglevel info ou debug)." } \ No newline at end of file diff --git a/admin/i18n/ru.json b/admin/i18n/ru.json index 25e444a..7f3f987 100644 --- a/admin/i18n/ru.json +++ b/admin/i18n/ru.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "Пароли не совпадают!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "Шаблоны исключения (по одному на строку)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob-шаблоны, * — подстановочный знак. Строки, начинающиеся с #, являются комментариями. Пусто = фильтр выключен." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob-шаблоны, * — подстановочный знак. Строки, начинающиеся с #, являются комментариями. Пусто = фильтр выключен.", + "Verbose filter logging": "Подробное логирование фильтра", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Когда включено, каждый исключённый entity_id логируется отдельно во время начальной синхронизации адаптера (требуется loglevel info или debug)." } \ No newline at end of file diff --git a/admin/i18n/uk.json b/admin/i18n/uk.json index 28ad24f..aa15ae0 100644 --- a/admin/i18n/uk.json +++ b/admin/i18n/uk.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "Паролі не збігаються!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "Шаблони виключення (по одному в рядку)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob-шаблони, * — підстановочний знак. Рядки, що починаються з #, є коментарями. Порожньо = фільтр вимкнено." + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob-шаблони, * — підстановочний знак. Рядки, що починаються з #, є коментарями. Порожньо = фільтр вимкнено.", + "Verbose filter logging": "Детальне логування фільтра", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "Коли увімкнено, кожен виключений entity_id логується окремо під час початкової синхронізації адаптера (потрібен loglevel info або debug)." } \ No newline at end of file diff --git a/admin/i18n/zh-cn.json b/admin/i18n/zh-cn.json index 2f36947..926adaf 100644 --- a/admin/i18n/zh-cn.json +++ b/admin/i18n/zh-cn.json @@ -6,5 +6,7 @@ "Passwords missmatch!": "密码不匹配!", "Secure": "HTTPS?", "Exclude patterns (one per line)": "排除模式(每行一个)", - "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob 模式,* 通配符。以 # 开头的行是注释。为空 = 过滤器关闭。" + "Glob patterns, * wildcard. Lines starting with # are comments. Empty = filter off.": "Glob 模式,* 通配符。以 # 开头的行是注释。为空 = 过滤器关闭。", + "Verbose filter logging": "详细过滤器日志", + "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).": "启用后,在适配器初始同步期间单独记录每个被排除的 entity_id(需要日志级别 info 或 debug)。" } \ No newline at end of file diff --git a/admin/jsonConfig.json b/admin/jsonConfig.json index fe90cc8..1355561 100644 --- a/admin/jsonConfig.json +++ b/admin/jsonConfig.json @@ -50,6 +50,12 @@ "multiline": true, "minRows": 6, "sm": 12 + }, + "verboseFilterLog": { + "type": "checkbox", + "label": "Verbose filter logging", + "help": "When enabled, log each excluded entity_id individually during the initial adapter sync (requires loglevel info or debug).", + "sm": 12 } } } diff --git a/io-package.json b/io-package.json index 3684fd7..dd74f9c 100644 --- a/io-package.json +++ b/io-package.json @@ -253,7 +253,8 @@ "port": 8123, "password": "", "secure": false, - "excludePatterns": "# Glob patterns, one per line. Lines starting with # are comments.\n# Example: filter out all entities prefixed with `iob_` regardless of domain:\n# *.iob_*" + "excludePatterns": "# Glob patterns, one per line. Lines starting with # are comments.\n# Example: filter out all entities prefixed with `iob_` regardless of domain:\n# *.iob_*", + "verboseFilterLog": false }, "protectedNative": [ "password" diff --git a/src/main.ts b/src/main.ts index ce09d7b..2826c08 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,6 +8,7 @@ interface HassAdapterConfig { password: string; secure: boolean; excludePatterns: string; + verboseFilterLog: boolean; } interface HassEntity { @@ -191,6 +192,7 @@ class HassAdapter extends Adapter { private syncDebounceTimeout: ReturnType | null = null; private stopped: boolean = false; private excludePatterns: string[] = []; + private initialSyncCompleted: boolean = false; public constructor(options: Partial = {}) { super({ @@ -458,6 +460,7 @@ class HassAdapter extends Adapter { const states: { id: string; lc?: number; ts?: number; val: ioBroker.StateValue; ack: boolean }[] = []; const expectedObjects = new Set(); let excludedCount = 0; + const excludedIds: string[] = []; for (let e = 0; e < entities.length; e++) { const entity = entities[e]; @@ -467,6 +470,9 @@ class HassAdapter extends Adapter { if (isExcluded(entity.entity_id, this.excludePatterns)) { excludedCount++; + if (this.config.verboseFilterLog && !this.initialSyncCompleted) { + excludedIds.push(entity.entity_id); + } continue; } @@ -667,6 +673,14 @@ class HassAdapter extends Adapter { `Entity filter excluded ${excludedCount} entit${excludedCount === 1 ? 'y' : 'ies'} from sync`, ); } + + if (excludedIds.length > 0) { + for (const id of excludedIds) { + this.log.info(`Entity filter excluded: ${id}`); + } + } + + this.initialSyncCompleted = true; } private async main(): Promise {