I want to add a simple webserver to my NodeMCU bot, and...
<begin old man grump>
In looking, I did not find anything really clean-cut, most of the examples I find for anything these days are so cluttered and look like they where written by a robot monkey (a poorly coded one). It's seems if there is no ide to keep things neat and clean, kids these days don't.
</begin old man grump>
With NodeMCU, you get kind of what they say it is, a Node.js type environment (kind of... :-) Most real Nodish programs are acting like a web server on a larger machine, like a Linux, Mac or even windows. When you look at the Node code, it always looks like they are really writing for the web client side and not the web server. It's a mess.
For what I want from it that does not really matter. I just want a simple easy to use scripting language to bang out code for the ESP with and Lua fits the bill for the most part (until the MicroPython port is completed :) I can keep my old man code all neat and beautiful!
Now back to the show...
My plans for the server is two-fold, control and status. I want to be able to see whats going on the bot and send commands to drive it or turn things on and off.
I figured I would share this for anyone wanting a clean NodeMCU httpd example.
Update 04/03/2015 - Added function to parse and build a lua table with the request data.
-- Simple NodeMCU web server (done is a not so nodeie fashion :-) -- -- Written by Scott Beasley 2015 -- Open and free to change and use. Enjoy. -- -- Your Wifi connection data local SSID = "xxxxxxxx" local SSID_PASSWORD = "xxxxxxxx" local function connect (conn, data) local query_data conn:on ("receive", function (cn, req_data) query_data = get_http_req (req_data) print (query_data["METHOD"] .. " " .. " " .. query_data["User-Agent"]) cn:send ("Hello World from ESP8266 and NodeMCU!!") -- Close the connection for the request cn:close ( ) end) end function wait_for_wifi_conn ( ) tmr.alarm (1, 1000, 1, function ( ) if wifi.sta.getip ( ) == nil then print ("Waiting for Wifi connection") else tmr.stop (1) print ("ESP8266 mode is: " .. wifi.getmode ( )) print ("The module MAC address is: " .. wifi.ap.getmac ( )) print ("Config done, IP is " .. wifi.sta.getip ( )) end end) end -- Build and return a table of the http request data function get_http_req (instr) local t = {} local first = nil local key, v, strt_ndx, end_ndx for str in string.gmatch (instr, "([^\n]+)") do -- First line in the method and path if (first == nil) then first = 1 strt_ndx, end_ndx = string.find (str, "([^ ]+)") v = trim (string.sub (str, end_ndx + 2)) key = trim (string.sub (str, strt_ndx, end_ndx)) t["METHOD"] = key t["REQUEST"] = v else -- Process and reamaining ":" fields strt_ndx, end_ndx = string.find (str, "([^:]+)") if (end_ndx ~= nil) then v = trim (string.sub (str, end_ndx + 2)) key = trim (string.sub (str, strt_ndx, end_ndx)) t[key] = v end end end return t end -- String trim left and right function trim (s) return (s:gsub ("^%s*(.-)%s*$", "%1")) end -- Configure the ESP as a station (client) wifi.setmode (wifi.STATION) wifi.sta.config (SSID, SSID_PASSWORD) wifi.sta.autoconnect (1) -- Hang out until we get a wifi connection before the httpd server is started. wait_for_wifi_conn ( ) -- Create the httpd server svr = net.createServer (net.TCP, 30) -- Server listening on port 80, call connect function if a request is received svr:listen (80, connect)