JnyJny / busylight

Control USB connected presence lights from multiple vendors via the command-line or web API.
Apache License 2.0
227 stars 25 forks source link

Kuando Busylight not working with QTimer #107

Closed henryruhs closed 2 years ago

henryruhs commented 2 years ago

Software Versions:

General Type of Problem

Describe the Problem The Kuando Busylight usually worked well with Chroma Feedback back in the days used the build-in threading. Since I switched to PyQt5 and therefore QTimer your implementation does not work any longer.

Expected Behavior The device is found on the first run but not on the second run of the QTime loop.

Example for reproduction

#!/usr/bin/env python3

from busylight.lights.kuando import Busylight

import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication

APPLICATION = None
TIMER = None
INTERVAL = 0

def get_application() -> QApplication:
    global APPLICATION

    if APPLICATION is None:
        APPLICATION = QApplication(sys.argv)
    return APPLICATION

def get_timer() -> QTimer:
    global TIMER

    if TIMER is None:
        TIMER = QTimer()
    return TIMER

def run() -> None:
    api = Busylight

    api.first_light().on((255, 255, 255))

def background_run() -> None:
    global INTERVAL

    timer = get_timer()

    # handle interval

    if INTERVAL == 5000:
        run()
        INTERVAL = 0
    else:
        INTERVAL += timer.interval()

if __name__ == '__main__':
    application = get_application()
    timer = get_timer()
    timer.setInterval(100)
    timer.timeout.connect(lambda: background_run())
    timer.singleShot(0, lambda: run())
    timer.start()
    sys.exit(application.exec_())
JnyJny commented 2 years ago

You're mis-using the busylight.lights.kuando.Busylight object and it has nothing to do with the timer functions available in PyQt5.

This modification to your script works, albeit calling LIGHT.on(...) more often than is strictly necessary:

#!/usr/bin/env python3

from busylight.lights.kuando import Busylight

import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication

APPLICATION = None
TIMER = None
INTERVAL = 0

LIGHT = Busylight.first_light()

def get_application() -> QApplication:
    global APPLICATION

    if APPLICATION is None:
        APPLICATION = QApplication(sys.argv)
    return APPLICATION

def get_timer() -> QTimer:
    global TIMER

    if TIMER is None:
        TIMER = QTimer()
    return TIMER

def run() -> None:
    LIGHT.on((255, 255, 255))

def background_run() -> None:
    global INTERVAL

    timer = get_timer()

    # handle interval

    if INTERVAL == 5000:
        run()
        INTERVAL = 0
    else:
        INTERVAL += timer.interval()

if __name__ == "__main__":
    application = get_application()
    timer = get_timer()
    timer.setInterval(100)
    timer.timeout.connect(lambda: background_run())
    timer.singleShot(0, lambda: run())
    timer.start()
    sys.exit(application.exec_())
henryruhs commented 2 years ago

Okay, so the trick was to keep the instance of lights outside... thanks for the fast response