Skip to main content

Pyowershades

Pyowershades is an asyncio Python library for communicating with PowerShades motorized shade controllers over UDP. It handles connection management, packet building and parsing, device discovery, and asynchronous status push callbacks. While orginally developed for use in Home Assistant it can work for any asyncio application.

Requirements

  • Python 3.12+

Installation

pip install pyowershades

Usage

Discover devices on the network

import asyncio
from pyowershades import async_discover_devices

async def main():
    devices = await async_discover_devices(["192.168.1.255"])
    for device in devices:
        print(device)  # {"ip": "192.168.1.50", "serial": 12345, "model": 1}

asyncio.run(main())

Connect to a shade and control it

import asyncio
from pyowershades import PowerShadesConnection, OP_SET_POSITION, build_set_position_payload

async def main():
    conn = PowerShadesConnection("192.168.1.50")
    await conn.async_connect()

    # Move to 50%
    await conn.async_request(OP_SET_POSITION, build_set_position_payload(50))

    conn.close()

asyncio.run(main())

Receive live status pushes

from pyowershades import PowerShadesConnection, StatusReply, parse_status_reply

def on_status(status: StatusReply) -> None:
    print(f"Position: {status.position}%  Battery: {status.battery_mv} mV")

conn = PowerShadesConnection("192.168.1.50")
conn.set_status_callback(on_status)
await conn.async_connect()

The shade sends status pushes to whichever UDP socket last sent it a command (the "UDP subscriber"). As long as your connection stays active and periodically polls the device, it will receive live position updates.

API reference

Discovery

async_discover_devices(local_addresses: list[str], timeout: float = ...) -> list[DiscoveredDevice]
async_get_device_info(ip: str, timeout: float = ...) -> PowerShadesDeviceInfo

Connection

class PowerShadesConnection:
    def __init__(self, ip: str) -> None
    async def async_connect(self) -> None
    async def async_request(self, op: int, payload: bytes = b"", ...) -> bytes
    def set_status_callback(self, callback: Callable[[StatusReply], None]) -> None
    def close(self) -> None

Raises PowerShadesTimeoutError if the device does not respond.

Packet building

Function Description
build_packet(op, payload) Build a raw UDP packet for any opcode
build_set_position_payload(percent) Payload for moving to a position (0–100)
build_set_limit_payload(limit_type) Payload for setting upper/lower limits
build_set_name_payload(name) Payload for renaming a PoE shade

Parsing

Function Description
parse_status_reply(data) Parse a status packet into a StatusReply
parse_serial_reply(data) Parse a serial/model reply
parse_shade_name_reply(data) Parse a shade name reply
parse_device_name_reply(data) Parse a device name reply
battery_percentage(battery_mv) Convert mV to a battery percentage (0–100)

Constants

Opcodes (OP_GET_STATUS, OP_SET_POSITION, OP_JOG_UP, OP_JOG_DOWN, OP_JOG_STOP, OP_STEP_UP, OP_STEP_DOWN, OP_SET_LIMIT, OP_CLEAR_LIMITS, OP_INDICATE, OP_GET_SERIAL, OP_GET_SHADE_NAME, OP_GET_DEVICE_NAME), limit types (LIMIT_UPPER, LIMIT_LOWER), and timing constants (REQUEST_TIMEOUT, REQUEST_RETRIES, DISCOVERY_TIMEOUT).

See docs/PROTOCOL.md for a full reference of every UDP command the protocol supports, including ones this library doesn't implement yet.

Notes

  • PowerShades devices send status pushes only to the last controller that sent them a command. If another controller (e.g. the PowerShades app or Control4) sends a command, your connection will stop receiving pushes until it sends one again.
  • State inference (opening, closing, open, closed) is not done by this library (beacuse the shade does not send it), only raw position values are reported.
  • Push packets are sent every ~10 seconds by the shade while its moving.
  • Tested with PoE PowerShades controllers. RF hub support is unknown.
  • No authentitcation is needed to control the shade, this means anyone on your local network using this can control your shade(s).

License

MIT

Metadata

Release files for pyowershades 0.2.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 pyowershades 0.2.0
File Size Uploaded
pyowershades-0.2.0.tar.gz 17.2 kB Details

Built distribution (wheel)

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

Total release size: 29.5 kB

Release files / pyowershades-0.2.0.tar.gz

Download URL pyowershades-0.2.0.tar.gz
Size 17.2 kB
Tags Source
SHA-256 checksum
How to use checksums
4a5658bedcb686f7ed54ed8f79b0d65f9b6f1e54c730ef70da790f63b1234115
BLAKE2b-256 checksum
How to use checksums
dc612a2bb49f4a21daf1bbaf83dc3f3e4fbbf56927d994837649dd2fde08b7a6
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 Sep 12, 2026.

Transparency log

Release files / pyowershades-0.2.0-py3-none-any.whl

Download URL pyowershades-0.2.0-py3-none-any.whl
Size 12.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9fffe4a2f33762c7e434ccfb1262a231a80112a1fce93906a4829ebf3c05db71
BLAKE2b-256 checksum
How to use checksums
59c5083da2bcce468074b785749bf6a03102434c6c9efb6e4f7821f0d0be112c
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 Sep 12, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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