Files
hh-bt-controller/controller/protocol.py
T

95 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
protocol.py - Command builder for common cheap BLE LED controller protocols.
These controllers all speak one of a handful of similar protocols.
We'll confirm which format the KAIYU uses after sniffing/probing.
Supported protocol families:
- 0x7E family (most common, used by ELK-BLEDOM, LEDBLE, etc.)
- 0x56 family (older MagicLight / JACKYLED style)
"""
class Protocol7E:
"""
The 0x7E protocol family.
Packet format: 7e 00 <CMD> <P1> <P2> <P3> <P4> <LED> ef
CMD 0x04 = power on/off
CMD 0x05 = set colour (P1=mode, P2=R, P3=G, P4=B)
CMD 0x01 = set brightness (P1=0x000x64)
CMD 0x03 = set effect/speed
"""
# Colour mode byte for CMD 0x05
MODE_STATIC = 0x03
MODE_EFFECT = 0x02
# LED channel — 0xFF = all channels
LED_ALL = 0xFF
@staticmethod
def set_color(r: int, g: int, b: int) -> bytes:
r, g, b = _clamp(r), _clamp(g), _clamp(b)
return bytes([0x7e, 0x00, 0x05, Protocol7E.MODE_STATIC, r, g, b, 0x00, 0xef])
@staticmethod
def set_brightness(level: int) -> bytes:
"""level: 0100"""
level = max(0, min(100, level))
return bytes([0x7e, 0x00, 0x01, level, 0x00, 0x00, 0x00, Protocol7E.LED_ALL, 0xef])
@staticmethod
def turn_on() -> bytes:
return bytes([0x7e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, Protocol7E.LED_ALL, 0xef])
@staticmethod
def turn_off() -> bytes:
return bytes([0x7e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef])
@staticmethod
def set_effect(effect_id: int, speed: int = 0x03) -> bytes:
"""
effect_id: 0x800x8b (varies by controller)
speed: 0x01 (fast) 0x0a (slow)
"""
return bytes([0x7e, 0x00, 0x03, effect_id, speed, 0x00, 0x00, Protocol7E.LED_ALL, 0xef])
class Protocol56:
"""
The 0x56 protocol family (older MagicLight style).
RGB command : 56 RR GG BB 00 f0 aa
White cmd : 56 00 00 00 WW 0f aa
Power on : cc 23 33
Power off : cc 24 33
"""
@staticmethod
def set_color(r: int, g: int, b: int) -> bytes:
r, g, b = _clamp(r), _clamp(g), _clamp(b)
return bytes([0x56, r, g, b, 0x00, 0xf0, 0xaa])
@staticmethod
def set_white(level: int) -> bytes:
level = _clamp(level)
return bytes([0x56, 0x00, 0x00, 0x00, level, 0x0f, 0xaa])
@staticmethod
def turn_on() -> bytes:
return bytes([0xcc, 0x23, 0x33])
@staticmethod
def turn_off() -> bytes:
return bytes([0xcc, 0x24, 0x33])
def _clamp(v: int) -> int:
return max(0, min(255, v))
# ── Convenience ───────────────────────────────────────────────────────────────
# Default to 7E family — update after confirming with scanner
ActiveProtocol = Protocol7E