Скрипты — различия между версиями

Материал из WebHMI Wiki
Перейти к: навигация, поиск
(SendTelegramMessage(chatId, message))
Строка 116: Строка 116:
 
Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие работающего интернет-подключения и доступа к серверу webhmicloud.com.<br>
 
Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие работающего интернет-подключения и доступа к серверу webhmicloud.com.<br>
  
Для получения ChatId перейдите по ссылке http://telegram.me/webhmibot на мобильном телефоне (предварительно установив Telegram) и начните диалог с ботом webhmibot командой /start. В ответ вы получите сообщение с уникальным идентификатором чата ChatId. Пример:
+
Для получения ChatId перейдите по ссылке http://telegram.me/webhmibot на мобильном телефоне (предварительно установив Telegram) и начните диалог с ботом webhmibot командой /start. В ответ вы получите сообщение с уникальным идентификатором чата ChatId.  
[[Файл:Chatid.png|400px]]
+
  
 +
Пример:
 +
[[Файл:Chatid.png|400px]]
  
 
== AddInfoMessage(message, userId) ==
 
== AddInfoMessage(message, userId) ==

Версия 13:25, 29 сентября 2016

О скриптах Lua

WebHMI начиная с версии 1.10.0.3393 позволяет создавать пользовательские скрипты на языке Lua 5.1 [1].

Управление скриптами происходит в пункте меню Setup --> Scripts:
Lua-scripts-1.png

Scripts edit.png

Каждый скрипт должен содержать в себе функцию с именем main. Именно она будет вызвана в необходимый момент (в зависимости от настроек скрипта - в каждом цикле, при действии на dashboard или при изменении значения регистра). Также, весь скрипт будет выполнен один раз при запуске демона. Это необходимо для компиляции сценария Lua и его валидации. Выполнен будет весь код, который находится в глобальной области видимости (т.е. вне функции main, функция main не будет вызвана). Это может быть полезно для инициализации некоторых переменный и т.п.

В функцию main будет передан один параметр — userId — ID пользователя, который выполнил этот скрипт. Если скрипт выполняется в каждом цикле или при изменении регистра то userId будет равен нулю.

WebHMI накладывает следующие ограничения на стандартные функции и библиотеки языка Lua:

  • не доступны такие функции и таблицы: require, print, loadfile, dofile, os.execute, os.getenv, os.remove, os.rename, os.tmpname, package, debug.debug, debug.getfenv, debug.getregistry, arg
  • не доступны библиотеки: io

Помимо стандартных функций Lua, в WebHMI определены еще такие функции:

  • GetReg
  • SetReg
  • WriteReg
  • AddInfoMessage
  • AddWarningMessage
  • AddAlertMessage
  • SendSMS
  • SendTelegramMessage
  • ERROR
  • INFO
  • DEBUG
  • TRACE
  • ApplyRecipe


Для удобства работы с регистрами из программ Lua, каждому регистру можно присвоить символическое имя и работать из Lua уже с этим именем. Это имя указывается в настройках регистра в поле Variable name:
Lua-scripts-3.png

Lua-scripts-4.png

Пример простейшего скрипта, который показывает вызовы всех WebHMI функций:

function main (userId)
    local randomVal = GetReg("random_val");
    SetReg("random_val_copy", randomVal);
    WriteReg("result", randomVal + 2);

    AddInfoMessage("This is a Lua script", userId);
    AddWarningMessage("Warning. This is a Lua script", userId);
    AddAlertMessage("Alert! This is a Lua script", userId);

    SendSMS("380501234567", "This is a test SMS");

    ERROR("This message will be added to communication log with ERROR level");
    INFO("This message will be added to communication log with INFO level");
    DEBUG("This message will be added to communication log with DEBUG level");
    TRACE("This message will be added to communication log with TRACE level");
end

Несмотря на то, что встроенный редактор проверяет синтаксис программы, он не в состоянии выявить все ошибки, которые могу возникнуть в процессе выполнения скрипта. В случаях, если во время его выполнения возникнут какие-либо ошибки, они будут выведены в Communication Log.

Например, при выполнении этого скрипта произойдет ошибка т.к. переменная random не объявлена.

function main (userId)
    
  local v1 = GetReg("Drying_Humidity1_Value");
  v1 = v1+random; -- ошибка здесь, если убрать random, всё становится ок
  
  SetReg("Drying_Humidity1_Value", v1);
  WriteReg("Drying_Humidity1_Value", v1); 
  
  AddInfoMessage(v1, userId);
end

В Communication Log можно будет увидеть такие записи:

Jan 23 12:09:27.047: ERROR: LUA scripts: Can't execute LUA script #1. Error #2: [string "Calculate humidity"]:4: attempt to perform arithmetic on a nil value (global 'random')
Jan 23 12:09:27.551: ERROR: LUA scripts: Can't execute LUA script #1. Error #2: [string "Calculate humidity"]:4: attempt to perform arithmetic on a nil value (global 'random')
Jan 23 12:09:28.051: ERROR: LUA scripts: Can't execute LUA script #1. Error #2: [string "Calculate humidity"]:4: attempt to perform arithmetic on a nil value (global 'random')

Здесь видно, что произошла ошибка при попытке выполнения арифметической операции с неопределенной переменной (nil). Ошибка произошла в скрипте номер 1, его название "Calculate humidity", ошибка произошла в строке номер 4. Переменная, которая вызвала ошибку называется 'random'.

Таким образом, с помощью этого лога можно найти все ошибки выполнения сценариев.

GetReg(variable_name[, connection_name])

Функция GetReg возвращает текущее значение регистра с именем переменной variable_name где variable_name — это значение Srcipt alias из настроек регистра. Вместо variable_name можно указывать число — ID регистра. Однако, ID регистра — это менее наглядный способ и он усложняет чтение программы.

Опциональный параметр connection_name можно указать если в нескольких разных соединениях есть регистры с одинаковым variable_name. В этом случае connection_name указывает из какого конкретно соединения необходимо читать регистр с именем variable_name. Также, вместо строки connection_name можно указывать ID соединения. Однако, опять же, константы усложняют чтение кода и предпочтительней использовать именованные строки.

Если регистр не найден или не был прочитан то возвращается значение nil.

Для удобства выбора регистров возле редактора скриптов есть три дополнительные кнопки.
Help-buttons.png

При нажатии на любую из них появляется всплывающее окно со списком регистров.
Regs-select.png

После щелчка по интересуещему регистру в редактор будет вставлен код с идентификатором выбранного регистра (variable_name если есть или ID) и комментарием с именем регистра, его адресом и именем соединения.
Reg-selected.png

SetReg(variable_name[,connection_name] , new_value)

Функция SetReg устанавливает текущее значение регистра с именем переменной variable_name в new_value для текущего цикла. Запись во внешние устройства не происходит и при опросе этого регистра в последующих циклах будет прочитано старое значение. Возвращает 1 если произошла ошибка и 0 в случае успеха.

Параметры variable_name и connection_name работают так же как и в функции GetReg.

WriteReg(variable_name, new_value)

Функция WriteReg устанавливает текущее значение регистра с именем переменной variable_name в new_value для текущего цикла цикле и записывает это значение во внешнее устройство в начале следующего цикла. При опросе этого регистра в последующих циклах будет прочитано новое значение (если оно не изменится самим устройством). Возвращает 1 если произошла ошибка и 0 в случае успеха.

Параметры variable_name и connection_name работают так же как и в функции GetReg.

SendSMS(phone_number, message)

Функция SendSMS отправляет запрос на отправку SMS на номер phone_number с текстом message. Возвращает false если произошла ошибка и true в случае успеха. Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие интернет-подключения и предоплаты за услуги SMS.
Формат phone_number — только цифры с указанием кода страны, без пробелов, скобок, знака плюс. Например, 380123456789.

SendTelegramMessage(chatId, message)

Функция SendTelegramMessage отправляет сообщение с текстом message в час с Id = chatId . Возвращает 1 если произошла ошибка и 0 в случае успеха. Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие работающего интернет-подключения и доступа к серверу webhmicloud.com.

Для получения ChatId перейдите по ссылке http://telegram.me/webhmibot на мобильном телефоне (предварительно установив Telegram) и начните диалог с ботом webhmibot командой /start. В ответ вы получите сообщение с уникальным идентификатором чата ChatId.

Пример: Chatid.png

AddInfoMessage(message, userId)

Функция AddInfoMessage добавляет сообщение message с уровнем Info в журнал Messages. userId — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.

AddWarningMessage(message, userId)

Функция AddWarningMessage добавляет сообщение message с уровнем Warning в журнал Messages. userId — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.

AddAlertMessage(message, userId)

Функция AddAlertMessage добавляет сообщение message с уровнем Alert в журнал Messages. userId — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.

ERROR(message)

Функция ERROR добавляет сообщение message уровня ERROR в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.

INFO(message)

Функция INFO добавляет сообщение message уровня INFO в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.

DEBUG(message)

Функция DEBUG добавляет сообщение message уровня DEBUG в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.

TRACE(message)

Функция TRACE добавляет сообщение message уровня TRACE в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.

ApplyRecipe(recipeId, userId)

Функция ApplyRecipe применяет рецепт с номером recipeId от имени пользователя с id = userId. Если у данного пользователя нет прав доступа к этому рецепту то рецепт применен не будет. Применение рецепта заключается в записи в регистры, которые указаны в рецепте, соответствующих значений.