feat(filter): integrate exclude filter into parseStates and state_changed
Adapter now consults the exclude-pattern list (new `native.excludePatterns` config option, multi-line string) at two points: - `parseStates()` skips matching entities entirely. They are not registered as ioBroker objects and no state is written. A summary INFO line reports the count when the filter dropped anything from a sync. - The `state_changed` event handler short-circuits matching live updates with a DEBUG line, so a filtered entity that still emits state changes in HA does not cause any churn in ioBroker. Patterns are parsed once at adapter start: trimmed, empty lines and lines starting with `#` are dropped. An empty resulting list means the filter is inactive — adapter behaviour is then identical to the previous version. Default config ships with example comments only, so existing installations see no functional change after the update.
This commit is contained in:
+34
@@ -1,11 +1,13 @@
|
||||
import { Adapter, type AdapterOptions } from '@iobroker/adapter-core';
|
||||
import HASS from './lib/hass';
|
||||
import { isExcluded } from './lib/entityFilter';
|
||||
|
||||
interface HassAdapterConfig {
|
||||
host: string;
|
||||
port: number;
|
||||
password: string;
|
||||
secure: boolean;
|
||||
excludePatterns: string;
|
||||
}
|
||||
|
||||
interface HassEntity {
|
||||
@@ -188,6 +190,7 @@ class HassAdapter extends Adapter {
|
||||
private delayTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
private syncDebounceTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
private stopped: boolean = false;
|
||||
private excludePatterns: string[] = [];
|
||||
|
||||
public constructor(options: Partial<AdapterOptions> = {}) {
|
||||
super({
|
||||
@@ -454,6 +457,7 @@ class HassAdapter extends Adapter {
|
||||
const objs: (ioBroker.ChannelObject | ioBroker.StateObject)[] = [];
|
||||
const states: { id: string; lc?: number; ts?: number; val: ioBroker.StateValue; ack: boolean }[] = [];
|
||||
const expectedObjects = new Set<string>();
|
||||
let excludedCount = 0;
|
||||
|
||||
for (let e = 0; e < entities.length; e++) {
|
||||
const entity = entities[e];
|
||||
@@ -461,6 +465,11 @@ class HassAdapter extends Adapter {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isExcluded(entity.entity_id, this.excludePatterns)) {
|
||||
excludedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const name = entity.name || entity.attributes?.friendly_name || entity.entity_id;
|
||||
const desc = entity.attributes?.attribution || undefined;
|
||||
|
||||
@@ -652,12 +661,32 @@ class HassAdapter extends Adapter {
|
||||
}
|
||||
this.log.info(`Synchronization completed: ${changes.join(', ')}`);
|
||||
}
|
||||
|
||||
if (excludedCount > 0) {
|
||||
this.log.info(
|
||||
`Entity filter excluded ${excludedCount} entit${excludedCount === 1 ? 'y' : 'ies'} from sync`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async main(): Promise<void> {
|
||||
this.config.host ||= '127.0.0.1';
|
||||
this.config.port = parseInt(String(this.config.port), 10) || 8123;
|
||||
|
||||
const rawPatterns = (this.config.excludePatterns || '').toString();
|
||||
this.excludePatterns = rawPatterns
|
||||
.split('\n')
|
||||
.map(s => s.trim())
|
||||
.filter(line => line.length > 0 && !line.startsWith('#'));
|
||||
|
||||
if (this.excludePatterns.length === 0) {
|
||||
this.log.info('Entity filter inactive (no exclude patterns configured)');
|
||||
} else {
|
||||
this.log.info(
|
||||
`Entity filter active: ${this.excludePatterns.length} pattern(s) loaded: ${this.excludePatterns.join(', ')}`,
|
||||
);
|
||||
}
|
||||
|
||||
await this.setStateAsync('info.connection', false, true);
|
||||
|
||||
this.hass = new HASS(this.config, this.log);
|
||||
@@ -670,6 +699,11 @@ class HassAdapter extends Adapter {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isExcluded(entity.entity_id, this.excludePatterns)) {
|
||||
this.log.debug(`Entity filter: ignored state_changed for ${entity.entity_id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const id = `entities.${entity.entity_id}.`;
|
||||
const lc = entity.last_changed ? new Date(entity.last_changed).getTime() : undefined;
|
||||
const ts = entity.last_updated ? new Date(entity.last_updated).getTime() : undefined;
|
||||
|
||||
Reference in New Issue
Block a user