This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Script not working properly
#1
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:

Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
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.
Reply
#2
Which firmware version are you running? How many groups do you have?
Reply
#3
Version is 20170927. I have 18 groups in total which are working in "OR" mode and each group consist of atleast 3-4 different light addresses.
Reply
#4
Try logging what grp.write returns:
Code:
12
res, err = grp.write(alias, value) log(res, err)
Reply
#5
It logs:

Quote:* arg: 1
 * nil
* arg: 2
 * string: cannot send nil value
Reply
#6
Try upgrading firmware to 2018 RC1 and see if it helps.
Reply


Forum Jump: