Skip to main content

tesserae-opendisplay

A bridge that pushes Tesserae-rendered dashboards to OpenDisplay BLE e-paper tags.

Tesserae renders your dashboards on the server; OpenDisplay tags are driven over Bluetooth LE. This bridge sits between them: it polls Tesserae's frame endpoint for each tag over the network, and when a frame changes it pushes the image to the tag over BLE with the py-opendisplay SDK, which dithers for whatever panel the tag advertises. One bridge drives many tags, and you can run several bridges (one per BLE cluster) against the same Tesserae server.

Requirements

  • A running Tesserae server reachable over the network.
  • A machine near your tags with a Bluetooth LE adapter (a Pi, a mini PC, an HA box) to run the bridge on.
  • Bluetooth (BlueZ) running on that machine. On Linux the bridge talks to the adapter through BlueZ, so it needs to be installed and running:
    sudo apt install bluez
    sudo systemctl enable --now bluetooth
    sudo rfkill unblock bluetooth
    bluetoothctl list      # should show a controller
    
    A container or VM has no Bluetooth unless a real adapter is passed through, so run the bridge on the host (or a host with a USB dongle).
  • Python 3.11+.

Install

pip install tesserae-opendisplay

Configure in a browser

The quickest way to set up: run the config web UI, then point a browser at the host on port 8080.

tesserae-opendisplay web            # then open http://<bridge-host>:8080/

It lets you point the bridge at your Tesserae server, scan for OpenDisplay tags over Bluetooth (reading each panel size), add them, and remove them, writing config.toml for you. Prefer the command line? Skip to Find your tags.

Find your tags

tesserae-opendisplay discover

This scans for tags in range and prints a [[tags]] stub for each, including the panel size it reads off the tag, so you can paste it straight into your config.

Configure

Create config.toml:

server_url = "http://tesserae.local:8000"
poll_interval_s = 300        # fallback cadence; the server can override per tag

[[tags]]
device_id = "kitchen"         # the Tesserae device id (you choose it)
ble = "AA:BB:CC:DD:EE:FF"      # tag BLE MAC (or a device name to auto-scan)
width = 800                   # the tag's panel, from `discover`
height = 480
pairing_code = "AB12CD"       # optional: a Tesserae pairing code to register this tag once
# token = "..."               # or a device token you already hold
# rotate = 0                  # optional 0 / 90 / 180 / 270
# fit = "contain"             # optional contain / cover / stretch / crop
# dither = "burkes"           # optional dither mode
# refresh = "full"            # optional full / partial

[[tags]]
device_id = "hall"
ble = "OpenDisplay-A1"
width = 400
height = 300
pairing_code = "AB12CD"

Generate a pairing code in Tesserae under Settings → Devices. The bridge registers each tag with that code on first run, then caches the token in config.toml.state.json so later runs skip registration. After a tag is registered it shows up in Tesserae like any other device: bind a dashboard, add it to a rotation, schedule it.

Run

tesserae-opendisplay --config config.toml

Each cycle the bridge asks Tesserae for every tag's frame (sending the last ETag, so unchanged frames cost nothing), and only pushes over BLE when a frame actually changed. BLE uploads happen one tag at a time (Bluetooth is serial), so a change to many tags refreshes them in sequence. Run it under systemd / an init supervisor for an always-on setup, or --once for a single pass (a cron-driven refresh).

Scaling to many tags

  • One bridge cycles its tags sequentially. Fine for a wall that updates on an e-paper cadence.
  • Multiple bridges, each on its own BLE adapter near its cluster of tags, all point at the same server_url. That's how you cover more tags or more rooms: shard the tags across bridges by location.

How it fits together

Tesserae server  ──HTTP /frame──►  bridge (this)  ──BLE upload──►  OpenDisplay tag
   renders                          polls + pushes                  displays

Tesserae renders each tag's dashboard as a full-colour PNG (the opendisplay device kind uses the pi_png renderer); the bridge hands that PNG to the OpenDisplay SDK, which does the panel-specific dithering. Nothing about the tag's geometry lives on the server beyond the panel size you register it with.

License

AGPL-3.0-or-later.

Metadata

Release files for tesserae-opendisplay 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tesserae-opendisplay 0.2.0
File Size Uploaded Provenance Actions
tesserae_opendisplay-0.2.0.tar.gz 35.9 kB With provenance Details for tesserae_opendisplay-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tesserae-opendisplay 0.2.0
File Interpreter ABI Platform Actions
tesserae_opendisplay-0.2.0-py3-none-any.whl Python 3 none any Details for tesserae_opendisplay-0.2.0-py3-none-any.whl

Total release size: 69.0 kB

Release files / tesserae_opendisplay-0.2.0.tar.gz

Download URL tesserae_opendisplay-0.2.0.tar.gz
Size 35.9 kB
Tags Source
SHA-256 checksum
How to use checksums
64c3b4ea198e3e459d8396311079e344fbd08fbb5946d996f314b9bc9ba13140
BLAKE2b-256 checksum
How to use checksums
8289dc9346a30bebaaf5e128f11120c3fdc93c5ea0be515a10507a513cd356d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.

Transparency log

Release files / tesserae_opendisplay-0.2.0-py3-none-any.whl

Download URL tesserae_opendisplay-0.2.0-py3-none-any.whl
Size 33.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3ba475761e54ed8cb8e103137b478a6550b7aa1f1f17ea95f9299a33e3c65f91
BLAKE2b-256 checksum
How to use checksums
a34fc3f3ef9bf23eaf91c709ae2aae88f37386be15cd74302c4eaaea3226e4e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.

Transparency log

Security for tesserae-opendisplay 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tesserae_opendisplay-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page