From 91cec7be82d21de81675166a97a5e4e3edcd7b3d Mon Sep 17 00:00:00 2001 From: Koen Kanters Date: Thu, 29 Aug 2024 22:22:27 +0200 Subject: [PATCH] Updates --- lib/extension/homeassistant.ts | 40 +++++++++++++++++----------------- lib/extension/publish.ts | 24 +++++++++++--------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/lib/extension/homeassistant.ts b/lib/extension/homeassistant.ts index 90a5e7bff4..d84551c394 100644 --- a/lib/extension/homeassistant.ts +++ b/lib/extension/homeassistant.ts @@ -21,7 +21,14 @@ interface DiscoveryEntry { discovery_payload: KeyValue; } -const sensorClick: DiscoveryEntry = { +interface Discovered { + mockProperties: Set; + messages: {[s: string]: {payload: string; published: boolean}}; + triggers: Set; + discovered: boolean; +} + +const SENSOR_CLICK: Readonly = { type: 'sensor', object_id: 'click', mockProperties: [{property: 'click', value: null}], @@ -32,22 +39,15 @@ const sensorClick: DiscoveryEntry = { }, }; -interface Discovered { - mockProperties: Set; - messages: {[s: string]: {payload: string; published: boolean}}; - triggers: Set; - discovered: boolean; -} - const ACCESS_STATE = 0b001; const ACCESS_SET = 0b010; -const GROUP_SUPPORTED_TYPES = ['light', 'switch', 'lock', 'cover']; +const GROUP_SUPPORTED_TYPES: Readonly = ['light', 'switch', 'lock', 'cover']; const DEFAULT_STATUS_TOPIC = 'homeassistant/status'; -const COVER_OPENING_LOOKUP = ['opening', 'open', 'forward', 'up', 'rising']; -const COVER_CLOSING_LOOKUP = ['closing', 'close', 'backward', 'back', 'reverse', 'down', 'declining']; -const COVER_STOPPED_LOOKUP = ['stopped', 'stop', 'pause', 'paused']; -const SWITCH_DIFFERENT = ['valve_detection', 'window_detection', 'auto_lock', 'away_mode']; -const LEGACY_MAPPING = [ +const COVER_OPENING_LOOKUP: Readonly = ['opening', 'open', 'forward', 'up', 'rising']; +const COVER_CLOSING_LOOKUP: Readonly = ['closing', 'close', 'backward', 'back', 'reverse', 'down', 'declining']; +const COVER_STOPPED_LOOKUP: Readonly = ['stopped', 'stop', 'pause', 'paused']; +const SWITCH_DIFFERENT: Readonly = ['valve_detection', 'window_detection', 'auto_lock', 'away_mode']; +const LEGACY_MAPPING: Readonly<{models: string[]; discovery: DiscoveryEntry}[]> = [ { models: [ 'WXKG01LM', @@ -79,7 +79,7 @@ const LEGACY_MAPPING = [ 'QBKG12LM', 'E1743', ], - discovery: sensorClick, + discovery: SENSOR_CLICK, }, { models: ['ICTC-G-1'], @@ -153,7 +153,7 @@ const BINARY_DISCOVERY_LOOKUP: {[s: string]: KeyValue} = { window: {device_class: 'window'}, window_detection: {icon: 'mdi:window-open-variant'}, window_open: {device_class: 'window'}, -}; +} as const; const NUMERIC_DISCOVERY_LOOKUP: {[s: string]: KeyValue} = { ac_frequency: {device_class: 'frequency', enabled_by_default: false, entity_category: 'diagnostic', state_class: 'measurement'}, action_duration: {icon: 'mdi:timer', device_class: 'duration'}, @@ -306,7 +306,7 @@ const NUMERIC_DISCOVERY_LOOKUP: {[s: string]: KeyValue} = { x_axis: {icon: 'mdi:axis-x-arrow'}, y_axis: {icon: 'mdi:axis-y-arrow'}, z_axis: {icon: 'mdi:axis-z-arrow'}, -}; +} as const; const ENUM_DISCOVERY_LOOKUP: {[s: string]: KeyValue} = { action: {icon: 'mdi:gesture-double-tap'}, alarm_humidity: {entity_category: 'config', icon: 'mdi:water-percent-alert'}, @@ -348,14 +348,14 @@ const ENUM_DISCOVERY_LOOKUP: {[s: string]: KeyValue} = { update: {device_class: 'update'}, volume: {entity_category: 'config', icon: 'mdi: volume-high'}, week: {entity_category: 'config', icon: 'mdi:calendar-clock'}, -}; +} as const; const LIST_DISCOVERY_LOOKUP: {[s: string]: KeyValue} = { action: {icon: 'mdi:gesture-double-tap'}, color_options: {icon: 'mdi:palette'}, level_config: {entity_category: 'diagnostic'}, programming_mode: {icon: 'mdi:calendar-clock'}, schedule_settings: {icon: 'mdi:calendar-clock'}, -}; +} as const; const featurePropertyWithoutEndpoint = (feature: zhc.Feature): string => { if (feature.endpoint) { @@ -1512,7 +1512,7 @@ export default class HomeAssistant extends Extension { }); if (isDevice && entity.options.hasOwnProperty('legacy') && !entity.options.legacy) { - configs = configs.filter((c) => c !== sensorClick); + configs = configs.filter((c) => c !== SENSOR_CLICK); } if (!this.legacyTrigger) { diff --git a/lib/extension/publish.ts b/lib/extension/publish.ts index 7bf055cfe5..824a88f8c1 100644 --- a/lib/extension/publish.ts +++ b/lib/extension/publish.ts @@ -18,11 +18,11 @@ export const loadTopicGetSetRegex = (): void => { }; loadTopicGetSetRegex(); -const stateValues = ['on', 'off', 'toggle', 'open', 'close', 'stop', 'lock', 'unlock']; -const sceneConverterKeys = ['scene_store', 'scene_add', 'scene_remove', 'scene_remove_all', 'scene_rename']; +const STATE_VALUES: Readonly = ['on', 'off', 'toggle', 'open', 'close', 'stop', 'lock', 'unlock']; +const SCENE_CONVERTER_KEYS: Readonly = ['scene_store', 'scene_add', 'scene_remove', 'scene_remove_all', 'scene_rename']; // Legacy: don't provide default converters anymore, this is required by older z2m installs not saving group members -const defaultGroupConverters = [ +const DEFAULT_GROUP_CONVERTERS: Readonly = [ zhc.toZigbee.light_onoff_brightness, zhc.toZigbee.light_color_colortemp, philips.tz.effect, // Support Hue effects for groups @@ -85,7 +85,7 @@ export default class Publish extends Extension { try { return JSON.parse(data.message); } catch { - if (stateValues.includes(data.message.toLowerCase())) { + if (STATE_VALUES.includes(data.message.toLowerCase())) { return {state: data.message}; } else { return undefined; @@ -183,11 +183,11 @@ export default class Publish extends Extension { re.zh.members.map((e) => [e.getDevice().ieeeAddr, this.state.get(this.zigbee.resolveEntity(e.getDevice().ieeeAddr)!)]), ) : undefined; - let converters: zhc.Tz.Converter[]; + let converters: Readonly; if (Array.isArray(definition)) { const c = new Set(definition.map((d) => d.toZigbee).flat()); - converters = c.size === 0 ? defaultGroupConverters : Array.from(c); + converters = c.size === 0 ? DEFAULT_GROUP_CONVERTERS : Array.from(c); } else { converters = definition?.toZigbee ?? []; } @@ -341,10 +341,14 @@ export default class Publish extends Extension { } } - const scenesChanged = Object.values(usedConverters).some((cl) => cl.some((c) => c.key?.some((k) => sceneConverterKeys.includes(k)))); - - if (scenesChanged) { - this.eventBus.emitScenesChanged({entity: re}); + outerLoop: for (const converters of Object.values(usedConverters)) { + for (const converter of converters) { + const scenesChanged = converter.key?.some((k) => SCENE_CONVERTER_KEYS.includes(k)); + if (scenesChanged) { + this.eventBus.emitScenesChanged({entity: re}); + break outerLoop; + } + } } } }