Skip to main content

Pure Python async/await implementation for controlling EASYWAVE radio modules (RX11, RX21, RX22, RX25, RX09)

Project description

EASYWAVE Home Control

Pure Python async/await implementation for controlling EASYWAVE radio modules (RX11, RX21, RX22, RX25, RX09).

Optimized for Home Assistant integration with 100% non-blocking async API.

Features

  • Pure Async/Await - No blocking calls on event loop, optimized for Home Assistant
  • Multi-Family Support - Binary protocol (RX11/21/22/25) + ASCII protocol (RX09)
  • High Performance - 115200 baud communication, request pipelining
  • Robust - Comprehensive error handling, health checks, timeout management
  • Clean API - Unified .create() factory method for all devices
  • Type Hints - Full Pylance strict-mode compliant type annotations
  • Well-Tested - Comprehensive examples and integration patterns

Installation

pip install easywave-home-control

Quick Start

Creating Devices

All devices use the unified .create() factory method:

import asyncio
from easywave_home_control import RX11Device, RX09Device

async def main():
    # Create and automatically connect to device
    device = await RX11Device.create(
        port="/dev/ttyUSB0",
        timeout=5.0
    )
    
    try:
        # Device is now connected and ready to use
        info = await device.get_device_info()
        print(f"Device: {info}")
        
        # Check connectivity
        connected = await device.ping_request(timeout=3.0)
        print(f"Connected: {connected}")
        
        # Use device-specific methods
        result, hw_version = await device.query_hw_version()
        if result == RX11Device.ErrorCode.SUCCESS:
            print(f"Hardware Version: {hw_version}")
    finally:
        # Always disconnect when done
        await device.disconnect()

asyncio.run(main())

Device Support

RxModule Family (Binary Protocol, 115200 baud)

Device Type Functions Features Baudrate
RX11 USB Transceiver 25 EW, Bidi, Secwave 115200
RX21 Serial Module 25 EW, Bidi, Secwave 115200
RX22 Serial Module 25 EW, Bidi, Secwave 115200
RX25 Serial Module 25 EW, Bidi, Secwave 115200

RX09 Family (ASCII Protocol, 57600 baud)

Device Type Functions Features Baudrate
RX09 Basic Receiver 11 EW Basic only 57600

Async API Documentation

Device Classes

RxModule Devices (Binary Protocol, 115200 baud)

from easywave_home_control import RX11Device, RX21Device, RX22Device, RX25Device

# All RxModule devices use the same interface
device = await RX11Device.create(port="/dev/ttyUSB0")

# RxModule-specific methods
result, hw_version = await device.query_hw_version()
result, fw_version = await device.query_fw_version()

# Easywave Basic (EW) functions
result, info_type, transmitter, info_data = await device.ew_rcv_button_request(timeout=30.0)
await device.ew_send_cmd_request(gateway=gateway_serial, button=0)

# Easywave Bidi (EWB) functions
result, receiver = await device.ewb_join_device_request(transmitter_serial)

# Check error codes
if result == RX11Device.ErrorCode.SUCCESS:
    print(f"Success: {info_type}")
else:
    print(f"Error: {result}")

RX09 Device (ASCII Protocol, 57600 baud)

from easywave_home_control import RX09Device

device = await RX09Device.create(port="/dev/ttyUSB0")

# RX09-specific methods
result, serial_number, button_code = await device.receive_telegramm(timeout=30.0)
result, position_count = await device.query_positions()
result = await device.send_telegramm(position=0, button_code="A")

# Check error codes
if result == RX09Device.ErrorCode.SUCCESS:
    print("Success")

Common Methods (All Devices)

# Connection management
# Note: .connect() is called automatically by .create() — only needed for direct instantiation
await device.connect() -> bool
await device.disconnect() -> None

# Device info
await device.get_device_info() -> dict[str, Any]
await device.ping_request(timeout=5.0) -> bool

# Properties (common)
device.is_connected -> bool

RxModule-Only Properties (RX11 / RX21 / RX22 / RX25)

