Skip to content
 
 

Repository files navigation

DeckaTV

A Decky Loader plugin for SteamOS that pairs with network TVs, switches their HDMI input from the Quick Access menu, and automatically wakes a TV and switches it to the right input when SteamOS connects to that screen — like HDMI-CEC, but over the network.

The core is brand-agnostic. Drivers ship for LG (webOS) and TCL (Google TV) (including the 75QM6K Pro); other brands plug in without touching the rest of the code.

Features

  • Pair one or more TVs (pick the brand, enter the IP).
  • Manually switch any paired TV's input.
  • Per-screen auto-switch rules: each connected display maps to a TV + input. When that screen appears — at boot, on resume, or when the TV reconnects — the TV is woken over the network (Wake-on-LAN) and switched to the chosen input automatically.

Architecture

main.py                         composition root: builds the driver registry, wires the plugin
backend/                        Python source (our code)
  tv_core/                      brand-agnostic core (knows no driver)
    driver.py                   TvDriver contract + registry (build/list/select)
    edid.py                     display detection
    store.py                    paired TVs + rules; TV = {host,name,brand,creds}
    tests/                      core unit tests (excluded from the release)
  tv_driver_lg/                 LG driver package (depends on tv_core)
    __init__.py                 LgDriver
    webos.py                    LG SSAP WebSocket client
  tv_driver_tcl/                TCL Google TV driver (Android TV Remote v2)
    __init__.py                 TclDriver
    atv.py                      pairing + app-link input switching
    discover.py                 mDNS browse for `_androidtvremote2._tcp`
src/                            React UI (generic; brand is just a dropdown)
scripts/                        build, deploy, and vendor tooling
py_modules/                     vendored pure-Python deps (gitignored; built in CI)

Single repository, single release. Dependencies point one way: tv_driver_* → tv_core, and main.py → drivers. The core never imports a driver; it only calls pair, list_inputs, and set_input on the TvDriver contract. Displays are identified by EDID, so a rule follows the physical TV rather than a port. A 5-second poll detects when a screen appears and applies its rule.

Adding a new brand

  1. Create backend/tv_driver_<brand>/ with a TvDriver subclass implementing pair, list_inputs, set_input, plus a unique name and label. Brands that show an on-screen PIN raise NeedsPin from pair when called without one (the UI already handles the follow-up PIN entry).
  2. Inject it in main.py: build_registry([LgDriver(), TclDriver(), …]).

Nothing in tv_core changes for prompt-only brands; PIN brands only need the existing pair_tv(..., pin) path.

Install (prebuilt)

Requires Decky Loader with Developer mode enabled — the plugin needs _root to read display info.

From URL (recommended)

  1. In Decky, go to Settings → Developer mode and choose Install Plugin from URL.

  2. Paste this URL — it always points to the latest release:

    https://github.com/hunguy/DeckaTV/releases/latest/download/deckatv.zip
    

    (This is the release zip URL, not the repository URL.)

  3. Restart Decky (or reboot) — plugins installed from a URL only appear after a restart. It shows up as "DeckaTV" in the plugin list.

Manual

Download the release .zip from the Releases page, extract it into ~/homebrew/plugins/, and restart Decky.

Usage

  1. Turn the TV on and connect it to your network.
  2. Open the plugin, pick the brand, enter the IP, press Pair.
    • LG: accept the prompt on the TV.
    • TCL (Google TV): enter the 6-character code shown on the TV.
  3. Use Switch input to change inputs manually.
  4. Under Auto-switch rules, pick the TV and input for each screen and enable the toggle.

For TCL wake-from-standby (PC resume / docking while the TV sleeps), enable on the TV:

  • Settings → System → Power & energy → Standby → Network standby (On)
  • Quick Start (On), if your firmware shows it

Without Network Standby the control ports go fully offline and Wake-on-LAN often fails on Wi‑Fi.

Build from source

pnpm install
pnpm run build          # produces dist/index.js

Pure-Python dependencies (websockets, protobuf) are vendored under py_modules/ by scripts/vendor_python.sh.

About

Decky Loader plugin that automatically wakes your smart TV and switches it to the right HDMI input — like HDMI-CEC, but over the network.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages