I want to get the time using an EPS8266 with nodeMCU to set my RTC over I2C.
This is my sript:
-- file print.lua
local file = assert(loadfile("httpget.lua"))
file() --get Date and Time from google
print("Print follows:") --this should be executed after "file()"
print(date)
This is file httpget.lua
:
-- file httpget.lua
print('httpget.lua started')
conn=net.createConnection(net.TCP, 0)
-- show the retrieved web page
conn:on("receive", function(conn, payload)
date = string.sub(payload,string.find(payload,"Date: ")
+6,string.find(payload,"Date: ")+35)
conn:close()
end)
conn:on("connection", function(conn, payload)
print('\nConnected')
conn:send("HEAD / HTTP/1.1\r\n"
.."Host: google.com\r\n"
.."Accept: */*\r\n"
.."User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)"
.."\r\n\r\n")
end)
-- when disconnected, let it be known
conn:on("disconnection", function(conn, payload)
print("Disconnected\r\n"..date)
end)
conn:connect(80,'google.com')
conn = nil
The result is:
> dofile("print.lua")
httpget.lua started
Print follows: -- this should be at the end
nil -- date==nil because httpget.lua not executed
>
Connected
Disconnected
Sun, 26 Apr 2015 10:30:03 GMT
If I execute the scipt again (without reset), I get date from the execution before. What can I do to execute "httpget.lua" and get the "date" in the scipt that follows?
I use a ESP8266 with NodeMCU 0.9.6 build 20150406 powered by Lua 5.1.4. https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en#index
I load the sripts via USB with ESPlorer v2.0 to my ESP8266. The conn.net... commands are part of the NodeMCU firmware (see link). You can only run the script with an EPS8288 and NodeMCU firmware. My problem is: I find no way to end conn:net routine properly and return data to the next programm part.
As the commenters point out the network code will run asynchronously, i.e. the
conn:on
calls will return immediately and their callbacks are invoked at a later point. Theconn:connect
call is probably not asynchronous, but that doesn't help.Directly after the
conn:connect
call finishes yourprint
calls will run, trying to print the global variabledate
. Most of the time this will printnil
since the network latency to fetch the data from Google will be in the >10's of milliseconds which means your code has already had plenty of time to execute the print statements. In some rare occasions you might actually get the correct date, if you are really lucky with the network latency (that would be very surprising though).To resolve this you need to put the code to be executed on the completion of the network request in a callback that you pass to the
conn:on
that receives the data. In your current code structure this is a bit difficult to do in a nice way though.A simple solution is to do:
Note that I've added a
onReceiveCb
function before including the httpget code. In httpget you invoke the callback: