-- 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' }}}}}}}}}})