This Christmas, I added a whole bunch of lights powered by 5V power sources. My goal was to switch them on at sunset, and switch them off on sunrise, by using a MOSFET for power control :)
While I was doing this, I wanted to send OTA updates of my Lua files to the ESP8266 via WiFi. For some unknown reason, I couldn’t use luatool.py’s TCP update method.
So, I ended up building my very own OTA update protocol (which turned out to be fun!). To begin, add ota.lua
to your project, and invoke it using dofile("ota.lua")
in your init.lua
:
— Send OTA updates to remotely update lua scripts on your ESP8266. | |
— | |
— LICENCE: http://opensource.org/licenses/MIT | |
— Created by Jude Pereira <contact@judepereira.com> | |
— See https://judepereira.com/blog/sending-ota-updates-over-wifi-to-your-esp8266/ | |
srv = net.createServer(net.TCP) | |
current_file_name = nil | |
srv:listen(8080, function(conn) | |
conn:on("receive", function(sck, payload) | |
if string.sub(payload, 1, 5) == "BEGIN" then | |
current_file_name = string.sub(payload, 7) | |
file.open(current_file_name, "w") | |
file.close() | |
sck:send("NodeMCU: Writing to " .. current_file_name .. '…\n') | |
elseif string.sub(payload, 1, 4) == "DONE" then | |
sck:send("NodeMCU: Wrote file " .. current_file_name .. "!\n") | |
current_file_name = nil | |
elseif string.sub(payload, 1, 7) == "RESTART" then | |
sck:send("NodeMCU: Restart!\n") | |
tmr.create():alarm(500, tmr.ALARM_SINGLE, node.restart) | |
else | |
if file.open(current_file_name, "a+") then | |
if file.write(payload) then | |
file.close() | |
sck:send("ok\n") | |
else | |
sck:send("NodeMCU: Write failed!\n") | |
end | |
else | |
sck:send("NodeMCU: Open failed!\n") | |
end | |
end | |
end) | |
conn:on("sent", function(sck) sck:close() end) | |
end) |
Then, to use this shiny new TCP endpoint created on your ESP8266/NodeMCU, create a wrapper shell script:
#!/bin/bash | |
# Wrapper script for sending OTA updates to your ESP8266 running NodeMCU. | |
# See https://judepereira.com/blog/sending-ota-updates-over-wifi-to-your-esp8266/ | |
HOST=192.168.178.25 | |
PORT=8080 | |
for i in "$@"; do | |
FILE=$i | |
echo "Sending $i…" | |
echo -n "BEGIN $FILE" | nc $HOST $PORT | |
while read -r line; do | |
#echo -n "write: $line … " | |
if ! echo "$line" | nc $HOST $PORT | grep "ok" &>/dev/null; then | |
echo "Write failed! Please retry…" | |
exit 1 | |
fi | |
done <"$FILE" | |
echo -n "DONE" | nc $HOST $PORT | |
done | |
echo -n "RESTART" | nc $HOST $PORT |
Heads up! Replace HOST
with the IP of your NodeMCU.
The wrapper script will automatically trigger a restart at the end. To use the wrapper script:
$ chmod +x ota.sh
$ ./ota.sh file1.lua file2.lua init.lua
And that’s it! OTA update away!