Files
patlite-mqtt/patlite_mqtt/device.py
2026-05-18 16:05:11 -04:00

58 lines
1.5 KiB
Python

import errno
import struct
import usb.core
import usb.util
from usb.core import USBError
VENDOR_ID = 0x191A
PRODUCT_ID = 0x8003
ENDPOINT = 1
class PatliteDevice:
def __init__(self):
self._dev = None
def connect(self):
dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID)
if dev is None:
raise RuntimeError(
f"Patlite not found (vendor={VENDOR_ID:#06x}, product={PRODUCT_ID:#06x})"
)
try:
if dev.is_kernel_driver_active(0):
dev.detach_kernel_driver(0)
dev.set_configuration()
except USBError as exc:
if exc.errno == errno.EACCES:
raise RuntimeError(
"USB access denied. On headless hosts, run ./scripts/install-udev.sh, "
"then 'newgrp patlite' (or re-login), unplug/replug the Patlite, and retry."
) from exc
raise
self._dev = dev
def close(self):
if self._dev is not None:
self.send(0x00, 0x00, 0x00)
usb.util.dispose_resources(self._dev)
self._dev = None
def send(self, ry: int, gb: int, w: int):
if self._dev is None:
return
data = struct.pack(
"BBBBBBBx",
0x00,
0x00,
0x0F,
0x00,
ry & 0xFF,
gb & 0xFF,
w & 0xFF,
)
self._dev.write(ENDPOINT, data)