Время наработки тега
Рассмотрим пример добавления пользовательской библиотеки. Для этого поместим модуль, написанный на языке Lua, в рабочий каталог программы.
Например, для решения задачи подсчета времени наработки агрегата в системе требуется создать скрипт с именем motoHours.lua, а затем разместить его в специально созданном каталоге для пользовательских библиотек, например, с именем lib. Данный каталог должен быть расположен по пути: C:\Users\Public\Documents\SimpLight_5.0\scripts\sdk.
motoHours.lua
local async = require("async")
local tagApi = require("simplight.api.channels")
local time = require("time")
local promise = require("promise")
local function timeSince(t)
local elapsedTime = time.now() - t
return elapsedTime
end
local function localStorage_getNumberDef(key, default)
local v = localStorage:getItem(key, default)
if v == nil then
return default
end
return tonumber(v)
end
local function composeLabel(tagName)
return string.format('$simplight.motoHours.%s.totalWorkTime', tagName)
end
local M = {}
local watchByTagNameMap = {}
local function checkTag(tagName, tagValue)
local watch = watchByTagNameMap[tagName]
if watch == nil or watch.isCalcing then
return promise.resolve(true)
end
return async(function()
watch.isCalcing = true
local label = composeLabel(watch.watchTagName)
local totalWorkTime = localStorage_getNumberDef(label, 0)
local v = watch.valueGetter(tagValue)
if v == 1 or v == true then
if not watch.isRun then
watch.lastUpdateTime = time.now()
watch.isRun = true
end
totalWorkTime = totalWorkTime + timeSince(watch.lastUpdateTime)
watch.lastUpdateTime = time.now()
else
if watch.isRun then
totalWorkTime = totalWorkTime + timeSince(watch.lastUpdateTime)
watch.lastUpdateTime = 0
watch.isRun = false
end
end
if watch.resetTagName ~= '' then
local resetTag = await(tagApi.read(watch.resetTagName))
if resetTag.value then
totalWorkTime = 0
watch.lastUpdateTime = 0
watch.isRun = false
await(tagApi.write(watch.resetTagName, 0, 0xC0))
end
end
watch.totalWorkTime = totalWorkTime
localStorage:setItem(label, totalWorkTime)
end):catch(function(err)
print("MotoHours.checkTag:", err)
end):finally(function()
watch.isCalcing = false
end)
end
function M.watch(options)
local watchTagName = options.watchTagName
if type(watchTagName) ~= "string" then
error("motoHours.watch: watchTagName must be string")
end
local label = composeLabel(watchTagName)
local totalWorkTime = localStorage_getNumberDef(label, 0)
local lWatch = {
lastUpdateTime = 0,
isRun = false,
resetTagName = options.resetTagName,
valueGetter = options.valueGetter,
totalWorkTime = totalWorkTime,
watchTagName = watchTagName,
}
if valueGetter == nil then
lWatch.valueGetter = function(srcValue)
return srcValue
end
end
watchByTagNameMap[watchTagName] = lWatch
local intervalId = setInterval(function()
async(function()
local tag = await(tagApi.read(watchTagName))
await(checkTag(tag.name, tag.value))
end):catch(function(err)
print("motoHours.watch: interval:", err)
end)
end, 10000)
return {
cancel = function()
clearInterval(intervalId)
watchByTagNameMap[watchTagName] = nil
end,
getTotalWorkTime = function()
return lWatch.totalWorkTime or 0
end
}
end
return M
Чтобы подключить данный модуль в скрипте требуется оформить вызов:
Пример:
Необходимо выводить сообщение с временем наработки тега waterPump в служебных сообщениях сервера каждые 10 секунд.
getWorkTime.lua
local async = require("async")
local motoHours = require("lib.motoHours")
local watch = motoHours.watch({
watchTagName = "waterPump",
resetTagName = "resetHours",
})
setInterval(function()
local t = watch.getTotalWorkTime() / 1000
print(string.format("Время наработки тега: %d сек", t))
end, 10 * 1000)