Skip to content

About

WebREPL client and related tools for MicroPython and Edrys

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Edrys MicroPython WebREPL Module

This module shares a MicroPython board's REPL from a station with everyone in the station's room. It talks to the board over WebREPL, MicroPython's REPL over a WebSocket, so the board only needs Wi-Fi, no USB connection to the station.

  • Everyone in the room types into the same REPL and sees its output, also students who join later.
  • Station and teachers can send files to the board and get files from it.
  • Editor modules can run code on the board (execute message, see Messages).
  • Optionally, an Arduino Alvik drives back to its charger when the last user leaves the room.

The module in a station: status, address, file transfer and the REPL

It is based on the official WebREPL client for MicroPython.

Usage

Add the module to your class with this URL:

https://edrys-labs.github.io/module-micropython-webrepl/

The module is only shown in stations (show-in: station), not in normal rooms. It follows the classroom's light or dark theme (the operating system's when opened on its own); the REPL stays dark in both.

  1. Enable WebREPL on the board and set its password (import webrepl_setup in the board's REPL, see the MicroPython documentation).
  2. Start the proxy on the station's computer.
  3. Set the board's address in the module's station settings (websocket, see Configuration), e.g. ws://localhost:8765/ws://192.168.4.1:8266, or type it into Address in the station.
  4. Open the station and click Connect (or a teacher in the station's room does). Then anyone in the room types the WebREPL password into the terminal.

The header shows the board's status to everyone: not connected, connecting… or connected. While a connection is wanted, the station keeps it up: after a reload of the station, or when the board drops the connection, it reconnects by itself (after 1, 2, 5, then every 10 seconds) until someone clicks Cancel or Disconnect. Errors are printed in the terminal, e.g. [cannot reach …, retrying…].

Roles

Station Teacher Student
See the board's status, type into the REPL, run code from an editor module yes yes yes
Connect / Disconnect, change the address yes yes –
Send and get files, Run Self Charge yes yes –

The station holds the connection to the board. Everyone else goes through it, so only the station needs to reach the board (or the proxy). Students don't get the controls, and the station also checks who asks: it carries out a connect, address, file or self charge request only from a teacher (by the sender's role in the class, which edrys-Lite signs), and puts the shared connection state back if anyone else changes it.

Files

Send a file: pick it and click Send to device. Get a file: type its name on the board (e.g. main.py) and click Get from device; the file is downloaded by whoever asked. Everyone in the room sees the transfer in the status line (Sent main.py, 15 bytes). File names may have up to 64 ASCII characters (a limit of WebREPL).

Configuration

All settings are under Station config in the module settings:

Field Type Default Description
websocket text (empty) Address of the board, usually through the proxy: ws://localhost:8765/ws://<board-ip>:8266. Changing it also changes the address in the station room.
execute text execute Message subject on which code from editor modules is run
self_charge_alvik boolean false Arduino Alvik: run self_charge.py on the board when the last user leaves the station room, and show a Run Self Charge button. The script must be on the board.
{
  "websocket": "ws://localhost:8765/ws://192.168.4.1:8266",
  "execute": "execute",
  "self_charge_alvik": false
}

Without an address, the module says how to set one.

The proxy

Edrys is served over https, and an https page may only open secure (wss://) WebSockets, except to localhost. MicroPython boards only offer plain ws://. The proxy (proxy/) runs on the station's computer, listens on localhost and forwards each connection to the board named in its path:

ws://localhost:8765/ws://192.168.4.1:8266   ->   ws://192.168.4.1:8266

So one proxy serves any number of stations and boards. Chrome, Edge and Firefox allow an https page to connect to ws://localhost.

Run it with Python 3:

pip install -r proxy/requirements.txt
python3 proxy/proxy.py

or with Docker:

docker run -it --network host edryslabs/micropython-webrepl-proxy:latest

(proxy/docker-compose.yml builds the image from this folder and restarts it with the computer: docker compose -f proxy/docker-compose.yml up -d.)

Settings, as environment variables:

Variable Default Description
PROXY_ALLOWED_TARGETS (empty: any) Boards the proxy may connect to, as comma-separated host or host:port patterns, e.g. 192.168.4.1,10.0.0.*:8266. Set it: without it, any web page open in the station's browser can use the proxy to reach any WebSocket in the local network.
PROXY_HOST localhost Address to listen on
PROXY_PORT 8765 Port to listen on
PROXY_LOG_LEVEL INFO DEBUG also logs the size of each message. Message contents (password, code) are never logged.
docker run -it --network host -e PROXY_ALLOWED_TARGETS=192.168.4.1 edryslabs/micropython-webrepl-proxy:latest

The image is built and pushed by .github/workflows/docker-publish.yml when the proxy changes, as :latest and as :<commit sha>.

For module developers

Messages

Other modules may send one message: code to run on the board.

Subject From → to Body
execute (setting execute) any module → station MicroPython code as a string

The station uploads the code as temp_code.py, waits until the board confirmed it, interrupts a running program (Ctrl-C) and runs the file with exec(open('temp_code.py').read()). Runs are queued, one at a time. If the station is not connected, everyone sees [code not run: not connected] in the terminal.

The other subjects are only accepted from this module itself. The station carries out those marked teacher only when a teacher sent them.

Subject From → to Body
write station → room terminal output
data peer → station keystrokes
history_request / history peer → station / station → room a peer that loads asks for the recent output (up to 16 KB); the answer carries the request's id
connect_request teacher → station true to connect, false to disconnect
set_url teacher → station the board's address
put_file teacher → station { filename, data }
get_file / got_file teacher → station / station → room { id, filename } / { id, filename, data | error }; only the requester saves it
run_self_charge teacher → station (empty)

Shared state

Room state (Edrys.getState(key, 'Value')), written only by the station; other peers read it:

Key Written by Value
url station (its Address field, a teacher's set_url, the config) the board's address
url_config station the websocket config the address was last taken from
wanted station (its button, a teacher's connect_request) a connection is wanted
connected station the station is connected to the board
file_status, file_busy station the file status line, and whether a transfer is running

Files

  • index.html: markup and the module's declarations (show-in, module-config)
  • app.js: the Edrys side: shared state, messages, the station's connection and the file boxes
  • webrepl.js: the board side: terminal (xterm.js 6, from jsDelivr), WebSocket and the WebREPL file transfer protocol; no Edrys code
  • styles.css, FileSaver.js (vendored, saves downloaded files)
  • proxy/: the proxy (proxy.py), its Docker image and compose file; separate from the module, which needs only the files above

There is no build step: serve the folder (e.g. python3 -m http.server) and add its URL to a class.

Tests

End-to-end tests run the module in a real edrys-Lite with a station, a teacher and students, against a fake MicroPython board. They are in the edrys-module-tests repository, under modules/module-micropython-webrepl. They read the terminal as window.term; keep that when changing the terminal.

License

MIT © edrys-labs, based on micropython/webrepl

About

WebREPL client and related tools for MicroPython and Edrys

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages