Skip to main content

couchctl

couchctl controls Samsung (Tizen) televisions and Android TV devices on your home network. It reads whether each screen is on, switches it on and off, opens apps, and sends the remote's app buttons to the apps you actually use.

Most remotes have buttons for apps you may never open (Prime Video, Disney+, a local streaming service). These buttons cannot be remapped on the device. couchctl watches which app is in front, and when a button opens one of those apps it opens your chosen app on top.

Install

pip install couchctl

Android TV devices also need adb (brew install android-platform-tools on macOS, apt install adb on Debian and Ubuntu).

Configure

couchctl reads ~/.config/couchctl/config.toml (or the file in $COUCHCTL_CONFIG, or --config). Copy examples/config.example.toml and change the addresses.

[devices.living-room]
kind = "samsung"
host = "192.168.1.20"
mac = "aa:bb:cc:dd:ee:ff"

[[devices.living-room.redirect]]
from = "3201910019365"
to = "3201606009684"
name = "Prime Video button to Spotify"

[devices.projector]
kind = "androidtv"
adb = "192.168.1.30:5555"

Give each television a fixed address in your router, so the config stays correct.

Use

couchctl state                    # on, off or unknown, for every device
couchctl pair living-room         # once per Samsung set, then choose Allow on the TV
couchctl off living-room
couchctl on living-room           # wake-on-LAN
couchctl launch living-room 3201606009684
couchctl key living-room KEY_HOME
couchctl front living-room        # which redirected app is on screen
couchctl watch                    # redirect the app buttons until stopped
couchctl watch --dry-run          # log presses without launching anything

Samsung televisions

The set answers HTTP on port 8001 without a password. That is enough to read its state, see which app is in front and open an app. Remote keys (power off, home, volume) use a websocket on port 8002, and newer sets ask for permission the first time. Run couchctl pair <device> while the set is on, and choose Allow on the television when it asks. couchctl keeps the token the set returns in ~/.config/couchctl/tokens.json (readable only by you) and uses it from then on.

couchctl on sends a wake-on-LAN packet to the mac in the config. The set only answers it when "Power on with mobile" is enabled (Settings, General, Network, Expert settings on most models).

A Samsung app id is the long number in the Samsung app store (3201606009684 is Spotify), or for a sideloaded app the id its package declares. To find the id behind a button, press the button and run couchctl front <device> <id> <id> ... with the ids you suspect, or read the list from the set with sdb shell 0 vd_applist if you have Tizen Studio.

Android TV

Turn on network debugging in the device's developer options and allow the adb prompt on screen once. Apps are named by their package (com.spotify.tv.android), and couchctl front prints whatever package is in front. A device in standby usually stops answering adb, so couchctl reconnects by itself when it comes back.

Most Android TV devices cannot be woken over the network. Some projectors only wake from a Bluetooth signal sent by their own remote.

How the redirect works

The watcher asks each device once a second which app is in front. When an app with a redirect becomes visible, it opens the replacement.

  • It acts only when the app appears, so if you go back to that app on purpose it is left alone.
  • When the watcher starts, or when a device comes back after being out of reach, the app already on screen is never treated as a press.
  • Each device has its own thread, so a television that is off does not slow down the others.

The original app does appear for a second or two before it is replaced, and the redirect works only while the watcher runs on the same network as the screens. A Raspberry Pi is a good host for it. A systemd unit is in examples/couchctl-watch.service.

With --report-url, every redirect is also posted as JSON (device, from, to, name, outcome, message, time), with an optional bearer token read from the environment variable named by --report-token-env.

Limits

  • couchctl must be on the same network as the screens. From another network every device reads as off, so use couchctl state --maybe-away on a laptop that moves between networks.
  • The Samsung websocket uses the set's own self-signed certificate, so that one connection is not verified.
  • Tested on Samsung Tizen televisions from recent years and an XGIMI projector running Android TV.

Development

python -m venv .venv && .venv/bin/pip install -e '.[test]'
.venv/bin/pytest

The tests use a fake Samsung set and a fake adb, so they need no hardware.

License

MIT

Metadata

Release files for couchctl 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for couchctl 0.1.0
File Size Uploaded
couchctl-0.1.0.tar.gz 18.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for couchctl 0.1.0
File Interpreter ABI Platform
couchctl-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 36.3 kB

Release files / couchctl-0.1.0.tar.gz

Download URL couchctl-0.1.0.tar.gz
Size 18.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0e1a96690ab052725b22db0a07923c99d8fcfd866d4bd029a23cd4f6641a75e4
BLAKE2b-256 checksum
How to use checksums
0151c7b175b740092910bd4683bd5739098c2fc880d1150c959314a749e848f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / couchctl-0.1.0-py3-none-any.whl

Download URL couchctl-0.1.0-py3-none-any.whl
Size 17.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4b8a5f681fdd7b6ce7f9f8afb44597892fc0a98fb78f5b9f87476d98a22fa6b4
BLAKE2b-256 checksum
How to use checksums
ba1ba6c843a1beea91273abe8db43fe2c89e91bfd67efccd2c6462f7ef33bb8f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page