pykaleidescape
Async Python client for controlling Kaleidescape devices via the Kaleidescape System Control Protocol.
Note: This library is not operated by, or affiliated with, Kaleidescape, Inc.
Features
- Async API built on
asyncio - High-level
Deviceabstraction for connecting to a Kaleidescape player - Mirrors device state into convenient dataclasses (
system,power,osd,movie,automation) - Event-driven integration via a lightweight
Dispatcher - Automation integration using user-defined events
Installation
pip install pykaleidescape
Quickstart
This minimal example connects to a Kaleidescape player and prints its power state. See the Examples section for more complete usage patterns.
import asyncio
import logging
from kaleidescape import const, Device
logging.basicConfig(level=logging.DEBUG)
async def main() -> None:
device = Device("<ipaddress>")
# Open the connection and perform initial state sync
await device.connect()
await device.refresh()
print(f"Power state is currently: {device.power.state}")
if __name__ == "__main__":
asyncio.run(main())
All library calls that talk to the device are async and must be awaited inside an event loop.
Examples
The examples/ directory contains small, runnable scripts that demonstrate typical usage patterns.
examples/basic.py– connect to a player, refresh state, and control power.examples/events.py– register an event listener withdevice.dispatcherand react to incoming events.examples/volume.py– implement external volume control by responding to Kaleidescape user-defined events.
API overview
Most users will interact with the Device class and constants from kaleidescape.const.
from kaleidescape import Device, const
Device lifecycle
A Device represents a single Kaleidescape player and manages the underlying TCP connection.
Device(host, *, port=..., timeout=..., reconnect=True, reconnect_delay=...)- Create a new client instance for the given
host.
- Create a new client instance for the given
await device.connect()- Resolve the host, open a TCP connection, and start the reader task.
await device.refresh()- Perform an initial or on-demand state sync (system, power, UI, movie, automation).
await device.disconnect()- Close the connection and stop reconnect behavior.
device.is_connected- Boolean indicating whether the underlying connection is currently open.
State dataclasses
After connect() and refresh(), the Device exposes several state objects that are kept up to date by incoming events:
device.system- System-level information such as serial number, IP, CPDID, model, friendly name, number of zones, firmware/protocol versions.
device.power- Power and readiness state, using constants from
kaleidescape.constsuch asDEVICE_POWER_STATE_ONandDEVICE_POWER_STATE_STANDBY.
- Power and readiness state, using constants from
device.osd- On-screen display state, including the current UI screen and highlighted item when available.
device.movie- Movie playback state such as play status, current location, and content handle (when applicable).
device.automation- Automation-centric fields (movie location, Cinemascape mode, mask information, etc.).
Common commands
All commands are async methods on Device and must be awaited.
Power
await device.leave_standby()– bring the player out of standby.await device.enter_standby()– put the player into standby.
Transport (availability may depend on the connected device)
await device.play()await device.pause()await device.stop()await device.next()await device.previous()await device.replay()await device.scan_forward()await device.scan_reverse()
Navigation & UI
await device.select()await device.up()/await device.down()await device.left()/await device.right()await device.cancel()await device.status_and_settings()await device.intermission_toggle()await device.go_movie_list()await device.go_movie_collections()await device.go_movies()await device.go_movie_covers()await device.menu_toggle()
System info & content
await device.get_system_pairing_info()– retrieve pairing-related information.await device.get_friendly_system_name()– get the configured friendly name.await device.get_available_devices()– query other devices visible to this system.await device.get_available_serial_numbers()– query serial numbers of available devices.await device.get_content_details(handle)– fetch rich metadata for a specific content handle.
Volume integration
The library supports integration with an external volume / AVR by responding to Kaleidescape user-defined events.
await device.set_volume_capabilities(bitmask)– advertise supported volume capabilities (seekaleidescape.constfor bit flags).await device.set_volume_level(level)– report the current volume level.await device.set_volume_muted(is_muted)– report the current mute state.
See examples/volume.py for a complete flow.
Events and dispatcher
The library is event-driven: incoming protocol messages are parsed into response objects and dispatched to subscribers.
-
device.dispatcheris aDispatcherinstance. -
Register a callback with:
async def handle_event(event: str, *args) -> None: print("Event received:", event, args) device.dispatcher.connect(handle_event)
-
Callbacks may be async or sync callables.
-
Events include power changes, system readiness updates, UI state changes, user-defined events (for volume integration), and more.
Async usage
pykaleidescape is built on asyncio.
- Use
asyncio.run(main())for simple scripts. - In larger applications (e.g., Home Assistant), reuse the application event loop rather than creating new ones.
- Do not call async methods like
connect(),refresh(), or command methods from synchronous code without running them in the event loop. - For long-running integrations:
- Create a single
Deviceper player. - Connect once, call
refresh()on startup, and keep the connection alive. - Use the
dispatcherto react to state changes instead of polling.
- Create a single
The underlying Connection supports automatic reconnect when enabled (see the Device constructor arguments), so transient network issues can often be handled transparently.
Development and testing
This repository includes a full test suite and an in-process emulator for the Kaleidescape System Control Protocol.
Project layout
kaleidescape/- Library code:
device.py,connection.py,message.py,dispatcher.py,const.py,error.py.
- Library code:
examples/- Runnable examples demonstrating common usage patterns.
tests/test_a_message.py– message parsing/formatting.test_b_connection.py– connection lifecycle & reconnect behavior.test_c_command.py– command behavior.test_d_device.py–Devicebehavior and state updates.emulator.py– protocol emulator used by the tests.
Local setup
The project is managed with uv:
uv sync
uv run prek install # optional: run the checks on every commit
Running tests
uv run pytest
The tests automatically start the in-process emulator; no physical Kaleidescape hardware is required.
To test against another supported Python version:
uv run --python 3.11 pytest
Linting, type checking, and formatting
Checks run as prek hooks: ruff (linting and formatting), codespell, zizmor, yamllint, mypy, and pylint.
uv run prek run --all-files
When contributing changes, please keep tests passing and the linters clean.
Limitations and notes
- This project is not affiliated with or endorsed by Kaleidescape, Inc.
- Behavior depends on the firmware and capabilities of your Kaleidescape system; some commands may only apply to movie players and not server-only devices.
- Network connectivity, DNS resolution, and firewall rules must allow outbound TCP connections to the Kaleidescape System Control Protocol port on your player.
License
This project is licensed under the terms specified in the LICENSE file included in this repository.
Metadata
Release files for pykaleidescape 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pykaleidescape-1.2.0.tar.gz | 35.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pykaleidescape-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.1 kB
Release files / pykaleidescape-1.2.0.tar.gz
| Download URL | pykaleidescape-1.2.0.tar.gz |
|---|---|
| Size | 35.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2d0a67e8882c2b050db92658f04b41cb3ef8903b4eac030ff3f92ee94b8d65b2
|
|
BLAKE2b-256 checksum How to use checksums |
567c00b18112c88d0e6ebcdffa16f92b527c7623e43fb5264cc2be87eaf577b8
|
| 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 11, 2026.
Transparency logRelease files / pykaleidescape-1.2.0-py3-none-any.whl
| Download URL | pykaleidescape-1.2.0-py3-none-any.whl |
|---|---|
| Size | 26.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
eeeb5d20a20560493edc53c679c5971cda6a4a3026c934fc1de1e32bf32adfd7
|
|
BLAKE2b-256 checksum How to use checksums |
51b45bf941d8f537570b8dc4a2db3c8ceb67ea4f72e31741e55b8c3b04484b9b
|
| 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 11, 2026.
Transparency log