fizzctl 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fizzctl/__init__.py +10 -0
- fizzctl/animations.py +145 -0
- fizzctl/blobs.py +353 -0
- fizzctl/capture.py +214 -0
- fizzctl/cfg.py +118 -0
- fizzctl/cli.py +409 -0
- fizzctl/effects.py +223 -0
- fizzctl/hid.py +255 -0
- fizzctl/keymap.py +178 -0
- fizzctl/protocol.py +97 -0
- fizzctl/udev_rules.py +89 -0
- fizzctl-0.2.0.dist-info/METADATA +179 -0
- fizzctl-0.2.0.dist-info/RECORD +15 -0
- fizzctl-0.2.0.dist-info/WHEEL +4 -0
- fizzctl-0.2.0.dist-info/entry_points.txt +4 -0
fizzctl/__init__.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""fizzctl — Linux tooling for the Redragon K617 Fizz.
|
|
2
|
+
|
|
3
|
+
User commands live in the :func:`main` entry point (rgb/effect/key/paint/
|
|
4
|
+
animate/keymap/setup-udev); the full reverse-engineering toolkit is exposed
|
|
5
|
+
by :func:`main_dev` via the ``fizzctl-dev`` console script.
|
|
6
|
+
"""
|
|
7
|
+
from .cli import main, main_dev
|
|
8
|
+
|
|
9
|
+
__all__ = ["main", "main_dev"]
|
|
10
|
+
__version__ = "0.2.0"
|
fizzctl/animations.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""Host-side per-key animations streamed at N fps via the Sinodragon protocol.
|
|
2
|
+
|
|
3
|
+
These are NOT firmware effects — they render color maps on the host and push
|
|
4
|
+
one 382-byte per-key report per frame (volatile; stop with Ctrl+C). Only the
|
|
5
|
+
8 firmware-native effects (`fizzctl effect`) survive a disconnect.
|
|
6
|
+
|
|
7
|
+
Animation helpers are pure ("render_frame(t, color, speed) -> dict") so they
|
|
8
|
+
can be unit-tested without hardware.
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import math
|
|
13
|
+
import time
|
|
14
|
+
|
|
15
|
+
from .effects import PER_KEY_POS, encode_per_key_frame, parse_color
|
|
16
|
+
|
|
17
|
+
ANIMATIONS = ["solid", "blink", "pulse", "chase", "wave", "rainbow", "drop"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def hsv(h: float, s: float, v: float) -> tuple[int, int, int]:
|
|
21
|
+
"""HSV (h 0..360, s/v 0..1) -> (r,g,b) 0..255."""
|
|
22
|
+
c = v * s
|
|
23
|
+
x = c * (1 - abs((h / 60) % 2 - 1))
|
|
24
|
+
m = v - c
|
|
25
|
+
if h < 60:
|
|
26
|
+
r, g, b = c, x, 0
|
|
27
|
+
elif h < 120:
|
|
28
|
+
r, g, b = x, c, 0
|
|
29
|
+
elif h < 180:
|
|
30
|
+
r, g, b = 0, c, x
|
|
31
|
+
elif h < 240:
|
|
32
|
+
r, g, b = 0, x, c
|
|
33
|
+
elif h < 300:
|
|
34
|
+
r, g, b = x, 0, c
|
|
35
|
+
else:
|
|
36
|
+
r, g, b = c, 0, x
|
|
37
|
+
return int((r + m) * 255), int((g + m) * 255), int((b + m) * 255)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def render_frame(t: float, anim: str, color: tuple[int, int, int],
|
|
41
|
+
speed: float = 1.0) -> dict[str, tuple[int, int, int]]:
|
|
42
|
+
"""Produce a color map for animation `anim` at time `t` (seconds).
|
|
43
|
+
|
|
44
|
+
speed scales the cycle period (higher = faster). Positions are the
|
|
45
|
+
verified col*6+row raster from effects.PER_KEY_POS.
|
|
46
|
+
"""
|
|
47
|
+
r, g, b = color
|
|
48
|
+
out: dict[str, tuple[int, int, int]] = {}
|
|
49
|
+
period = max(0.1, 2.0 / speed)
|
|
50
|
+
|
|
51
|
+
if anim == "solid":
|
|
52
|
+
return {k: color for k in PER_KEY_POS}
|
|
53
|
+
|
|
54
|
+
if anim == "blink":
|
|
55
|
+
cycle = (t / period) % 1
|
|
56
|
+
return {k: color if cycle < 0.5 else (0, 0, 0) for k in PER_KEY_POS}
|
|
57
|
+
|
|
58
|
+
if anim == "pulse":
|
|
59
|
+
v = 0.5 + 0.5 * math.sin(2 * math.pi * t / period)
|
|
60
|
+
dim = tuple(int(c * v) for c in color)
|
|
61
|
+
return {k: dim for k in PER_KEY_POS}
|
|
62
|
+
|
|
63
|
+
if anim == "chase":
|
|
64
|
+
order = sorted(PER_KEY_POS, key=lambda k: PER_KEY_POS[k])
|
|
65
|
+
idx = int((t / period) * len(order)) % len(order)
|
|
66
|
+
for i, k in enumerate(order):
|
|
67
|
+
dist = (i - idx) % len(order)
|
|
68
|
+
frac = max(0.0, 1.0 - dist / 5)
|
|
69
|
+
out[k] = tuple(int(c * frac) for c in color) if dist < 5 else (0, 0, 0)
|
|
70
|
+
return out
|
|
71
|
+
|
|
72
|
+
if anim == "wave":
|
|
73
|
+
for k, pos in PER_KEY_POS.items():
|
|
74
|
+
col = pos // 6
|
|
75
|
+
phase = (t / period + col / 14) % 1
|
|
76
|
+
v = 0.5 + 0.5 * math.sin(2 * math.pi * phase)
|
|
77
|
+
out[k] = tuple(int(c * v) for c in color)
|
|
78
|
+
return out
|
|
79
|
+
|
|
80
|
+
if anim == "rainbow":
|
|
81
|
+
order = sorted(PER_KEY_POS, key=lambda k: PER_KEY_POS[k])
|
|
82
|
+
for i, k in enumerate(order):
|
|
83
|
+
hue = (360 * t / period + 360 * i / len(order)) % 360
|
|
84
|
+
out[k] = hsv(hue, 1.0, 1.0)
|
|
85
|
+
return out
|
|
86
|
+
|
|
87
|
+
if anim == "drop":
|
|
88
|
+
for k, pos in PER_KEY_POS.items():
|
|
89
|
+
col = pos // 6
|
|
90
|
+
row = pos % 6
|
|
91
|
+
phase = ((t * speed + col) % 6) - row
|
|
92
|
+
out[k] = color if 0 <= phase < 1 else (0, 0, 0)
|
|
93
|
+
return out
|
|
94
|
+
|
|
95
|
+
raise ValueError(f"unknown animation {anim!r}; choose from {', '.join(ANIMATIONS)}")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def run_animation(dev, anim: str, color: tuple[int, int, int],
|
|
99
|
+
fps: int = 30, speed: float = 1.0, duration: float | None = None) -> None:
|
|
100
|
+
"""Stream `anim` until Ctrl+C (or `duration` seconds)."""
|
|
101
|
+
from .hid import send_per_key
|
|
102
|
+
|
|
103
|
+
period = 1.0 / fps
|
|
104
|
+
start = time.monotonic()
|
|
105
|
+
try:
|
|
106
|
+
while True:
|
|
107
|
+
if duration is not None and time.monotonic() - start >= duration:
|
|
108
|
+
break
|
|
109
|
+
frame = encode_per_key_frame(render_frame(time.monotonic() - start, anim, color, speed))
|
|
110
|
+
send_per_key(dev, frame)
|
|
111
|
+
time.sleep(period)
|
|
112
|
+
except KeyboardInterrupt:
|
|
113
|
+
pass
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def cmd_animate(args):
|
|
117
|
+
"""fizzctl animate <name> [--color HEX] [--speed N] [--fps N] [--duration S]"""
|
|
118
|
+
from .hid import NoDeviceError, open_device
|
|
119
|
+
|
|
120
|
+
anim = args.name
|
|
121
|
+
if anim is None:
|
|
122
|
+
print("Host-side animations (volatile — lost on disconnect). Run like:")
|
|
123
|
+
print(" fizzctl animate chase --color yellow --speed 2 --fps 30")
|
|
124
|
+
for name in ANIMATIONS:
|
|
125
|
+
print(f" {name}")
|
|
126
|
+
return 0
|
|
127
|
+
if anim not in ANIMATIONS:
|
|
128
|
+
print(f"unknown animation {anim!r}. Available: {', '.join(ANIMATIONS)}")
|
|
129
|
+
return 1
|
|
130
|
+
color = parse_color(args.color or "ff0000")
|
|
131
|
+
if color is None:
|
|
132
|
+
print(f"bad color {args.color!r}")
|
|
133
|
+
return 1
|
|
134
|
+
try:
|
|
135
|
+
dev = open_device(debug=getattr(args, 'debug', False))
|
|
136
|
+
except NoDeviceError:
|
|
137
|
+
return 1
|
|
138
|
+
if dev is None:
|
|
139
|
+
return 1
|
|
140
|
+
try:
|
|
141
|
+
print(f"streaming {anim} at {args.fps}fps (Ctrl+C to stop)...")
|
|
142
|
+
run_animation(dev, anim, color, fps=args.fps, speed=args.speed, duration=args.duration)
|
|
143
|
+
finally:
|
|
144
|
+
dev.close()
|
|
145
|
+
return 0
|
fizzctl/blobs.py
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"""Baked firmware bytes, inlined as hex so the package ships no binary files.
|
|
2
|
+
|
|
3
|
+
All constants come from USB captures of the OEM software:
|
|
4
|
+
* CONST_MODE / CONST_CANVAS / CONST_ROUTING / CONST_EXEC — the
|
|
5
|
+
four constant 1032-byte frames of the Restore sequence.
|
|
6
|
+
* FW_FRAMES — the 5-frame static-effect template used for RGB writes.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
CONST_MODE = bytes.fromhex(
|
|
10
|
+
"0608b80040000000000000000000000000000000000000000000000000ff0000"
|
|
11
|
+
"0000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00"
|
|
12
|
+
"ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff000000"
|
|
13
|
+
"00ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff"
|
|
14
|
+
"00ffffffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000"
|
|
15
|
+
"ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00"
|
|
16
|
+
"ffffffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff"
|
|
17
|
+
"00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ff"
|
|
18
|
+
"ffffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00"
|
|
19
|
+
"ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ffff"
|
|
20
|
+
"ffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff"
|
|
21
|
+
"00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ffffff"
|
|
22
|
+
"ffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00"
|
|
23
|
+
"ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ffffffff"
|
|
24
|
+
"ffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ff"
|
|
25
|
+
"ff00ff00ff00ffffffffff000000000000000000000000000000000000000000"
|
|
26
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
27
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
28
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
29
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
30
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
31
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
32
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
33
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
34
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
35
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
36
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
37
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
38
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
39
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
40
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
41
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
42
|
+
"0000000000000000"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
CONST_CANVAS = bytes.fromhex(
|
|
46
|
+
"0609bc0040000000000000000000000000000000000000000000000000000000"
|
|
47
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
48
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
49
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
50
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
51
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
52
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
53
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
54
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
55
|
+
"00000000000000000000000000000000ff000000000000000000000000000000"
|
|
56
|
+
"00000000ffffff00000000000000000000000000000000000000000000000000"
|
|
57
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
58
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
59
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
60
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
61
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
62
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
63
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
64
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
65
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
66
|
+
"0000000000000000000000000000000000000000ffffffffff00000000000000"
|
|
67
|
+
"0000000000000000ffffffffff0000000000000000000000000000000000ffff"
|
|
68
|
+
"ff00ff000000000000000000000000000000ff0000000000ff00000000000000"
|
|
69
|
+
"00000000000000ff00ff0000ff00000000000000000000000000000000000000"
|
|
70
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
71
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
72
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
73
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
74
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
75
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
76
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
77
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
78
|
+
"0000000000000000"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
CONST_ROUTING = bytes.fromhex(
|
|
82
|
+
"0609c00040000000000000000000ffffffffffffff0000000000000000000000"
|
|
83
|
+
"000000ffffffffff00000000000000000000000000000000ffffffffff000000"
|
|
84
|
+
"000000000000000000000000ff000000ffff0000000000000000000000000000"
|
|
85
|
+
"00ff000000000000000000000000000000000000000000000000000000000000"
|
|
86
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
87
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
88
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
89
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
90
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
91
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
92
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
93
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
94
|
+
"0000000000000000ffffffffffffff0000000000000000000000000000ffffff"
|
|
95
|
+
"ff0000000000000000000000000000000000ffffffff00000000000000000000"
|
|
96
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
97
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
98
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
99
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
100
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
101
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
102
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
103
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
104
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
105
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
106
|
+
"000000000000000000000000000000000000000000000000ff00ff0000000000"
|
|
107
|
+
"000000000000000000000000ffffff0000000000000000000000000000000000"
|
|
108
|
+
"ff0000000000000000000000000000000000000000ff00ff0000000000000000"
|
|
109
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
110
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
111
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
112
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
113
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
114
|
+
"0000000000000000"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
CONST_EXEC = bytes.fromhex(
|
|
118
|
+
"0603b600000000000000000000005aa503030300000b20010000000055550100"
|
|
119
|
+
"00000000ffff0733073307330733073307330733073307330733073307330733"
|
|
120
|
+
"07330733073307330733073307335aa500100744074407440744074407440744"
|
|
121
|
+
"0404040404040404040400000000000000000000000000000000000000000000"
|
|
122
|
+
"0000000000000000005aa5030303000000000000000000000000000000000000"
|
|
123
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
124
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
125
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
126
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
127
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
128
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
129
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
130
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
131
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
132
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
133
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
134
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
135
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
136
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
137
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
138
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
139
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
140
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
141
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
142
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
143
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
144
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
145
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
146
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
147
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
148
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
149
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
150
|
+
"0000000000000000"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
FW_FRAMES = [
|
|
154
|
+
# frame 0: 6B
|
|
155
|
+
bytes.fromhex(
|
|
156
|
+
"0583b6000000"
|
|
157
|
+
),
|
|
158
|
+
# frame 1: 1032B
|
|
159
|
+
bytes.fromhex(
|
|
160
|
+
"0608b80040000000000000000000000000000000000000000000000000ff0000"
|
|
161
|
+
"0000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00"
|
|
162
|
+
"ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff000000"
|
|
163
|
+
"00ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff"
|
|
164
|
+
"00ffffffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000"
|
|
165
|
+
"ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00"
|
|
166
|
+
"ffffffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff"
|
|
167
|
+
"00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ff"
|
|
168
|
+
"ffffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00"
|
|
169
|
+
"ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ffff"
|
|
170
|
+
"ffffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff"
|
|
171
|
+
"00ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ffffff"
|
|
172
|
+
"ffffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00"
|
|
173
|
+
"ffff00ff00ff00ffffffffffff00000000ff00ff00ffff00ff00ff00ffffffff"
|
|
174
|
+
"ffff00000000ff00ff00ffff00ff00ff00ffffffffffff00000000ff00ff00ff"
|
|
175
|
+
"ff00ff00ff00ffffffffff000000000000000000000000000000000000000000"
|
|
176
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
177
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
178
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
179
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
180
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
181
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
182
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
183
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
184
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
185
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
186
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
187
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
188
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
189
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
190
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
191
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
192
|
+
"0000000000000000"
|
|
193
|
+
),
|
|
194
|
+
# frame 2: 1032B
|
|
195
|
+
bytes.fromhex(
|
|
196
|
+
"0609bc0040000000000000000000000000000000000000000000000000000000"
|
|
197
|
+
"00000000000000000000000000000000000000ff00ff00ff0000000000000000"
|
|
198
|
+
"0000000000000000ffffff00ff0000000000000000000000000000000000ff00"
|
|
199
|
+
"ff00ff0000000000000000000000000000000000000000000000000000000000"
|
|
200
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
201
|
+
"00000000ff00ff00000000000000000000ff00ff00ff00000000000000000000"
|
|
202
|
+
"000000000000ffffff00ff0000ff0000ff0000000000000000000000ff00ff00"
|
|
203
|
+
"ff0000ffffff0000000000000000000000000000000000000000000000000000"
|
|
204
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
205
|
+
"0000ff00ff000000000000000000000000000000000000000000000000000000"
|
|
206
|
+
"0000000000000000000000ff0000ff0000000000000000000000000000000000"
|
|
207
|
+
"00ffffff00000000000000000000000000000000000000000000000000000000"
|
|
208
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
209
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
210
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
211
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
212
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
213
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
214
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
215
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
216
|
+
"0000000000000000000000000000000000000000ffffffffff00000000000000"
|
|
217
|
+
"0000000000000000ffffffffff0000000000000000000000000000000000ffff"
|
|
218
|
+
"ff00ff000000000000000000000000000000ff0000000000ff00000000000000"
|
|
219
|
+
"00000000000000ff00ff0000ff00000000000000000000000000000000000000"
|
|
220
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
221
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
222
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
223
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
224
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
225
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
226
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
227
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
228
|
+
"0000000000000000"
|
|
229
|
+
),
|
|
230
|
+
# frame 3: 1032B
|
|
231
|
+
bytes.fromhex(
|
|
232
|
+
"0609c00040000000000000000000ffffffffffffff0000000000000000000000"
|
|
233
|
+
"000000ffffffffff00000000000000000000000000000000ffffffffff000000"
|
|
234
|
+
"000000000000000000000000ff000000ffff0000000000000000000000000000"
|
|
235
|
+
"00ff000000000000000000000000000000000000000000000000000000000000"
|
|
236
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
237
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
238
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
239
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
240
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
241
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
242
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
243
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
244
|
+
"0000000000000000ffffffffffffff0000000000000000000000000000ffffff"
|
|
245
|
+
"ff0000000000000000000000000000000000ffffffff00000000000000000000"
|
|
246
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
247
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
248
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
249
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
250
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
251
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
252
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
253
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
254
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
255
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
256
|
+
"000000000000000000000000000000000000000000000000ff00ff0000000000"
|
|
257
|
+
"000000000000000000000000ffffff0000000000000000000000000000000000"
|
|
258
|
+
"ff0000000000000000000000000000000000000000ff00ff0000000000000000"
|
|
259
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
260
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
261
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
262
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
263
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
264
|
+
"0000000000000000"
|
|
265
|
+
),
|
|
266
|
+
# frame 4: 1032B
|
|
267
|
+
bytes.fromhex(
|
|
268
|
+
"0603b600000000000000000000005aa503030000000120010000000055550100"
|
|
269
|
+
"00000000ffff0034073307330733073307330733073307330733073307330733"
|
|
270
|
+
"07330733073307330733073307335aa500100744074407440744074407440744"
|
|
271
|
+
"0404040404040404040400000000000000000000000000000000000000000000"
|
|
272
|
+
"0000000000000000005aa5030300000000000000000000000000000000000000"
|
|
273
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
274
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
275
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
276
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
277
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
278
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
279
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
280
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
281
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
282
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
283
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
284
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
285
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
286
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
287
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
288
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
289
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
290
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
291
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
292
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
293
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
294
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
295
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
296
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
297
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
298
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
299
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
300
|
+
"0000000000000000"
|
|
301
|
+
),
|
|
302
|
+
]
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
# --- RGB static-color protocol ---
|
|
307
|
+
RGB_INIT = bytes.fromhex("0583b6000000")
|
|
308
|
+
# P1 canvas is BUILT (header + split-plane colors + SEC at 660), not taken from
|
|
309
|
+
# a template. P2 routing is the same 06 09 c0 block used by the Restore
|
|
310
|
+
# sequence (matches RESTORE_CONSTANT_FRAMES[2] exactly). EXEC must be the
|
|
311
|
+
# static-color variant: effect_id=0x01, brightness=0x15.
|
|
312
|
+
RGB_SEC = bytes.fromhex(
|
|
313
|
+
"ffffffffff000000000000000000000000000000ffffffffff00000000000000"
|
|
314
|
+
"00000000000000000000ffffff00ff000000000000000000000000000000ff00"
|
|
315
|
+
"0000000000ff0000000000000000000000000000ff00ff0000ff000000000000"
|
|
316
|
+
"00000000000000000000"
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
RGB_EXEC = bytes.fromhex(
|
|
320
|
+
"0603b600000000000000000000005aa503030300011520010000000055550100"
|
|
321
|
+
"00000000ffff0032073307330733074407330733073307330733073307220733"
|
|
322
|
+
"07330733073307330733073307335aa500100744074407440744074407440744"
|
|
323
|
+
"0404040404040404040400000000000000000000000000000000000000000000"
|
|
324
|
+
"0000000000000000005aa5030303000000000000000000000000000000000000"
|
|
325
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
326
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
327
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
328
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
329
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
330
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
331
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
332
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
333
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
334
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
335
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
336
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
337
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
338
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
339
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
340
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
341
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
342
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
343
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
344
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
345
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
346
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
347
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
348
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
349
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
350
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
351
|
+
"0000000000000000000000000000000000000000000000000000000000000000"
|
|
352
|
+
"0000000000000000"
|
|
353
|
+
)
|