# BYOD/S

In the BYOD/S configuration, the only TRMNL IP is our [open source firmware](https://github.com/usetrmnl/firmware).

### Device setup

See our [alternate screens](https://github.com/usetrmnl/#alternative-screens-and-clients) and [BYOD guide](https://docs.trmnl.com/go/diy/byod) for instructions to jailbreak or build a device that's compatible with our firmware.

### Server quickstart

The TRMNL web server generates PNG images. When a device pings our [Display API](https://docs.trmnl.com/go/private-api/screens), the next-in-queue image is shared as an absolute URL inside a JSON response like this:

```
{
  "image_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.png"
}
```

For ready-made OSS server clients, see [BYOS Implementations](https://docs.trmnl.com/go/diy/byos#implementations). To develop your own server that is TRMNL firmware compatible out of the box:

1. [Build or jailbreak a device](https://docs.trmnl.com/go/diy/byod)
2. Change the base URL to your own server or local network from the WiFi Captive Portal
3. Mimic the `api/setup` and `api/display` endpoints per our [firmware README](https://github.com/usetrmnl/firmware)
4. Follow our [ImageMagick guide](https://docs.trmnl.com/go/diy/imagemagick-guide) to create TRMNL firmware compatible images
5. Profit(?)

### Other infrastructure

In the quickstart above we glossed over a critical element: "next-in-queue" images.

At TRMNL we use a Playlists table to manage the ordering of plugin instances, letting users drag/drop different items in whatever sequence they prefer.

<figure><img src="https://1607647240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnXhDs1PQJ2VX7ppA91eY%2Fuploads%2FWc6lzvJShblFqp1oM4F6%2FTRMNL-playlist-items.png?alt=media&#x26;token=e5b44b3c-350a-479b-8b48-672075779d8d" alt=""><figcaption><p>Drag/Drop Playlists UI</p></figcaption></figure>

Each item in a Playlist is an *instance* of a Plugin, which we call a PluginSetting.

This keeps our Plugins table immutable, for example Google Calendar is just a name, icon, and form field parameters. Meanwhile details about a *connection* to Google Calendar are stored inside a PluginSetting record. Keep this in mind as you build your own server -- do you want to allow multiple connections to the same parent plugin?

TRMNL also offers a [Scheduler](https://help.trmnl.com/en/articles/11663305-playlist-scheduler). This makes it easy to dictate conditions for when and why a given plugin is displayed on your device.

<figure><img src="https://1607647240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnXhDs1PQJ2VX7ppA91eY%2Fuploads%2Fgit-blob-eab7edc539f4b3a1a6f9e67ea84d9b614206d0d7%2FTRMNL-playlist-scheduler.png?alt=media" alt="Scheduler in action"><figcaption><p>Playlist scheduler in action</p></figcaption></figure>

Following our architecture is unnecessary for a self-hosted ePaper dashboard, but we do encourage you to check out those which have already been implemented in [BYOS clients](https://docs.trmnl.com/go/diy/byos).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.trmnl.com/go/diy/byod-s.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
