Logic Machine Forum
problem with logical script - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: problem with logical script (/showthread.php?tid=4093)



problem with logical script - Frank68 - 16.06.2022

Greetings

I have problems with the script that I am attaching does not work, it only works if I stop it and restart it.
some of the group addresses have multiple tags could this be the problem?

Code:
-- POSSIBILITA DI FARE AND , OR , O MEDIE ASSEGANDO TAG PER IDENTIFICARE OPERANDI E METTERE USCITA SU INDIRIZZO DI GRUPPO
if not client then
 
  -- each group has 3 fields:
  -- tag - status object tag
  -- output - status output object
  -- mode - calculate mode (and/or/avg)

  groups = {
    { tag = 'ORALM', output = '32/1/200', mode = 'or' },
    { tag = 'ORINS', output = '32/1/201', mode = 'or' },
    { tag = 'ORP', output = '0/2/100', mode = 'or' },
    { tag = 'ORMOV', output = '32/2/5', mode = 'or' },
    { tag = 'ORPN', output = '32/2/6', mode = 'or' },
    { tag = 'ORPS', output = '32/2/7', mode = 'or' },
    { tag = 'ERRV', output = '4/6/21', mode = 'and' },     
    --{ tag = 'my_group_avg', output = '1/1/5', mode = 'avg' },
  }

  -- time to wait between last telegram from any status in group and update
  updatedelay = 0.5

  -- 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.update(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

Thank you


RE: problem with logical script - admin - 16.06.2022

What is the script sleep time set to?


RE: problem with logical script - Frank68 - 29.06.2022

(16.06.2022, 08:55)admin Wrote: What is the script sleep time set to?
I try to ghange tiem now 8 seconds, but the script frozen, i restart script and the result is ok , when one of addres ghange the script not work( test now on OR function).

Thank's


RE: problem with logical script - admin - 29.06.2022

Sleep time must be 0 for this script.


RE: problem with logical script - victor.back - 08.11.2022

(29.06.2022, 08:14)admin Wrote: Sleep time must be 0 for this script.

Hi Admin.

Maybe this is obviously, but why does this script needs to have 0 sleep time? =)


RE: problem with logical script - admin - 08.11.2022

If you add a delay the script will only be able to process one group telegram per X seconds.