# Detailed status — one of: "connected", "disconnected", "reconnecting", "error", "hardware_error"
device.connection_status -> str
device.has_hardware_error -> bool  # True after USB disconnect or I/O error
device.state_good -> bool          # False if protocol errors have occurred
device.last_error -> str | None    # Last error message, if any

Error Codes

Each device family has device-specific error code enums:

# RxModule devices (RX11, RX21, RX22, RX25)
from easywave_home_control import RX11Device

if result == RX11Device.ErrorCode.SUCCESS:
    print("Command successful")
elif result == RX11Device.ErrorCode.ERR_RF_TIMEOUT:
    print("RF communication timeout")
elif result == RX11Device.ErrorCode.ERR_FAILSTATE:
    print("Device in failure state")

# RX09 device
from easywave_home_control import RX09Device

if result == RX09Device.ErrorCode.SUCCESS:
    print("Command successful")

Callbacks

Register callbacks to respond to device events:

def on_disconnect():
    print("Device disconnected or hardware error occurred")

device.set_disconnect_callback(on_disconnect)

# Register callback for spontaneous RCV messages (RX09 only)
def on_button_pressed(data: dict[str, Any]):
    serial = data["serial_number"]
    button = data["button_code"]
    print(f"Button {button} pressed on {serial:06X}")

device.register_rcv_callback(on_button_pressed)

Examples

See the examples/ directory for complete working examples:

Protocol Details

RxModule Protocol (RX11/21/22/25)

Binary request/response protocol at 115200 baud with:

  • Packet structure: [SOP(0x81)] [Function+Params] [EOP(0x82)]
  • Byte stuffing for bytes in range 0x80-0x82
  • Request/response IRP/ICP pairs with handles
  • Timeout support (default 5.0s, RCV functions support indefinite waiting)

RX09 Protocol (RX09)

ASCII text-based protocol at 57600 baud with:

  • Comma-separated commands (e.g., CMD,PARAM1,PARAM2)
  • CR (0x0D) line terminator
  • Simple request/response matching
  • Limited function set (Easywave Basic only)

Type Hints & Validation

The library is fully typed and passes Pylance strict-mode validation:

pylance --mode=strict

All generic types are explicitly specified (no Unknown types):

  • dict[str, Any] instead of dict
  • list[bytes] instead of list
  • asyncio.Task[None] instead of asyncio.Task

Requirements

  • Python 3.9+
  • pyserial >= 3.5

License

Apache License 2.0 - See LICENSE for details.

Contributing

Contributions are welcome! Please submit issues and pull requests to the Home Assistant repository.

Support

For support, please refer to the Home Assistant Easywave Integration documentation.

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

easywave_home_control-0.1.0.tar.gz (36.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

easywave_home_control-0.1.0-py3-none-any.whl (38.6 kB view details)

Uploaded Python 3

File details

Details for the file easywave_home_control-0.1.0.tar.gz.

File metadata

  • Download URL: easywave_home_control-0.1.0.tar.gz
  • Upload date:
  • Size: 36.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for easywave_home_control-0.1.0.tar.gz
Algorithm Hash digest
SHA256 902908768842cf01c7cce03a5c1c71b221e5baf5646603412612dee7964c12af
MD5 73b4b0666edd1d6c0c38924a58857d4d
BLAKE2b-256 8e8d9d37ed6d498fd8d0e6372096825f660963d343d84ac018962bcad31c4e0a

See more details on using hashes here.

Provenance

The following attestation bundles were made for easywave_home_control-0.1.0.tar.gz:

Publisher: publish.yml on eldateas/PyPI-EasywaveHomeControl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file easywave_home_control-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for easywave_home_control-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ef9b1ac00cdd1bd9f39ffdde335e47dc1f6e49cb89437358cac06ead4b5fd70d
MD5 86e718e66a3203c08ee5e01f9e8d3b01
BLAKE2b-256 8698f11fcc887cf657f367873d8bc8948df4a6e1925a61a6d83a19ad1b63b033

See more details on using hashes here.

Provenance

The following attestation bundles were made for easywave_home_control-0.1.0-py3-none-any.whl:

Publisher: publish.yml on eldateas/PyPI-EasywaveHomeControl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page