-- Somfy module example (beside somfy module requires also CJSON 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. config_file = "somfy." -- somfy.cfg looks like -- {"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}} local tmr_cache = tmr.create() local tmr_delay = tmr.create() pin = 4 gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP) 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 function readconfig() local cfg, ok, 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 = cjson.decode(ln) config_saved = deepcopy(config) end 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(cjson.encode, config) if ok then file.writeline(cfg) else print("Config not saved!") end file.close() config_saved = deepcopy(config) end function writeconfig() tmr.stop(tmr_cache) local savenow = false local savelater = false --print("Config: "..cjson.encode(config)) --print("Config saved: "..cjson.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.alarm(tmr_cache, 65000, tmr.ALARM_SINGLE, writeconfighard) end end --======================================================================================================-- 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 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 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 function upStep(remote, cb, par) 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 function wait(ms, cb, par) par = par or {} print("wait: ".. ms) if cb then tmr.alarm(tmr_delay, ms, tmr.ALARM_SINGLE, function () cb(unpack(par)) end) end end --======================================================================================================-- if not config then readconfig() end if #config == 0 then -- somfy.cfg does not exist config = cjson.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' }}}}}}}}}})