Skip to content

rabidfurball/adb-atv-manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

adb-atv-manager

Centralized ADB control for a fleet of Android TV / Fire TV devices, wrapped in a single Docker container with a metrics dashboard.

What it adds on top of scavin/ws-scrcpy:

  • ADB-managed device pool — connects to all your devices on startup so they show up in ws-scrcpy's device list immediately (no per-device adb connect clicking)
  • Metrics dashboard at :8095 — Glances-style cards per device with CPU / RAM / disk / temps / running app / top-5 processes / screenshot
  • JSON API at :8095/api (and root) — same data structured for Homepage customapi widgets or your own scrape
  • Per-device screenshots at :8095/screenshot/<Name> — refreshed on each poll cycle, suitable for Homepage thumbnail widgets
  • One-click ADB shell or screen mirror from each dashboard card
  • ws-scrcpy quality-of-life patches — bumps default bitrate from ~500 kbps to 4 Mbps and forces fit-to-screen so the stream actually fills the iframe instead of showing a tiny corner

Why this exists

Out of the box ws-scrcpy requires re-establishing ADB connections manually each time the container starts. With a fleet of always-on streaming devices that get rebooted occasionally, that's tedious.

It also shows nothing useful at-a-glance — you have to drill into each device to see if it's even online. The metrics dashboard gives a single page summary of the whole fleet that you can drop into Homepage (or any iframe-friendly dashboard) and click through to the screen mirror or shell when something looks off.

Compatible devices

Anything with ADB over network support, which in practice is:

  • NVIDIA SHIELD Android TV (any model with developer mode + network ADB)
  • Amazon Fire TV (any generation with ADB enabled)
  • Google Chromecast w/ Google TV
  • Google TV Streamer
  • Sideloaded Android TV boxes (whatever you've got)

Tested on a mixed fleet of NVIDIA SHIELDs and Fire TVs. Should work with anything ADB can connect to over IP.

Quick start

git clone https://github.com/rabidfurball/adb-atv-manager.git
cd adb-atv-manager
# Edit docker-compose.yml — set ADB_DEVICES + SCRCPY_HOST_URL
docker compose up -d

Then open the dashboard at http://<docker-host>:8095 and the raw ws-scrcpy at http://<docker-host>:8096.

First-run device pairing

Each device needs to authorize this container's ADB key the first time it tries to connect. After docker compose up -d:

  1. The container will try to adb connect to each device on startup
  2. Each device should show an "Allow USB debugging?" prompt with the container's RSA fingerprint
  3. Tick "Always allow from this computer" on the device screen, then OK
  4. The connection should then succeed (visible in docker compose logs adb)

The ADB keys are persisted in a named Docker volume (adb-keys) so this only happens once per device.

To enable ADB debugging on a fresh device:

  • NVIDIA SHIELD: Settings → Device Preferences → About → tap Build 7 times → back → Developer Options → Network debugging ON
  • Fire TV: Settings → My Fire TV → About → tap Serial Number 7 times → back → Developer Options → ADB Debugging ON

Configuration

All via environment variables in docker-compose.yml:

Var Default Purpose
ADB_DEVICES (none — required) Comma-separated Name:IP pairs. Names appear in the dashboard, IPs are the LAN address of each device. Port 5555 is implied.
SCRCPY_HOST_URL http://localhost:8096 Public URL for ws-scrcpy. Used to build mirror links and WebSocket URLs in the dashboard. Must match the URL your browser will use to reach port 8096 of this container.
POLL_INTERVAL 30 Seconds between metrics polls. Lower = fresher data, higher = lower load on devices. 30 is a reasonable default.
METRICS_PORT 8080 (internal) Port the metrics server listens on inside the container. The compose file maps it to host 8095.
SCRCPY_PORT 8000 (internal) Port ws-scrcpy listens on inside the container. The compose file maps it to host 8096.
TZ UTC Timezone for log timestamps.

To add a new device after first deploy: edit ADB_DEVICES, run docker compose up -d adb (recreates the container), accept the ADB authorization prompt on the new device's screen.

Endpoints

URL Purpose
http://<host>:8095/ Dashboard (HTML) — auto-refreshes every 30s
http://<host>:8095/api JSON metrics — full payload of all devices
http://<host>:8095/screenshot/<Name> Latest PNG screenshot for one device
http://<host>:8095/refresh Trigger an out-of-cycle metrics poll (for "refresh now" buttons)
http://<host>:8096/ Raw ws-scrcpy UI — device list, dev tools, file manager

JSON shape

The /api endpoint returns:

{
  "timestamp": "2026-04-24T01:30:00Z",
  "devices": [
    {
      "name": "Theatre",
      "ip": "192.168.1.10",
      "status": "online",
      "model": "SHIELD Android TV",
      "cpu_user": 12,
      "cpu_idle": 80,
      "mem_total_mb": 3000,
      "mem_avail_mb": 1200,
      "storage_total": "13G",
      "storage_used": "9G",
      "storage_pct": 73,
      "cpu_temp": 45.2,
      "gpu_temp": 50.8,
      "app": "com.plexapp.android",
      "top_processes": [
        {"pid": 1234, "cpu": "10", "mem": "5", "name": "com.plexapp.android"}
      ]
    }
  ]
}

Offline devices return only name, ip, and status: "offline".

Homepage integration

To show the dashboard as a Homepage widget, use a customapi widget pointing at the JSON endpoint. Example:

- ATV Fleet:
    icon: mdi-android
    href: http://<host>:8095
    widget:
      type: customapi
      url: http://<host>:8095/api
      mappings:
        - field: devices.0.app  # currently playing on first device
          label: Theatre
        - field: devices.1.app
          label: Bedroom

Or use individual iframe widgets pointing at http://<host>:8095/screenshot/<Name> for thumbnail strips.

License

MIT — see LICENSE.

The wrapped ws-scrcpy upstream is GPL-3.0; nothing in this repo modifies that container image's source. We patch its bundled JS at container start (bitrate + fit-to-screen defaults) and that patch is applied at runtime, not redistributed.

Acknowledgements

About

Centralized ADB management for a fleet of Android TV devices (Shields, Fire TVs, etc.) — wraps scavin/ws-scrcpy with a polling metrics dashboard, JSON API for Homepage widgets, and per-device screenshots

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages