Найти в Дзене
SLS. Просто о сложном

Урок 1. Автоматизации. SimpleBind. LUA

Всем здрасте! Мы уже познакомились с интерфейсом управления шлюзом SLS Gateway и научились подключать к шлюзу устройства. Теперь пора научиться этими устройствами управлять. Также, неплохо бы было, чтобы устройства управлялись без нашего вмешательства, по заданным нами сценариям. Другими словами из безумного дома будем делать Умный. Предполагаем, что нам не нужен сервер умного дома и мы будем реализовывать наши странные желания средствами одного лишь SLS. Для этого SLS имеет практически безграничные возможности. Надо лишь научиться этими возможностями эффективно пользоваться. Надо сказать, я долго думал, как подойти к подаче обучающего материала. Ведь сразу всё не охватить. Знаний потребуется не мало. И, решил подавать также, как изучал сам. От простого к сложному. От простых автоматизаций SimpleBind, до написания сложных скриптов в несколько сотен строк. Поэтому не всё сразу станет понятно. Наберитесь терпения и просветление придет. А я вам в этом помогу. Да, начинал я с Home Assistan
Оглавление

Всем здрасте!

Мы уже познакомились с интерфейсом управления шлюзом SLS Gateway и научились подключать к шлюзу устройства. Теперь пора научиться этими устройствами управлять. Также, неплохо бы было, чтобы устройства управлялись без нашего вмешательства, по заданным нами сценариям. Другими словами из безумного дома будем делать Умный.

Предполагаем, что нам не нужен сервер умного дома и мы будем реализовывать наши странные желания средствами одного лишь SLS.

Для этого SLS имеет практически безграничные возможности. Надо лишь научиться этими возможностями эффективно пользоваться.

Надо сказать, я долго думал, как подойти к подаче обучающего материала. Ведь сразу всё не охватить. Знаний потребуется не мало. И, решил подавать также, как изучал сам. От простого к сложному. От простых автоматизаций SimpleBind, до написания сложных скриптов в несколько сотен строк. Поэтому не всё сразу станет понятно. Наберитесь терпения и просветление придет. А я вам в этом помогу.

Да, начинал я с Home Assistant. Но он мне быстро надоел. Для пары десятков устройств эта неповоротливая махина ни к чему. Да, там можно мышкой натыкать автоматизации. Но, чтобы к этой простоте подойти, нужно тоже изучить немало материала и порвать ни один бубен.

Возможности автоматизации

SimpleBind

SimpleBind, позволяет выполнять различные действия при изменении состояния устройств: управлять другими устройствами, вызвать скрипт LUA или выполнить его код, записать значение в Объект.

Скрипты LUA

Большинство автоматизаций, где требуется что-то большее, чем если-то-всё, пишется на языке программирования LUA в виде скриптов. Эти скрипты могут выполняться как по изменению состояния устройств, так и по таймерам или по изменению объектов. Также, скрипты можно запускать снаружи, с помощью HTTP API. Ну и конечно, скрипты могут запускаться при старте системы и из других скриптов.

Сценарии

Система сценариев позволяет сконфигурировать логику автоматизаций в шлюзе без написания скриптов. Позволяла бы, если бы её довели до ума. А пока она находится в зачаточном состоянии аж с ноября 2021.

Задача №1

Итак, предположим на входной двери в квартиру у нас установлен zigbee датчик открытия, а в прихожей есть источник света, включенный через zigbee реле.

Устройства у нас уже подключены и имеют такие свойства (листайте карусель)):

Нам потребуются данные:

Адрес устройства, которым будем управлять. Здесь можно использовать ieeeAddr, nwkAddr и Friendly name (FN). Советую использовать ieeeAddr, потому что nwkAddr может поменяться при повторном спаривании устройства и все автоматизации поломаются, а FN может и вовсе не быть. ieeeAddr - это, как вы помните, физический адрес и он прибит гвоздями к устройству.

Состояния устройств. Нам нужно контролировать состояние contact датчика открытия. И, в зависимости от его значения, которые могут принимать true (дверь закрыта, контакт замкнут) или false (дверь открыта, контакт разомкнут)включать или отключать реле, записывая в состояние state значения ON или OFF.

С такой простой задачей справится базовый функционал SimpleBind. Рассмотрим, как составляются правила. Синтаксис правил такой:

rule1[;rule2;ruleN]

Одно правило = одно действие, с одним условием. Несколько правил - это некое подобие ветвления.

Синтаксис правила:

[condition] srcStateValue, dstDeviceId, dstStateName, DstStateValue

где:
-
condition - необязательное условие >, <, =, !, >=, <=, !=, <>
-
srcState - значение состояния при котором будет выполняться правило
-
dstDeviceId - идентификатор устройства которому будем отправлять команду. Допускается FriendlyName, ieeeAddr, nwkAddr
-
dstStateName - имя состояния которым будем управлять
-
dstStateValue - значение которое будем отправлять в целевое состояние

Теперь, со знанием дела формируем наши правила:

true, 0xA4C138D8A539DB0F, state, OFF; false, 0xA4C138D8A539DB0F, state, ON

Таким образом, при открытии двери, значение состояния contact датчика переходит в FALSE и мы отправляем в состояние state нашего реле значение ON. И, при закрытии двери всё наоборот. Эти два правила похожи на ветвление:

ЕСЛИ contact равен "false" ТО
включить свет
ИНАЧЕ
выключить свет
ВСЁ

Записываем полученное правило в управляющее устройство (датчик открытия) и привязываем к состоянию contact в поле SBRule

-3

Задача №2

Мы понимаем, что в контексте входной двери, такое правило мало кому интересно. Ну как? Зашел в квартиру, закрыл дверь и свет выключился. "АААА! Глаза лопнули!" Хочется организовать, как минимум, задержку на выключение.

Для такой задачки уже нужно подключать умение SimpleBind запускать скрипты LUA. И, здесь у нас открываются практически безграничные возможности. Например, кроме задержки на отключение, можно дополнительно контролировать датчик движения или присутствия и при движении продлевать задержку. Также, можно проверить, а может все покинули квартиру и задержка не требуется.

Углубляться в написание скриптов здесь не будем. Покажу лишь принцип.

Итак, с новыми вводными, наше ветвление преобразится в подобный вид:

ЕСЛИ contact равен "false" ТО
включить свет
ИНАЧЕ
запустить таймер, который выключит свет, через время delay
ВСЁ

Правило в таком случае будет такое:

script.lua, 300

Где:
-
script.lua - собственно скрипт, который будет обрабатывать значение состояния contact, принимать решение вкл или выкл и запускать таймер
- 300 - опционально можно передать в скрипт параметр - в нашем случае время задержки в сек.

Записываем полученное правило в управляющее устройство (датчик открытия) и привязываем к состоянию contact в поле SBRule

-4

Теперь пишем скрипт script.lua

-5

Разберем, что происходит:
- при каждой сработке датчика, срабатывает правило SimpleBind, которое вызывает скрипт
script.lua и передает в него параметр 300
- скрипт, во 2 строчке проверяет полученное значение, которое попадает в скрипт через переменную событий Event.State.Value
- если значение = FALSE (открыли дверь), то выполняется строчка 4 скрипта, которая функцией
zigbee.set(), записывает в состояние state, нашего реле значение "ON"
- если значение не равно FALSE, а равно TRUE (дверь закрыли), то выполняется строчка 8 скрипта, в которой задается таймер на 300 секунд функцией
scripts.setTimer(). Время задержки передается в скрипт через переменную Event.Param

Дальше этот скрипт может обрастать различными проверками, зависящими от вашей фантазии

Например, мой скрипт, умеет контролировать датчик открытия, кнопку, наличие людей в квартире и прочие штуки. Он же обрабатывает таймер. Для изменения параметров, таких как задержка, целевое устройство и его состояние, управляющее состояние, нет необходимости лезть в сам скрипт - всё управляется параметрами его запуска. Писал я его, когда активно изучал LUA. Сейчас же считаю это всё избыточным. Но, для опыта самое то. Вызываю я его так:

script.lua,mag|false|rel_tambur|state|ON|300

Напишите в комментариях, интересен ли его разбор или ну его...

Задача №3

Предположим, у нас есть глупый увлажнитель воздуха и мы хотим сделать его умным. Нам хочется включать его и выключать по показаниям датчика влажности. Для этого понадобится умный датчик влажности. Такой или такой, или любой другой. Также, понадобится умная розетка. Для очУмелых ручек можно использовать и реле.

Контролировать будем состояние humidity датчика климата и по его значению включать или выключать розетку, к которой подключен увлажнитель. В самом простом случае нам подойдут правила SimpleBind.

<40, humidifier_plug, state, ON; >60, humidifier_plug, state, OFF

включает увлажнитель если влажность (состояние humidity) меньше 40% и выключает если больше 60%, отправляя ON или OFF в состояние state розетки humidifier_plug.

-6

Внимательные читатели, наверное заметили SBRule room.temperature. Здесь как раз использовано умение SimpleBind записывать значение в Объект. Зачем это надо, я не постиг, но наверное зачем то надо. Напишите в комментариях ваши мысли и кейсы использования этого умения.

Задача №4

Увлажнители бывают разные. Среди них попадаются довольно шумные и не хотелось бы слушать потуги такого устройства всю ночь. Что же делать? Используем всемогущий LUA. Напишем скрипт который кроме проверки диапазона влажности, будет проверять еще и время, в рамках которого можно шуметь:

-7

Хоть скрипт достаточно подробно комментирован, давайте разберем, что здесь происходит:

Объявляем переменные с временем начала и конца тишины:

local startHour = 22 -- часы
local startMin = 0 -- минуты
local endHour = 5 -- часы
local endMin = 50 -- минуты

Получаем текущее время, которое передается в скрипт через переменные Event.Time.*:

local nowHour = Event.Time.hour -- часы
local nowMin = Event.Time.min -- минуты

Преобразуем часы и минуты в минуты и сохраняем полученные значения в новых переменных

local startRange = startHour * 60 + startMin -- начало тишины в минутах
local endRange = endHour * 60 + endMin -- конец тишины в минутах
local nowTime = nowHour * 60 + nowMin -- текущее время в минутах

Проверяем: попадает ли текущее время в заданный диапазон.
Объявляем переменную - флаг - в которой будем хранить результат проверки. Изначально флаг опущен

local inRange = false

Проверяем, переходит ли искомый диапазон через 0:00 часов.

if startRange > endRange then

Если переходит, то считаем так: Если ("время начала тишины" <= "текущее время" <= 0:00) или (0:00 <= "текущее время" <= "время конца тишины") то текущее время попало в диапазон

if ((startRange <= nowTime and nowTime <= 24*60) or (0 <= nowTime and nowTime <= endRange)) then
inRange = true -- поднимаем флаг
end

Если НЕ переходит через 0:00 часов, то считаем так: Если ("время начала тишины" <= "текущее время" <= "время конца тишины") то текущее время попало в диапазон

else
if (startRange <= x and x <= endRange) then
inRange = true
-- поднимаем флаг
end
end

Далее проверяем наш флаг: если текущее время попало в диапазон тишины

if inRange then -- значит ночь 22:00 .. 5:50

то выключаем увлажнитель

zigbee.set("0xA4C138E143F426BA", "state", "OFF")

Если текущее время НЕ попало в диапазон тишины

else

Управляем увлажнителем в зависимости от влажности от 40% до 60%
Если влажность меньше заданного минимума, то включаем увлажнитель

if (Event.State.Value < 40) then
zigbee.set("0xA4C138E143F426BA", "state", "ON")

Если влажность больше заданного максимума, то выключаем увлажнитель

elseif (Event.State.Value > 60) then
zigbee.set("0xA4C138E143F426BA", "state", "OFF")
end
end

Значение влажности передается в скрипт через переменную события Event.State.Value.

Вот и всё.

Как вы успели заметить, на Дзен код выглядит предельно убого. Поэтому я постараюсь в будущем скрипты максимально снабжать комментариями и ссылаться на их листинги на GitHub

Домашнее задание

UPD 22.03.2024

Внимательный читатель заметил "ошибки" в задачах 1 и 2. Найдите их и напишите в комментариях:
- Ошибки ли это?
- Могут ли скрипты с ними работать?
- Если не могут, то почему?
- Если могут не полностью, то в какой части и почему?
- Если не могут, то почему?
- Как исправить и надо ли?

Заключение

Эти простые примеры помогут вам разобраться с автоматизацией большинства простых задач и не очень. Так что подписывайтесь, читайте, ставьте лайки и пишите комментарии. Решайте ДЗ, а мы позже разберем ваши ответы в работе над ошибками. Пока, пока!

TODO: здесь будет видео с разбором автоматизаций SimpleBind.

----------
Листинги скриптов
Поддержать канал
Заказать обучение
Поболтать