Skip to content

๐Ÿฆ€ Hackable information display fully built in Rust

License

Notifications You must be signed in to change notification settings

eliabieri/wg_display

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

49 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation




๐Ÿฆ€ Hackable information display fully built in Rust and extensible through WebAssembly Components ๐Ÿฆ€

Extensible, open-source and connected to the local community


GitHub Workflow Status GitHub Workflow Status

GitHub release (latest SemVer) GitHub commits since latest release (by SemVer)

โญ๏ธ What WG Display can show you

  • ๐Ÿš‚ The next public transport connections between two stations
  • ๐ŸŠ๐Ÿป The current temperature of the Aare River and whether it is a good idea to take a dip
  • โฐ The current date and time
  • ๐Ÿง–๐Ÿฝโ€โ™€๏ธ The current occupancy in the "Sauna Lorrainebad" in Bern, CH
  • ๐Ÿ•บ๐Ÿพ The next event at the Cafete Club
  • .. what ever idea you might have? Simply write your own widget

โœจ Features

  • ๐Ÿฆ€ Fully built in Rust
  • ๐Ÿ”ง Extensible through WebAssembly. Write your own widget in Rust or any other language that compiles to WebAssembly
  • ๐Ÿš€ Easy deployment. Compiles to single binary
  • ๐Ÿค‘ Only needs a Raspberry Pi (64-bit capable) and a 15$ display
  • โš™๏ธ Widgets can be configured by the user via a web interface

๐Ÿ“š Table of contents

WG Display image front


Configuration dashboard The web interface allows the users to configure system aspects like the background color used on the display or various configuration options of the different widgets.

๐Ÿš€ Getting started

  1. Flash the latest Raspberry Pi OS Lite (64-bit) image to an SD card.
    You can use the Raspberry Pi Imager. It allows you to configure the Wi-Fi credentials and enable SSH (you'll need it in the next step).
  2. SSH into the Raspberry Pi and run the installation script
    # SSH into the Raspberry Pi
    ssh [email protected]
    # Run the installation script (after you've logged in over SSH)
    curl -sL https://raw.githubusercontent.com/eliabieri/wg_display/main/install_on_raspberry.py | python3

The configuration dashboard should be available at wgdisplay.local

๐Ÿ› ๏ธ Assembling the hardware

WG Display is best deployed on a Raspberry Pi and a cheap display hat.

๐Ÿ’ก Even a Raspberry PI Zero 2 W is sufficient! 
The application is very ressource efficient and generally only utilizes around 3% CPU on a Raspberry PI 3B.

Some displays that are tested to be good

  • 5" MIPI DIS Display
    • โœจ Requires no driver
    • โœจ Includes stand
    • ๐Ÿ“ Large enough to display ~ 6 widgets
    • ๐Ÿ’ฒ๐Ÿ’ฒ๐Ÿ’ฒ
  • 3.5" HAT Display
    • โœจ Includes enclosure for wall mounting
    • โš ๏ธ Requires a driver
    • ๐Ÿ“ Large enough to display ~ 3 widgets
    • ๐Ÿ’ฒ
  • 3.5" HAT HDMI Display
    • โœจ Requires no driver
    • ๐Ÿ“ Large enough to display ~ 3 widgets
    • ๐Ÿ’ฒ๐Ÿ’ฒ
  • Any other display you might find
    • WG Display uses the terminal for rendering, so there are no special display requirements

๐Ÿ”จBuilding from source

Prerequisites

First, install rustup then

# Install WebAssembly target
rustup target add wasm32-unknown-unknown
# Install trunk for building the frontend
cargo install --locked trunk
# Install NPM dependencies
cd frontend && npm install

Prerequisites for cross-compilation

First, install docker, then

cargo install cross --git https://github.com/cross-rs/cross

Building the project

# Native build
make
# Cross compilation (Raspberry Pi 3/4/Zero 2 W with 64-bit OS)
make app_aarch64

Then simply copy over the generated binary to the target and run it.

๐Ÿ’ก To run it at boot, simply add the path to the binary to the end of the ~/.bashrc file.

๐Ÿ‘ Writing your own widget

Want your WG Display to show you

  • ๐Ÿฅณ the upcoming events in your favorite nightclub
  • ๐Ÿšฎ the trash calendar in your municipality
  • ๐Ÿบ beers on sale in your local supermarket?

You've got two options

  • Write your own widget. It's easy using the provided guide and reference implementations
  • In case you don't feel capable of writing it yourself, open a feature request and tag it using the widget request label

๐Ÿ“– Documentation (rustdocs)

The rustdocs can be built using

make docs

This generates three separate documentations, one for each crate

app: app/target/doc/app/index.html
common: common/target/doc/common/index.html
frontend: frontend/target/doc/frontend/index.html

๐Ÿงช Testing

Widgets should provide unit tests for their functionality where adequate.
Asynchronous functions can be tested using the tokio_test::block_on function.

๐Ÿ”ฎ What comes next

  • Add installation script
  • Dynamically load widgets
  • Template repository for widgets written in Rust
  • Smoothen up web interface (e.g. add loading indicator, allow updating of widgets)
  • Template repository for widgets written in JS
  • Allow user to configure Wi-Fi credentials via web interface
  • Starting the binary through systemd
  • Implement an update mechanism
  • Implement authentication for the web interface

๐Ÿ”’ Safety

This project uses #[forbid(unsafe_code)] in all crates to ensure that no unsafe Rust is ever added to the project

โ™ป๏ธ Updating the dependencies

# To update the dependencies in all crates, simply run
scripts/update_dependencies.sh

๐Ÿฆพ Developing on target

When developing, an occasional run on a target may be required.
You can the following script as a template to copy over the binary to the target and restart it

#!/bin/sh
set -e

# Note:
# - Set hostname of target to wgdisplay
# - Add public key to authorized_keys on target
# - Enable root ssh login: https://raspberrypi.stackexchange.com/questions/48056/how-to-login-as-root-remotely

make app_arm
ssh [email protected] "sudo /usr/bin/pkill -9 app || true"
scp /Users/eliabieri/git/wg_display/app/target/arm-unknown-linux-gnueabihf/release/app [email protected]:/home/pi
ssh [email protected] "sudo reboot"