User Tools

Site Tools


scripts

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
scripts [2019/01/09 10:13] akuzmukscripts [2019/01/09 10:37] (current) – removed akuzmuk
Line 1: Line 1:
- 
-===== Libraries ===== 
-Since version 3.2 you can create your own libraries. These are special scripts that can be included from other scripts so you can share the same code across multiple scripts. Use special keyword **include** to include another script. Provide script title as parameter to include call. Here is example: 
- 
-<code lua>  
-include "common.lua" 
-function main(userId) 
-  myCommonFunction(); 
-end 
-</code> 
- 
-Best practice it is to put include outside any function calls. Please note that global variables in libraries will not be shared across all scripts. Only code will be shared. 
- 
-===== Data-related functions ===== 
- 
-==== GetReg(variable_name[, connection_name]) ==== 
-The GetReg function returns the current value of the specified register. 
- 
-Before version 3.2 following notation was used: 
- 
-The variable name **variable_name** where **variable_name** is the value of **Script alias** from the register's settings. Instead of variable_name you can specify a number - the register ID. However, the register ID is a less obvious way and it complicates the reading of the program. 
- 
-The optional parameter **connection_name** can be specified if in several different connections there are registers with the same **variable_name**. In this case, connection_name indicates from which particular connection it is necessary to read the register named variable_name. Also, instead of the string connection_name, you can specify the connection ID. However, again, constants complicate the reading of the code and it is preferable to use named lines. 
- 
-Since version 3.2 new enhanced notation used: 
- 
-There is no **connection_name** parameter anymore. **variable_name** is the only parameter. It can be in one of 3 following formats: 
-  - number with register Id. Not recommended to use because it is hard to read code with hardcoded numbers. Example: GetReg(12) 
-  - string with script alias of register. Example: GetReg("speed") 
-  - string in format "connection_alias.register_alias" where first part is connection alias and second part is register alias. Example: GetReg("mixer.speed"); In this example value or "speed" register from "mixer" connection will be fetched. 
- 
-If the register was not found or was not read, then the value **nil** is returned. 
- 
-For the convenience of selecting registers for GetReg, there is a special button in toolbar (4). 
- 
-{{ :get_reg_button.png?direct&300 |}} 
- 
-When you click on any of them, a pop-up window appears with a list of registers. 
- 
-{{ :select_register_dialog.png?direct&800 |}} 
- 
-After clicking on the register of interest, the editor will insert the code with the identifier of the selected register (variable_name if exists or ID) and a comment with the register name, its address and the connection name. 
- 
-{{ :reg_inserted_after_getreg.png?600 |}} 
- 
----- 
-==== GetRegStatus(variable_name) ==== 
-The GetRegStatus function returns the status of specified register. Function works exactly like function **GetReg**. 
- 
-On success function will return one of the following states: 
-  * unknown 
-  * disabled 
-  * normal 
-  * warning 
-  * alert 
- 
----- 
-==== GetRegFromLog(variable_name, query_parameters) ==== 
- 
-The GetRegFromLog function fetches data from register log. **varialbe_name** is an identified of register (see GetReg function for details). **query_parameters** is a table with up to 4 parameters: 
-   * from (unixtime, required) 
-   * to (unixtime, required) 
-   * order ("ASC" or "DECS, ASC is default) 
-   * limit (integer number between 1 and 5000, 1000 is default) 
- 
-Using these parameters WebHMI will construct query like: 
-SELECT * FROM log WHERE reg = //regId// AND datetime >= //from// AND datetime <= //to// ORDER by //order// LIMIT //limit// 
- 
-On success function will return table with register records from log database. Each row is a table with following records: 
-  * state (unknown, disabled, normal, warning, alert) 
-  * regid (integer) 
-  * time (unixtime) 
-  * value (string) 
- 
-Example: 
- 
-<code lua> 
-function tprint (tbl, indent) 
-  if not indent then indent = 0 end 
-  for k, v in pairs(tbl) do 
-    formatting = string.rep("  ", indent) .. k .. ": " 
-    if type(v) == "table" then 
-      ERROR(formatting) 
-      tprint(v, indent+1) 
-    else 
-      ERROR(formatting .. v)  
-    end 
-  end 
-end 
- 
-function main (userId) 
-    now = os.time(); 
-     
-    data = GetRegFromLog("myconn.myreg", {from = now-3600, to = now, order = "desc", limit = 10}); 
- 
-    tprint(data); 
-end 
-</code> 
- 
-Output: 
-<code> 
-Sep 13 17:37:25.098: ERROR: LUA scripts: 0:  
-Sep 13 17:37:25.098: ERROR: LUA scripts:   state: disabled 
-Sep 13 17:37:25.098: ERROR: LUA scripts:   regid: 1 
-Sep 13 17:37:25.098: ERROR: LUA scripts:   time: 1536849431 
-Sep 13 17:37:25.098: ERROR: LUA scripts:   value: 1 
-Sep 13 17:37:25.598: ERROR: LUA scripts: 1:  
-Sep 13 17:37:25.598: ERROR: LUA scripts:   state: disabled 
-Sep 13 17:37:25.598: ERROR: LUA scripts:   regid: 1 
-Sep 13 17:37:25.598: ERROR: LUA scripts:   time: 1536849410 
-Sep 13 17:37:25.598: ERROR: LUA scripts:   value: 0 
-</code> 
- 
----- 
-==== SetReg(variable_name[,connection_name], new_value) ==== 
-The SetReg function sets the current value of the register with the name of the variable **variable_name** to **new_value** for the current scan. This function **DOES NOT** send new value to external devices. When polling this register in subsequent cycles, the old value will be read.  
- 
-Function returns 1 if an error occurred and 0 on success. 
- 
-The parameters **variable_name** and **connection_name** work just like in the GetReg function. Since version 3.2 there is no more **connection_name** parameter. 
- 
----- 
-==== WriteReg(variable_name[, connection_name], new_value) ==== 
-The WriteReg function sets the current value of the register with the name of the variable **variable_name** (optionally you can specify the connection **connection_name**) to provided **new_value** for the current scan and writes this value to the external device in the beginning of the next cycle. When polling this register in subsequent scans, a new value will be read (if it was not changed by the device itself).  
- 
-Function returns 1 if any error occurred and 0 on success. 
- 
-The parameters **variable_name** and **connection_name** work just like in the GetReg function. Since version 3.2 there is no more **connection_name** parameter. 
- 
----- 
-==== ApplyRecipe(recipeId, userId) ==== 
-The **ApplyRecipe** function applies the recipe with the number **recipeId** on behalf of the user with id = **userId**. If this user does not have permissions for this recipe, the recipe will not be applied.  
- 
-The application of the recipe is to write the corresponding values to the registers that are specified in the recipe. 
- 
-==== GetRecipeById(recipeId) ==== 
-The **GetRecipeById** function gets the recipe with the number **recipeId**. Function is available since WebHMI v 3.2. 
- 
-On success table with following fields will be returned: 
-  * id - Recipe Id 
-  * title - Recipe title 
-  * registers - table with Register Id as key and new value as value 
- 
-On error (recipe not found, etc) false will be returned. 
- 
----- 
-==== GetCurrentAlerts() ==== 
- 
-The **GetCurrentAlerts** function returns a list of current alerts. Type of returned value is table. Its key is the alarm number, the value is the another table with the alert properties.  
- 
-Alert properties are: 
- 
-^Key ^Description                                                       ^Data type^                                           
-|startTime |Alert trigger time | Number, UnixTime| 
-|regId |The number of the register in which the flag of the alert led to this alert   |Number   | 
-|regAlias |Variable name for programs |String| 
-|bit |Number of the bit with the alarm flag |Number| 
-|title |Alert name |String| 
-|connectionTitle |Connection name |String| 
-|connectionId |Connection ID |Number| 
-|connectionAlias |The name of the connection variable for programs|String| 
-|acknowledgedBy| User name, who confirmed the alert. If the alert is not confirmed - empty string.|String| 
-|acknowledgedTime |Time, when the alert was confiremed. If the alert is not confirmed - 0.|Number, UnixTime| 
-|canBeAcknowledged |The flag indicates the alert can be confirmed. |Boolean| 
- 
-Using this structure, it is possible to implement, for example, various notification scenarios about unconfirmed accidents. 
- 
-An example of such program: 
-<code lua> 
-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; -- notify about alerts that are not confirmed for more than 5 minutes 
-            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", "The alert is not confirmed: " .. alert['title']); 
-                        if (notificationsSent[regId] == nil) then 
-                            notificationsSent[regId] = {}; 
-                        end 
-                        notificationsSent[regId][bit] = startTime; 
-                    end 
-                end 
-            end 
-        end 
-    end 
-end 
-</code> 
- 
-===== Writing to communication log ===== 
- 
-==== ERROR(message) ==== 
- 
-The function adds the **message** with the ERROR level to communication log (**Maintenance -> WebHMI Log**). Function returns 1 if any error occurred and 0 on success. 
- 
----- 
-==== INFO(message) ==== 
- 
-The function adds the **message** with the INFO level to communication log (**Maintenance -> WebHMI Log**). Function returns 1 if any error occurred and 0 on success. 
- 
----- 
-==== DEBUG(message) ==== 
- 
-The function adds the **message** with the DEBUG level to communication log (**Maintenance -> WebHMI Log**). Function returns 1 if any error occurred and 0 on success. 
- 
----- 
-==== TRACE(message) ==== 
- 
-The function adds the **message** with the TRACE level to communication log (**Maintenance -> WebHMI Log**). Function returns 1 if any error occurred and 0 on success. 
- 
-===== Writing to message log ===== 
- 
-==== AddInfoMessage(message, userId)==== 
-The AddInfoMessage function adds the message **message** with the Info level to the Messages log. **userId** is the user ID on whose behalf the message should be added. Returns 1 if an error occurred and 0 if successful. 
- 
-**AddWarningMessage** and **AddAlertMessage** - are full analogs of AddInfoMessage, writing to Warning and Alert message levels respectively.  
- 
-===== Notification functions ===== 
- 
-==== SendSMS(phone_number, message) ==== 
-The SendSMS function sends a request to send an SMS to the number **phone_number** with the text **message**. Returns false if an error occurred and true if successful. Success does not mean delivering a message, but only success when creating a query. This function requires an Internet connection, an account in [[http://docs.webhmi.com.ua/introduction_to_level2 | Level2]] system and a positive balance in it. The service is paid. 
- 
-Format of **phone_number** - only digits with the country code, without spaces, brackets, plus sign. For example, "380123456789". 
- 
-==== SendEmailMessage(emailAddress, subject, message) ==== 
- 
-The SendEmailMessage function sends a request to send an e-mail to **emailAddress** with the subject of the letter **subject** and the text **message**. Returns false if an error occurred and true if successful. Success does not mean delivering a message, but only success when creating a query. This function requires an Internet connection, an account in [[http://docs.webhmi.com.ua/introduction_to_level2 | Level2]] system and a positive balance in it. The service is paid. 
- 
-The field **message** can contain the html-code. 
- 
-Example: 
-<code lua> 
-function main (userId) 
-    SendEmailMessage("address@company.com",  
-               "Cooler malfunction. Low oil level.",  
-                "<p style='color: red;'>Cooler error #12 has occurred.</p><p>Низкий уровень масла.</p>"); 
-end 
-</code> 
- 
-The function is available since WebHMI 2.7.4710 version. 
- 
-==== SendTelegramMessage(chatId, message) ==== 
-The SendTelegramMessage function sends a message with the text **message** to the chat with Id = **chatId**. Returns 1 if an error occurred and 0 if successful. Success does not mean delivering a message, but only success when creating a query. To use this function, you must have an Internet connection, an account in the [[Introduction to Level2 | Level2]] system. The service is free. 
-To get ChatId, go to [[http://telegram.me/webhmibot]] on your mobile phone (by pre-installing Telegram) and start the dialog with bot webhmibot using the /start command. In response you will receive a message with a unique chatId. 
- 
-Example: 
- 
-{{ :telegram_screenshot.png?direct&400 |}} 
- 
-==== SendViberMessage(chatId, message) ==== 
-The SendViberMessage function sends a message with the text 'message' to the chat with Id = **chatId**. Returns 1 if an error occurred and 0 if successful.  
-Success does not mean delivering a message, but only success when creating a query. To use this function, you must have a working Internet connection, an account in the system [[Introduction to Level2 | Level2]] and a positive balance in this system. The service is chargeable. This feature is available starting with firmware version 2.4.4227.  
-To get ChatId, go to [[http://viber.com/webhmi]] on your mobile phone (having previously installed Viber), click 'Have a look' button. 
- 
-{{ :viber_1.png?direct&400 |}} 
- 
-You will be taken to the public WebHMI account. Go to the personal messages of the public account by clicking the button at the top right. 
- 
-{{ :viber_2.png?direct&400 |}} 
- 
-Write any text in the chat. In response you will receive a message with a unique chatId chat ID. 
- 
-{{ :viber_3.png?direct&400 |}} 
- 
-===== Weather and resource monitoring ===== 
- 
- 
-==== GetForecastWeather(interval) ==== 
- 
-The GetForecastWeather function returns the weather forecast at the WebHMI installation location to the specified interval. The data is updated approximately every two hours. The service requires an Internet connection, an account in Level2 and a subscription to the weather forecast. The function is available since version 2.5.2400. 
- 
-If for some reason the data has not been received, the value nil will be returned. 
- 
-The interval is a three-hour time interval in the future. From zero to 6. Total six intervals. Zero interval is the forecast in about 3 hours. The first interval is the forecast in six hours. Etc. The format of the returned data is identical to the function GetCurrentWeather. 
- 
-An example of a simple program that turns on and off the warm floor before entering the store, depending on the weather conditions. 
-<code lua> 
-function main (userId) 
-    local current = GetCurrentWeather(); 
-    local nextForecast = GetForecastWeather(0); 
-     
-    if (nextForecast.temperature > 6 and current.temperature > 6) then -- positive temperature 
-        WriteReg(91, 0); -- turn anti-ice off  
-    end 
- 
-    if (current.snow < 1 and nextForecast.snow < 1) then -- not snowing  
-        WriteReg(91, 0); -- turn anti-ice off 
-    end 
- 
-    if (current.cloudness < 20 and nextForecast.cloudness < 20) then -- clear 
-        WriteReg(91, 0); -- turn anti-ice 
-    end 
- 
-    if (current.snow > 2 or nextForecast.snow > 2) then -- it's snowing 
-        WriteReg(91, 1); -- turn anti-ice on 
-    end 
-end 
-</code> 
- 
-==== GetSunriseTime(interval) ==== 
-The function GetSunriseTime returns the time in the format Unixtime of the sunrise in the current day. 
-The service requires an Internet connection, an account in Level2 and a subscription to the weather forecast. The function is available since version 2.5.2400. 
-If for some reason the data has not been received, the value nil will be returned. 
- 
-==== GetSunsetTime(interval) ==== 
-The function GetSunsetTime returns the time in Unixtime format of sunset in the current day. 
-The service requires an Internet connection, an account in Level2 and a subscription to the weather forecast. The function is available since version 2.5.2400. 
-If for some reason the data has not been received, the value nil will be returned. 
- 
-==== GetMeterConsumption(variable_name[, connection_name]) ==== 
-The GetMeterConsumption function returns the resource consumption for the specified counter. Parameters **variable_name** and //connection_name// work in the same way as in the function GetReg - they determine the register with the resource counter. Since version 3.2 there is no more **connection_name** parameter. 
- 
-Returned consumption of resources is the consumption of the meter for each hour from the beginning of the month to the current moment. Data is taken from Level2 times per hour. Why not from the local database? Because a) the data storage period on the SD card can be less than 1 month and b) because the SD card may fail and if it is replaced in the middle of the month, the data will be unreliable. 
- 
-The service requires an Internet connection, an account in Level2, and an active data storage service. The function is available since version 2.9. 
- 
-If for some reason the data has not been received, the value nil will be returned. 
- 
-==== GetResourceLimit(resource_name) ==== 
- 
-The GetResourceLimit function returns the limit of the specified resource for the current month. Limits are set in the Level2 system. 
- 
-Possible resources names are: "ELECTRICITY", "GAS", "HEAT", "WATER", "HOTWATER", "CUSTOM" 
- 
-Data is taken from Level2. Data on WebHMI is usually updated no later than 1 hour after they are updated in Level2. If there is no connection, the system will return the limits from the cache. The cache stores the limits for the current and the next two months. 
- 
-The service requires an Internet connection, an account in Level2. The function is available since version 2.9. 
- 
-If for some reason the data has not been received, the value nil will be returned. 
- 
-==== GetTodayDayType() ==== 
- 
-The GetTodayDayType function returns the type of the current day: work, holiday, holiday. The types of days are set in the Level2 system. 
- 
-Three types are valid: "Working", "Weekend", "Holiday". 
- 
-Data is taken from Level2. Data on WebHMI is usually updated no later than 1 hour after they are updated in Level2. If there is no connection, the system will return the limits from the cache. The cache stores the limits for the current and the next two months. 
- 
-The service requires an Internet connection, an account in Level2. The function is available since version 2.9. 
- 
-If for some reason the data has not been received, the value nil will be returned. 
- 
-==== GetTomorrowDayType() ==== 
- 
-The GetTomorrowDayType function is completely analogous to GetTodayDayType with the only difference that it returns data about the future. 
- 
-==== GetHolidaysStats() ==== 
- 
-GetHolidaysStats returns a table with the following fields: 
- 
-  ***currentMonthDays** – number of days in the current month 
-  ***nextMonthDays** - number of days in the next month 
-  ***currentMonthWeekends** - the number of dayoffs (according to the settings in the Level2 system) in the current month 
-  ***nextMonthWeekends** - the number of dayoffs (according to the settings in the Level2 system) in the next month 
-  ***currentMonthHolidays** - number of holidays (according to the settings in the Level2 system) in the current month 
-  ***nextMonthHolidays** - number of holidays (according to the settings in the Level2 system) in the next month 
- 
-Data is taken from Level2. Data on WebHMI is usually updated no later than 1 hour after they are updated in Level2. If there is no connection, the system will return the limits from the cache. The cache stores the limits for the current and the next two months. 
- 
-The service requires an Internet connection, an account in Level2. The function is available since version 2.9. 
- 
-If for some reason the data has not been received, the value nil will be returned. 
- 
-===== Connection control ===== 
- 
-==== GetConnectionAddress (connection) ==== 
-The GetConnectionAddress function returns the current address of the device with which it is communicating. The function is available since version 3.0. 
- 
-The //connection// parameter specifies which connection to take the address from: 
-  *connection ID  
-  *Lua variable name 
-<code> 
-  Please note that numerical constants like ID numbers complicate the reading of the code and it is preferable to  
-  use named lines. 
-</code> 
- 
-If no connection is found, nil is returned. 
- 
-For connections connected via RS-485, the address is a number. GetConnectionAddress will return values ​​of type number. 
- 
-For TCP and UDP connections, the address is its IP address or host name. GetConnectionAddress will return values ​​of type string. 
- 
-==== SetConnectionAddress (connection, new_address) ==== 
-The SetConnectionAddress function replaces the current address of the device being communicated with a new one. The function is available since version 3.0. SetConnectionAddress is designed to work in projects with hot backup controllers and allows you to read registers from a particular (active, working) PLC. 
- 
-The //connection// parameter specifies for which connection the address should be replaced: 
-  *connection ID  
-  *Lua variable name  
- 
-If no connection is found, nil is returned. If the address was changed successfully, the function returns true. If you try to replace the address in internal register connection, the function returns false. 
- 
-For connections connected via RS-485, the address is a number. SetConnectionAddress expects the value of new_address to be of type number. 
- 
-For TCP and UDP connections, the address is its IP address or host name. SetConnectionAddress expects the values ​​of new_address to be of type string. 
- 
-==== GetConnectionUnitId (mb_connection) ==== 
-The GetConnectionUnitId function returns the current Unit Id of the specified Modbus TCP connection. The function is available since version 3.1. 
- 
-The //mb_connection// parameter is the Modbus connectoin ID or its Lua name.  
- 
-If no connection was found, nil will be returned. 
- 
-Unit Id is a number (0 .. 255). GetConnectionUnitId will return values ​​of type number. 
- 
-==== SetConnectionUnitId(mb_connection, new_unit_id) ==== 
-The SetConnectionUnitId function replaces the current Unit Id in provided Modbus TCP connection. The function is available since version 3.1. SetConnectionUnitId is designed to work in projects with hot backup controllers and allows you to read registers from a particular (active, working) PLC. 
- 
-  * mb_connection - Modbus TCP connection ID or its Lua name.   
- 
-If no connection is found, nil is returned. If the unit id was changed successfully, the function returns true. If you try to replace the address in internal register connection, the function returns false. 
- 
-Unit Id is a number (0 .. 255). SetConnectionUnitId expects the value of new_unit_id to be of type number. 
- 
-==== EnableConnection (connection) ==== 
-EnableConnection turns on polling registers "on-the-fly" in the specified connection. The function is available since version 3.0. In the project configuration, the checkbox 'Disconnect' for the specified connection does not change. 
- 
-  *connection - ID or Lua name  
- 
-==== DisableConnection(connection) ==== 
-DisableConnection disables polling registers "on the fly" in the specified connection. The function is available since version 3.0. In the project configuration, the checkbox 'Disconnect' for the specified connection does not change. 
- 
-  *connection - ID or Lua name  
- 
-==== IsConnectionEnabled(connection) ==== 
- 
-The IsConnectionEnabled function tells whether the polling of registers in the specified connection is enabled. The function is available since version 3.0. 
- 
-  *connection - ID or Lua name for the connection to be enabled.  
- 
-==== GetConnectionErrors(connection) ==== 
- 
-The GetConnectionErrors function reports whether there were errors while reading the registers in the last scan in the specified connection. The function is available since version 3.0. 
- 
-  *connectoin - ID of Lua name of the connection being checked 
- 
-If there were no errors, then the function returns zero. If there were errors, then the ID of the last register is returned, which was not read. 
- 
- 
-==== GetConnectionScanTime(connection) ==== 
- 
-The GetConnectionScanTime function returns the time taken to poll the registers in the last scan in the specified connection. The function is available since version 3.0. 
- 
-  *connectoin - ID or Lua variable name 
- 
-The function returns the time in milliseconds. 
- 
- 
-==== GetConnectionErrorScans(connection) ==== 
- 
-The GetConnectionErrorScans function returns the number of consecutive scans in which there were errors reading the registers in the specified connection. The function is available since version 3.0. 
- 
-  *connection - ID or Lua variable name  
- 
-The function returns the number of scans in which read errors occurred. If in any scan there were no read errors in this connection, the counter is reset to zero. 
- 
-===== Status ===== 
- 
-==== IsInternetConnectionAlive ==== 
-The IsInternetConnectionAlive function returns 1 when Internet connection is active and working. Otherwise it returns 0. The function is available since version 3.2. 
- 
-==== IsVPNConnectionAlive ==== 
-The IsVPNConnectionAlive function returns 1 when VPN connection is active and working. Otherwise it returns 0. The function is available since version 3.2. 
  
scripts.1547028813.txt.gz · Last modified: 2019/01/09 10:13 by akuzmuk

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki