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.

Some assistance needed to improve HTTP call efficiency
#1
Hi,
I am running some scripts in my LM (a Schneider branded one for the CBUS protocol), and am using it to control a number of Sonoff relays via HTTP. My command to each device works perfect, I have an event script on each Group address I want to control a given Sonoff. Any time I activate my Cbus Group, the Sonoff follows it, as needed.
My Sonoff’s also have local switches connected to their GPIO pins, and if a user presses one of the physical buttons on the Sonoff, the Group addresses ‘Status’ is then out of sync. So, I then created a resident script to run every 2 seconds to poll all the Sonoffs , retrieve their current status, and then update the Group address status if needed, putting things back in sync.  I have about 10 Sonoffs, and I poll each one in a For loop, so it’s not the quickest… Also, unfortunately, when I fix the Group address Status/State with my resident script, it triggers another event script on that GA, which is not really necessary and is just consuming resources…
I will post an abbreviation of my code here, but would love to get some advice on a more streamlined way to do the feedback part, without consuming too much CPU etc. 
Also, my resident script runs two-second intervals, but I could extend this out to 10 or 15 if needed. But still, would like to keep it as snappy as possible...

Event Script
Code:
-- Enter IP Address of Tasmota Device
IPaddr = '192.168.0.212'
-- Enter Tasmota Channel Number
CH = 1
-- Enter Group Number of CBUS GA
GA = 100 -- (This is the Garage Main Lights)

function send_tasmota_http_command(ip, ch, state)
   http = require('socket.http')
   res, err = http.request({
      url = 'http://' .. ip .. '/cm?cmnd=Power' .. ch .. '%20' .. state,
    method = 'GET',
  })
end

storage.set('Tasmota_Update_Event_Blocker', true)

if (GetLightingState(GA) == true) then
  send_tasmota_http_command(IPaddr, CH, 'On')
elseif (GetLightingState(GA) == false)  then
  send_tasmota_http_command(IPaddr, CH, 'Off')
end

os.sleep(1)
storage.set('Tasmota_Update_Event_Blocker', false)



Resident Script



Code:
-- Enter IP Address of Tasmota Device
IPaddr = '192.168.0.212' -- (This is the Garage Main Light)
-- Enter Tasmota Channel Number
CH = 1
-- Enter Group Number of CBUS GA
GA = 100 -- (This is the Garage Main Light)

-- In reality this function is in a User Library but shown here for simplicity

-- A function to request status feedback from a Tasmota Device
function Request_tasmota_http_get_feedback(ip, CH)
   http = require('socket.http')
   ltn12 = require('ltn12')
   require('json')
   sink = {}
   res, err = http.request({
      url = 'http://' .. ip .. '/cm?cmnd=Power' ..CH,
      method = 'GET',
      headers = {["Content-Type"] = "application/json"},
      sink = ltn12.sink.table(sink)
  })

  if sink then
    return table.concat(sink)
  else
    return nil, err
  end
end

-- Again in reality, the remainder of this code runs in a for loop, iterating through an array of approx 10 devices
-- The array is a LUA table containing the IP, Sonoff Channel number and Group address of each device to be polled...

  reply = Request_tasmota_http_get_feedback(IPaddr, CH) -- Returns an array
  -- Walk through array, load into a LUA table
  data = {}
  for val in string.gmatch(reply, "\"(%a+)\"") do -- split the array on double quotes (needs to be escaped with \ )
          table.insert(data, val)
       end
  --log(data) -- Log the array if needed, to find the correct index
  --log("Resident: Light at Address : " .. GA .. " is " .. data[2])
    
Update_Blocked = storage.get('Tasmota_Update_Event_Blocker', false) -- get unblocker status, with default of false if not set
--log("Update_Blocked is : ", Update_Blocked)

-- Fix The feeback, if allowed
if (data[2] == 'ON' and (GetLightingState(GA) == false) and (Update_Blocked == false)) then
    SetLightingState(GA, true)
elseif (data[2] == 'OFF' and (GetLightingState(GA) == true) and (Update_Blocked == false)) then
    SetLightingState(GA, false)
end



Would appreciate any suggestions on how to make this process more efficient/quicker. It works ok most of the time, but sometimes the scripts seem to step on each other, or the feedback is still out of sync. Particularly if there is a lot of persistent and quick pressing of the buttons (kids!). - Thanks.
Reply


Messages In This Thread
Some assistance needed to improve HTTP call efficiency - by Paddyb - 21.02.2021, 20:44

Forum Jump: