forked from nodemcu/nodemcu-firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
somfy.lua
145 lines (128 loc) · 4.61 KB
/
somfy.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
-- 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.
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 = sjson.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(sjson.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: "..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.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 = 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'
}}}}}}}}}})