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
 
 
 
 |