From 50500e97be95ec3dfde929e27e776242848b5425 Mon Sep 17 00:00:00 2001 From: Adrian Jagielak Date: Fri, 26 Sep 2025 20:00:11 +0200 Subject: [PATCH] Use `light` entity for out_lvl_switch if the device type is "light" --- futurehome/src/services/out_lvl_switch.ts | 128 +++++++++++++++++----- 1 file changed, 98 insertions(+), 30 deletions(-) diff --git a/futurehome/src/services/out_lvl_switch.ts b/futurehome/src/services/out_lvl_switch.ts index 469796b..05427da 100644 --- a/futurehome/src/services/out_lvl_switch.ts +++ b/futurehome/src/services/out_lvl_switch.ts @@ -16,36 +16,104 @@ export function out_lvl_switch__components( const minLvl = svc.props?.min_lvl ?? 0; const maxLvl = svc.props?.max_lvl ?? 100; - return { - components: { - [svc.addr]: { - unique_id: svc.addr, - platform: 'number', - name: 'Level Switch', - min: minLvl, - max: maxLvl, - step: 1, - command_topic: commandTopic, - optimistic: false, - value_template: `{{ value_json['${svc.addr}'].lvl }}`, - }, - }, + const isLightDevice = device.type?.type === 'light'; - commandHandlers: { - [commandTopic]: async (payload: string) => { - const lvl = parseInt(payload, 10); - if (Number.isNaN(lvl)) { - return; - } - - await sendFimpMsg({ - address: svc.addr!, - service: 'out_lvl_switch', - cmd: 'cmd.lvl.set', - val: lvl, - val_t: 'int', - }); + if (isLightDevice) { + // Use light component for light devices + return { + components: { + [`${svc.addr}_light`]: { + unique_id: `${svc.addr}_light`, + platform: 'light', + name: 'Light', + brightness: true, + brightness_scale: maxLvl, + command_topic: commandTopic, + optimistic: false, + state_topic: `${topicPrefix}${svc.addr}/state`, + state_value_template: `{% if value_json['${svc.addr}'].lvl > 0 %}ON{% else %}OFF{% endif %}`, + brightness_state_topic: `${topicPrefix}${svc.addr}/state`, + brightness_value_template: `{{ value_json['${svc.addr}'].lvl }}`, + }, + + // Remove the no longer needed `number` entity by setting it to an empty value + [svc.addr]: { + unique_id: svc.addr, + } as any, }, - }, - }; + + commandHandlers: { + [commandTopic]: async (payload: string) => { + const command = JSON.parse(payload); + + if (command.state === 'ON') { + let lvl = maxLvl; + if (command.brightness !== undefined) { + lvl = Math.round(command.brightness); + } + + await sendFimpMsg({ + address: svc.addr!, + service: 'out_lvl_switch', + cmd: 'cmd.lvl.set', + val: lvl, + val_t: 'int', + }); + } else if (command.state === 'OFF') { + await sendFimpMsg({ + address: svc.addr!, + service: 'out_lvl_switch', + cmd: 'cmd.lvl.set', + val: minLvl, + val_t: 'int', + }); + } else if (command.brightness !== undefined) { + const lvl = Math.round(command.brightness); + + await sendFimpMsg({ + address: svc.addr!, + service: 'out_lvl_switch', + cmd: 'cmd.lvl.set', + val: lvl, + val_t: 'int', + }); + } + }, + }, + }; + } else { + // Use number component for non-light devices + return { + components: { + [svc.addr]: { + unique_id: svc.addr, + platform: 'number', + name: 'Level Switch', + min: minLvl, + max: maxLvl, + step: 1, + command_topic: commandTopic, + optimistic: false, + value_template: `{{ value_json['${svc.addr}'].lvl }}`, + }, + }, + + commandHandlers: { + [commandTopic]: async (payload: string) => { + const lvl = parseInt(payload, 10); + if (Number.isNaN(lvl)) { + return; + } + + await sendFimpMsg({ + address: svc.addr!, + service: 'out_lvl_switch', + cmd: 'cmd.lvl.set', + val: lvl, + val_t: 'int', + }); + }, + }, + }; + } }