2025-07-23 23:19:06 +02:00

64 lines
2.0 KiB
TypeScript

import { sendFimpMsg } from "../fimp/fimp";
import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device";
import { ServiceComponentsCreationResult } from "../ha/publish_device";
export function fan_ctrl__components(
topicPrefix: string,
device: VinculumPd7Device,
svc: VinculumPd7Service
): ServiceComponentsCreationResult | undefined {
const supModes: string[] = svc.props?.sup_modes ?? [];
if (!supModes.length) return undefined; // nothing useful to expose
const commandTopic = `${topicPrefix}${svc.addr}/command`;
return {
components: {
[svc.addr]: {
unique_id: svc.addr,
p: "fan",
command_topic: commandTopic,
optimistic: true,
preset_modes: supModes,
preset_mode_command_topic: commandTopic,
preset_mode_state_template: `{{ value_json['${svc.addr}'].mode }}`,
// Fan is considered "on" if mode is not off/stop
state_value_template: `{{ 'ON' if value_json['${svc.addr}'].mode not in ['off', 'stop'] else 'OFF' }}`,
preset_mode_value_template: `{{ value_json['${svc.addr}'].mode }}`,
},
},
commandHandlers: {
[commandTopic]: async (payload: string) => {
// Handle both on/off commands and preset mode commands
if (payload === 'ON' || payload === 'OFF') {
// For simple on/off, use the first available mode for "on"
const mode = payload === 'ON' ? supModes[0] : 'off';
if (supModes.includes(mode) || mode === 'off') {
await sendFimpMsg({
address: svc.addr!,
service: "fan_ctrl",
cmd: "cmd.mode.set",
val: mode,
val_t: "string",
});
}
} else {
// Treat as preset mode command
if (supModes.includes(payload)) {
await sendFimpMsg({
address: svc.addr!,
service: "fan_ctrl",
cmd: "cmd.mode.set",
val: payload,
val_t: "string",
});
}
}
},
},
};
}