-- Copyright 2016 jankop@volny.cz, MIT license, http://opensource.org/licenses/MIT _,BoRe=node.bootreason() print("** sonoffset ",BoRe) rtcmem.write32(0,0) rtcmem.write32(1,0) GPIO0 = 3 -- button GPIO12 = 6 -- relay (active high) GPIO13 = 7 -- GREEN LED (active low) code="sonoff" mode="APO" chan=6 pwm.setup(GPIO13, 3, 500) pwm.start(GPIO13) gpio.mode(GPIO0,gpio.INT) gpio.mode(GPIO12, gpio.OUTPUT) gpio.write(GPIO12,0) if file.exists("code.inf") then file.open("code.inf","r") pcode=file.readline() pmode=file.readline() pchan=file.readline() file.close() if pcode~=nil then code=string.sub(pcode,1,#pcode-1) end if pmode~=nil then mode=string.sub(pmode,1,#pmode-1) end if pchan~=nil then chan=(string.sub(pchan,1,#pchan-1)) end end ssid, passw = wifi.sta.getconfig() wifi.setmode(wifi.STATIONAP) cfg={} --cfg.channel=chan --cfg.auth=wifi.WPA_WPA2_PSK cfg.auth=wifi.WPA_PSK cfg.ssid="SET"..node.chipid() cfg.pwd= "esp"..node.chipid() wifi.ap.config(cfg) dhcp_config ={} dhcp_config.start = "192.168.4.2" wifi.ap.dhcp.config(dhcp_config) wifi.ap.dhcp.start() --start server srv=net.createServer(net.TCP,300) srv:listen(80, function(conn) conn:on("receive", function(client,payload) actIP,actPort=conn:getpeer() if string.match(wifi.ap.getip(),"%d+%.%d+%.%d+%.")~=string.match(actIP,"%d+%.%d+%.%d+%.") then return end function Send() lenght= #buff buff = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n'.. 'Content-Length: '.. lenght ..'\r\n'.. 'Cache-Control: no-cache\r\n'.. 'Pragma: no-cache\r\n'.. 'Connection: keep-alive\r\n\r\n'..buff client:send(string.sub(buff,1, (#buff > 1460) and 1460 or #buff), function() if #buff>1460 then client:send(string.sub(buff,1461,(#buff > 2920) and 2920 or #buff), function() buff=nil collectgarbage() end) end end) end -- send data to client function SendData() if mode~="APO" then stasta=wifi.sta.status() staip=wifi.sta.getip() if staip==nil then staip="No IP address" end if stasta==0 then pohl="STATION IDLE"end if stasta==1 then pohl="STATION CONNECTING"end if stasta==2 then pohl="STATION WRONG PASSWORD"end if stasta==3 then pohl="STATION NO AP FOUND"end if stasta==4 then pohl="STATION CONNECT FAIL"end if stasta==5 then pohl="STATION GOT IP"end buff= '\ \ \ SONOFF\ \

Sonoff ID:'..node.chipid()..'

\ '..pohl..'
\ IP address : '..staip..'
\
\ Set your WiFi Router parameters:
\ SSID
\ PASSWORD

\ Set password for relay control:
\ PASSCODE

\ Set single Access Point mode only:\

\ AP WiFi channel
\

\ \ \
\ node.heap : '..node.heap()..'\ ' else buff= '\ \ \ SONOFF\ \

Sonoff ID:'..node.chipid()..'

\ Access point mode only
\ IP address : 192.168.4.1
\
\ Set your WiFi Router parameters:
\ SSID
\ PASSWORD

\ Set password for relay control:
\ PASSCODE

\ Set single Access Point mode only:\

\ AP WiFi channel
\

\ \ \
\ node.heap : '..node.heap()..'\ ' end Send() end -- send error "FILE NOT FOUND" to client function Send404() buff= '\ \ \ 404\ \

404 - Page not found


\ ' Send() end function ParseData() -- parser of POST parameters function cgidecode(str) return (str:gsub('+', ' '):gsub("%%(%x%x)", function(xx) return string.char(tonumber(xx, 16)) end)) end function parsecgi(str, keys, ignore_invalid) keyfound = {} for pair in str:gmatch"[^&]+" do key, val = pair:match"([^=]*)=(.*)" if not key then print("1.IQS") end default = keys[key] if default == nil then if not ignore_invalid then print("2.IQS") end else if type(default) == "table" then default[#default+1] = cgidecode(val) elseif keyfound[key] then print("3.IQS") else keyfound[key] = true keys[key] = cgidecode(val) end end end return keys end str=string.match(payload,"POST / HTTP/%d%.%d\r\n.+\r\n\r\n(.+=.+)") keys={count = 6, start = 1, SSID="", PASSW="", BUTTON="", CODE="",SQUARE="", CHANNEL=""} parsecgi(str, keys, false) if keys.BUTTON=="SUBMIT" and keys.SQUARE=="CHECKED" then mode="APO" end if keys.BUTTON=="SUBMIT" and keys.SQUARE~="CHECKED" then mode="STA" end if keys.BUTTON=="SUBMIT" then ssid=keys.SSID code=keys.CODE temp=string.match(keys.CHANNEL,"(%d+)") if temp~=nil then temp=tonumber(temp) if temp>0 and temp<14 then chan=temp end end if #keys.PASSW > 7 then passw=keys.PASSW end wifi.sta.config(ssid,passw,1) end if keys.BUTTON=="EXIT" then srv:close() file.open("code.inf", "w") file.writeline(code) file.writeline(mode) file.writeline(chan) file.close() dofile("RESTART!") end keys=nil end -- serve POST request with parameters if string.find(payload,"POST / HTTP/%d%.%d\r\n.+\r\n\r\n(.+=.+)")~=nil then oldIP=nil ParseData() SendData() -- serve POST request without parameters elseif string.find(payload,"POST / HTTP/%d%.%d\r\n.*Content%-Length:%s*%d+.*\r\n\r\n$")~=nil then DataLenght=tonumber(string.match(payload,"Content%-Length:%s*(%d+)")) oldIP=actIP oldPort=actPort oldPayload=payload -- serve GET request elseif string.find(payload,"GET / HTTP/%d%.%d\r\n.+\r\n\r\n$")~=nil then oldIP=nil SendData() -- serve separate POST parameters elseif (#payload==DataLenght) and (oldIP==actIP) and (oldPort==actPort) then payload=oldPayload..payload oldIP=nil ParseData() SendData() -- serve error "FILE NOT FOUND" else Send404() end payload=nil collectgarbage() end) end) --button control function borz() gpio.trig(GPIO0) timpres=1 tmr.alarm(0,100,1, function() timpres=timpres+1 if gpio.read(GPIO0)==0 then return end tmr.stop(0) if timpres > 1 then srv:close() dofile("RESTART!") else gpio.trig(GPIO0,"down",function() borz() end) end end) end gpio.trig(GPIO0,"down",function() borz() end)