// Animated scenarios — auto-play with controls const SCENARIOS = [ { id: "leak", title: "Протечка", short: "Кран перекрыт за 2 секунды", color: "var(--leak)", icon: "drop", steps: [ { t: "00:00", icon: "drop", text: "Датчик под мойкой касается воды", who: "Датчик протечки" }, { t: "00:01", icon: "valve", text: "Сервер посылает команду на кран", who: "Локальный сервер" }, { t: "00:02", icon: "check", text: "Кран перекрыт, насосная станция выключена", who: "Кран Aqara" }, { t: "00:03", icon: "phone", text: "Уведомление в Telegram и звонок", who: "Telegram-бот" }, ], }, { id: "away", title: "Ушли из дома", short: "Один тап — дом готов остаться один", color: "var(--ink-2)", icon: "key", steps: [ { t: "Нажали", icon: "key", text: "Сценарий «Ушёл» активирован", who: "Виджет в телефоне" }, { t: "+1с", icon: "bulb", text: "Свет во всех комнатах выключен", who: "12 точек освещения" }, { t: "+2с", icon: "thermo", text: "Отопление в эко-режиме +18°", who: "Термоголовки" }, { t: "+3с", icon: "shield", text: "Охрана включена, окна на контроле", who: "Датчики открытия" }, ], }, { id: "morning", title: "Утро", short: "Дом просыпается вместе с вами", color: "var(--accent)", icon: "sun", steps: [ { t: "07:00", icon: "sun", text: "Сервер ловит рассвет", who: "Сценарий по времени" }, { t: "07:00", icon: "thermo", text: "Гостиная и кухня — на +22°", who: "Климат-контроль" }, { t: "07:02", icon: "bulb", text: "Плавный свет в кухне (10% → 60%)", who: "Диммер" }, { t: "07:30", icon: "mic", text: "«Алиса, прогноз погоды»", who: "Голос" }, ], }, { id: "night", title: "Ночь", short: "Мягкая подсветка, тихий климат", color: "var(--ink-2)", icon: "moon", steps: [ { t: "23:00", icon: "moon", text: "Активируется «Ночь»", who: "Время + датчик присутствия" }, { t: "23:00", icon: "bulb", text: "Свет везде, кроме спальни, выключен", who: "Освещение" }, { t: "02:14", icon: "motion", text: "Движение в коридоре — подсветка 20%", who: "Датчик движения" }, { t: "02:16", icon: "bulb", text: "Через 60с — выключение", who: "Авто-таймер" }, ], }, { id: "humidity", title: "Влажность ночью", short: "Увлажнитель сам держит комфорт", color: "var(--good)", icon: "humid", steps: [ { t: "22:00–08:00", icon: "moon", text: "Активен ночной сценарий влажности", who: "Расписание" }, { t: "<30%", icon: "humid", text: "Влажность в спальне ниже 30%", who: "Датчик влажности" }, { t: "+1с", icon: "cloud-off", text: "Сервер понимает: воздух слишком сухой", who: "Локальный сервер" }, { t: "+2с", icon: "fan", text: "Включается увлажнитель воздуха", who: "Умная розетка / реле" }, { t: ">45%", icon: "humid", text: "Влажность поднялась выше 45%", who: "Датчик влажности" }, { t: "стоп", icon: "check", text: "Увлажнитель выключается автоматически", who: "Сценарий РазумДом" }, ], }, { id: "smoke", title: "Дым", short: "Система предупреждает сразу", color: "var(--warn)", icon: "smoke", steps: [ { t: "00:00", icon: "smoke", text: "Датчик дыма фиксирует задымление", who: "Датчик дыма" }, { t: "00:01", icon: "cloud-off", text: "Сервер запускает сценарий безопасности", who: "Локальный сервер" }, { t: "00:02", icon: "bulb", text: "Включается свет и звуковое оповещение", who: "Сирена / освещение" }, { t: "00:03", icon: "phone", text: "Уведомление уходит в Telegram и на телефон", who: "РазумДом" }, { t: "00:04", icon: "fan", text: "Можно подключить вытяжку или отключение опасной нагрузки", who: "Дополнительный сценарий" }, ], }, ]; const Scenarios = () => { const [active, setActive] = React.useState(0); const [step, setStep] = React.useState(0); const [playing, setPlaying] = React.useState(true); const sc = SCENARIOS[active]; React.useEffect(() => { if (!playing) return; const t = setInterval(() => { setStep(p => { if (p + 1 >= sc.steps.length) { // hop to next scenario setTimeout(() => { setActive(a => (a + 1) % SCENARIOS.length); setStep(0); }, 1400); return p; } return p + 1; }); }, 1500); return () => clearInterval(t); }, [playing, active, sc.steps.length]); React.useEffect(() => { setStep(0); }, [active]); return (
Сценарии

Как это выглядит
в реальной жизни.

{SCENARIOS.map((s, i) => ( ))}
{/* Timeline */}

{sc.title}

{String(step + 1).padStart(2, "0")} / {String(sc.steps.length).padStart(2, "0")}

{sc.short}

{sc.steps.map((s, i) => { const done = i < step; const cur = i === step; return (
step ? 0.35 : 1, transition: "opacity 250ms", }}>
{s.t}
{cur && ( )}
{s.text}
{s.who}
); })}
{/* Phone preview */}
Уведомление
Что произошло
{sc.steps[step]?.text}
{sc.title} ЛОКАЛЬНО · АВТОНОМНО
); }; const PhoneNotification = ({ scenario, step }) => { const s = scenario.steps[step]; if (!s) return null; return (
РазумДом
{s.t}
{s.text}
); }; window.Scenarios = Scenarios;