156 lines
4.8 KiB
Lua
156 lines
4.8 KiB
Lua
|
-- Somfy module example (beside somfy module requires also SJSON module)
|
||
|
-- The rolling code number is stored in the file somfy.cfg.
|
||
|
-- A cached write of the somfy.cfg file is implemented in order to reduce
|
||
|
-- the number of write to the EEPROM memory. Together with the logic of the
|
||
|
-- file module it should allow long lasting operation.
|
||
|
|
||
|
local config_file = "somfy."
|
||
|
local config, config_saved
|
||
|
-- somfy.cfg looks like
|
||
|
-- {"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}}
|
||
|
|
||
|
local tmr_cache = tmr.create()
|
||
|
local tmr_delay = tmr.create()
|
||
|
|
||
|
local pin = 4
|
||
|
|
||
|
local function deepcopy(orig)
|
||
|
local orig_type = type(orig)
|
||
|
local copy
|
||
|
if orig_type == 'table' then
|
||
|
copy = {}
|
||
|
for orig_key, orig_value in next, orig, nil do
|
||
|
copy[deepcopy(orig_key)] = deepcopy(orig_value)
|
||
|
end
|
||
|
setmetatable(copy, deepcopy(getmetatable(orig)))
|
||
|
else -- number, string, boolean, etc
|
||
|
copy = orig
|
||
|
end
|
||
|
return copy
|
||
|
end
|
||
|
|
||
|
local function readconfig()
|
||
|
local ln
|
||
|
if file.exists(config_file.."cfg") then
|
||
|
print("Reading config from "..config_file.."cfg")
|
||
|
file.open(config_file.."cfg", "r+")
|
||
|
ln = file.readline()
|
||
|
file.close()
|
||
|
else
|
||
|
if file.exists(config_file.."bak") then
|
||
|
print("Reading config from "..config_file.."bak")
|
||
|
file.open(config_file.."bak", "r+")
|
||
|
ln = file.readline()
|
||
|
file.close()
|
||
|
end
|
||
|
end
|
||
|
if not ln then ln = "{}" end
|
||
|
print("Configuration: "..ln)
|
||
|
config = sjson.decode(ln)
|
||
|
config_saved = deepcopy(config)
|
||
|
end
|
||
|
|
||
|
local function writeconfighard()
|
||
|
print("Saving config")
|
||
|
file.remove(config_file.."bak")
|
||
|
file.rename(config_file.."cfg", config_file.."bak")
|
||
|
file.open(config_file.."cfg", "w+")
|
||
|
local ok, cfg = pcall(sjson.encode, config)
|
||
|
if ok then
|
||
|
file.writeline(cfg)
|
||
|
else
|
||
|
print("Config not saved!")
|
||
|
end
|
||
|
file.close()
|
||
|
|
||
|
config_saved = deepcopy(config)
|
||
|
end
|
||
|
|
||
|
local function writeconfig()
|
||
|
tmr_cache:stop()
|
||
|
local savenow = false
|
||
|
local savelater = false
|
||
|
|
||
|
--print("Config: "..sjson.encode(config))
|
||
|
--print("Config saved: "..sjson.encode(config))
|
||
|
|
||
|
local count = 0
|
||
|
for _ in pairs(config_saved) do count = count + 1 end
|
||
|
if count == 0 then
|
||
|
config_saved = readconfig()
|
||
|
end
|
||
|
for remote,cfg in pairs(config_saved) do
|
||
|
savelater = savelater or not config[remote] or config[remote].rc > cfg.rc
|
||
|
savenow = savenow or not config[remote] or config[remote].rc > cfg.rc + 10
|
||
|
end
|
||
|
savelater = savelater and not savenow
|
||
|
if savenow then
|
||
|
print("Saving config now!")
|
||
|
writeconfighard()
|
||
|
end
|
||
|
if savelater then
|
||
|
print("Saving config later")
|
||
|
tmr_cache:alarm(65000, tmr.ALARM_SINGLE, writeconfighard)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--======================================================================================================--
|
||
|
local function wait(ms, cb, par)
|
||
|
par = par or {}
|
||
|
print("wait: ".. ms)
|
||
|
if cb then tmr_delay:alarm(ms, tmr.ALARM_SINGLE, function () cb(unpack(par)) end) end
|
||
|
end
|
||
|
|
||
|
local function down(remote, cb, par)
|
||
|
par = par or {}
|
||
|
print("down: ".. remote)
|
||
|
config[remote].rc=config[remote].rc+1
|
||
|
somfy.sendcommand(pin, config[remote].address, somfy.DOWN, config[remote].rc, 16, function() wait(100, cb, par) end)
|
||
|
writeconfig()
|
||
|
end
|
||
|
|
||
|
local function up(remote, cb, par)
|
||
|
par = par or {}
|
||
|
print("up: ".. remote)
|
||
|
config[remote].rc=config[remote].rc+1
|
||
|
somfy.sendcommand(pin, config[remote].address, somfy.UP, config[remote].rc, 16, function() wait(100, cb, par) end)
|
||
|
writeconfig()
|
||
|
end
|
||
|
|
||
|
local function downStep(remote, cb, par)
|
||
|
par = par or {}
|
||
|
print("downStep: ".. remote)
|
||
|
config[remote].rc=config[remote].rc+1
|
||
|
somfy.sendcommand(pin, config[remote].address, somfy.DOWN, config[remote].rc, 2, function() wait(300, cb, par) end)
|
||
|
writeconfig()
|
||
|
end
|
||
|
|
||
|
local function upStep(remote, cb, par) -- luacheck: ignore
|
||
|
par = par or {}
|
||
|
print("upStep: ".. remote)
|
||
|
config[remote].rc=config[remote].rc+1
|
||
|
somfy.sendcommand(pin, config[remote].address, somfy.UP, config[remote].rc, 2, function() wait(300, cb, par) end)
|
||
|
writeconfig()
|
||
|
end
|
||
|
|
||
|
--======================================================================================================--
|
||
|
gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP)
|
||
|
|
||
|
if not config then readconfig() end
|
||
|
if #config == 0 then -- somfy.cfg does not exist
|
||
|
config = sjson.decode([[{"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}}]])
|
||
|
config_saved = deepcopy(config)
|
||
|
end
|
||
|
down('window1',
|
||
|
wait, {60000,
|
||
|
up, {'window1',
|
||
|
wait, {9000,
|
||
|
downStep, {'window1',
|
||
|
downStep, {'window1',
|
||
|
downStep, {'window1',
|
||
|
downStep, {'window1',
|
||
|
downStep, {'window1',
|
||
|
downStep, {'window1',
|
||
|
downStep, {'window1'
|
||
|
}}}}}}}}}})
|