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

Материал из WebHMI Wiki
Перейти к: навигация, поиск
(Отметить эту версию для перевода)
Строка 1: Строка 1:
 
<translate>
 
<translate>
== О скриптах Lua ==
+
== О скриптах Lua == <!--T:1-->
 
WebHMI начиная с версии 1.10.0.3393 позволяет создавать пользовательские программы (скрипты) на языке Lua 5.1 [https://ru.wikipedia.org/wiki/Lua].
 
WebHMI начиная с версии 1.10.0.3393 позволяет создавать пользовательские программы (скрипты) на языке Lua 5.1 [https://ru.wikipedia.org/wiki/Lua].
  
 +
<!--T:2-->
 
Управление скриптами происходит в пункте меню Setup --> Scripts:<br>
 
Управление скриптами происходит в пункте меню Setup --> Scripts:<br>
 
[[Файл:Lua-scripts-1.png|800px]]<br>
 
[[Файл:Lua-scripts-1.png|800px]]<br>
  
 +
<!--T:3-->
 
[[Файл:Scripts edit.png|800px]]<br>
 
[[Файл:Scripts edit.png|800px]]<br>
  
 +
<!--T:4-->
 
Каждый скрипт должен содержать в себе функцию с именем '''main'''. Именно она будет вызвана в необходимый момент (в зависимости от настроек скрипта - в каждом цикле, при действии на dashboard или при изменении значения регистра). Также, весь скрипт будет выполнен один раз при запуске демона. Это необходимо для компиляции сценария Lua и его валидации. Выполнен будет весь код, который находится в глобальной области видимости (т.е. вне функции main, функция main не будет вызвана). Это может быть полезно для инициализации некоторых переменный и т.п.
 
Каждый скрипт должен содержать в себе функцию с именем '''main'''. Именно она будет вызвана в необходимый момент (в зависимости от настроек скрипта - в каждом цикле, при действии на dashboard или при изменении значения регистра). Также, весь скрипт будет выполнен один раз при запуске демона. Это необходимо для компиляции сценария Lua и его валидации. Выполнен будет весь код, который находится в глобальной области видимости (т.е. вне функции main, функция main не будет вызвана). Это может быть полезно для инициализации некоторых переменный и т.п.
  
 +
<!--T:5-->
 
В функцию main будет передан один параметр — userId — ID пользователя, который выполнил этот скрипт. Если скрипт выполняется в каждом цикле или при изменении регистра то userId будет равен нулю.
 
В функцию main будет передан один параметр — userId — ID пользователя, который выполнил этот скрипт. Если скрипт выполняется в каждом цикле или при изменении регистра то userId будет равен нулю.
  
 +
<!--T:6-->
 
WebHMI накладывает следующие ограничения на стандартные функции и библиотеки языка Lua:
 
WebHMI накладывает следующие ограничения на стандартные функции и библиотеки языка Lua:
 
* не доступны такие функции и таблицы: require, print, loadfile, dofile, os.execute, os.getenv, os.remove, os.rename, os.tmpname, package, debug.debug, debug.getfenv, debug.getregistry, arg
 
* не доступны такие функции и таблицы: require, print, loadfile, dofile, os.execute, os.getenv, os.remove, os.rename, os.tmpname, package, debug.debug, debug.getfenv, debug.getregistry, arg
 
* не доступны библиотеки: io
 
* не доступны библиотеки: io
  
 +
<!--T:7-->
 
Помимо стандартных функций Lua, в WebHMI определены еще такие функции:
 
Помимо стандартных функций Lua, в WebHMI определены еще такие функции:
 
* GetReg
 
* GetReg
Строка 41: Строка 47:
 
* GetHolidaysStats
 
* GetHolidaysStats
  
 +
<!--T:8-->
 
Для удобства работы с регистрами из программ Lua, каждому регистру можно присвоить символическое имя и работать из Lua уже с этим именем. Это имя указывается в настройках регистра в поле '''Имя переменной (Variable name)''':<br>
 
Для удобства работы с регистрами из программ Lua, каждому регистру можно присвоить символическое имя и работать из Lua уже с этим именем. Это имя указывается в настройках регистра в поле '''Имя переменной (Variable name)''':<br>
 
[[Файл:Lua-scripts-3.png|800px]]<br>
 
[[Файл:Lua-scripts-3.png|800px]]<br>
  
 +
<!--T:9-->
 
[[Файл:Lua-scripts-4.png|800px]]<br>
 
[[Файл:Lua-scripts-4.png|800px]]<br>
  
 +
<!--T:10-->
 
Пример простейшего скрипта, который показывает вызовы всех WebHMI функций:<br>
 
Пример простейшего скрипта, который показывает вызовы всех WebHMI функций:<br>
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Строка 53: Строка 62:
 
     WriteReg("result", randomVal + 2);
 
     WriteReg("result", randomVal + 2);
  
     AddInfoMessage("This is a Lua script", userId);
+
     <!--T:11-->
 +
AddInfoMessage("This is a Lua script", userId);
 
     AddWarningMessage("Warning. This is a Lua script", userId);
 
     AddWarningMessage("Warning. This is a Lua script", userId);
 
     AddAlertMessage("Alert! This is a Lua script", userId);
 
     AddAlertMessage("Alert! This is a Lua script", userId);
  
     SendSMS("380501234567", "This is a test SMS");
+
     <!--T:12-->
 +
SendSMS("380501234567", "This is a test SMS");
  
     ERROR("This message will be added to communication log with ERROR level");
+
     <!--T:13-->
 +
ERROR("This message will be added to communication log with ERROR level");
 
     INFO("This message will be added to communication log with INFO 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");
 
     DEBUG("This message will be added to communication log with DEBUG level");
Строка 66: Строка 78:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
<!--T:14-->
 
Несмотря на то, что встроенный редактор проверяет синтаксис программы, он не в состоянии выявить все ошибки, которые могу возникнуть в процессе выполнения скрипта. В случаях, если во время его выполнения возникнут какие-либо ошибки, они будут выведены в Communication Log.
 
Несмотря на то, что встроенный редактор проверяет синтаксис программы, он не в состоянии выявить все ошибки, которые могу возникнуть в процессе выполнения скрипта. В случаях, если во время его выполнения возникнут какие-либо ошибки, они будут выведены в Communication Log.
  
 +
<!--T:15-->
 
Например, при выполнении этого скрипта произойдет ошибка т.к. переменная '''random''' не объявлена.
 
Например, при выполнении этого скрипта произойдет ошибка т.к. переменная '''random''' не объявлена.
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Строка 82: Строка 96:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
<!--T:16-->
 
В Communication Log можно будет увидеть такие записи:
 
В Communication Log можно будет увидеть такие записи:
 
<pre>
 
<pre>
Строка 90: Строка 105:
 
Здесь видно, что произошла ошибка при попытке выполнения арифметической операции с неопределенной переменной (nil). Ошибка произошла в скрипте номер 1, его название "Calculate humidity", ошибка произошла в строке номер 4. Переменная, которая вызвала ошибку называется 'random'.
 
Здесь видно, что произошла ошибка при попытке выполнения арифметической операции с неопределенной переменной (nil). Ошибка произошла в скрипте номер 1, его название "Calculate humidity", ошибка произошла в строке номер 4. Переменная, которая вызвала ошибку называется 'random'.
  
 +
<!--T:17-->
 
Таким образом, с помощью этого лога можно найти все ошибки выполнения сценариев.
 
Таким образом, с помощью этого лога можно найти все ошибки выполнения сценариев.
  
== GetReg(variable_name[, connection_name]) ==
+
== GetReg(variable_name[, connection_name]) == <!--T:18-->
 
Функция GetReg возвращает текущее значение регистра с именем переменной '''variable_name''' где '''variable_name''' — это значение Srcipt alias из настроек регистра. Вместо '''variable_name''' можно указывать число — ID регистра. Однако, ID регистра — это менее наглядный способ и он усложняет чтение программы.
 
Функция GetReg возвращает текущее значение регистра с именем переменной '''variable_name''' где '''variable_name''' — это значение Srcipt alias из настроек регистра. Вместо '''variable_name''' можно указывать число — ID регистра. Однако, ID регистра — это менее наглядный способ и он усложняет чтение программы.
  
 +
<!--T:19-->
 
Опциональный параметр '''connection_name''' можно указать если в нескольких разных соединениях есть регистры с одинаковым '''variable_name'''. В этом случае '''connection_name''' указывает из какого конкретно соединения необходимо читать регистр с именем variable_name. Также, вместо строки connection_name можно указывать ID соединения. Однако, опять же, константы усложняют чтение кода и предпочтительней использовать именованные строки.
 
Опциональный параметр '''connection_name''' можно указать если в нескольких разных соединениях есть регистры с одинаковым '''variable_name'''. В этом случае '''connection_name''' указывает из какого конкретно соединения необходимо читать регистр с именем variable_name. Также, вместо строки connection_name можно указывать ID соединения. Однако, опять же, константы усложняют чтение кода и предпочтительней использовать именованные строки.
  
 +
<!--T:20-->
 
Если регистр не найден или не был прочитан то возвращается значение '''nil'''.
 
Если регистр не найден или не был прочитан то возвращается значение '''nil'''.
  
 +
<!--T:21-->
 
Для удобства выбора регистров возле редактора скриптов есть три дополнительные кнопки.<br>
 
Для удобства выбора регистров возле редактора скриптов есть три дополнительные кнопки.<br>
 
[[Файл:Help-buttons.png|600px]]<br>
 
[[Файл:Help-buttons.png|600px]]<br>
  
 +
<!--T:22-->
 
При нажатии на любую из них появляется всплывающее окно со списком регистров.<br>
 
При нажатии на любую из них появляется всплывающее окно со списком регистров.<br>
 
[[Файл:Regs-select.png|600px]]<br>
 
[[Файл:Regs-select.png|600px]]<br>
  
 +
<!--T:23-->
 
После щелчка по интересуещему регистру в редактор будет вставлен код с идентификатором выбранного регистра (variable_name если есть или ID) и комментарием с именем регистра, его адресом и именем соединения.<br>
 
После щелчка по интересуещему регистру в редактор будет вставлен код с идентификатором выбранного регистра (variable_name если есть или ID) и комментарием с именем регистра, его адресом и именем соединения.<br>
 
[[Файл:Reg-selected.png|600px]]<br>
 
[[Файл:Reg-selected.png|600px]]<br>
  
== SetReg(variable_name[,connection_name] , new_value) ==
+
== SetReg(variable_name[,connection_name] , new_value) == <!--T:24-->
 
Функция SetReg устанавливает текущее значение регистра с именем переменной '''variable_name''' в '''new_value''' для текущего цикла. Запись во внешние устройства не происходит и при опросе этого регистра в последующих циклах будет прочитано старое значение. Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция SetReg устанавливает текущее значение регистра с именем переменной '''variable_name''' в '''new_value''' для текущего цикла. Запись во внешние устройства не происходит и при опросе этого регистра в последующих циклах будет прочитано старое значение. Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
 +
<!--T:25-->
 
Параметры '''variable_name''' и '''connection_name''' работают так же как и в функции GetReg.
 
Параметры '''variable_name''' и '''connection_name''' работают так же как и в функции GetReg.
  
== WriteReg(variable_name[, connection_name], new_value) ==
+
== WriteReg(variable_name[, connection_name], new_value) == <!--T:26-->
 
Функция WriteReg устанавливает текущее значение регистра с именем переменной '''variable_name''' (опционально можно указать и соединение '''connection_name''') в '''new_value''' для текущего цикла цикле и записывает это значение во внешнее устройство в начале следующего цикла. При опросе этого регистра в последующих циклах будет прочитано новое значение (если оно не изменится самим устройством).  Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция WriteReg устанавливает текущее значение регистра с именем переменной '''variable_name''' (опционально можно указать и соединение '''connection_name''') в '''new_value''' для текущего цикла цикле и записывает это значение во внешнее устройство в начале следующего цикла. При опросе этого регистра в последующих циклах будет прочитано новое значение (если оно не изменится самим устройством).  Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
 +
<!--T:27-->
 
Параметры '''variable_name''' и '''connection_name''' работают так же как и в функции GetReg.
 
Параметры '''variable_name''' и '''connection_name''' работают так же как и в функции GetReg.
  
== SendSMS(phone_number, message)  ==
+
== SendSMS(phone_number, message)  == <!--T:28-->
 
Функция SendSMS отправляет запрос на отправку SMS на номер '''phone_number''' с текстом '''message'''. Возвращает false если произошла ошибка и true в случае успеха. Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие интернет-подключения, учетная запись в системе Level2 и положительного баланса в ней. Услуга платная.<br>
 
Функция SendSMS отправляет запрос на отправку SMS на номер '''phone_number''' с текстом '''message'''. Возвращает false если произошла ошибка и true в случае успеха. Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие интернет-подключения, учетная запись в системе Level2 и положительного баланса в ней. Услуга платная.<br>
 
Формат '''phone_number''' — только цифры с указанием кода страны, без пробелов, скобок, знака плюс. Например, 380123456789.
 
Формат '''phone_number''' — только цифры с указанием кода страны, без пробелов, скобок, знака плюс. Например, 380123456789.
  
== SendEmailMessage(emailAddress, subject, message)  ==
+
== SendEmailMessage(emailAddress, subject, message)  == <!--T:29-->
 
Функция SendEmailMessage отправляет запрос на отправку e-mail по адресу '''emailAddress''' с темой письма '''subject''' и текстом '''message'''. Возвращает false если произошла ошибка и true в случае успеха. Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие интернет-подключения, учетная запись в системе Level2 и положительного баланса в ней. Услуга платная.<br>
 
Функция SendEmailMessage отправляет запрос на отправку e-mail по адресу '''emailAddress''' с темой письма '''subject''' и текстом '''message'''. Возвращает false если произошла ошибка и true в случае успеха. Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие интернет-подключения, учетная запись в системе Level2 и положительного баланса в ней. Услуга платная.<br>
 
Поле '''message''' может содержать html-код.  
 
Поле '''message''' может содержать html-код.  
  
 +
<!--T:30-->
 
Пример:
 
Пример:
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Строка 135: Строка 159:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
<!--T:31-->
 
Функция доступна начиная с версии WebHMI 2.7.4710
 
Функция доступна начиная с версии WebHMI 2.7.4710
  
== SendTelegramMessage(chatId, message)  ==
+
== SendTelegramMessage(chatId, message)  == <!--T:32-->
 
Функция SendTelegramMessage отправляет сообщение с текстом '''message''' в чат с Id = '''chatId''' . Возвращает 1 если произошла ошибка и 0 в случае успеха.  
 
Функция SendTelegramMessage отправляет сообщение с текстом '''message''' в чат с Id = '''chatId''' . Возвращает 1 если произошла ошибка и 0 в случае успеха.  
 
Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие интернет-подключения, учетная запись в системе Level2. Услуга бесплатная.<br>
 
Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие интернет-подключения, учетная запись в системе Level2. Услуга бесплатная.<br>
  
 +
<!--T:33-->
 
Для получения ChatId перейдите по ссылке http://telegram.me/webhmibot на мобильном телефоне (предварительно установив Telegram) и начните диалог с ботом webhmibot командой /start. В ответ вы получите сообщение с уникальным идентификатором чата ChatId.  
 
Для получения ChatId перейдите по ссылке http://telegram.me/webhmibot на мобильном телефоне (предварительно установив Telegram) и начните диалог с ботом webhmibot командой /start. В ответ вы получите сообщение с уникальным идентификатором чата ChatId.  
  
 +
<!--T:34-->
 
Пример:
 
Пример:
  
 +
<!--T:35-->
 
[[Файл:Chatid.png|400px]]
 
[[Файл:Chatid.png|400px]]
  
  
== SendViberMessage(chatId, message)  ==
+
== SendViberMessage(chatId, message)  == <!--T:36-->
 
Функция SendViberMessage отправляет сообщение с текстом '''message''' в чат с Id = '''chatId'''. Возвращает 1 если произошла ошибка и 0 в случае успеха. <br/>
 
Функция SendViberMessage отправляет сообщение с текстом '''message''' в чат с Id = '''chatId'''. Возвращает 1 если произошла ошибка и 0 в случае успеха. <br/>
 
Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие работающего интернет-подключения, учетной записи в системе [http://wiki.webhmi.com.ua/index.php/%D0%9F%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_WebHMI_%D0%BA_Level2 Level2] и положительного баланса в этой системе. Услуга платная. Эта возможность доступна начиная с версии прошивки 2.4.4227.<br/>
 
Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие работающего интернет-подключения, учетной записи в системе [http://wiki.webhmi.com.ua/index.php/%D0%9F%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_WebHMI_%D0%BA_Level2 Level2] и положительного баланса в этой системе. Услуга платная. Эта возможность доступна начиная с версии прошивки 2.4.4227.<br/>
  
 +
<!--T:37-->
 
Для получения ChatId перейдите по ссылке http://viber.com/webhmi на мобильном телефоне (предварительно установив Viber), нажмите кнопку Have a look.<br/>
 
Для получения ChatId перейдите по ссылке http://viber.com/webhmi на мобильном телефоне (предварительно установив Viber), нажмите кнопку Have a look.<br/>
 
[[Файл:Viber-pa.png|400px]]<br/>
 
[[Файл:Viber-pa.png|400px]]<br/>
  
 +
<!--T:38-->
 
Вы попадете в публичный аккаунт WebHMI. Перейдите в личные сообщения публичного аккаунта нажав кнопку справа вверху. <br/>
 
Вы попадете в публичный аккаунт WebHMI. Перейдите в личные сообщения публичного аккаунта нажав кнопку справа вверху. <br/>
 
[[Файл:Viber-private-message.png|400px]]<br/>
 
[[Файл:Viber-private-message.png|400px]]<br/>
  
 +
<!--T:39-->
 
Напишите любой текст в чате. В ответ вы получите сообщение с уникальным идентификатором чата ChatId. <br/>
 
Напишите любой текст в чате. В ответ вы получите сообщение с уникальным идентификатором чата ChatId. <br/>
 
[[Файл:Viber-chat-id.png|400px]]<br/>
 
[[Файл:Viber-chat-id.png|400px]]<br/>
  
== AddInfoMessage(message, userId) ==
+
== AddInfoMessage(message, userId) == <!--T:40-->
 
Функция AddInfoMessage добавляет сообщение '''message''' с уровнем Info в журнал Messages. '''userId''' — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция AddInfoMessage добавляет сообщение '''message''' с уровнем Info в журнал Messages. '''userId''' — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
== AddWarningMessage(message, userId) ==
+
== AddWarningMessage(message, userId) == <!--T:41-->
 
Функция AddWarningMessage добавляет сообщение '''message''' с уровнем Warning в журнал Messages. '''userId''' — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция AddWarningMessage добавляет сообщение '''message''' с уровнем Warning в журнал Messages. '''userId''' — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
== AddAlertMessage(message, userId) ==
+
== AddAlertMessage(message, userId) == <!--T:42-->
 
Функция AddAlertMessage добавляет сообщение '''message''' с уровнем Alert в журнал Messages. '''userId''' — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция AddAlertMessage добавляет сообщение '''message''' с уровнем Alert в журнал Messages. '''userId''' — это ID пользователя, от имени которого должно быть добавлено сообщение. Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
== ERROR(message) ==
+
== ERROR(message) == <!--T:43-->
 
Функция ERROR добавляет сообщение '''message''' уровня ERROR в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция ERROR добавляет сообщение '''message''' уровня ERROR в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
== INFO(message) ==
+
== INFO(message) == <!--T:44-->
 
Функция INFO добавляет сообщение '''message''' уровня INFO в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция INFO добавляет сообщение '''message''' уровня INFO в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
== DEBUG(message) ==
+
== DEBUG(message) == <!--T:45-->
 
Функция DEBUG добавляет сообщение '''message''' уровня DEBUG в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция DEBUG добавляет сообщение '''message''' уровня DEBUG в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
== TRACE(message) ==
+
== TRACE(message) == <!--T:46-->
 
Функция TRACE добавляет сообщение '''message''' уровня TRACE в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.
 
Функция TRACE добавляет сообщение '''message''' уровня TRACE в Communication Log (Maintenance --> Communication Log). Возвращает 1 если произошла ошибка и 0 в случае успеха.
  
== ApplyRecipe(recipeId, userId) ==
+
== ApplyRecipe(recipeId, userId) == <!--T:47-->
 
Функция ApplyRecipe применяет рецепт с номером '''recipeId''' от имени пользователя с id = '''userId'''. Если у данного пользователя нет прав доступа к этому рецепту то рецепт применен не будет.
 
Функция ApplyRecipe применяет рецепт с номером '''recipeId''' от имени пользователя с id = '''userId'''. Если у данного пользователя нет прав доступа к этому рецепту то рецепт применен не будет.
 
Применение рецепта заключается в записи в регистры, которые указаны в рецепте, соответствующих значений.
 
Применение рецепта заключается в записи в регистры, которые указаны в рецепте, соответствующих значений.
  
  
== GetCurrentAlerts() ==
+
== GetCurrentAlerts() == <!--T:48-->
 
Функция GetCurrentAlerts возвращает список текущих аварий.  
 
Функция GetCurrentAlerts возвращает список текущих аварий.  
 
Возвращаемое значение — таблица. Ключем является номер аварии, значением — таблица со свойствами аварии.
 
Возвращаемое значение — таблица. Ключем является номер аварии, значением — таблица со свойствами аварии.
Строка 206: Строка 237:
 
</table>
 
</table>
  
 +
<!--T:49-->
 
Используя данную структуру, можно реализовать, например, различные сценарии оповещения о неподтвержденных авариях.
 
Используя данную структуру, можно реализовать, например, различные сценарии оповещения о неподтвержденных авариях.
  
 +
<!--T:50-->
 
Пример такой программы:
 
Пример такой программы:
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Строка 240: Строка 273:
  
  
== GetCurrentWeather() ==
+
== GetCurrentWeather() == <!--T:51-->
 
Функция GetCurrentWeather возвращает текущие метеоусловия в месте установки WebHMI.  
 
Функция GetCurrentWeather возвращает текущие метеоусловия в месте установки WebHMI.  
 
Данные обновляются примерно каждые два часа. Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.
 
Данные обновляются примерно каждые два часа. Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.
  
 +
<!--T:52-->
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
  
 +
<!--T:53-->
 
<p>Функция возвращает таблицу с такими полями:<br>
 
<p>Функция возвращает таблицу с такими полями:<br>
 
'''time''' — время, для которого был получены метеоданные <br>
 
'''time''' — время, для которого был получены метеоданные <br>
Строка 258: Строка 293:
 
'''snow''' — количество осадков (снег), в мм</p>
 
'''snow''' — количество осадков (снег), в мм</p>
  
== GetForecastWeather(interval) ==
+
== GetForecastWeather(interval) == <!--T:54-->
 
Функция GetForecastWeather возвращает прогноз погоды в месте установки WebHMI на указанный интервал.  
 
Функция GetForecastWeather возвращает прогноз погоды в месте установки WebHMI на указанный интервал.  
 
Данные обновляются примерно каждые два часа. Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.
 
Данные обновляются примерно каждые два часа. Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.
  
 +
<!--T:55-->
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
  
 +
<!--T:56-->
 
Интервал — это трехчасовой промежуток времени в будущем. От нуля до 6. Всего шесть интервалов. Нулевой интервал — это прогноз примерно через 3 часа. Первый интервал — прогноз через шесть часов. И т.д.  
 
Интервал — это трехчасовой промежуток времени в будущем. От нуля до 6. Всего шесть интервалов. Нулевой интервал — это прогноз примерно через 3 часа. Первый интервал — прогноз через шесть часов. И т.д.  
 
Формат возвращаемых данных идентичен функции GetCurrentWeather.
 
Формат возвращаемых данных идентичен функции GetCurrentWeather.
  
 +
<!--T:57-->
 
Пример простой программы, которая включает и выключает теплый пол перед входом в магазин в зависимости от погодных условий.
 
Пример простой программы, которая включает и выключает теплый пол перед входом в магазин в зависимости от погодных условий.
  
 +
<!--T:58-->
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
 
function main (userId)
 
function main (userId)
Строка 278: Строка 317:
 
     end
 
     end
  
     if (current.snow < 1 and nextForecast.snow < 1) then -- снег не идет
+
     <!--T:59-->
 +
if (current.snow < 1 and nextForecast.snow < 1) then -- снег не идет
 
         WriteReg(91, 0); -- выключить антилед
 
         WriteReg(91, 0); -- выключить антилед
 
     end
 
     end
  
     if (current.cloudness < 20 and nextForecast.cloudness < 20) then -- ясно
+
     <!--T:60-->
 +
if (current.cloudness < 20 and nextForecast.cloudness < 20) then -- ясно
 
         WriteReg(91, 0); -- выключить антилед
 
         WriteReg(91, 0); -- выключить антилед
 
     end
 
     end
  
     if (current.snow > 2 or nextForecast.snow > 2) then -- идет снег
+
     <!--T:61-->
 +
if (current.snow > 2 or nextForecast.snow > 2) then -- идет снег
 
         WriteReg(91, 1); -- включить антилед
 
         WriteReg(91, 1); -- включить антилед
 
     end
 
     end
Строка 292: Строка 334:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== GetSunriseTime(interval) ==
+
== GetSunriseTime(interval) == <!--T:62-->
 
Функция GetSunriseTime возвращает время в формате Unixtime восхода Солнца в текущих сутках.  
 
Функция GetSunriseTime возвращает время в формате Unixtime восхода Солнца в текущих сутках.  
  
 +
<!--T:63-->
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.
  
 +
<!--T:64-->
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
  
  
== GetSunsetTime(interval) ==
+
== GetSunsetTime(interval) == <!--T:65-->
 
Функция GetSunsetTime возвращает время в формате Unixtime заката Солнца в текущих сутках.  
 
Функция GetSunsetTime возвращает время в формате Unixtime заката Солнца в текущих сутках.  
  
 +
<!--T:66-->
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.
  
 +
<!--T:67-->
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
  
  
== GetMeterConsumption(variable_name[, connection_name]) ==
+
== GetMeterConsumption(variable_name[, connection_name]) == <!--T:68-->
 
Функция GetMeterConsumption возвращает расход ресурсов для указанного счетчика. Параметры '''variable_name''' и '''connection_name''' работают так же как и в функции GetReg – они опеределяют регистр со счетчиком ресурсов.
 
Функция GetMeterConsumption возвращает расход ресурсов для указанного счетчика. Параметры '''variable_name''' и '''connection_name''' работают так же как и в функции GetReg – они опеределяют регистр со счетчиком ресурсов.
  
 +
<!--T:69-->
 
Возвращаемый расход ресурсов – это расход счетчика за каждый час с начала месяца по текущий момент. Данные берутся с Level2 раз в час. Почему не из локальной БД? Потому что а) срок хранения данных на SD-карте может быть меньше 1 месяца и б) потому что возможны сбои SD-карты и если ее заменить посреди месяца, то данные будут недостоверны.
 
Возвращаемый расход ресурсов – это расход счетчика за каждый час с начала месяца по текущий момент. Данные берутся с Level2 раз в час. Почему не из локальной БД? Потому что а) срок хранения данных на SD-карте может быть меньше 1 месяца и б) потому что возможны сбои SD-карты и если ее заменить посреди месяца, то данные будут недостоверны.
  
 +
<!--T:70-->
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и активная услуга хранения данных. Функция доступна начиная с версии 2.9.
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и активная услуга хранения данных. Функция доступна начиная с версии 2.9.
  
 +
<!--T:71-->
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
  
  
== GetResourceLimit(resource_name) ==
+
== GetResourceLimit(resource_name) == <!--T:72-->
 
Функция GetResourceLimit возвращает лимит указанного ресурса на текущий месяц. Лимиты задаются в системе Level2.
 
Функция GetResourceLimit возвращает лимит указанного ресурса на текущий месяц. Лимиты задаются в системе Level2.
  
 +
<!--T:73-->
 
Допустимые имена ресурсов: "ELECTRICITY", "GAS", "HEAT", "WATER", "HOTWATER", "CUSTOM"
 
Допустимые имена ресурсов: "ELECTRICITY", "GAS", "HEAT", "WATER", "HOTWATER", "CUSTOM"
  
 +
<!--T:74-->
 
Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать лимиты из кеша. В кеше хранятся лимиты за текущий и два последующих месяца.
 
Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать лимиты из кеша. В кеше хранятся лимиты за текущий и два последующих месяца.
  
 +
<!--T:75-->
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.
  
 +
<!--T:76-->
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
  
  
== GetTodayDayType() ==
+
== GetTodayDayType() == <!--T:77-->
 
Функция GetTodayDayType возвращает тип текущего дня: рабочий, выходной, праздник. Типы дней задаются в системе Level2.
 
Функция GetTodayDayType возвращает тип текущего дня: рабочий, выходной, праздник. Типы дней задаются в системе Level2.
  
 +
<!--T:78-->
 
Доступны три типа: "Working", "Weekend", "Holiday".
 
Доступны три типа: "Working", "Weekend", "Holiday".
  
 +
<!--T:79-->
 
Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать данные из кеша. В кеше хранятся типы дней за текущий и два последующих месяца.
 
Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать данные из кеша. В кеше хранятся типы дней за текущий и два последующих месяца.
  
 +
<!--T:80-->
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.
  
 +
<!--T:81-->
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
  
== GetTomorrowDayType() ==
+
== GetTomorrowDayType() == <!--T:82-->
 
Функция GetTomorrowDayType полностью аналогична GetTodayDayType с той лишь разницей, что возвращает данные о завтрашнем дне.
 
Функция GetTomorrowDayType полностью аналогична GetTodayDayType с той лишь разницей, что возвращает данные о завтрашнем дне.
  
== GetHolidaysStats() ==
+
== GetHolidaysStats() == <!--T:83-->
 
Функция GetHolidaysStats возвращает таблицу с такими полями:
 
Функция GetHolidaysStats возвращает таблицу с такими полями:
 
   
 
   
Строка 354: Строка 411:
 
* '''nextMonthHolidays''' – количество праздничных дней (согласно настроек в системе Level2) в следующем месяце
 
* '''nextMonthHolidays''' – количество праздничных дней (согласно настроек в системе Level2) в следующем месяце
  
 +
<!--T:84-->
 
Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать данные из кеша. В кеше хранятся типы дней за текущий и два последующих месяца.
 
Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать данные из кеша. В кеше хранятся типы дней за текущий и два последующих месяца.
  
 +
<!--T:85-->
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.
 
Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.
  
 +
<!--T:86-->
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.
 
</translate>
 
</translate>

Версия 15:36, 12 октября 2017

О скриптах 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
  • SendEmailMessage
  • SendTelegramMessage
  • SendViberMessage
  • ERROR
  • INFO
  • DEBUG
  • TRACE
  • ApplyRecipe
  • GetCurrentAlerts
  • GetCurrentWeather
  • GetForecastWeather
  • GetSunriseTime
  • GetSunsetTime
  • GetTodayDayType
  • GetTomorrowDayType
  • GetHolidaysStats

Для удобства работы с регистрами из программ 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[, connection_name], new_value)

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

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

SendSMS(phone_number, message)

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

