import type { VoiceTool } from './_types' import { tabletJson } from './_http' /** * Сцены (макросы над несколькими устройствами) и «выключить всё». * Entity-конфиг переиспользует те же переменные, что control_light/tv/climate. */ function lightIds(): string[] { const def = ['light.bedside', 'light.reading'] try { const raw = process.env.LIGHT_ENTITIES_JSON if (raw) { const m = JSON.parse(raw) as Record const ids = Object.entries(m).filter(([k]) => k !== 'default').map(([, v]) => v) return ids.length ? Array.from(new Set(ids)) : def } } catch {} return def } const tvId = () => process.env.TV_ENTITY || 'media_player.tv' const purifierId = 'fan.air_purifier' async function ha(domain: string, service: string, entity_id: string, extra: Record = {}) { try { await tabletJson('POST', '/api/voice/tools/smart-home', { domain, service, entity_id, ...extra }) } catch { /* устройство может быть mock — не валим сцену */ } } async function lightsOff() { await Promise.all(lightIds().map(id => ha('light', 'turn_off', id))) } async function lightsOn(pct?: number) { await Promise.all(lightIds().map(id => ha('light', 'turn_on', id, pct != null ? { brightness_pct: pct } : {}))) } const setScene: VoiceTool = { schema: { type: 'function', function: { name: 'set_scene', description: 'Активировать сцену — одной командой меняет несколько устройств. ' + 'night (ночь: свет выкл, очиститель в ночной режим), movie (кино: свет приглушить, ТВ вкл), ' + 'morning (утро: свет вкл, очиститель авто), away (ушёл: всё выключить). ' + 'Используй для «включи сцену ночь», «режим кино», «я ушёл».', parameters: { type: 'object', properties: { scene: { type: 'string', enum: ['night', 'movie', 'morning', 'away'], description: 'Какая сцена' }, }, required: ['scene'], }, }, }, async execute(args) { const scene = String(args?.scene || '') switch (scene) { case 'night': await lightsOff() await ha('fan', 'set_preset_mode', purifierId, { preset_mode: 'Night' }) break case 'movie': await lightsOn(20) await ha('media_player', 'turn_on', tvId()) await ha('fan', 'set_preset_mode', purifierId, { preset_mode: 'Night' }) break case 'morning': await lightsOn() await ha('fan', 'set_preset_mode', purifierId, { preset_mode: 'Auto' }) break case 'away': await lightsOff() await ha('media_player', 'turn_off', tvId()) await ha('fan', 'turn_off', purifierId) break default: return { error: `unknown scene: ${scene}` } } return { success: true, scene } }, } const allOff: VoiceTool = { schema: { type: 'function', function: { name: 'all_off', description: 'Выключить всё: весь свет, телевизор, очиститель. Для «выключи всё», «отключи всё дома».', parameters: { type: 'object', properties: {} }, }, }, async execute() { await lightsOff() await ha('media_player', 'turn_off', tvId()) await ha('fan', 'turn_off', purifierId) return { success: true, turned_off: 'lights, tv, purifier' } }, } export const tools: VoiceTool[] = [setScene, allOff]