Skip to content

AbsenteeAtom/Lightwave3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

lightwave3

A Python 3.11-compatible, aiohttp 3.10+ compatible client for the LightWaveRF Gen2 WebSocket API.

This is a community fork of the abandoned lightwave2 library, fixing several breaking issues that make it unusable on modern Python and aiohttp versions.

Why this exists

lightwave2 has not been updated since 2022. Running it on Python 3.11 with aiohttp ≥ 3.10 produces errors like:

RuntimeError: Timeout context manager should be used inside a task
AttributeError: 'NoneType' object has no attribute 'send_str'
asyncio.locks.Event object is bound to a different event loop

Commands appear to succeed (no exception raised to the caller) but devices do not respond. The root causes are:

  1. @asyncio.coroutine / yield from — removed in Python 3.11; the consumer handler crashed silently
  2. async_connect() infinite recursion — no retry limit; when called outside a Task context, asyncio.sleep() raises RuntimeError in aiohttp 3.10+ which uses asyncio.timeout() internally
  3. Consumer Task not started before authenticate_authenticate() blocks on asyncio.Event.wait() with nobody reading the socket, causing a 60-second hang
  4. _websocket.send_str() on None — after a failed reconnect, _websocket is None; calling send_str raises AttributeError rather than a clean error

What's fixed

Issue Fix
@asyncio.coroutine / yield from Rewritten as async def / await throughout
Infinite reconnect loop Iterative async_connect() with configurable max_tries (default 8); raises ConnectionError on exhaustion
Consumer not running during auth Consumer Task created via asyncio.create_task() before _authenticate()
send_str on None Guard in _async_sendmessage; raises ConnectionError instead of AttributeError
Feature model _LWRFFeature objects with .id and ._state (replacing bare [id, value] lists)
Callback signature callback(feature_name, feature_id, prev_value, new_value)

Installation

Copy lightwave3.py into your project. No package installation required.

Or install directly from this repo:

pip install git+https://github.com/AbsenteeAtom/Lightwave3.git

Usage

The API is a drop-in replacement for lightwave2.LWLink2 (WebSocket/local app API):

import lightwave3 as lightwave2   # or: import lightwave3

link = lightwave3.LWLink2(email, password)
await link.async_connect()
await link.async_get_hierarchy()

# Register a state-change callback
await link.async_register_callback(my_callback)
# my_callback(feature_name, feature_id, prev_value, new_value)

# Control devices
await link.async_turn_on_by_featureset_id(featureset_id)
await link.async_turn_off_by_featureset_id(featureset_id)
await link.async_set_brightness_by_featureset_id(featureset_id, level)

# Inspect featuresets
for fs_id, fs in link.featuresets.items():
    for feat_name, feat in fs.features.items():
        print(fs.name, feat_name, feat.id, feat._state)

Rolling back to lightwave2

# lightwave3:
import lightwave3 as lightwave2

# lightwave2 (original):
from lightwave2 import lightwave2

Tested against

Package Version
Python 3.11
aiohttp 3.13.3
websockets 16.0

Not included

LWLink2Public (the HTTP public API variant) is not implemented. This library covers the local WebSocket API (wss://v1-linkplus-app.lightwaverf.com) only.

Licence

MIT — same as the original lightwave2.

About

Python 3.11 + aiohttp 3.10+ compatible LightWaveRF Gen2 client (fork of lightwave2)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages