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
Resident Script
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.
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.