SendEmailMessage(emailAddress, subject, message)

Функция SendEmailMessage отправляет запрос на отправку e-mail по адресу emailAddress с темой письма subject и текстом message. Возвращает false если произошла ошибка и true в случае успеха. Успех не означает доставку сообщения, а только успех при создании запроса. Для работы этой функции необходимо наличие интернет-подключения, учетная запись в системе Level2 и положительного баланса в ней. Услуга платная.
Поле message может содержать html-код.

Пример:

function main (userId)
    SendEmailMessage("address@company.com", 
               "Авария охладителя. Низкий уровень масла.", 
                "<p style='color: red;'>Произошла ошибка охладителя #12</p><p>Низкий уровень масла.</p>");
end

Функция доступна начиная с версии WebHMI 2.7.4710

SendTelegramMessage(chatId, message)

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

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

Пример:

Chatid.png


SendViberMessage(chatId, message)

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

Для получения ChatId перейдите по ссылке http://viber.com/webhmi на мобильном телефоне (предварительно установив Viber), нажмите кнопку Have a look.
Viber-pa.png

Вы попадете в публичный аккаунт WebHMI. Перейдите в личные сообщения публичного аккаунта нажав кнопку справа вверху.
Viber-private-message.png

Напишите любой текст в чате. В ответ вы получите сообщение с уникальным идентификатором чата ChatId.
Viber-chat-id.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. Если у данного пользователя нет прав доступа к этому рецепту то рецепт применен не будет. Применение рецепта заключается в записи в регистры, которые указаны в рецепте, соответствующих значений.


GetCurrentAlerts()

Функция GetCurrentAlerts возвращает список текущих аварий. Возвращаемое значение — таблица. Ключем является номер аварии, значением — таблица со свойствами аварии. Свойства аварии:

СвойствоОписаниеТип данных
startTimeВремя возникновения аварииNumber, UnixTime
regIdНомер регистра, в котором флаг аварии привел к этой аварииNumber
regAliasИмя переменной регистра для программString
bitНомер бита с флагом аварииNumber
titleНазвание аварииString
connectionTitleНазвание соединенияString
connectionIdID соединенияNumber
connectionAliasИмя переменной соединения для программString
acknowledgedByИмя пользователя, который подтвердил аварию. Если авария не подтверждена — пустая строка.String
acknowledgedTimeВремя, когда авария был подтверждена. Если авария не подтверждена — 0.Number, UnixTime
canBeAcknowledgedФлаг, обозначающий что данную аварию можно подтверждать.Boolean

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

Пример такой программы:

local notificationsSent = {};
function main (userId)
    local alerts = GetCurrentAlerts();
    if (#alerts > 0) then
        for num,alert in pairs(alerts) do 
            local now = os.time();
            local canBeAcknowledged = alert['canBeAcknowledged'];
            local acknowledgedTime = alert['acknowledgedTime'];
            local startTime = alert['startTime'];
            local waitSecondsBeforeEscalate = 300; -- оповещать об авариях, которые неподтвержены более 5 минут
            local regId = alert['regId'];
            local bit = alert['bit'];
            if (canBeAcknowledged and acknowledgedTime == 0) then
                if (now - startTime > waitSecondsBeforeEscalate) then
                    if (notificationsSent[regId] == nil or notificationsSent[regId][bit] ~= startTime) then
                        --ERROR("Alert" .. alert['title'] .. " was not acknowledged!");
                        SendSMS("380501234567", "Не подтведжена авария: " .. alert['title']);
                        if (notificationsSent[regId] == nil) then
                            notificationsSent[regId] = {};
                        end
                        notificationsSent[regId][bit] = startTime;
                    end
                end
            end
        end
    end
end


GetCurrentWeather()

Функция GetCurrentWeather возвращает текущие метеоусловия в месте установки WebHMI. Данные обновляются примерно каждые два часа. Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.

Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.

Функция возвращает таблицу с такими полями:
time — время, для которого был получены метеоданные
text — краткое текстовое описание текущей погоды
temperature — температура воздуха в градусах Цельсия
pressure — атмосферное давление в hPa
humidity — относительная влажность воздуха в %
windDirection — навравление, откуда дует ветер. метрологические градусы (сервер — 0 градусов)
windSpeed — скокрость ветра в м/c
cloudness — покрытие неба облаками в процентах
rain — количество осадков (дождь), в мм
snow — количество осадков (снег), в мм

GetForecastWeather(interval)

Функция GetForecastWeather возвращает прогноз погоды в месте установки WebHMI на указанный интервал. Данные обновляются примерно каждые два часа. Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.

Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.

Интервал — это трехчасовой промежуток времени в будущем. От нуля до 6. Всего шесть интервалов. Нулевой интервал — это прогноз примерно через 3 часа. Первый интервал — прогноз через шесть часов. И т.д. Формат возвращаемых данных идентичен функции GetCurrentWeather.

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

function main (userId)
    local current = GetCurrentWeather();
    local nextForecast = GetForecastWeather(0);
    
    if (nextForecast.temperature > 6 and current.temperature > 6) then -- положительная температура
        WriteReg(91, 0); -- выключить антилед
    end

    if (current.snow < 1 and nextForecast.snow < 1) then -- снег не идет
        WriteReg(91, 0); -- выключить антилед
    end

    if (current.cloudness < 20 and nextForecast.cloudness < 20) then -- ясно
        WriteReg(91, 0); -- выключить антилед
    end

    if (current.snow > 2 or nextForecast.snow > 2) then -- идет снег
        WriteReg(91, 1); -- включить антилед
    end
end

GetSunriseTime(interval)

Функция GetSunriseTime возвращает время в формате Unixtime восхода Солнца в текущих сутках.

Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.

Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.


GetSunsetTime(interval)

Функция GetSunsetTime возвращает время в формате Unixtime заката Солнца в текущих сутках.

Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и подписка на метеопрогноз. Функция доступна начиная с версии 2.5.2400.

Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.


GetMeterConsumption(variable_name[, connection_name])

Функция GetMeterConsumption возвращает расход ресурсов для указанного счетчика. Параметры variable_name и connection_name работают так же как и в функции GetReg – они опеределяют регистр со счетчиком ресурсов.

Возвращаемый расход ресурсов – это расход счетчика за каждый час с начала месяца по текущий момент. Данные берутся с Level2 раз в час. Почему не из локальной БД? Потому что а) срок хранения данных на SD-карте может быть меньше 1 месяца и б) потому что возможны сбои SD-карты и если ее заменить посреди месяца, то данные будут недостоверны.

