nodemcu-firmware/lua_examples/somfy.lua

146 lines
4.6 KiB
Lua
Raw Permalink Normal View History

2016-10-14 00:49:58 +02:00
-- 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'
}}}}}}}}}})