Skip to content

Поддержка lua скриптов

Введение

Шлюз SLS самодостаточен и может обходиться без внешних систем управления Умным домом. Для реализации автоматизаций, он поддерживает скриптовый язык программирования LUA. При разработке скриптов можно использовать функции как встроенные в прошивку шлюза, так и функции поддерживаемых шлюзом библиотек LUA. Текущая, поддерживаемая, версия LUA 5.4.6 (с версии прошивки 2023.10.25d1).


Соглашения

Немного о форматировании и названиях различных объектов шлюза.

Для работы с различными объектами используется формат кода типа zigbee.getStatus(). В терминологии LUA это выглядит как библиотека.функция(). Поэтому постараемся придерживаться подобного именования объектов SLS.

Форматирование текста:

  • пункты меню: File -> Save
  • небольшие куски кода: print(a)
  • многострочный код:
lua
local var = 0
print(var)
local var = 0
print(var)

Описание синтаксиса:

lua
-- пример описания функции
result = function(var1, var2[, var3 = value])
-- Описание переменных, передаваемых в функцию и их тип
-- var1 - STR, переменная 1
-- var2 - INT, переменная 2
-- var3 - BOOL, переменная 3 (если в [квадратных] скобках, то передавать не обязательно)
-- нотация var3 = value указывает на то, что для val3 значением по умолчанию является value
-- описание результата
-- result - type, если функция что-то возвращает, описывается здесь
-- Пример реального использования
-- fn(var1, var2[, var3 = value]) описание 
res = fn("sin", 0, true)
-- или
res = fn("sin", 0) -- при этом параметр var3 задан по-умолчанию и установлен в false
-- пример описания функции
result = function(var1, var2[, var3 = value])
-- Описание переменных, передаваемых в функцию и их тип
-- var1 - STR, переменная 1
-- var2 - INT, переменная 2
-- var3 - BOOL, переменная 3 (если в [квадратных] скобках, то передавать не обязательно)
-- нотация var3 = value указывает на то, что для val3 значением по умолчанию является value
-- описание результата
-- result - type, если функция что-то возвращает, описывается здесь
-- Пример реального использования
-- fn(var1, var2[, var3 = value]) описание 
res = fn("sin", 0, true)
-- или
res = fn("sin", 0) -- при этом параметр var3 задан по-умолчанию и установлен в false

Примечания:

  • draft - черновик или будет добавлено в будущем
  • deprecated - будет удалено в будущем

Асинхронное программирование

Немного о модели программирования для нашего шлюза. При проектировании алгоритмов лучше не использовать функции а-ля os.delay() и самописные аналоги, выполняющие паузы в работе сценария более 1 секунды. Вместо этого лучше проектировать вызовы кусков кода из разных скриптов.

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


Примеры кода

Все примеры скриптов собраны здесь


Редактор скриптов и отладка

Редактор скриптов, по совместительству с файловым менеджером предназначен для создания, удаления и редактирования файлов, в том числе и скриптов. Найти его можно в меню Actions -> Files (в старых версиях прошивки Actions -> Scripts). lua Script Editor Редактор разделен на несколько областей:

  • Меню, с кнопками:
    • Toggle files - скрыть / отобразить панель файлов
    • Save - сохранить
    • Run - запустить скрипт на исполнение
    • Clear output - очистить панель вывода
  • Панель Files. Позволяет управлять файлами:
    • Создать - New file
    • Удалить - значок корзины напротив имени каждого файла
    • Открыть на редактирование - каждый файл представляет собой ссылку, по которой файл открывается в панели редактора
  • Панель редактора
  • Панель вывода - консоль для вывода результатов работы редактируемого скрипта

Скриптовый stdout функции LUA print() выводит информацию на Панель вывода, а также в системный лог (меню Log) шлюза. Данную функцию удобно использовать для отладки.

Для разработки или отладки скрипта, необходимо создать новый файл или открыть существующий. Например, с именем test.lua и в него ввести код на языке LUA.

Отладка скриптов выполняется преимущественно в Редакторе скриптов SLS. Однако, некоторые пользовательские функции может быть удобнее разрабатывать во "взрослых" IDE. Например, нативный ZeroBrain Studio, VS Code, Atom и других.


Типы данных

Описывать типы данных всех сущностей особого смысла нет, поскольку шлюз динамично развивается и также могут меняться и типы данных. Например, до конца 2022 года тип состояний Boolean возвращался как String. Поэтому тип данных лучше проверить, дабы не было разночтений.

Для проверки типа имеется функция LUA type(). Пример:

lua
local var = true -- объявил локальную переменную и присвоил ей логическое значение
print(type(var)) -- выводим в STDOUT тип переменной
var = "строка" -- присвоил переменной значение типа String
print(type(var)) -- выводим в STDOUT тип переменной
-- в STDOUT получим:
-- boolean
-- string
local var = true -- объявил локальную переменную и присвоил ей логическое значение
print(type(var)) -- выводим в STDOUT тип переменной
var = "строка" -- присвоил переменной значение типа String
print(type(var)) -- выводим в STDOUT тип переменной
-- в STDOUT получим:
-- boolean
-- string

Запуск скриптов

В зависимости от задач, выполняемых той или иной автоматизацией, доступны несколько вариантов запуска скриптов:

  1. из скрипта инициализации
  2. при изменении состояния устройства
  3. по событию изменения объекта
  4. запуск из другого скрипта
  5. с помощью HTTP API
  6. периодический запуск (Таймеры)
  7. по подписке mqtt (в разработке).

Также, в любом месте, где прописывается имя файла скрипта, возможно писать сразу код в таком формате:

lua
'#code', где code - тело скрипта
--Например:
scripts.setTimer('#zigbee.set("0x0123456789012345", "state", "ON")', 10, "ку")
'#code', где code - тело скрипта
--Например:
scripts.setTimer('#zigbee.set("0x0123456789012345", "state", "ON")', 10, "ку")

Скрипт инициализации

При запуске системы выполняется скрипт инициализации init.lua, если он есть. Перед началом работы со скриптами, рекомендуется проверить его наличие рядом со всеми остальными скриптами *.lua. Если файла нет, то его нужно в редакторе скриптов. В init.lua полезно инициализировать переменные для работы с устройством, а также выполнить какие либо действия. Например:

lua
-- init.lua --
-- Уведомление в Telegram о старте шлюза --
telegram.settoken("51778***5:AAG0bvK***")
telegram.setchat("-3348***")
telegram.send("SLS загружен!!!")
-- init.lua --
-- Уведомление в Telegram о старте шлюза --
telegram.settoken("51778***5:AAG0bvK***")
telegram.setchat("-3348***")
telegram.send("SLS загружен!!!")

Запуск скрипта при изменении состояния устройства

Скрипт можно запускать как одно из правил SimpleBind.

Синтаксис: scriptname.lua[,Param]

Например, так может выглядеть запись SB Rule для датчика открытия SB Rule

  • mainDoorOnLight.lua - имя запускаемого скрипта
  • Param - необязательный параметр, через который в скрипт можно передать необходимые аргументы. Принимается он в скрипте через Событие Event.Param Аргументов может быть несколько. В данном примере передается 3 аргумента, разделенные символом :: целевое устройство, которым должен управлять датчик по сработке; контролируемый статус; задержка управляющего действия. Если аргументы не прописывать, то при изменении условий, придется менять эти значения в теле скрипта. Пример похожего скрипта здесь

Также, в Simple Bind можно запускать текст скрипта: SB Rule Run Lua Code


Запуск скрипта по событию изменения объекта

Привязка к объекту скрипта: obj.setScript()


Запуск LUA скрипта из другого скрипта

dofile()

Выполняет текст скрипта в контексте текущего.

lua
dofile(scriptPath)
-- scriptPath - STR, путь к запускаемому скрипту вида "/int/script.lua"
dofile(scriptPath)
-- scriptPath - STR, путь к запускаемому скрипту вида "/int/script.lua"

scripts.run()

lua
scripts.run(script[, Param])
-- script - STR, имя файла скрипта, без расширения `lua`
-- Param - STR, аргументы, передаваемые в скрипт
scripts.run(script[, Param])
-- script - STR, имя файла скрипта, без расширения `lua`
-- Param - STR, аргументы, передаваемые в скрипт

Библиотеки SLS

В прошивку шлюза встроены следующие библиотеки:

  • obj. - работа с объектами
  • Event. - работа с событиями
  • zigbee. - управление zigbee устройствами
  • mqtt. - работа с MQTT брокером
  • http. - взаимодействие с внешними системами по HTTP
  • telegram. - отправка уведомлений и управление шлюзом. Подробнее здесь
  • os. - взаимодействие с операционной системой шлюза. Работа с хранилищем
  • gpio. - управление GPIO
  • audio. - управление встроенным в шлюза звуком
  • net. - получение IP адресов шлюза
  • yeelight. - управление устройствами Yeelight
  • cloud. - работа с облаком SLS cloud.slsys.io

Примеры использования.

Библиотека EVENT

Библиотека Event служит для передачи данных в скрипт, в зависимости от того, из какой подсистемы он вызван.

Типы событий

События различаются типом Event.Type. В скрипт передается числовое значение типа события, позволяющее определить источник вызова и получить различные параметры:

  1. Вызов по изменению состояния привязанного сенсора. Правило Simple Bind. SCRIPT_EVENT_TYPE_STATE_UPDATE
  2. Вызов по изменению объекта. SCRIPT_EVENT_TYPE_OBJ_CHANGE
  3. Вызов по входящему сообщению Telegram SCRIPT_EVENT_TYPE_TLG_MESSAGE
  4. Таймер однократный. SCRIPT_EVENT_TYPE_TIMEOUT
  5. Таймер периодический. SCRIPT_EVENT_TYPE_INTERVAL
  6. Таймер Cron. SCRIPT_EVENT_TYPE_CRON
  7. Вызов из LUA командой scripts.run() SCRIPT_EVENT_TYPE_RUN

Свойства событий

Для всех типов событий передаются следующие свойства:

  • Event.Type - тип события INT
  • Event.Name - имя файла вызванного скрипта с расширением
  • Event.Time - время вызова скрипта table(sec, min, hour, day, wday, month, year).

Вызов из SB Rule

  • Event.Param - аргументы
  • Event.nwkAddr - nwkAddr вызывающего устройства
  • Event.ieeeAddr - ieeeAddr вызывающего устройства
  • Event.ModelId - ModelId вызывающего устройства
  • Event.FriendlyName - FriendlyName вызывающего устройства
  • Event.State.Name - имя вызывающего "состояния"
  • Event.State.Value - текущее значение "состояния"
  • Event.State.OldValue - предыдущее значение "состояния"

Event.State.Value возвращает значение с типом, заданным состоянию конвертером. Проверить можно функцией LUA type()

Вызов по однократному таймеру

  • Event.Param - аргументы

Вызов по периодическому таймеру

  • Event.Param - аргументы

Вызов по таймеру Cron

  • Event.Param - аргументы

Библиотека ZIGBEE

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

zigbee.getStatus()

Возвращает статус координатора. Если запущен, вернёт 9. Начиная с версии 2022.07.24d1.

lua
coord_status = zigbee.getStatus()
-- coord_status - INT, статус zigbee координатора. 9 - OK
coord_status = zigbee.getStatus()
-- coord_status - INT, статус zigbee координатора. 9 - OK

zigbee.join()

Включает режим сопряжения для подключения новых устройств

lua
zigbee.join(duration = 255[, router])
-- duration - INT, время в секундах, на которое включить Join
-- router - STR, FriendlyName, ieeeAddr или nwkAddr устройства - роутера. Если опустить этот параметр, сопряжение будет открыто для всей сети
zigbee.join(duration = 255[, router])
-- duration - INT, время в секундах, на которое включить Join
-- router - STR, FriendlyName, ieeeAddr или nwkAddr устройства - роутера. Если опустить этот параметр, сопряжение будет открыто для всей сети

zigbee.value()

Возвращает значения состояния устройства из кэша

lua
result = zigbee.value(device, state)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- state - STR, состояние, значение которого необходимо получить
-- result - значение состояния
result = zigbee.value(device, state)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- state - STR, состояние, значение которого необходимо получить
-- result - значение состояния

zigbee.get()

Вызывает функцию GET в конвертере. Возвращает true в случае успеха.

lua
result = zigbee.get(device, state)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- state - STR, состояние, значение которого необходимо получить
-- result - BOOL, true - успех, false - вероятно в конвертере нет команды GET
result = zigbee.get(device, state)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- state - STR, состояние, значение которого необходимо получить
-- result - BOOL, true - успех, false - вероятно в конвертере нет команды GET

zigbee.set()

Устанавливает значение состояния устройства

lua
result = zigbee.set(device, stateName, stateValue)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- stateName - STR, имя состояния, значение которого необходимо изменить
-- stateValue - значение состояние. Тип - свой для каждого значения. Например, для кнопки State:Action тип будет STR, а для яркости State:brightness тип будет INT
-- result - NIL - устройство не найдено, BOOL, true - успех, false - ошибка в имени состояния и/или его значении
result = zigbee.set(device, stateName, stateValue)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- stateName - STR, имя состояния, значение которого необходимо изменить
-- stateValue - значение состояние. Тип - свой для каждого значения. Например, для кнопки State:Action тип будет STR, а для яркости State:brightness тип будет INT
-- result - NIL - устройство не найдено, BOOL, true - успех, false - ошибка в имени состояния и/или его значении

