sony-tv-rs232
Async Python library to control Sony Bravia TVs over RS232 serial, built on serialkit and serialx.
Installation
pip install sony-tv-rs232
# To talk to a TV over an ESPHome serial proxy:
pip install 'sony-tv-rs232[esphome]'
Requires Python 3.14+.
Quick start
import asyncio
from sony_tv_rs232 import SonyTV, InputSource
async def main():
tv = SonyTV("/dev/ttyUSB0")
await tv.connect()
await tv.enable_standby_listening() # so power_on works from standby
await tv.power_on()
await tv.set_volume(20)
await tv.select_input_source(InputSource.HDMI1)
await tv.disconnect()
asyncio.run(main())
CLI
python -m sony_tv_rs232 /dev/ttyUSB0 # query + print status
python -m sony_tv_rs232 socket://192.168.1.29:5000 # raw TCP bridge
python -m sony_tv_rs232 'esphome://192.168.1.29/?port_name=TTL'
python -m sony_tv_rs232 /dev/ttyUSB0 --power on
python -m sony_tv_rs232 /dev/ttyUSB0 --input HDMI1
python -m sony_tv_rs232 /dev/ttyUSB0 --diagnose # raw wiring diagnosis
Protocol notes
Sony's consumer RS-232C protocol is effectively set-only: the TV acknowledges every Set command but most models ignore query packets, and the answer frame carries no echo of which command it answers. The library:
- updates
stateoptimistically when a Set is acknowledged, and from query replies on the Pro Bravia displays that answer them; - runs every command as an exclusive exchange, because answers are unaddressed — holding the wire for one send-and-read round, anchored on arrival order, is what keeps a dropped or garbled answer from being read as the next command's;
- paces commands ≥ 500 ms apart, as the Sony spec requires;
- reconnects automatically when the serial link drops.
All of that machinery lives in serialkit; this library is the Sony command
surface plus a checksum-discriminated answer framer.
Connection handling
from sony_tv_rs232 import CommandTimeoutError, ConnectionLostError, SonyCommandError
try:
await tv.set_volume(50)
except SonyCommandError as err: # TV returned a non-zero answer code
...
except CommandTimeoutError: # no answer in time (common on set-only TVs)
...
except ConnectionLostError: # serial link dropped
...
Subscribe to state changes; callbacks receive a TVState snapshot, or None
when the connection is lost:
unsub = tv.subscribe(lambda state: print("state:", state))
Serial connection
Sony Bravia sets use 9600 baud, 8N1. The library accepts any
serialx-compatible URL (/dev/ttyUSB0, socket://host:port,
esphome://host/?port_name=TTL).
Development
uv run --python 3.14 pytest
uvx ruff check
The RS-232C protocol reference is in docs/.
License
MIT
Release files for sony-tv-rs232 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sony_tv_rs232-0.2.1.tar.gz | 15.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sony_tv_rs232-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.7 kB
Release files / sony_tv_rs232-0.2.1.tar.gz
| Download URL | sony_tv_rs232-0.2.1.tar.gz |
|---|---|
| Size | 15.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0aae948cc0d3731ed840a96400b61a552d059d69a3700f192048c27b1d30fb84
|
|
BLAKE2b-256 checksum How to use checksums |
c696cae84249ad39f675cfc5ca641d34b45c6efb9a2ca569e7bd8ad284e72777
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 28, 2026.
Transparency logRelease files / sony_tv_rs232-0.2.1-py3-none-any.whl
| Download URL | sony_tv_rs232-0.2.1-py3-none-any.whl |
|---|---|
| Size | 19.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4078cde47071e9504302a79dee0591c2247f8b5ff3bbfad0324a9c8999f9072a
|
|
BLAKE2b-256 checksum How to use checksums |
282dd0d643b78bacb656f36acf4d2f013909ff96c7f14a7ce53a9412311f4e23
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 28, 2026.
Transparency log