// 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 (
{sc.short}
Как это выглядит
в реальной жизни.
{sc.title}
{String(step + 1).padStart(2, "0")} / {String(sc.steps.length).padStart(2, "0")}