Python client for Seymour masking screens, connected via direct serial or Global Caché iTach IP2SL
Project description
seymourlib
Python client for Seymour masking screens, connected via direct serial or Global Caché iTach IP2SL. Built for rock-solid control loops, Home Assistant integrations, and quick bench testing. 😎
Highlights
- Async-first client and transport abstractions (TCP/IP2SL vs native serial) with consistent APIs.
- Protocol helpers that mirror the official Seymour RS232 spec, including parsing/validation utilities.
seymourctlCLI for one-off commands, scripting, and smoke tests in CI.- Zero-config Global Caché IP2SL and serial-port discovery via async helpers and CLI subcommands.
- Movement/preset commands poll controller status and return only once the motors report HALTED/STOPPED, so scripts never race ahead.
- Batteries-included retry logic (
tenacity), timeout handling, and graceful cancellation viaanyio.
Architecture at a Glance
flowchart TB
App[Your automation / HA stack] -->|async API| Client[SeymourClient]
Client --> Protocol[Protocol helpers]
Client --> Transport
Transport -->|TCP 4999| IP2SL[Global Caché IP2SL]
Transport -->|RS232| Screen[Seymour Masking Screen]
IP2SL -->|RS232| Screen
Installation
Requirements
- Python 3.11+
uv>= 0.9 (preferred) or classicpip
Quick install (recommended)
uv tool install --python 3.11 "seymourlib[serial]"
- This pulls the published wheel straight from PyPI and drops a
seymourctlexecutable anywhere on yourPATH. - Use
seymourctl --helpto confirm things are wired up, then jump straight to the CLI examples below.
Existing virtual environments
Already have a project venv or uv workspace? Install directly:
uv add "seymourlib[serial]"
This will update your project's dependencies, install the latest source distribution of seymourlib, and update whatever lockfiles your project may use.
💡 The optional
serialextra pulls inpyserial-asyncioso the same client works over USB/RS232 without the IP bridge. If you want to trim your project's dependency graph and never plan to talk over direct RS232, you can skip it.
Classic pip fallback
python -m venv .venv
. .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install "seymourlib[serial]"
Local Development
To debug, contribute code, or run the full test suite:
- Clone & bootstrap
git clone https://github.com/richard-berg/seymourlib.gitcd seymourlibuv sync --all-extras
- Sanity-test the library
uv run pytestfor local regression.SEYMOUR_HOST=<HOSTNAME> uv run seymourctl -v statusto hit your target once hardware is reachable.
- Wire up hardware
- Confirm straight-through RS232 between IP2SL and the Seymour control port.
- For direct USB serial, a FTDI-based adapter keeps timing stable.
- Pick your transport
TCPTransport(host, port=4999)for IP2SL.SerialTransport(port="COM5")for direct connection (requires[serial]).
Usage Examples
Python API
import asyncio
from seymourlib.client import SeymourClient
from seymourlib.transport import TCPTransport
async def main() -> None:
async with SeymourClient(TCPTransport("192.168.1.70")) as client:
status = await client.get_status()
print(status)
asyncio.run(main())
CLI
seymourctl --host 192.168.1.70 status
seymourctl --host 192.168.1.70 preset apply 235
seymourctl --help
Motion-oriented commands such as calibrate, positions in/out/home, and preset apply block until the controller reports HALTED or STOPPED_AT_RATIO, keeping CI and automation flows deterministic without manual sleep calls.
Transport discovery (Python API)
import asyncio
from seymourlib.discovery import (
enumerate_serial_transports,
enumerate_tcp_transports,
)
async def main() -> None:
tcp_devices = await enumerate_tcp_transports() # listens for Global Caché beacons
serial_ports = await enumerate_serial_transports()
print("TCP devices:")
for device in tcp_devices:
print(device.host, device.metadata.get("Model", ""))
print("Serial ports:")
for port in serial_ports:
print(port.device, port.description)
asyncio.run(main())
enumerate_tcp_transports() joins the Global Caché multicast group and returns deduplicated IP2SL candidates (override interval to listen longer or interface_ip to bind a specific NIC). enumerate_serial_transports() surfaces every local serial adapter with the proper Seymour baud rate by default.
Transport discovery (CLI)
seymourctl discover tcp
seymourctl discover serial
Use discover tcp when you need to confirm IP2SL devices are visible on the LAN; the table output includes the advertised model, status, and UUID from the Global Caché beacons. discover serial lists local USB/RS232 adapters with hardware IDs so you can select the right port before launching the client.
IP2SL Setup & Diagnostics
1. Test direct serial first
- Connect a laptop directly to the Seymour RS232 port with a known-good USB adapter.
- Use
RealTerm,CoolTerm, or any tty tool (115200 8N1 by default - verify via Seymour docs) to send aPS?(position status) command. - Once commands succeed locally, you know the projector + cable + command syntax are correct before adding the network hop.
2. Discover the IP2SL via iHelp
- Download Global Caché iHelp and run it on the same subnet.
- Press Scan to locate the IP2SL; note the MAC, firmware, and current IP.
- If nothing shows up, temporarily disable host firewalls or plug directly into a laptop + small DHCP scope.
3. Pin the network configuration
- Point a browser at
http://<your-ip>/(from step 2) if you want a point-and-click GUI for DHCP/static IP, firmware, and reboot controls. - Otherwise, install Global Caché iTest.
- Use iTest or telnet into port 4998 (the configuration/control port).
- Send
set dhcp 0,set ip <static>,set mask <subnet>,set gateway <gw>, thensaveto burn settings.
- Reboot (power cycle or
rebootcommand) and confirm the device responds on the static IP. - Document the MAC/IP in your DHCP reservations to avoid future collisions.
4. Lock the serial parameters
- Open the IP2SL web UI and switch to the Serial tab, or telnet/iTest into port 4998 for command-line configuration.
- Ensure the port is set to 115200 baud, 8 data bits, no parity, 1 stop bit to match Seymour’s RS232 spec.
- Saving via the UI writes immediately; if you used the control port, run
set baud 115200,set data 8,set parity 0,set stop 1, thensaveand reboot so the bridge always boots with the correct framing.
5. Exercise the serial bridge with iTest
- Open iTest (or
telnet) - Target port 4999 on the static IP, choose RAW mode, and click Connect.
- Send a few simple commands (e.g.
[01S],[01P]). The response should echo immediately. - If latency creeps in, verify telnet keep-alives/device busy LEDs. Keep the window open while you walk through automation flows to watch the live traffic.
6. Promote to seymourlib
- Update your
.env/ config with the same host/port verified above. - Start with
uv run seymourctl -v status(verbose logging shows full request/response frames). - Flip to automation (Home Assistant, Homebridge, etc.) once CLI calls are boringly reliable.
Troubleshooting & Field Notes
- ⚡ No response over TCP but serial works - Ensure port 4999 is open on local firewalls and that the IP2SL LED blinks on connect; if not, recheck the static IP settings from step 3.
- 🔌 Commands hang after a day - The IP2SL can queue stale sockets; send
set rs232disconnect 1over port 4998 so idle TCP clients auto-close. - 🔁 Race conditions from HA automations - Wrap your automations with seymourlib's async context manager so only one command pipeline exists per transport.
- 🧪 Need deeper diagnostics - Add
--verbosetoseymourctlto dump protocol frames, or enable debug logging to capture per-request timestamps. - 🛠️ Firmware drift - Global Caché publishes release notes; mismatched firmware sometimes defaults back to DHCP on reboot. Always export a config snapshot in iHelp after upgrades.
Related Docs & Inspiration
- Seymour Screen Excellence RS232 Protocol PDF (request via dealer portal).
- Global Caché Knowledge Base.
- Home Assistant Template Switch Cookbook for inspiration on wiring seymourlib into HA.
- CoolTerm Serial Terminal - handy for the direct-serial smoke test.
Contributing
- Fork, create a feature branch, and open a PR (tests + type checks 🚦 required).
pre-commit runbefore pushing.- Issues and hardware findings are welcome - real-world serial logs are gold for regression tests.
Need something else? Open a discussion or ping via Issues and we’ll figure it out together. 🙌
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file seymourlib-0.1.4.tar.gz.
File metadata
- Download URL: seymourlib-0.1.4.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
637f15d7ed0709f321c5019027e29224e827ebf40003c72ba13a48255aec6671
|
|
| MD5 |
c6812750f78098d1b32ebeabbce928ea
|
|
| BLAKE2b-256 |
9484a09e62967e23a35d720aaaeba1781d52e3db8d1e417c5ec41bde692942db
|
File details
Details for the file seymourlib-0.1.4-py3-none-any.whl.
File metadata
- Download URL: seymourlib-0.1.4-py3-none-any.whl
- Upload date:
- Size: 20.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee3c07ac26c60dba70ed15d233f00248d15bf88475fea90c83e1e23d596d2e86
|
|
| MD5 |
c3c84d3bdc0ecb3527a63e287cb69604
|
|
| BLAKE2b-256 |
54d8a04e46a8d028c2ad5374abb0484b32acd41f02de690c66008e54ec49e85f
|