cat

RETAINED

That old tablet in your drawer? Mount it on the wall.

Retained connects to your MQTT brokers and turns sensor data into live gauges, charts and indicators — on the phone in your hand, or a tablet mounted on the wall. Android 6.0 and up, so the one in the drawer works too.

  • android 6.0+
  • 3 mb
  • free
  • no account
  • no cloud
  • no ads

dashboard

A wall-mounted tablet showing temperature, humidity, pressure and CO2 as coloured arc gauges, an hour of chart history, a gas bar and a temperature sparkline.
A real ESP32 BME680 feed on a wall-mounted tablet. Each gauge carries its own colour zones, so the dial says what the number means before you have read it — and the CO2 reading has gone red on a threshold rule. Nothing here is a mockup.

./preview

See the payload. See the value. As you type.

Point Retained at a topic and it shows you the last real message that arrived, with your extracted value updating live while you edit the path. No save-and-hope loop, no guessing whether $.sensors[0].temp was the right path.

Pull a value out of whatever shape it arrives in — JSON via JSONPath, CSV by delimiter and column, regex capture groups, or raw binary by byte offset and type (u8, i16, f32, either endianness). Then transform it: x / 10, round(x, 1), whatever quirk the sensor has.

live preview

The data source editor showing a raw MQTT payload and the extracted value, 22.3 C, updating beneath it.

ls features/

What it does

connections

Any broker

MQTT 3.1.1 and 5.0 over TCP, TLS, WebSocket or secure WebSocket. Username and password, client certificates, self-signed certs. Last will, clean start, session expiry. Automatic reconnect with backoff, held open by a foreground service.

widgets

Ten widget types

Value cards, arc and bar gauges, line charts, sparklines, LED indicators and scrolling text logs — plus buttons, switches and sliders that publish back to your broker.

rules

Reacts to thresholds

Colour zones on gauges, and rules that recolour a widget, blink it, or raise a notification when a reading goes out of range.

layout

One layout that reflows

Arrange a page once and rotating the device re-columns it. No second grid to keep in sync, and no widgets landing on top of each other.

kiosk

Kiosk mode

Screen on, system bars hidden, editing locked out. A dimming schedule for quiet hours, tap to wake, optional PIN to leave. Full always-on engages only while charging, so an unplugged tablet is not cooked overnight.

performance

Built for old hardware

Updates conflated to a few a second, history kept as in-memory ring buffers and downsampled before drawing, charts drawn straight to canvas. No chart library, no WebView. There is an e-paper mode for e-ink panels.

new hardware too

Old is the floor, not the target

Android 6.0 is the minimum, not the intended device. Retained runs on a current phone or tablet exactly the same way — it is simply built so that a decade-old one is not excluded. Phones, tablets and e-ink panels all work.

home assistant

MQTT Discovery

Opt in per connection and Retained reads Home Assistant MQTT Discovery, then offers what it found as one-tap data sources. Nothing is created behind your back.

config

Export and import

The whole configuration round-trips through a single JSON file. Set up one tablet, move it to the next. Passwords are deliberately left out of the export.

ls widgets/

Every widget type, one page

Two air-quality sensors on one board, read side by side: a BME680 running BSEC and an SGP41 reporting its own VOC and NOx indices. Arc and bar gauges, a two-series chart, a sparkline, an LED, a scrolling feed of the raw values — and the three control widgets, which publish back to the broker rather than only listening to it.

widgets

A dashboard page combining arc gauges, linear gauges, a two-series chart, a sparkline, an LED indicator, a live text log and publish button, switch and slider controls.
The same broker, a second page. Both sensors’ air-quality estimates are plotted against each other, and the bells mark the widgets a threshold rule has already fired on.

cat model.txt

Define a value once, use it everywhere

A data source is a named value — Temperature, CO2 — not a widget. Define the extraction once and every gauge, card and chart on every page reads from it, with one shared history behind them. Change the topic later and nothing downstream needs rebuilding.

data sources

The data source list showing named values with their live readings.
Data sources with live values. Widgets reference these, so the same reading can appear as a gauge on one page and a chart series on another.
  • Staleness is visible. If a reading stops arriving, the widget greys out and tells you how old it is. A frozen gauge that still looks healthy is worse than an obvious error.
  • Failures are loud. A path that stops matching shows an error badge on the widget. It never silently renders the last good value.
  • Multiple brokers at once. Connections are independent, so one page can mix sensors from your ESP32 broker and your Home Assistant broker.

privacy

Retained has no backend. There is nothing to sign up for, no analytics SDK, no crash reporting and no advertising. The app makes network connections only to the brokers you enter yourself, broker credentials are encrypted on-device with a key held in the Android Keystore, and uninstalling removes everything.

read the privacy policy >>

before you mount it

Android will kill a background network connection to save power, and that is the single most common cause of a dashboard that is dead by morning. Retained explains this on first run and asks to be exempted from battery optimisation. You can decline and the app still works — less reliably in the background. Grant it, and plug the tablet in.

Free, with no account and nothing to configure in the cloud.