Для работы сервиса требуется интернет-подключение, учетная запись в Level2 и активная услуга хранения данных. Функция доступна начиная с версии 2.9.

Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.


GetResourceLimit(resource_name)

Функция GetResourceLimit возвращает лимит указанного ресурса на текущий месяц. Лимиты задаются в системе Level2.

Допустимые имена ресурсов: "ELECTRICITY", "GAS", "HEAT", "WATER", "HOTWATER", "CUSTOM"

Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать лимиты из кеша. В кеше хранятся лимиты за текущий и два последующих месяца.

Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.

Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.


GetTodayDayType()

Функция GetTodayDayType возвращает тип текущего дня: рабочий, выходной, праздник. Типы дней задаются в системе Level2.

Доступны три типа: "Working", "Weekend", "Holiday".

Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать данные из кеша. В кеше хранятся типы дней за текущий и два последующих месяца.

Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.

Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.

GetTomorrowDayType()

Функция GetTomorrowDayType полностью аналогична GetTodayDayType с той лишь разницей, что возвращает данные о завтрашнем дне.

GetHolidaysStats()

Функция GetHolidaysStats возвращает таблицу с такими полями:

  • currentMonthDays – количество дней в текущем месяце
  • nextMonthDays – количество дней в следующем месяце
  • currentMonthWeekends – количество выходных дней (согласно настроек в системе Level2) в текущем месяце
  • nextMonthWeekends – количество выходных дней (согласно настроек в системе Level2) в следующем месяце
  • currentMonthHolidays – количество праздничных дней (согласно настроек в системе Level2) в текущем месяце
  • nextMonthHolidays – количество праздничных дней (согласно настроек в системе Level2) в следующем месяце

Данные берутся с Level2. Данные на WebHMI обновляются обычно не позже чем через 1 час после обновления их в Level2. При отсутствии связи, система будет возвращать данные из кеша. В кеше хранятся типы дней за текущий и два последующих месяца.

Для работы сервиса требуется интернет-подключение, учетная запись в Level2. Функция доступна начиная с версии 2.9.

Если по каким-либо причинам данные не были получены, то будет возвращено значение nil.