Skip to content

Repository files navigation

Tesserae for reMarkable

Turn a reMarkable tablet into a Tesserae dashboard panel. The app runs inside the reMarkable's own interface through AppLoad, pairs with your self-hosted Tesserae server over its v1 REST device API, fetches each rendered frame, shows it, and puts the tablet into deep sleep until the server wants it back. Refresh cadence, schedules, rotations and quiet hours are all decided on the server; the tablet just wakes, paints and sleeps.

  • reMarkable 2 (tested) and reMarkable 1: 1404 x 1872, 16-level greyscale, dithered on the server with the algorithm you pick per device.
  • reMarkable Paper Pro: 1620 x 2160 colour PNG through the tablet's own colour pipeline (built, not yet confirmed on hardware).
  • Zero-touch pairing: the tablet announces itself, you click Register in Tesserae. A 6-digit pairing code works too.
  • Deep sleep between refreshes with an RTC wake alarm. By default the tablet stays awake while charging (for up to four hours) and sleeps on battery.
  • ETag-conditional polls, so unchanged content costs one small request and no e-ink flash. Battery, signal, IP and errors are reported to the device card.
  • Keeps the last frame on screen when the network is down, with a bounded retry backoff, and forwards errors to Tesserae's Events page.

This is a community project. It is not affiliated with reMarkable or with the Tesserae maintainer, and a reMarkable firmware update can break it. It is derived from the MIT-licensed TRMNL for reMarkable app, which did the hard work of running a Go backend and a QML frontend inside xochitl; see THIRD_PARTY_NOTICES.md.

Caution

Enabling Developer Mode factory-resets the tablet. Sync or export everything you care about first. Developer Mode also lowers the tablet's security, and uninstalling this app does not turn it back off. Read reMarkable's Developer Mode notes before you start.

How it works

reMarkable (AppLoad app)                         Tesserae server
  Tesserae.qml  <-- AppLoad socket -->  backend/entry (Go)
                                          |  POST /api/v1/device/discover   (until you click Register)
                                          |  POST /api/v1/device/<id>/status -> next_poll_s, config
                                          |  GET  /api/v1/device/<id>/frame  -> 200 envelope | 304 | 204
                                          |  GET  /renders/<render_id>.bin|png
                                          v
                              paint -> arm RTC alarm -> systemctl suspend

The server renders your dashboard at the panel's exact size. For the greyscale tablets it sends a packed 4-bit, 16-grey buffer already dithered (esp32_gray_bin); the app unpacks it into an image and hands it to the tablet's display stack. For the Paper Pro it sends a plain 24-bit PNG.

What you need

Tablet reMarkable 2 or reMarkable 1 on OS 3.20 to 3.27, or a Paper Pro on 3.26 or 3.27, with Developer Mode (SSH) enabled andXOVI + AppLoad installed
Server A runningTesserae (0.392 or newer), reachable from the tablet's Wi-Fi network. Plain http:// on your LAN is fine
Computer macOS, Linux or Windows with Go 1.22+ and Qt 6 (for rcc), and SSH access to the tablet

Step 1: enable SSH on the tablet

reMarkable Paper Pro and reMarkable 2 on recent firmware (3.20+): Developer Mode

  1. Sync or export your notebooks. The next step erases the tablet.

  2. On the tablet open Settings → General → Software → Advanced (the exact place has moved between releases; look for Developer mode) and turn it on. Confirm the factory reset and complete the onboarding again.

  3. Go to Settings → General → Help → Copyrights and licenses. At the bottom you will find the SSH password and the USB address (10.11.99.1).

  4. Connect the USB cable and check you can log in from your computer:

    ssh root@10.11.99.1
    

    On Wi-Fi the tablet's address is shown under Settings → Help → Copyrights and licenses too, or on your router.

reMarkable 1 and older reMarkable 2 firmware

These do not have a Developer Mode switch: SSH is always on. The password is under Settings → Help → Copyrights and licenses → GPLv3 Compliance (scroll down). Use it with ssh root@10.11.99.1 over USB.

Once you are in, copy your SSH key so the deploy script does not ask for the password each time:

