Upy WiFi 03 Websockets
Upy WiFi 03 Websockets
odt 1
For all examples it is assumed that there is a program main.py defining an accesspoint at boot time,
as described here:
http://staff.ltam.lu/feljc/electronics/uPython/uPy_WiFi_01.pdf
# ----------------------------------------------------------------------------
def _closedCallback(webSocket) :
print("WS CLOSED")
# ----------------------------------------------------------------------------
import time
if __name__ == "__main__":
print("Preparing server")
srv = MicroWebSrv(webPath='www/')
srv.MaxWebSocketRecvLen = 256
srv.WebSocketThreaded = True
srv.AcceptWebSocketCallback = _acceptWebSocketCallback
print("Starting server")
srv.Start(threaded = True)
while True:
print("*", end = '')
time.sleep(2)
<html>
<head>
<meta charset="utf-8" />
<title>MicroWebSocket Switch LED</title>
<meta http-equiv="Pragma" content="no-cache">
uPy_WiFi_03_websockets.odt 3
<script>
var output;
function init() {
output = document.getElementById("output");
function onOpen(evt) {
writeToScreen("<strong>-- CONNECTED --</strong>");
SendMsg("Hello world :)");
}
function onClose(evt) {
writeToScreen("<strong>-- DISCONNECTED --</strong>");
}
function onMessage(evt) {
writeToScreen('MSG FROM ESP32 : <span style="color: blue;">' +
evt.data + '</span>');
}
function onError(evt) {
writeToScreen('ERROR : <span style="color: red;">' +
evt.data + '</span>');
}
function SendMsg(msg) {
writeToScreen('MSG TO ESP32 : <span style="color: green;">' +
msg + '</span>');
websocket.send(msg);
}
function writeToScreen(s) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = s;
output.appendChild(pre);
}
function sayHello() {
writeToScreen("HELLO");
websocket.send("HELLO from button");
}
function LEDon() {
writeToScreen("LED on");
websocket.send("LEDon");
}
uPy_WiFi_03_websockets.odt 4
function LEDoff() {
writeToScreen("LED off");
websocket.send("LEDoff");
}
function closeconnection() {
writeToScreen("Closing ...");
websocket.close();
}
</script>
</head>
<body>
<h2>Switch LED with websockets</h2>
<button type="button" onClick = "sayHello()">Say HELLO</button>
<button type="button" onClick = "LEDon()">LED ON</button>
<button type="button" onClick = "LEDoff()">LED OFF</button>
<button type="button" onClick ="closeconnection()">Close connection</button>
<div id="output"></div>
</body>
</html>
The server and the websockets are started and handlers for incoming messages (and for close) are defined.
Now the server is ready and waiting for incoming connections.
Now on a remote PC or tablet (the client), a browser tries to open the webpage “192.168.179.1/led.html”
in the www folder of the ESP:
uPy_WiFi_03_websockets.odt 6
The browser displays the webpage and, as there is an event listener for the load event, calls the init
function:
This function upgrades the HTTP connection to a websocket connection and defines handlers for open,
close, errors, and the most important, for an incoming message.
Once the connection is ready, the OnOpen event is fired on the client side and a message is sent to the
server, who replies:
The function writeToScreen is a helper function that it is called by the onMessage event. It displays the
message in the browser window.
All that is described above happens automatically and gives this result in the browser:
User action:
In the HTML file we have defined some buttons and the corresponding handler functions:
uPy_WiFi_03_websockets.odt 7
Th
The most important for us are the LED buttons. When a LED button is pushed, the message “LEDon” or
“LEDoff” is sent to the server:
The server replies with “Reply for LED on” or “Reply for LED off” to the client.
When the user presses the “Close connection” button, the websocket connection is closed on the client
side. The server reacts to this event with the _closedCallback function.
You are not using the HTML file saved to the ESP device, but the one saved to your computer.
Be sure to save “to Micropython device”.
In Firefox you can see the source code under “Developer options” and so verify if you have the
right version.
• There is a bug in the HTML file.
In this case eventually a previous version is loaded and you are wondering what happens.
I have experienced a strange behavior. Sometimes when the page was refreshed it did not work, but after
looking at the source code and then refreshing the web page it worked.
3.6. Appendix
A simple example of communication over websockets:
The ESP server is contacted over HTTP by the remote browser, sends the file wstest.html which starts a
conversation.
# ----------------------------------------------------------------------------
def _closedCallback(webSocket) :
print("WS CLOSED")
# ----------------------------------------------------------------------------
import time
if __name__ == "__main__":
print("Preparing server")
srv = MicroWebSrv(webPath='www/')
srv.MaxWebSocketRecvLen = 256
#srv.WebSocketThreaded = True
srv.AcceptWebSocketCallback = _acceptWebSocketCallback
print("Starting server")
srv.Start()
The program defines callback handlers for received text messages and a close handler.
In the www folder of the ESP, we have a HTML file that contains a Javascript part to handle the
Websocket communication:
wstest.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>MicroWebSocket Test 2</title>
uPy_WiFi_03_websockets.odt 9
</head>
<script language="javascript">
var output;
function init()
{
output = document.getElementById("output");
function onOpen(evt)
{
writeToScreen("<strong>-- CONNECTED --</strong>");
SendMsg("Hello world :)");
setTimeout( function() { websocket.close() }, 5000 )
}
function onClose(evt)
{
writeToScreen("<strong>-- DISCONNECTED --</strong>");
}
function onMessage(evt)
{
writeToScreen('MSG FROM ESP32 : <span style="color: blue;">' +
evt.data + '</span>');
}
function onError(evt)
{
writeToScreen('ERROR : <span style="color: red;">' + evt.data +
'</span>');
}
function SendMsg(msg)
{
writeToScreen('MSG TO ESP32 : <span style="color: green;">' +
msg + '</span>');
websocket.send(msg);
}
function writeToScreen(s)
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = s;
output.appendChild(pre);
}
</script>
<body>
<h2>MicroWebSocket Test :</h2>
<div id="output"></div>
</body>