Inital!
This commit is contained in:
57
patlite_mqtt/device.py
Normal file
57
patlite_mqtt/device.py
Normal file
@@ -0,0 +1,57 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user