Реализация расписания и автоматизации IoT-устройств через мобильное приложение
Расписание для IoT-устройства — «включить свет в 07:00, выключить в 23:00 по рабочим дням». Автоматизация сложнее: «если температура упала ниже +18°C и время между 22:00 и 08:00 — включить обогреватель». Обе задачи решаются на уровне бэкенда, но мобильное приложение должно предоставить UI для их создания и редактирования без инструкции.
Расписание: модель данных и UI
Типичный Schedule:
{
"device_id": "abc123",
"action": "turn_on",
"days_of_week": [1, 2, 3, 4, 5],
"time": "07:00",
"timezone": "Europe/Moscow",
"enabled": true
}
Часовой пояс — обязательное поле. Без него расписание сработает неправильно после перелёта или при пользователях из разных регионов. Хранить на сервере в UTC, конвертировать при отображении в timezone устройства/пользователя.
UI выбора времени на Android Compose — Material3 TimePicker или TimePickerDialog. Выбор дней недели — горизонтальный ряд чипов с множественным выбором:
val days = listOf("Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс")
var selectedDays by remember { mutableStateOf(setOf<Int>()) }
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
days.forEachIndexed { index, label ->
FilterChip(
selected = index + 1 in selectedDays,
onClick = {
selectedDays = if (index + 1 in selectedDays)
selectedDays - (index + 1)
else
selectedDays + (index + 1)
},
label = { Text(label) }
)
}
}
Список расписаний — LazyColumn с возможностью включить/выключить каждое через Switch без открытия редактора. PATCH-запрос только поля enabled = false — не весь объект.
Автоматизации: модель условий и действий
Автоматизации строятся по модели ECA (Event-Condition-Action):
- Event (триггер): значение датчика пересекло порог, наступило время, устройство изменило статус
- Condition (условие): текущее время в диапазоне, другое устройство онлайн
- Action (действие): отправить команду устройству, отправить уведомление, вызвать webhook
Хранить как JSON на сервере:
{
"trigger": {
"type": "sensor_value",
"device_id": "temp_sensor_1",
"parameter": "temperature",
"operator": "lt",
"value": 18
},
"conditions": [
{
"type": "time_range",
"from": "22:00",
"to": "08:00"
}
],
"actions": [
{
"type": "device_command",
"device_id": "heater_1",
"command": "turn_on"
}
]
}
Выполнение логики — на сервере. Мобильное приложение не исполняет автоматизации, только создаёт и редактирует их.
UI конструктора автоматизаций
Drag-and-drop конструктор — сложно и избыточно для большинства сценариев. Проще: пошаговый wizard.
Шаг 1 — Триггер. Выбор устройства → выбор параметра → условие (больше/меньше/равно) → значение. Или выбор «По расписанию».
Шаг 2 — Условия (опционально). «Добавить условие» → выбор типа (время, день недели, статус другого устройства).
Шаг 3 — Действие. Выбор устройства → выбор команды. Возможность добавить несколько действий.
Шаг 4 — Название и сохранение.
Каждый шаг валидируется отдельно. Нельзя перейти к следующему без заполнения обязательных полей — показывать inline ошибку, не блокировать всё приложение.
Список автоматизаций и отладка
Пользователь создаёт автоматизацию и не понимает, почему она не сработала. Лог выполнения — обязательная фича. Каждый тригер → запись в историю: сработал/не сработал, почему, какое действие было выполнено.
14:32 · Температура упала до 16.8°C
✓ Условие: время 22:00–08:00 — не выполнено (сейчас 14:32)
✗ Автоматизация не сработала
Такой лог снижает количество обращений в поддержку в разы.
Конфликты расписаний
Два расписания на одно устройство могут конфликтовать: первое включает в 07:00, второе выключает в 07:30, третье включает в 07:15. На сервере нужна логика разрешения конфликтов — последнее по времени команды побеждает. В UI — предупреждение при создании пересекающихся расписаний.
Реализация расписаний с пошаговым wizard: 3–4 недели. Полный конструктор автоматизаций с условиями и логом выполнения: 6–8 недель. Стоимость рассчитывается индивидуально.







