-
Notifications
You must be signed in to change notification settings - Fork 37
/
actuator.lua
290 lines (262 loc) · 8.76 KB
/
actuator.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
-- constants
ACTUATOR_VERSION = "0.4.0"
TMR_ACTUATOR_ID = 0
TMR_ACTUATOR_INTERVAL_IN_MS = 150
TMR_RELAY1_DELAY_ID = 6
TMR_RELAY2_DELAY_ID = 5
RELAY_STATE_OFF = 0
RELAY_STATE_ON = 1
SWITCH_STATE_CLOSED = gpio.LOW -- is 0
SWITCH_STATE_OPEN = gpio.HIGH -- is 1
-- user defined options
INTERLOCK_ENABLED = false -- if active, only one relay can be on at the same time
DELAY_TIMER_ENABLED = false -- timer to switch off relays after a specified time
RELAY1_DELAY_TIME_IN_SEC = 10 -- delay time to switch off in seconds for relay 1
RELAY2_DELAY_TIME_IN_SEC = 10 -- delay time to switch off in seconds for relay 2
RELAY1_SID = "Test_Light1" -- openhab itemname / shc sid of item
RELAY2_SID = "Test_Light2" -- openhab itemname / shc sid of item
-- config gpios
RELAY1_PIN = 4 -- GPIO2
RELAY2_PIN = 5 -- GPIO14
gpio.mode(RELAY1_PIN, gpio.OUTPUT)
gpio.mode(RELAY2_PIN, gpio.OUTPUT)
SWITCH1_PIN = 6 -- GPIO 12
SWITCH2_PIN = 7 -- GPIO 13
gpio.mode(SWITCH1_PIN, gpio.INPUT, gpio.PULLUP)
gpio.mode(SWITCH2_PIN, gpio.INPUT, gpio.PULLUP)
-- init variables with default values
relay1_state = 0 -- 0 is off
relay2_state = 0 -- 0 is off
tcp_server_started = false -- tcp server needs to be started after ESP got an IP
switch1_prev_state = SWITCH_STATE_OPEN
switch2_prev_state = SWITCH_STATE_OPEN
-----------------------------------------------
function relay1_switchOff()
gpio.write(RELAY1_PIN, gpio.HIGH) -- NC version: HIGH is off
end
function relay1_switchOn()
gpio.write(RELAY1_PIN, gpio.LOW) -- NC version: LOW is on
end
function relay2_switchOff()
gpio.write(RELAY2_PIN, gpio.HIGH) -- NC version: HIGH is off
end
function relay2_switchOn()
gpio.write(RELAY2_PIN, gpio.LOW) -- NC version: LOW is on
end
function send_to_visu(sid, cmd)
local HOST = "192.168.0.54"
local PLATFORM = "Openhab" -- SHC or Openhab
local port = 80
local link = ""
if (PLATFORM == "SHC") then
port = 80
link = "/shc/index.php?app=shc&a&ajax=executeswitchcommand&sid="..sid.."&command="..cmd
end
if (PLATFORM == "Openhab") then
local switch
if (cmd == 1) then
switch = "ON"
elseif (cmd == 0) then
switch = "OFF"
end
port = 8080
link = "/CMD?" ..sid.."=" ..switch
end
print(link)
local conn = net.createConnection(net.TCP, 0) -- 0 means unencrypted
conn:on("connection", function(conn, payload)
conn:send("GET "..link.. " "..
"Host: "..HOST.. "\r\n"..
"Accept: /\r\n"..
"User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)"..
"\r\n\r\n")
end)
time_before = tmr.now()
conn:on("receive", function(conn, payload)
print('\nRetrieved in '..((tmr.now()-time_before)/1000)..' milliseconds.')
--print(payload)
conn:close()
end)
conn:connect(port, HOST)
end
function read_temp(pin)
local status, temp, humi, temp_dec, humi_dec = dht.read(pin)
if (status == dht.OK) then
print(temp.."|"..humi)
elseif (status == dht.ERROR_CHECKSUM) then
print("DHT Checksum error.");
elseif (status == dht.ERROR_TIMEOUT) then
print("DHT timed out.");
end
-- temp and humi are -999 when an error occurs
return temp, humi
end
function start_tcp_server()
local TCP_PORT = 9274
local TIMEOUT_IN_SEC = 1
local CMD_RESTART = 0
local CMD_SWITCH = 2
local CMD_STATUS = 3
local CMD_TEMP = 4
local CMD_VERSION = 9
local srv = net.createServer(net.TCP, TIMEOUT_IN_SEC)
srv:listen(TCP_PORT, function(conn)
conn:on("receive", function(conn, pl)
print(pl)
-- split payload (string indices start at 1 in Lua)
local command_type = tonumber(string.sub(pl, 1, 1))
local pin = tonumber(string.sub(pl, 3, 3)) -- only single-digit pins!
local command = tonumber(string.sub(pl, 5, 5))
if (command_type == CMD_RESTART) then
node.restart()
elseif (command_type == CMD_SWITCH) then
if (command == 1) then
print("cmd switch on")
if (pin == RELAY1_PIN) then
relay1_state = 1
end
if (pin == RELAY2_PIN) then
relay2_state = 1
end
end
if (command == 0) then
print("cmd switch off")
if(pin == RELAY1_PIN) then
relay1_state = RELAY_STATE_OFF
end
if(pin == RELAY2_PIN) then
relay2_state = RELAY_STATE_OFF
end
end
elseif (command_type == CMD_STATUS) then
conn:send(gpio.read(pin))
print("request pin "..pin.."| state = "..gpio.read(pin))
elseif (command_type == CMD_TEMP) then
local temp, humi = read_temp(pin)
conn:send(temp.."|"..humi)
elseif (command_type == CMD_VERSION) then
conn:send(ACTUATOR_VERSION)
end
if string.sub(pl, 0, 11) == "**command**" then
payload = pl
tmr.stop(TMR_ACTUATOR_ID)
dofile("wifi_tools.lua")
end
end)
end)
end
function init_delay_timers()
tmr.register(TMR_RELAY1_DELAY_ID, RELAY1_DELAY_TIME_IN_SEC*1000, tmr.ALARM_SEMI, function()
if(DELAY_TIMER_ENABLED == true) then
relay1_state = RELAY_STATE_OFF
end
end)
tmr.register(TMR_RELAY2_DELAY_ID, RELAY2_DELAY_TIME_IN_SEC*1000, tmr.ALARM_SEMI, function()
if(DELAY_TIMER_ENABLED == true) then
relay2_state = RELAY_STATE_OFF
end
end)
end
-- start actuator
print("Actuator starting...")
init_delay_timers()
-- begin actuator timer to handle switches and relays
tmr.alarm(TMR_ACTUATOR_ID, TMR_ACTUATOR_INTERVAL_IN_MS, tmr.ALARM_AUTO, function()
if wifi.sta.getip() == nil then
print("No IP yet!")
elseif (tcp_server_started == false) then
print("Running version "..ACTUATOR_VERSION)
print(wifi.sta.getip())
tcp_server_started = true
start_tcp_server()
end
-- read gpio states from switches and relays
local switch1_gpio_state = gpio.read(SWITCH1_PIN)
local switch2_gpio_state = gpio.read(SWITCH2_PIN)
local relay1_gpio_state = gpio.read(RELAY1_PIN)
local relay2_gpio_state = gpio.read(RELAY2_PIN)
-- begin switch1
if (switch1_gpio_state == SWITCH_STATE_CLOSED and switch1_prev_state ~= switch1_gpio_state) then
switch1_prev_state = SWITCH_STATE_CLOSED
--print("debug if 1")
if (relay1_state == RELAY_STATE_OFF) then
relay1_state = RELAY_STATE_ON
--print("relay1_state = 1")
send_to_visu(RELAY1_SID, relay1_gpio_state)
elseif (relay1_state == RELAY_STATE_ON) then
relay1_state = RELAY_STATE_OFF
--print("relay1_state = 0")
send_to_visu(RELAY1_SID, relay1_gpio_state)
end
elseif (switch1_gpio_state == SWITCH_STATE_OPEN and switch1_prev_state ~= switch1_gpio_state) then
switch1_prev_state = SWITCH_STATE_OPEN
--print("debug if 2")
if (relay1_state == RELAY_STATE_OFF) then
relay1_state = RELAY_STATE_ON
-- print("relay1_state = 1")
send_to_visu(RELAY1_SID, relay1_gpio_state)
elseif (relay1_state == RELAY_STATE_ON) then
relay1_state = RELAY_STATE_OFF
--print("relay1_state = 0")
send_to_visu(RELAY1_SID, relay1_gpio_state)
end
end
-- end switch1
-- begin switch2
if (switch2_gpio_state == SWITCH_STATE_CLOSED and switch2_prev_state ~= switch2_gpio_state) then
switch2_prev_state = SWITCH_STATE_CLOSED
--print("debug2 if 1")
if (relay2_state == RELAY_STATE_OFF) then
relay2_state = RELAY_STATE_ON
--print("relay2_state = 1")
send_to_visu(RELAY2_SID, relay2_gpio_state)
elseif (relay2_state == RELAY_STATE_ON) then
relay2_state = RELAY_STATE_OFF
-- print("relay2_state = 0")
send_to_visu(RELAY2_SID, relay2_gpio_state)
end
elseif (switch2_gpio_state == SWITCH_STATE_OPEN and switch2_prev_state ~= switch2_gpio_state) then
switch2_prev_state = SWITCH_STATE_OPEN
--print("debug2 if 2")
if (relay2_state == RELAY_STATE_OFF) then
relay2_state = RELAY_STATE_ON
--print("relay2_state = 1")
send_to_visu(RELAY2_SID, relay2_gpio_state)
elseif (relay2_state == RELAY_STATE_ON) then
relay2_state = RELAY_STATE_OFF
-- print("relay2_state = 0")
send_to_visu(RELAY2_SID, relay2_gpio_state)
end
end
-- end switch2
-- begin switching relays
if (relay1_state == RELAY_STATE_ON) then
if(INTERLOCK_ENABLED == true) then
relay2_state = RELAY_STATE_OFF
end
if(DELAY_TIMER_ENABLED == true) then
tmr.start(TMR_RELAY1_DELAY_ID)
end
relay1_switchOn()
--print("switch relay1 on")
end
if (relay1_state == RELAY_STATE_OFF) then
relay1_switchOff()
--print("switch relay1 off")
end
if (relay2_state == RELAY_STATE_ON) then
if(INTERLOCK_ENABLED == true) then
relay1_state = RELAY_STATE_OFF
end
if(DELAY_TIMER_ENABLED == true) then
tmr.start(TMR_RELAY2_DELAY_ID)
end
relay2_switchOn()
--print("switch relay2 on")
end
if (relay2_state == RELAY_STATE_OFF) then
relay2_switchOff()
--print("switch relay2 off")
end
-- end switching relays
end) -- end actuator timer function