forked from nodemcu/nodemcu-firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
somfy.lua
155 lines (138 loc) · 4.77 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
146
147
148
149
150
151
152
153
154
155
-- 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'
}}}}}}}}}})