17.11.2018, 23:19
Hello everyone,
In the past we used to make our light group feedbacks via event scripts tagged to specific group, but recently I found this script, which makes this job a bit easier:
Problem is, that this script works for awhile, but if many groups are starting to send feedbacks it kind of "crashes" because it stops sending feedbacks and to overcome this you have to disable/enable script to make it work again, why does this happen and is there a fix to it? I could of course use some kind of method to automatically disable/enable script once in awhile but I dont think this is a good practice and effective way of doing it. Maybe someone have ideas or had this problem before?
Thanks in advance.
In the past we used to make our light group feedbacks via event scripts tagged to specific group, but recently I found this script, which makes this job a bit easier:
Code:
if not client then
-- each group has 3 fields:
-- tag - status object tag
-- output - status output object
-- mode - calculate mode (and/or/avg)
groups = {
}
-- time to wait between last telegram from any status in group and update
updatedelay = 1
-- object value cache
values = {}
-- object datatype cache
datatypes = {}
-- send update only when value changes
grp.checkupdate = function(alias, value)
if values[ alias ] ~= value then
grp.write(alias, value)
end
end
calc = {}
-- AVERAGE value
calc['avg'] = function(group)
local result, count, value = 0, 0
for _, address in ipairs(group.objects) do
value = values[ address ]
-- number must be in [0..100] range
if type(value) == 'number' then
result = result + value
count = count + 1
-- boolean true is 100%, false is 0%
elseif type(value) == 'boolean' then
if toboolean(value) then
result = result + 100
end
count = count + 1
end
end
if count > 0 then
result = math.floor(result / count + 0.5)
grp.checkupdate(group.output, result)
end
end
-- AND gate
calc['and'] = function(group)
local result = true
for _, address in ipairs(group.objects) do
result = result and toboolean(values[ address ])
end
grp.checkupdate(group.output, result)
end
-- OR gate
calc['or'] = function(group)
local result = false
for _, address in ipairs(group.objects) do
result = result or toboolean(values[ address ])
end
grp.checkupdate(group.output, result)
end
-- prepare each group
for _, group in ipairs(groups) do
object = grp.find(group.output)
-- cache output status object value and datatype
values[ object.address ] = object.data
datatypes[ object.address ] = object.datatype
group.output = object.address
-- group input status object list
group.objects = {}
-- find all status objects and cache values and datatypes
objects = grp.tag(group.tag)
for _, object in ipairs(objects) do
values[ object.address ] = object.data
datatypes[ object.address ] = object.datatype
table.insert(group.objects, object.address)
end
-- force update on first run
group.timer = 0
-- calc function reference
group.fn = calc[ group.mode ]
end
-- handle group writes
function eventhandler(event)
local dst, datatype
dst = event.dst
datatype = datatypes[ event.dst ]
-- unknown object, stop
if not datatype then
return
end
values[ dst ] = dpt.decode(event.datahex, datatype)
-- check if any group needs to be updated
for _, group in ipairs(groups) do
for _, address in ipairs(group.objects) do
if address == dst then
group.timer = updatedelay
end
end
end
end
require('genohm-scada.eibdgm')
client = eibdgm:new({ timeout = 0.25 })
client:sethandler('groupwrite', eventhandler)
end
tsec, tusec = os.microtime()
client:step()
delta = os.udifftime(tsec, tusec)
-- check if any group has an active timer
for _, group in ipairs(groups) do
timer = group.timer
if timer then
timer = timer - delta
-- timer expired, run calc function
if timer <= 0 then
group.fn(group)
timer = nil
end
group.timer = timer
end
end
Problem is, that this script works for awhile, but if many groups are starting to send feedbacks it kind of "crashes" because it stops sending feedbacks and to overcome this you have to disable/enable script to make it work again, why does this happen and is there a fix to it? I could of course use some kind of method to automatically disable/enable script once in awhile but I dont think this is a good practice and effective way of doing it. Maybe someone have ideas or had this problem before?
Thanks in advance.