Example - copy and change it
The widget showcase: everything the dashboard can draw
- Source:
examples/widget_showcase.py- Widgets:
- Gauge, Status, Chart, Button, Toggle, Select, Slider, Camera, Files
- Hardware:
- None to run it (the camera shows a test pattern); a Pi camera to see a real picture
- Status:
- Tested with a fake connection, including a check that it uses every widget the frontend can draw. Started on a Pi Zero W against the dev server and connected; the dashboard for it has not yet been looked over in a browser. Files is new and untested on a real device or in a real browser.
The widget showcase: what the dashboard can draw
Most examples show one idea. This one is the menu: each kind of widget, in one short program, each with a comment saying what it is for. Copy the part you want.
Four programs, four sections
readouts = Program(id="readouts", name="Showcase: Readouts")
controls = Program(id="controls", name="Showcase: Controls")
camera_section = Program(id="camera", name="Showcase: Camera")
files_section = Program(id="files", name="Showcase: Files")
Each Program becomes a section on the dashboard, with a heading made from its name. You never say where anything goes: you say what each widget is, and the dashboard lays them out. Gauges and statuses become tiles, buttons share a row, toggles, selects and sliders become slim rows, and a chart or a video gets a line to itself.
Readouts: the device talks, the dashboard shows
A Gauge is one number (.set(22.5)), a Status is a word that the dashboard colours (Online is green, Warning amber, Offline red), and a Chart is several numbers sent together (.set_values({...})), drawn over time as one small panel each. The numbers here are made up and drift smoothly, so you can watch them move; replace _read_conditions() with a real sensor.
Controls: the dashboard talks back
A Button runs your code:
@widget.handler
def pressed(command):
print("pressed")
controls.info("Lights: On") # shows in the Notification history
Give buttons a group= and they sit under a small heading. The showcase has two groups of three, and they are two rows.
A Toggle, a Select and a Slider are settings. The dashboard changes them, the device checks the value (a bad one is refused with a warning), saves it so it survives a restart, publishes it back so every open page agrees, and then calls your apply function, which is where you act on it.
Camera
The Camera is a live picture that goes straight from the device to your browser, only while someone is watching, with buttons to take a snapshot, record and go full screen. It is the same widget the Bird Box uses. Without a Pi camera the picture is a moving test pattern (a bright bar sweeping across a gradient, so you can see it is live); on a Pi with a camera it is the real camera.
There is also a plain Video widget (the picture without the buttons). The showcase leaves it out on purpose: a device streams one camera at a time and every video widget for it plays that stream, so a Video next to a Camera would just play in step with it.
Files
The Files widget lists one or more folders on the device and downloads what is in them, straight to your own machine - peer to peer, so it needs the video extras and a direct connection, the same as the Camera's live picture. The showcase points it at the Camera's own Videos and Photos folders:
files = files_section.output(id="files", type="Files")
files.add_folder("Videos", recorder.store.directory)
files.add_folder("Photos", camera.snapshot_directory)
recorder.on_saved(lambda _recording: files.publish()) # a finished recording appears without a page reload
Every file starts checked, so "Download Selected" grabs everything by default - untick what you do not want first. It asks Chrome or Edge for a folder once and writes every file into it as it arrives; elsewhere it falls back to the browser's own downloads, one at a time. A file is only deleted off the device once its full byte count has actually arrived - the widget's own toggle, on by default, turns that off if you would rather keep both copies.
Notifications
info, warning and error appear on the dashboard. A warning stays until someone acknowledges it. The showcase raises one when the temperature crosses a line, once, not on every reading.
Keeping it complete
This program is meant to stay a full list. A test compares it with the widgets the frontend registers, and fails when a widget is added to the platform without a place here (or without a written reason for leaving it out, as with the plain Video).
Running it
Copy widget_showcase.py anywhere and run it:
python widget_showcase.py
The Camera needs the video extras (pip install "thepihub[webrtc]"). If this is the first time you have connected from this device, it prints a link and a code to approve in the browser; answer y when the terminal asks you to confirm the account. That makes the device yours and gives it an id. After that it simply connects.