zigbee.setState()

Устанавливает значение состояния устройства. Можно указать тип значения (по умолчанию STR) и необходимо ли выполнять события (с версии 2022.07.24d1, по умолчанию true) . В отличие от zigbee.set() позволяет создавать свои состояния, виртуальные. Например, для хранения данных какого-либо состояния, в альтернативных единицах измерения. Также zigbee.set() не позволяет изменять виртуальные состояния.

При создании состояния желательно выполнить os.save()

lua
result = zigbee.setState(device, stateName, stateValue[[, type], events])
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- stateName - STR, имя состояния, значение которого необходимо изменить
-- stateValue - значение состояние
-- type - STR, тип значений состояния
-- events - BOOL, выполнять события (по умолчанию true)
-- result - BOOL,  true - успех, false - устройство не найдено
result = zigbee.setState(device, stateName, stateValue[[, type], events])
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- stateName - STR, имя состояния, значение которого необходимо изменить
-- stateValue - значение состояние
-- type - STR, тип значений состояния
-- events - BOOL, выполнять события (по умолчанию true)
-- result - BOOL,  true - успех, false - устройство не найдено
Как удалить виртуальное состояние

Вариант 1

  • обнулить конвертер: кнопка Reload converter Id на вкладке Info устройства
  • выполнить Action -> Save 2 раза для удаления из devices.json и devices.json.bak (устройства сохраняются 2 раза в час автоматически, поэтому если произойдет рестарт по питанию ранее 30 минут, то состояние не будет удалено)

Выриант 2

  • удалить из devices.json и devices.json.bak и перезагрузить шлюз по питанию

Пример с состоянием test

До:

json
"st": {
      "backlight_mode": "OFF",
      "child_lock": false,
      "current": 0,
      "last_seen": 1699669806,
      "linkquality": 127,
      "power": 0,
      "power_on_behavior": "OFF",
      "state": "OFF",
      "test": "0",
      "trSeqNum": 150,
      "voltage": 225
"st": {
      "backlight_mode": "OFF",
      "child_lock": false,
      "current": 0,
      "last_seen": 1699669806,
      "linkquality": 127,
      "power": 0,
      "power_on_behavior": "OFF",
      "state": "OFF",
      "test": "0",
      "trSeqNum": 150,
      "voltage": 225

После:

json
"st": {
      "backlight_mode": "OFF",
      "child_lock": false,
      "current": 0,
      "last_seen": 1699669806,
      "linkquality": 127,
      "power": 0,
      "power_on_behavior": "OFF",
      "state": "OFF",
      "trSeqNum": 150,
      "voltage": 225
"st": {
      "backlight_mode": "OFF",
      "child_lock": false,
      "current": 0,
      "last_seen": 1699669806,
      "linkquality": 127,
      "power": 0,
      "power_on_behavior": "OFF",
      "state": "OFF",
      "trSeqNum": 150,
      "voltage": 225

zigbee.setTimeout()

Изменяет таймаут опроса отдельного устройства для определения состояния online. Глобально таймауты задаются в меню Zigbee -> Config:

  • Routers global timeout - период опроса роутеров (по умолчанию 10 минут)
  • EndDevices global timeout - период опроса конечных устройств (по умолчанию 25 часов)
lua
zigbee.setTimeout(device, timeout)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- timeout - INT, таймаут опроса в секундах
zigbee.setTimeout(device, timeout)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- timeout - INT, таймаут опроса в секундах

Для сохранения настройки после перезагрузки, добавить в init.lua.

zigbee.setModel()

Программное переназначение типа устройства.

lua
zigbee.setModel(device, ModelId)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- ModelId - STR, ModelId устройства, которое поддерживается шлюзом.
zigbee.setModel(device, ModelId)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- ModelId - STR, ModelId устройства, которое поддерживается шлюзом.

В некоторых случаях протокол взаимодействия новых устройств совпадает с теми, что уже поддерживаются шлюзом SLS. В таком случае можно при загрузке шлюза подменять идентификаторы, добавив в init.lua код:

lua
zigbee.setModel("xBox", "ptvo.switch")
zigbee.setModel("xBox", "ptvo.switch")

Данный функционал будет полезен пользователям генератора прошивок ptvo, кто самостоятельно изменит имя устройства на кастомное.

zigbee.readAttr() - draft

Отправляет запрос на чтение атрибута в кластере.

lua
zigbee.readAttr(device, epId, clusterId, AttrId[, manufId])
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- epID - INT, номер эндпоинта
-- clusterID - INT, номер кластера
-- AttrId - INT, номер атрибута
-- Например, вернуть атрибут swBuild в кластере genBasic в 1 эндпоинте:
zigbee.readAttr("0x90FD9FFFFEF7E26D", 1, 0x4000, 0x0000)
zigbee.readAttr(device, epId, clusterId, AttrId[, manufId])
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- epID - INT, номер эндпоинта
-- clusterID - INT, номер кластера
-- AttrId - INT, номер атрибута
-- Например, вернуть атрибут swBuild в кластере genBasic в 1 эндпоинте:
zigbee.readAttr("0x90FD9FFFFEF7E26D", 1, 0x4000, 0x0000)

zigbee.writeAttr() - draft

Записывает значение атрибута в кластере.

lua
zigbee.writeAttr(device, epId, clusterId, AttrId, dataType, value[, manufId])
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- epID - INT, номер эндпоинта
-- clusterID - INT, номер кластера
-- AttrId - INT, номер атрибута
-- dataType - INT, тип данных. Например UINT8 - это 0x20
-- value - значение атрибута
zigbee.writeAttr(device, epId, clusterId, AttrId, dataType, value[, manufId])
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- epID - INT, номер эндпоинта
-- clusterID - INT, номер кластера
-- AttrId - INT, номер атрибута
-- dataType - INT, тип данных. Например UINT8 - это 0x20
-- value - значение атрибута

zigbee.configReport() - draft

Конфигурирует репортинг атрибута в кластере.

lua
zigbee.configReport(device, epId, clusterId, AttrId, dataType, minRepInt, maxRepInt, repChange)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- epID - INT, номер эндпоинта
-- clusterID - INT, номер кластера. Например GEN_POWER_CFG - это 0x0001
-- AttrId - INT, номер атрибута. Например BatteryVoltage - это 0x0020
-- dataType - INT, тип данных. Например UINT8 - это 0x20
-- minRepInt - INT, минимальный интервал отправки в сек
-- maxRepInt - INT, максимальный интервал отправки в сек
-- repChange - INT, минимальное значение, на которое должен измениться атрибут, для репортинга
zigbee.configReport(device, epId, clusterId, AttrId, dataType, minRepInt, maxRepInt, repChange)
-- device - STR, FriendlyName, ieeeAddr или nwkAddr устройства
-- epID - INT, номер эндпоинта
-- clusterID - INT, номер кластера. Например GEN_POWER_CFG - это 0x0001
-- AttrId - INT, номер атрибута. Например BatteryVoltage - это 0x0020
-- dataType - INT, тип данных. Например UINT8 - это 0x20
-- minRepInt - INT, минимальный интервал отправки в сек
-- maxRepInt - INT, максимальный интервал отправки в сек
-- repChange - INT, минимальное значение, на которое должен измениться атрибут, для репортинга

Например:

lua
zigbee.configReport("0x90FD9FFFFEF7E26D", 1, 0x0001, 0x0021, 0x20, 1800, 3600, 1)
-- 0x90FD9FFFFEF7E26D - ieeeAddr устройства
-- 1 - первый эндпоинт
-- 0x0001 - кластер GEN_POWER_CFG
-- 0x0021 - атрибут BatteryPercentageRemaining
-- 0x20 - тип данных UINT8
-- 1800, 3600, 1 - репортить от 30 мин до 1 часа при изменении атрибута на 1
zigbee.configReport("0x90FD9FFFFEF7E26D", 1, 0x0001, 0x0021, 0x20, 1800, 3600, 1)
-- 0x90FD9FFFFEF7E26D - ieeeAddr устройства
-- 1 - первый эндпоинт
-- 0x0001 - кластер GEN_POWER_CFG
-- 0x0021 - атрибут BatteryPercentageRemaining
-- 0x20 - тип данных UINT8
-- 1800, 3600, 1 - репортить от 30 мин до 1 часа при изменении атрибута на 1

Библиотека MQTT

Подробное описание здесь


Библиотека HTTP

http.request2()

Служит для отправки HTTP (HTTPS в разработке) запросов во внешние системы. Поддерживает методы GET и POST.

lua
http.request2 (url[:port], [method, headers, body])
-- url:port - STR, URL адрес и порт целевого ресурса
-- method - STR, метод POST или GET
-- headers - STR, заголовки запроса
-- body - STR, тело запроса
http.request2 (url[:port], [method, headers, body])
-- url:port - STR, URL адрес и порт целевого ресурса
-- method - STR, метод POST или GET
-- headers - STR, заголовки запроса
-- body - STR, тело запроса

Примеры

http.request() - deprecated


Библиотека TELEGRAM

Подробное описание здесь


Библиотека OS

Примеры

os.time()

Возвращает Unix время. Вызывается без параметров.

os.setTime()

Устанавливает время шлюза

lua
os.setTime(unixtime)
-- unixtime - STR, время в формате unixtime
os.setTime(unixtime)
-- unixtime - STR, время в формате unixtime

os.sunrise([offset])

Возвращает время восхода солнца (часы, минуты). Для правильной работы требуется выполнить настройки Settings -> Time & Location

lua
os.sunrise([offset])
-- offset - INT, позволяет добавить смещение в минутах к результату вывода
-- Пример:
sunriseH, sunriseM = os.sunrise()
print("Восход солнца в " .. sunriseH .. ":" .. sunriseM )
-->  Восход солнца в 10:55
os.sunrise([offset])
-- offset - INT, позволяет добавить смещение в минутах к результату вывода
-- Пример:
sunriseH, sunriseM = os.sunrise()
print("Восход солнца в " .. sunriseH .. ":" .. sunriseM )
-->  Восход солнца в 10:55

os.sunset([offset])

Возвращает время заката солнца (часы, минуты). Для правильной работы требуется выполнить настройки Settings -> Time & Location

lua
os.sunset([offset])
-- offset - INT, позволяет добавить смещение в минутах к результату вывода
os.sunset([offset])
-- offset - INT, позволяет добавить смещение в минутах к результату вывода

os.setSleep()

Включает и выключает режим сна для модема WiFi. По-умолчанию выключено. Также можно заставить систему заснуть глубоким сном на time секунд, тем самым снизив энергопотребление практически до нуля. В этом режиме не работает ничего, кроме таймера отсчета до окончания сна, по прошествии которого система перезагрузится. Это может использоваться при питании от аккумулятора.

lua
os.setSleep(enable[,time])
-- enable - BOOL, включить = true, выключить = false спящий режим
-- time - INT, время сна в сек.
os.setSleep(enable[,time])
-- enable - BOOL, включить = true, выключить = false спящий режим
-- time - INT, время сна в сек.

os.delay()

Выполняет паузу выполнения скрипта на указанное время. Не рекомендуется делать паузу более чем на 1 секунду.

lua
os.delay(time)
-- time - INT, время паузы в миллисекундах (1 сек = 1000 мс)
os.delay(time)
-- time - INT, время паузы в миллисекундах (1 сек = 1000 мс)

os.millis()

Возвращает количество миллисекунд с момента загрузки системы. Вызывается без параметров.

os.getUptime()

Возвращает время с момента загрузки системы. Вызывается без параметров.

Пример:

lua
print('Uptime: ' .. os.getUptime())
--> Uptime: 11 days 17:43:03
print('Uptime: ' .. os.getUptime())
--> Uptime: 11 days 17:43:03

os.ntp()

Возвращает статус подключения к серверу времени (NTP): true - синхронизация с сервером NTP выполнена успешно.

lua
os.ntp([server])
-- server - STR, адрес сервера NTP
os.ntp([server])
-- server - STR, адрес сервера NTP

Пример лога

[11:01:50.374] [Time] Get time from NTP: pool.ntp.org, use TimeZone: UTC+5:00
[11:01:52.422] [Time] NTP Updated! UnixTime: 1698300112, time: 26.10.2023 11:01:52, ms: 45
[11:01:50.374] [Time] Get time from NTP: pool.ntp.org, use TimeZone: UTC+5:00
[11:01:52.422] [Time] NTP Updated! UnixTime: 1698300112, time: 26.10.2023 11:01:52, ms: 45

os.freeMem()

Возвращает количество свободной памяти в байтах.

lua
os.freeMem([type])
-- type - STR, heap, psram
-- без параметров возвращает объем FreeHeap
os.freeMem([type])
-- type - STR, heap, psram
-- без параметров возвращает объем FreeHeap

os.save()

Сохраняет данные. Тоже, что и меню Actions -> Save. Вызывается без параметров.

os.restart()

Перезагружает ОС. Вызывается без параметров.

os.ping()

Отправляет запросы ICMP PING на тестируемый хост. Возвращает среднее время ответа или -1 при недоступности.

lua
os.ping(host[, count])
-- host - STR, IP или DNS адрес хоста
-- count - INT, количество запросов (по-умолчанию 1)
os.ping(host[, count])
-- host - STR, IP или DNS адрес хоста
-- count - INT, количество запросов (по-умолчанию 1)

os.wdtesp()

Включается и выключает WDT (Сторожевой таймер). Может использоваться для отладки незапланированных перезагрузок. Если шлюз перезагружен по WDT, в сериал логе появится соответствующая запись. Включен по умолчанию.

lua
os.wdtesp(enable)
-- enable - BOOL, включить (true), выключить (false)
os.wdtesp(enable)
-- enable - BOOL, включить (true), выключить (false)

os.wdt()

Управляет сторожевым таймером в модуле (RTC + WDT) SLS Hub. Без параметров возвращает время в сек. до перезагрузки. Модуль, по окончании таймера, дергает пин reset MCU.

lua
os.wdt([time, enable])
-- enable - BOOL, включить (true), выключить (false)
-- time - INT, время в сек., на которое включается WDT
os.wdt([time, enable])
-- enable - BOOL, включить (true), выключить (false)
-- time - INT, время в сек., на которое включается WDT

os.udplogenable()

Включает логирование через UDP. Примеры получения лога

lua
os.udplogenable(enable)
-- enable - BOOL, включить UDP лог (true); выключить (false)
os.udplogenable(enable)
-- enable - BOOL, включить UDP лог (true); выключить (false)

os.setAssets()

Задает место хранения ресурсов web-интерфейса, для размещения на альтернативном web-сервере, например локальном. В разработке хранение web-ресурсов в хранилище SLS, для систем без выхода в интернет.

lua
os.setAssets(url)
-- url - STR, источник ресурсов
os.setAssets(url)
-- url - STR, источник ресурсов

os.led()

lua
os.led(mode, brightness, r, g, b[, effect])
-- mode - STR, режим. OFF - выключено, ON - включено, AUTO - индикация режимов/состояний шлюза (см. описание далее)
-- brightness - INT, яркость (целое, от 0 до 255)
-- r, g, b - INT, цвет (целое, от 0 до 255 или -1, если цвет менять не требуется)
-- effect - INT, включает эффекты в соответствии с таблицей
os.led(mode, brightness, r, g, b[, effect])
-- mode - STR, режим. OFF - выключено, ON - включено, AUTO - индикация режимов/состояний шлюза (см. описание далее)
-- brightness - INT, яркость (целое, от 0 до 255)
-- r, g, b - INT, цвет (целое, от 0 до 255 или -1, если цвет менять не требуется)
-- effect - INT, включает эффекты в соответствии с таблицей

Подробнее о работе с LED здесь

os. функции для работы с хранилищем

Описание функций для работы с хранилищем здесь


Библиотека GPIO

Управление контактами ввода/вывода (GPIO) чипа ESP32.

gpio.mode()

Управление режимом контакта:

  • gpio.INPUT: ввод
  • gpio.OUTPUT: вывод
  • gpio.INPUT_PULLUP: подтянуть к VCC
  • gpio.INPUT_PULLDOWN: подтянуть к GND
lua
gpio.mode(pin, mode)
-- pin: номер контакта
-- mode: режим контакта - gpio.INPUT, gpio.INPUT_PULLUP, gpio.INPUT_PULLDOWN, gpio.OUTPUT
gpio.mode(pin, mode)
-- pin: номер контакта
-- mode: режим контакта - gpio.INPUT, gpio.INPUT_PULLUP, gpio.INPUT_PULLDOWN, gpio.OUTPUT

gpio.read()

Чтение сигнала с GPIO

lua
gpio.read(pin[, ADC)
-- pin: номер контакта
-- ADC: true - чтение ADC; false - чтение цифрового сигнала
gpio.read(pin[, ADC)
-- pin: номер контакта
-- ADC: true - чтение ADC; false - чтение цифрового сигнала

Задать каналу 2 режим входа, получить его значение:

lua
gpio.mode(25, gpio.INPUT)
local value = gpio.read(25)
print(value)
gpio.mode(25, gpio.INPUT)
local value = gpio.read(25)
print(value)

gpio.write()

Запись уровня в GPIO

lua
gpio.write(pin, level)
-- pin: номер контакта
-- level: уровень - gpio.HIGH - высокий, gpio.LOW - низкий
gpio.write(pin, level)
-- pin: номер контакта
-- level: уровень - gpio.HIGH - высокий, gpio.LOW - низкий

Например, задать каналу 4 режим выхода и включить его на 100мс:

lua
gpio.mode(27, gpio.OUTPUT)
gpio.write(27, 1)
os.delay(100)
gpio.write(27, 0)
gpio.mode(27, gpio.OUTPUT)
gpio.write(27, 1)
os.delay(100)
gpio.write(27, 0)

PWM (ШИМ)

ШИМ-контроллер ESP32 имеет 16 независимых каналов, которые можно настроить для генерации ШИМ-сигналов с различными свойствами. Все выводы, которые могут выступать в качестве выходов, могут использоваться в качестве выводов ШИМ (GPIO с 34 по 39 не могут генерировать ШИМ).

gpio.pwmSetup()

Настройка ШИМ

lua
gpio.pwmSetup(channel, pin[, freq = 5000[, resolution = 8]])
-- chanel: канал ШИМ - 0-15
-- pin: номер контакта
-- resolution: разрешение 1-16 bits
-- freq: частота
gpio.pwmSetup(channel, pin[, freq = 5000[, resolution = 8]])
-- chanel: канал ШИМ - 0-15
-- pin: номер контакта
-- resolution: разрешение 1-16 bits
-- freq: частота

gpio.pwm()

Управление ШИМ

lua
gpio.pwm(channel, value)
-- channel: канал 0-15
-- value: значение ШИМ
gpio.pwm(channel, value)
-- channel: канал 0-15
-- value: значение ШИМ

Например, задать каналу 1 режим выхода и включить ШИМ со скважностью 50%

lua
gpio.pwmSetup(3, 32)
gpio.pwm(3, 255/100*50)
gpio.pwmSetup(3, 32)
gpio.pwm(3, 255/100*50)

Библиотека AUDIO

Управление звуком

lua
audio.playurl(url) -- проигрывание звука из URL
audio.geturl() -- возвращает текущий URL
audio.stop() -- остановить проигрывание
audio.setvolume(volume_percent) -- установить уровень громкости
audio.getvolume() -- возвращает текущий уровень громкости
audio.getstatus() -- возвращает текущий статус
audio.playurl(url) -- проигрывание звука из URL
audio.geturl() -- возвращает текущий URL
audio.stop() -- остановить проигрывание
audio.setvolume(volume_percent) -- установить уровень громкости
audio.getvolume() -- возвращает текущий уровень громкости
audio.getstatus() -- возвращает текущий статус

Библиотека NET

net.localIP()

Возвращает адрес устройства SLS в локальной сети. Выполняется без параметров.

net.remoteIP()

Возвращает внешний адрес SLS в сети интернет (если доступен). Выполняется без параметров.


Библиотека Yeelight

Примеры

yeelight.send()

Управляет устройством Yeelight. Описание протокола.

lua
result = yeelight.send(id, method, param)
-- id - STR, IP адрес устройства
-- method - STR, команда
-- param - STR, параметры команды
-- result - JSON строка, согласно описания протокола
result = yeelight.send(id, method, param)
-- id - STR, IP адрес устройства
-- method - STR, команда
-- param - STR, параметры команды
-- result - JSON строка, согласно описания протокола

Библиотека Cloud

cloud.isConnected()

Возвращает статус подключения к облаку SLS cloud.slsys.io

lua
result = cloud.isConnected()
-- result - BOOL, true шлюз подключен к облаку SLS
result = cloud.isConnected()
-- result - BOOL, true шлюз подключен к облаку SLS

Функции LUA SLS

Функции LUA, встроенные в прошивку SLS, которые не объединены той или иной библиотекой.

explode()

Разбивает строку с помощью разделителя. Результат помещает в таблицу.

lua
explode(separator, string)
-- string - STR, строка, которую необходимо разбить
-- separator - STR, символ разделителя
-- пример:
local string = "param1|param2|param3"
local t = explode("|", string)
local param1 = t[1]
local param2 = t[2]
local param3 = t[3]
explode(separator, string)
-- string - STR, строка, которую необходимо разбить
-- separator - STR, символ разделителя
-- пример:
local string = "param1|param2|param3"
local t = explode("|", string)
local param1 = t[1]
local param2 = t[2]
local param3 = t[3]

Обработка нажатий аппаратной кнопки шлюза

Многие ревизии шлюзов имеют кнопку, нажатия которой можно обрабатывать скриптами. Например, для включения "режима сопряжения" при нажатии на боковую кнопку шлюза Необходимо привязать скрипт btn_sw1.lua

lua
zigbee.join(255, "0x0000")
zigbee.join(255, "0x0000")

и привязать его выполнение в init.lua

lua
obj.setScript("io.input0.value", "btn_sw1.lua")
obj.setScript("io.input0.value", "btn_sw1.lua")
  • где io.input0.value - номер обрабатываемого порта (в примере указана кнопка для круглого шлюза)

Более подробно вопрос с обработкой событий gpio разобран в разделе Модуля ввода-вывода


Полезные ссылки

  1. Примеры типовых сценариев
  2. On-line учебник по lua
  3. Генератор lua скриптов на основе Blockly