ssh-copy-id root@10.11.99.1

(If ssh-copy-id is missing: cat ~/.ssh/id_ed25519.pub | ssh root@10.11.99.1 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'.)

Step 2: install XOVI and AppLoad

The app is an AppLoad application. Follow the install instructions in the rm-appload and rm-xovi-extensions READMEs for your tablet, then confirm the AppLoad icon appears in the reMarkable sidebar and that this directory exists on the tablet:

/home/root/xovi/exthome/appload

XOVI is not persistent across reboots by design: after a reboot run /home/root/xovi/start over SSH to bring AppLoad back.

Step 3: build and copy the app

On your computer:

brew install go qt          # macOS; on Debian/Ubuntu: golang qt6-base-dev-tools qt6-declarative-dev-tools
git clone https://github.com/partridgeworks/tesserae.remarkable
cd tesserae.remarkable
make test                   # unit tests, vet, QML lint
make build                  # dist/tesserae-remarkable-app (Paper Pro) and dist/tesserae-remarkable-app-arm32 (rM1/rM2)
make deploy TABLET=root@10.11.99.1

make deploy detects the tablet's architecture, copies the matching bundle to /home/root/xovi/exthome/appload/tesserae-remarkable, runs the bundle's self-check on the tablet, and restarts a running backend. Settings, cache and pairing survive a redeploy.

When redeploying a newer version, note that xochitl keeps the app's QML cached in memory once it has been opened. A new backend is picked up on the next launch, but a changed screen layout needs xochitl restarted: reboot the tablet (or ssh root@10.11.99.1 systemctl restart xochitl, which on some firmware also reboots), then run /home/root/xovi/start and open the app again.

Prefer to copy by hand? After make build:

scp -r dist/tesserae-remarkable-app-arm32 root@10.11.99.1:/home/root/xovi/exthome/appload/tesserae-remarkable

(use dist/tesserae-remarkable-app for a Paper Pro).

Optionally seed the server address so you do not have to type it on the tablet:

ssh root@10.11.99.1 'mkdir -p ~/.config/tesserae-remarkable && printf "%s\n" "{\"server_url\": \"http://192.168.1.4:8765\"}" > ~/.config/tesserae-remarkable/config.json && chmod 600 ~/.config/tesserae-remarkable/config.json'

Step 4: tell Tesserae about the tablet (recommended)

Tesserae picks the renderer from the device kind. The reMarkable kinds are data-only catalog entries in server/hardware/remarkable/ until they ship with Tesserae. Install them on your server and restart it:

  • Docker: copy the files next to your compose file and bind-mount them, then docker compose up -d:

    volumes:
      - ./hardware/remarkable/remarkable_2.json:/app/hardware/remarkable/remarkable_2.json:ro
      - ./hardware/remarkable/remarkable_1.json:/app/hardware/remarkable/remarkable_1.json:ro
      - ./hardware/remarkable/paper_pro.json:/app/hardware/remarkable/paper_pro.json:ro
  • Bare install / LXC: copy them to <tesserae>/hardware/remarkable/ and restart the service.

docker logs tesserae | grep "hardware-catalog kind remarkable" confirms they loaded. Without them the app pairs as the stock esp32_client kind (which renders a colour Spectra-6 buffer the app converts to grey) and moves itself to the right kind automatically the first time it finds the entry installed.

Step 5: open the app and pair

  1. On the tablet open AppLoad and tap Tesserae.
  2. If you did not seed the address, tap the top-right corner, open Settings, enter the server address (for example http://192.168.1.2:8765), tap Test connection, then Save.
  3. The screen shows Waiting for Register in Tesserae with the device id and MAC. In Tesserae open Settings → Devices; the tablet is in the Discovered strip. Click Register (optionally rename it).
  4. Within 30 seconds the tablet receives its token and shows bind a dashboard. In Tesserae, bind a dashboard to the device and press Send.
  5. The first frame appears. From now on the tablet follows the server's Sleep interval (device card), schedules and rotations.

Can't be at the browser while the tablet announces itself? Mint a code under Settings → Devices → Pair new device, type it into the app's Settings and tap Pair with code.

Using it

What Where
Menu (controls, settings, diagnostics) Tap the upper-right corner
Refresh now / Fetch latest / Previous frame / Sleep now Buttons in the menu
Front light and weekly brightness schedule (Paper Pro) Menu
History of refreshes, sleeps and errors Menu
Diagnostics (token redacted) Menu → Diagnostics
Back to reMarkable AppLoad's swipe from the top centre, the on-screen button, or hold the upper-left corner for two seconds

Settings live in /home/root/.config/tesserae-remarkable/config.json (mode 0600, token included); cache in ~/.cache/tesserae-remarkable; logs and state in ~/.local/share/tesserae-remarkable.

Power and sleep

The server decides when the tablet should come back (next_poll_s, or an absolute wake_at with synchronized wake). The app decides what the tablet does in between:

Power mode Behaviour
Sleep on battery, stay awake while charging (default) On battery the tablet arms its RTC alarm and suspends a few seconds after each refresh. On the charger it stays awake and polls, for up to 4 hours (configurable), then sleeps between refreshes anyway.
Always sleep between refreshes Best battery life.
Never sleep For a mains-powered wall panel. The app advertises can_stay_awake, which unlocks Tesserae's Always on / Awake poll interval options on the device card for near-instant pushes.

Settings also offer the grace period before sleeping, a floor under the refresh interval, and a battery saver that stretches the interval below 20%. A touch on the screen or an open menu postpones the sleep. Manual sends and webhooks reach a sleeping tablet on its next wake; if that matters, shorten the sleep interval on the device card or use always-on.

Recommended tablet settings: leave reMarkable's Auto sleep on and Auto power-off off; a powered-off tablet cannot wake itself.

Removing it

ssh root@10.11.99.1 rm -rf /home/root/xovi/exthome/appload/tesserae-remarkable

Add ~/.config/tesserae-remarkable ~/.cache/tesserae-remarkable ~/.local/share/tesserae-remarkable to also erase settings, cache and logs. Delete the device in Tesserae's Settings → Devices. XOVI and AppLoad are left alone; see their own docs for removing them.

Troubleshooting

Problem Try
Server not reachable Check the address and that the tablet is on Wi-Fi. Use the IP rather than a .local name if mDNS does not resolve on the tablet.
plain HTTP is only allowed for servers on your local network The address is not a private/LAN one. Use HTTPS, or turn onAllow plain HTTP to any host in Settings.
Stuck onWaiting for Register Open Tesserae → Settings → Devices and click Register in the Discovered strip. The device id and MAC are on the tablet's screen.
bind a dashboard never goes away Bind a dashboard to this device in Tesserae and press Send.
Frames look 1-bit or wrongly coloured The catalog entry is missing on the server (step 4). Diagnostics shows the paired kind and renderer.
Tablet does not wake for the refresh Diagnostics shows the wake alarm state. Make sure Auto power-off is off. After a reboot run /home/root/xovi/start and open the app again.
Gone after reboot XOVI does not persist across reboots; run /home/root/xovi/start over SSH.

Logs: /home/root/.local/share/tesserae-remarkable/tesserae.log on the tablet, and Tesserae's Settings → Events for forwarded errors.

Development

make test          # go test, vet, gofmt, qmllint
make integration   # AppLoad socket harness against the mock server (Linux only: needs SOCK_SEQPACKET)
make mock          # run the mock Tesserae server on 127.0.0.1:9988

Layout:

  • app/ui/Tesserae.qml: the AppLoad frontend
  • backend/cmd/tesserae-remarkable: the device backend (pairing, polling, painting, sleep)
  • backend/internal/tesserae: the REST client; frame: frame decoders; power: RTC alarm and suspend
  • backend/cmd/tesserae-mock: a small Tesserae stand-in for tests
  • server/hardware/remarkable: Tesserae hardware catalog entries
  • device/: on-device install, uninstall, recovery and diagnostics scripts
  • scripts/deploy.sh: build-and-copy over SSH

Licence

MIT. See LICENSE and THIRD_PARTY_NOTICES.md.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages