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
endProblem 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.
 
 

 
