Сценарии для дома: Климат-контроль по расписанию
id: COURSE-01-M05-L02
title: "Сценарии для дома: Климат-контроль по расписанию"
level: foundation
course: COURSE-01
module: COURSE-01-M05
tags: ["климат-контроль", "расписание", "Node-RED", "MQTT", "автоматизация", "энергоэффективность"]
prerequisites: ["COURSE-01-M05-L01"]
version: 1.0.0
status: published
learning_outcomes:
- Проектировать MQTT-структуру для управления климатическими зонами.
- Настраивать сложные расписания в Node-RED с помощью узла cron-plus.
- Разрабатывать логику управления температурой на основе расписания и данных с датчиков.
- Формировать и отправлять управляющие команды на исполнительные устройства по протоколу MQTT.
- Понимать принципы расширения сценария за счет гибридных режимов и внешних данных.
key_concepts:
- Зональный климат-контроль
- Автоматизация по расписанию
- Node-RED
- MQTT
- Уставка (Setpoint)
- Wirenboard
- Датчики и исполнительные устройства
- Узел node-red-contrib-cron-plus
## Введение в зональный климат-контроль по расписанию
Сценарий «Климат-контроль по расписанию» является одним из фундаментальных в современной автоматизации зданий. Его основная задача — автоматически поддерживать заданную температуру в различных помещениях (зонах) в зависимости от времени суток, дня недели и присутствия людей. Это решает две ключевые задачи:
Повышение комфорта: Система самостоятельно прогревает или охлаждает помещения к приходу жильцов, поддерживает комфортную температуру во время их активности и снижает ее для комфортного сна. Пользователю не нужно вручную регулировать термостаты.
Энергоэффективность: Снижение температуры в периоды отсутствия людей (например, в рабочее время) или ночью позволяет значительно сократить потребление энергоресурсов (электричества, газа), что приводит к экономии на коммунальных платежах.
Центральным понятием в этом сценарии является климатическая зона. Зона — это логически объединенное пространство с собственными требованиями к температуре и независимым управлением. Как правило, одной зоной является одна комната (спальня, гостиная, кабинет), но возможно и объединение нескольких помещений (например, кухня-столовая).
Для реализации зонального климат-контроля необходим слаженный комплекс из трех типов устройств, подключенных к нашему контроллеру:
- Датчики: Основные "органы чувств" системы. В каждой зоне должен быть установлен как минимум один датчик температуры. Часто используются комбинированные датчики температуры и влажности. Наш контроллер поддерживает различные типы, включая цифровые датчики 1-Wire (например, DS18B20), которые легко подключаются к универсальным входам.
- Контроллер: "Мозг" системы. Он получает данные от датчиков, сравнивает их с заданными параметрами (уставками) в соответствии с расписанием и принимает решение о воздействии на исполнительные устройства. В нашей экосистеме эту роль выполняет основной контроллер на базе Linux и Node-RED.
- Исполнительные устройства: "Руки" системы. Это оборудование, которое непосредственно изменяет температуру в зоне. В зависимости от типа системы отопления/охлаждения, они подключаются к релейным выходам контроллера.
* Радиаторы отопления: Управляются через сервоприводы, установленные на коллекторе. Сервопривод открывает или закрывает подачу теплоносителя в контур. Реле контроллера подает питание на сервопривод.
* Теплые полы (электрические): Управляются напрямую через силовое реле или контактор, который коммутирует питание нагревательного мата.
* Фанкойлы (конвекторы): Управляются путем включения/выключения вентилятора через реле. Более сложные системы могут требовать управления скоростью вентилятора и клапанами горячей/холодной воды.
> 💡 Подсказка: Правильное размещение датчика температуры критически важно для корректной работы системы. Устанавливайте датчики на высоте примерно 1.5 метра от пола, вдали от прямых солнечных лучей, сквозняков, отопительных приборов и источников тепла (телевизоры, компьютеры). Не размещайте их за мебелью или шторами.
Архитектура решения: MQTT-топики и структура данных
Основой взаимодействия всех компонентов в нашей платформе является протокол MQTT, который мы подробно рассматривали ранее. Грамотно спроектированная структура MQTT-топиков — залог стабильной, масштабируемой и легко отлаживаемой системы.
> 💡 Подсказка: Используйте стандартную схему именования топиков, принятую в экосистеме Wirenboard, для единообразия. Это упростит отладку и интеграцию с другими системами, такими как панели визуализации iRidium или системы верхнего уровня (BMS).
Стандартная структура топика Wirenboard выглядит так: `/devices/DEVICE_ID/controls/CONTROL_ID`.
1. Топики для получения данных с датчиков:
Когда вы подключаете к контроллеру датчик, например, модуль `wb-msw-v3` с датчиками температуры, влажности и освещенности, драйвер `wb-mqtt-serial` автоматически создает для него топики. Чтобы узнать температуру, мы должны читать (подписаться на) топик:
/devices/wb-msw-v3_21/controls/Temperature
Здесь `wb-msw-v3_21` — это уникальный идентификатор устройства, а `Temperature` — идентификатор конкретного канала (контрола). Сообщение в этом топике будет содержать текущее значение температуры, например, `22.5`.
2. Топики для управления исполнительными устройствами:
Для управления реле, к которому подключен сервопривод радиатора или теплый пол, мы используем топики для записи. Например, для первого реле на модуле `wb-mrm2-mini` с ID `55`, топик будет:
/devices/wb-mrm2-mini_55/controls/K1/on
Чтобы включить реле, мы должны опубликовать (записать) в этот топик значение `1`. Чтобы выключить — `0`.
3. Управляющие топики и контракт сообщения:
Помимо топиков устройств, нам нужны "виртуальные" топики для хранения состояния нашей логики. Это уставки температуры и текущий режим работы (`комфорт`, `эко`, `ночь`). Эти топики мы создадим сами в Node-RED. Они служат для связи между логикой расписания, интерфейсом пользователя и логикой управления.
Пример структуры виртуальных топиков для зоны "Гостиная":
- `/myhome/climate/living_room/setpoint` — Целевая температура (уставка). Например, `23.0`.
- `/myhome/climate/living_room/mode` — Текущий режим. Например, `comfort`.
- `/myhome/climate/living_room/temperature` — Копия текущей температуры с датчика. Удобно для отладки.
- `/myhome/climate/living_room/heating_state` — Состояние исполнительного механизма (`0` или `1`).
При публикации в эти топики крайне важно использовать флаг `retained` (удержания). Это гарантирует, что при перезапуске Node-RED или подключении нового клиента (например, панели iRidium) они немедленно получат последнее актуальное состояние.
Контракт сообщения для управления режимом может быть простым строковым значением (`comfort`) или, для большей гибкости, JSON-объектом:
json
{
"mode": "comfort",
"source": "cron"
}
Это позволяет в будущем отслеживать, что именно изменило режим: расписание (`cron`), пользователь (`user_panel`) или другой сценарий (`presence_sensor`).
Практика: Создание расписаний в Node-RED
Для гибкого управления расписаниями в Node-RED мы будем использовать один из самых мощных и популярных узлов — `node-red-contrib-cron-plus`. Если он не установлен, его можно легко добавить через `Меню -> Управление палитрой -> Установка`, введя в поиске `cron-plus`.
Этот узел позволяет создавать сложные, динамические расписания с использованием стандартного синтаксиса Cron.
1. Конфигурация узла `cron-plus`:
После добавления узла на холст, откройте его настройки. Ключевые параметры:
- Имя: Дайте узлу осмысленное имя, например, "Расписание климата Гостиной".
- Schedules: Основная область, где мы создаем наши расписания. Каждое расписание имеет имя, выражение Cron и полезную нагрузку (payload), которая будет отправлена в момент срабатывания.
- Timezone: Обязательно установите вашу временную зону (например, `Europe/Moscow`), чтобы расписания работали корректно независимо от настроек сервера.
2. Синтаксис Cron и создание расписаний:
Выражение Cron состоит из 5 или 6 полей, разделенных пробелами: `[минута] [час] [день месяца] [месяц] [день недели]`. `cron-plus` также поддерживает поле для секунд в начале.
`` — любое значение
- `5` — точное значение (например, 5-я минута)
- `1-5` — диапазон (с 1 по 5)
`/15` — каждые 15 (каждые 15 минут)
Создадим несколько типовых расписаний для рабочей недели и выходных. Нажмите "add" в списке Schedules, чтобы добавить новое расписание:
- Название: `Будни.Утро`
Выражение: `0 7 * 1-5` (В 07:00, с понедельника по пятницу)
* Тип Payload: `JSON`
* Payload: `{"mode": "comfort", "zone": "living_room"}`
- Название: `Будни.День`
Выражение: `30 8 * 1-5` (В 08:30, с понедельника по пятницу, когда все уходят)
* Тип Payload: `JSON`
* Payload: `{"mode": "eco", "zone": "living_room"}`
- Название: `Будни.Вечер`
Выражение: `0 18 * 1-5` (В 18:00, с понедельника по пятницу, к возвращению домой)
* Тип Payload: `JSON`
* Payload: `{"mode": "comfort", "zone": "living_room"}`
- Название: `Ночь`
Выражение: `0 23 ` (В 23:00, каждый день)
* Тип Payload: `JSON`
* Payload: `{"mode": "night", "zone": "living_room"}`
- Название: `Выходной.День`
Выражение: `0 9 * 0,6` (В 09:00, в субботу и воскресенье)
* Тип Payload: `JSON`
* Payload: `{"mode": "comfort", "zone": "living_room"}`
Теперь узел `cron-plus` в указанное время будет генерировать сообщение `msg` с соответствующим `msg.payload`. Это сообщение станет триггером для всей остальной логики.
> 📋 Ключевые понятия:
> Динамическое управление: `cron-plus` позволяет добавлять, удалять или изменять расписания "на лету", отправляя ему управляющие сообщения. Например, можно создать в интерфейсе iRidium форму для редактирования расписаний, которая будет отправлять в Node-RED сообщения вида `{ "command": "add", "name": "Новое Расписание", "expression": "0 15 ", "payload": {"mode": "custom"} }`.
Реализация логики: от расписания к команде
Теперь, когда у нас есть источник событий (расписаний), нам нужно преобразовать их в конкретные команды для исполнительных устройств. Весь поток можно разделить на две параллельные ветки:
Обработка событий от `cron-plus` для установки целевой температуры (уставки).
Постоянное сравнение текущей температуры с уставкой и управление реле.
> ⚠️ Внимание: Избегайте жесткого кодирования температурных уставок напрямую в потоках. Используйте контекстные переменные (flow/global context) или UI-элементы (например, `node-red-dashboard`) для легкой настройки пользователем без необходимости редактировать логику. Это значительно повышает гибкость и удобство системы.
Схема логики (ASCII Flow Diagram):
(Установка режима и уставки) (Логика управления)
Время Режим Уставка Температура
[cron-plus] ---> [switch: mode] --> (comfort) --> [change: setpoint=23] --+
| (eco) --> [change: setpoint=18] --|--> [mqtt out: setpoint] (retained)
| (night) --> [change: setpoint=20] --+ (topic: /myhome/climate/living_room/setpoint)
|
+----------------- [mqtt out: mode] (retained)
(topic: /myhome/climate/living_room/mode)
[mqtt in: temp] ---------------+
(topic: .../Temperature) |
+--> [join] --> [function: hysteresis] --> [rbe] --> [mqtt out: relay]
| (topic: .../K1/on)
[mqtt in: setpoint] -----------+
(topic: .../setpoint)
Шаг 1: Преобразование режима в уставку
Выход узла `cron-plus` соедините с узлом `switch`. Настройте `switch` на проверку свойства `msg.payload.mode`.
Создайте выходы для каждого возможного режима: `comfort`, `eco`, `night`.
К каждому выходу узла `switch` подключите узел `change`.
* Для ветки `comfort`: настройте `change` на "установить" `flow.setpoint_comfort` в `msg.setpoint`. Для начала, можно задать уставки в узле Inject и сохранить в контекст, чтобы не редактировать flow.
* Для ветки `eco`: "установить" `flow.setpoint_eco` в `msg.setpoint`.
* Для ветки `night`: "установить" `flow.setpoint_night` в `msg.setpoint`.
После всех узлов `change` поставьте общий узел `MQTT out`. Настройте его на публикацию `msg.setpoint` в топик `/myhome/climate/living_room/setpoint` с флагом `retained`.
Также от узла `cron-plus` можно напрямую отправить `msg.payload.mode` в топик `/myhome/climate/living_room/mode` (тоже с флагом `retained`).
Шаг 2: Реализация логики гистерезиса
Эта часть потока работает непрерывно.
Добавьте узел `MQTT in`, подписанный на топик с температурой датчика (например, `/devices/wb-msw-v3_21/controls/Temperature`).
Добавьте второй узел `MQTT in`, подписанный на наш виртуальный топик уставки `/myhome/climate/living_room/setpoint`.
Используйте узел `join` для объединения этих двух потоков. Настройте его на создание `ключа/значения` объекта после получения сообщений по двум темам. На выходе `join` будет `msg.payload` со значениями и температуры, и уставки.
Подключите `join` к узлу `function`. Здесь будет основная логика.
javascript
// Получаем переменные из контекста или напрямую
const currentTemp = parseFloat(msg.payload.temperature);
const setpoint = parseFloat(msg.payload.setpoint);
// Гистерезис - зона нечувствительности для предотвращения "дребезга" реле
const hysteresis = 0.5; // 0.5 градуса Цельсия
// Получаем последнее известное состояние, чтобы не отправлять лишних команд
// Узел `rbe` (report-by-exception) делает это лучше, но для понимания полезно
// let lastState = context.get('heatingState') || 0;
let command = null;
// Логика включения
if (currentTemp < setpoint - hysteresis) {
command = 1; // Включить нагрев
}
// Логика выключения
else if (currentTemp >= setpoint) {
command = 0; // Выключить нагрев
}
// В зоне гистерезиса ничего не меняем. Если command == null, узел ничего не отправит.
if (command !== null) {
msg.payload = command;
// context.set('heatingState', command); // Сохраняем состояние
return msg;
}
return null; // Ничего не отправляем, если не нужно менять состояние
Выход узла `function` соедините с узлом `rbe` (Report by Exception). Этот узел будет пропускать сообщение дальше только в том случае, если его `payload` (`0` или `1`) изменился по сравнению с предыдущим. Это обязательный элемент для предотвращения флуда команд в MQTT и лишнего щелканья реле.
Последний узел в цепи — `MQTT out`, который публикует `msg.payload` (`0` или `1`) в топик управления реле, например, `/devices/wb-mrm2-mini_55/controls/K1/on`.
Резюме и дальнейшее развитие сценария
В этом уроке мы спроектировали и реализовали полнофункциональный сценарий зонального климат-контроля по расписанию. Мы прошли весь путь: от определения концепции зон и выбора оборудования до построения архитектуры MQTT-топиков и разработки логики в среде Node-RED.
Ключевые этапы, которые мы освоили:
- Использование узла `cron-plus` для создания гибких расписаний.
- Разделение логики на установку параметров (уставка, режим) и непосредственное управление.
- Применение виртуальных MQTT-топиков с флагом `retained` для хранения и синхронизации состояния.
- Реализация управляющей логики с гистерезисом для стабильной работы исполнительных устройств.
- Использование узла `rbe` для оптимизации количества отправляемых команд.
Этот сценарий является надежной основой, которую можно и нужно развивать.
Идеи для усложнения и улучшения:
- Гибридный режим (ручной + автомат): Добавить возможность ручного изменения уставки с панели управления. Эта ручная уставка должна действовать ограниченное время (например, 2 часа) или до следующего события по расписанию, после чего система вернется в автоматический режим.
- Интеграция с датчиками присутствия и окон: Если в комнате никого нет (по данным датчика движения) или открыто окно (по данным геркона), система должна принудительно переходить в режим `eco` для максимальной экономии, игнорируя расписание.
- Предиктивное управление: Использовать внешние данные, например, прогноз погоды из интернета. Если завтра ожидается солнечный день, система может заранее немного снизить интенсивность утреннего прогрева, зная, что помещение нагреется от солнца.
- Визуализация и управление: Создать интерфейс на панели iRidium или в `node-red-dashboard`, который будет отображать текущую температуру, уставку, режим работы и состояние нагрева, а также позволит пользователю легко изменять уставки для каждого режима и редактировать расписания.
> 🔗 Связанный материал: Логика сочетания ручного и автоматического режимов подробно разбирается в курсе для уровня Automation, в уроке MODULE-06-M02-L03: "Проектирование гибридных систем управления".
---
Подготовка к лабораторной работе и аттестации
Лабораторные работы (предстоящие):
COURSE-01-M05-LAB01: Базовая настройка климата. Вам предстоит создать поток Node-RED для одной зоны, включающий узел `cron-plus` с двумя режимами (`день`/`ночь`), узлы `change` для установки уставки и логику управления реле на основе моделируемых данных с датчика температуры.
COURSE-01-M05-LAB02: Расширение до двух зон. Модифицировать предыдущий поток для управления двумя независимыми климатическими зонами, используя параметризованные топики MQTT и функции для избежания дублирования кода.
Тест по модулю (COURSE-01-M05-QUIZ):
Тест будет содержать 10-15 вопросов, проверяющих ваше понимание структуры MQTT-топиков для климата, синтаксиса Cron, назначения узлов `switch`, `change`, `function`, `join`, `rbe` и принципа работы гистерезиса.
Мини-runbook "Если не работает":
- Нагрев не включается, хотя в комнате холодно:
1. Проверьте логику: Подключите узел `debug` к выходу `function`. Соответствует ли `msg.payload` ожидаемому (`1`)?
2. Проверьте уставку: Подпишитесь на топик `/myhome/climate/living_room/setpoint` утилитой `mqtt-cli` или в Node-RED. Корректное ли там значение?
3. Проверьте датчик: Проверьте топик `/devices/wb-msw-v3_21/controls/Temperature`. Приходят ли оттуда актуальные данные?
4. Проверьте `rbe`: Временно отключите узел `rbe`. Начали ли приходить команды? Если да, значит, логика не генерирует смену состояния.
5. Проверьте реле: Опубликуйте вручную `1` в топик `/devices/wb-mrm2-mini_55/controls/K1/on`. Сработало ли реле (слышен щелчок, загорелся индикатор)? Если нет — проблема в физическом подключении или конфигурации `wb-mqtt-serial`.
- Нагрев не выключается, хотя в комнате жарко:
1. Проделайте те же шаги, что и выше, но ожидая `0` в качестве команды на выключение. Проверьте, что логика корректно сравнивает `currentTemp` и `setpoint`.
Что дальше?
В следующем уроке, COURSE-01-M05-L03, мы разберем критически важный сценарий для обеспечения безопасности — "Защита от протечек воды". Мы научимся подключать датчики протечки, мгновенно перекрывать воду с помощью электроприводов и отправлять экстренные уведомления владельцу.