Logic Machine Forum
update value of object - 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: update value of object (/showthread.php?tid=4863)



update value of object - rocfusion - 06.07.2023

Hi,

Is there an grp. script command that will update the value of an object that does not write to the TP or IP bus under any condition.  It ONLY changes the value of the object no matter the value of the object.  I know you have grp.update and grp.checkupdate.  

When you have resident scripts that should change other objects on the event that an groupwrite telegram has been sent to that object AND they also act as the status object.  These scripts will continuously run. Both grp.update and grp.checkupate send back a groupwrite telegram.  Is there something else just to change the value, without messing with the underlying DB.


Many thanks


Roger


RE: update value of object - admin - 07.07.2023

Can you provide an example of what you are trying to achieve?


RE: update value of object - rocfusion - 07.07.2023

Hi 

I have the following resident script running, to give the status of a group of lights ( room ).  The second script is an event script for controlling that group of lights.  Now right now I have to use a separate object which responds with the status.  

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 = {
    { tag= 'cinema', output= '5/2/5', mode= 'avg' },
    { tag= 'living', output= '5/3/5', mode= 'avg' },
    { tag= 'kitchen', output= '5/4/5', mode= 'avg' },
    { tag= 'master', output= '5/5/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 = {}

  -- Temperature AVERAGE value
  calc['tempavg'] = function(group)
    local result, count, value = 0, 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
      end
    end
    if count > 0 then
      result = ((result / count)* 9 / 5) + 32
      local fahren= math.floor(result+0.5)
      grp.checkupdate(group.output, fahren)
    end
  end   
 
  -- AVERAGE value
  calc['avg'] = function(group)
    local result, count, switch, value = 0, 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
        if value > 0 then
         count = count + 1
        end
      -- boolean true is 100%, false is 0%
      elseif type(value) == 'boolean' then
        if toboolean(value) then
       --   result = result + ( result / count )
          switch = switch + 1
        end       
      end
    end

    if count > 0 then
      if result > 0 then
        result = math.floor(result / count + 0.5)       
      end       
      grp.checkupdate(group.output, result)
    elseif switch > 0 then
        grp.checkupdate(group.output, 100)
      else
       grp.checkupdate(group.output, 0)
    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

Event script

Code:
if (event.type=='groupread') then
  grp.response(event.dst,grp.getvalue(event.dst))
elseif (event.type=='groupwrite') then
  grp.write('0/2/104',grp.getvalue(event.dst),dt.scale)
  grp.write('0/2/105',grp.getvalue(event.dst),dt.scale)
  if(event.getvalue()==0) then
    grp.write('0/0/107',false,dt.bool)
  else
    grp.write('0/0/107',true,dt.bool)
  end
end



RE: update value of object - Daniel - 10.07.2023

When you use Virtual groups then the value is not sent to TP or IP. For normal objects write will send to TP and IP , where update will send to IP but not to TP.


RE: update value of object - admin - 10.07.2023

You can also use grp.sender / event.sender to block event script execution when a different script changed the value. See this: https://forum.logicmachine.net/showthread.php?tid=4516&pid=29215#pid29215