Organize the lighting project and ship the combined XCHC show.

Group workspaces, generators, stage map, and tests into clear folders, and add the unified cans+movers show plus a simple shared/individual RGBW control board.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-08 00:59:36 +12:00
co-authored by Cursor
parent c92094cc26
commit 5eb623d6af
17 changed files with 7457 additions and 1195 deletions
+4
View File
@@ -0,0 +1,4 @@
__pycache__/
*.py[cod]
*.qxw~
.DS_Store
+47
View File
@@ -1,2 +1,49 @@
# qlcplus # qlcplus
QLC+ show files, fixture definitions, and generators for the XCHC stage
(8× beamZ BCC145 parcans + 2× Small Eye 7 movers).
## Layout
```
fixtures/ Fixture definitions (.qxf) — install into QLC+ if needed
shows/ Workspaces to open in QLC+
xchc.qxw Main show (patterns + movers, unified VC)
simple.qxw Manual board: M1/M2 pads, shared + individual RGBW
small_eye.qxw Movers-only figure-of-8 show
archive/ Older scratch workspaces
scripts/ Generators / patchers for the shows
stage/ Stage map (SVG, JSON, canvas)
tests/ Art-Net / fixture helpers used by scripts
```
## Open in QLC+
- Full show: `shows/xchc.qxw`
- Simple RGBW + positions: `shows/simple.qxw`
## Scripts
```bash
# Rebuild simple manual board
python3 scripts/make_simple_vc.py
# Rewrite can/mover patterns from stage layout
python3 scripts/integrate_u_patterns.py
# Unify Patterns + Movers into one Show frame
python3 scripts/unify_vc.py
# Figure-of-8 (live Art-Net or write/merge workspace)
python3 scripts/figure8_small_eye.py --write-qxw shows/small_eye.qxw
```
## Fixtures / DMX
| Fixture | Mode | Addresses |
|---------|------|-----------|
| Small Eye 7 #1–#2 | 43ch | 1–43, 45–87 |
| BCC145 #1–#8 | 8ch | 87–150 (starts 87, 95, …) |
Copy `.qxf` files from `fixtures/` into QLC+’s fixture library if the
manufacturer/model is missing.
+4 -4
View File
@@ -27,10 +27,10 @@
</Channel> </Channel>
<Channel Name="Lens Rotate"> <Channel Name="Lens Rotate">
<Group Byte="0">Prism</Group> <Group Byte="0">Prism</Group>
<Capability Min="0" Max="127">Index 0–60°</Capability> <Capability Min="0" Max="127">Index 0–60° (no spin)</Capability>
<Capability Min="128" Max="191" Preset="RotationCounterClockwiseFastToSlow">Rotate CCW fast to slow</Capability> <Capability Min="128" Max="188" Preset="RotationCounterClockwiseFastToSlow">Spin CCW fast to slow</Capability>
<Capability Min="192" Max="199">Stop</Capability> <Capability Min="189" Max="193">Stop</Capability>
<Capability Min="200" Max="255" Preset="RotationClockwiseSlowToFast">Rotate CW slow to fast</Capability> <Capability Min="194" Max="255" Preset="RotationClockwiseSlowToFast">Spin CW slow to fast</Capability>
</Channel> </Channel>
<Channel Name="Lens Rotate 35"> <Channel Name="Lens Rotate 35">
<Group Byte="0">Prism</Group> <Group Byte="0">Prism</Group>
File diff suppressed because it is too large Load Diff
+366
View File
@@ -0,0 +1,366 @@
#!/usr/bin/env python3
"""Rewrite xchc pattern scenes so the U of cans + centre movers act as one.
Building 7 m wide. Coordinates in metres:
X = 0 at centre line, +X to the right
Y = 0 at the row of 4, +Y toward audience (in front of the 4)
Audience
1 8 ← wall-mounted sides @ 2.4 m in front of the 4
2 M1 M2 7 ← wall-mounted sides @ 1.2 m; movers @ 1.1 m, ±0.3 m
3 — 4 — 5 — 6 ← row of 4 at ±0.6 m and ±1.8 m from centre
Building 7 m → side walls at ±3.5 m. #1,#2 left wall; #7,#8 right wall.
#1 front left. Movers 1.1 m in front of the row of 4, 0.3 m off centre.
"""
from __future__ import annotations
import re
from pathlib import Path
CANS = list(range(8))
MOVERS = (8, 9)
WALL = 3.5 # building half-width
# Fixture ID → (x_m, y_m) — Y=0 = row of 4; +Y toward audience
LAYOUT_M = {
0: (-WALL, 2.4), # #1 front left — left wall
1: (-WALL, 1.2), # #2 — left wall
2: (-1.8, 0.0), # #3 row of 4
3: (-0.6, 0.0), # #4 row of 4
4: (0.6, 0.0), # #5 row of 4
5: (1.8, 0.0), # #6 row of 4
6: (WALL, 1.2), # #7 — right wall
7: (WALL, 2.4), # #8 front right — right wall
8: (-0.3, 1.1), # Small Eye #1 — 0.3 m off centre, 1.1 m in front of row of 4
9: (0.3, 1.1), # Small Eye #2 — 0.3 m off centre, 1.1 m in front of row of 4
}
# Walk U: #1 → #2 → along row of 4 L→R → #7 → #8
U_WALK = [0, 1, 2, 3, 4, 5, 6, 7]
LEFT_SIDE = {0, 1}
RIGHT_SIDE = {6, 7}
ROW4 = {2, 3, 4, 5}
RINGS = [
{8, 9},
{8, 9, 3, 4}, # movers + centre of row of 4
{8, 9, *ROW4},
{8, 9, *CANS},
]
LEFT = LEFT_SIDE | {2, 3, 8}
RIGHT = RIGHT_SIDE | {4, 5, 9}
GRID_W = 7.0
GRID_H = 3.2
X_ORIGIN = -3.5
def m_to_grid(x_m: float, y_m: float) -> tuple[float, float]:
gx = round(x_m - X_ORIGIN, 2)
# Row of 4 (y=0) toward top; audience / front sides toward bottom
gy = round(y_m, 2)
return gx, gy
COLORS = {
"Red": (255, 0, 0),
"Orange": (255, 127, 0),
"Yellow": (255, 255, 0),
"Green": (0, 255, 0),
"Cyan": (0, 255, 255),
"Blue": (0, 0, 255),
"Violet": (127, 0, 255),
"Magenta": (255, 0, 255),
"White": (255, 255, 255),
}
RAINBOW = [
(255, 0, 0),
(255, 127, 0),
(255, 255, 0),
(0, 255, 0),
(0, 255, 255),
(0, 0, 255),
(127, 0, 255),
(255, 0, 255),
]
def can_channels(r: int, g: int, b: int, *, white: int = 0, on: bool = True) -> str:
if not on:
return "0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0"
if white:
return f"1,0,2,0,3,0,4,0,5,{white},6,0,7,0"
return f"1,0,2,{r},3,{g},4,{b},5,0,6,0,7,0"
def mover_channels(r: int, g: int, b: int, *, on: bool = True, dim: int = 255) -> str:
if not on or (r == g == b == 0):
dim = 0
r = g = b = 0
parts = [
0, 128, 2, 80, 4, 0, 5, 0, 6, 191, 7, 70, 8, dim, 9, 0,
10, r, 11, g, 12, b, 13, 0,
]
for pixel in range(1, 7):
base = 10 + pixel * 4
parts.extend([base, 0, base + 1, 0, base + 2, 0, base + 3, 0])
return ",".join(str(x) for x in parts)
def fixture_vals(
lit: dict[int, tuple[int, int, int] | None], *, white_ids: set[int] | None = None
) -> str:
white_ids = white_ids or set()
lines = []
for fid in list(CANS) + list(MOVERS):
rgb = lit.get(fid)
if rgb is None:
ch = (
mover_channels(0, 0, 0, on=False)
if fid in MOVERS
else can_channels(0, 0, 0, on=False)
)
lines.append(f' <FixtureVal ID="{fid}">{ch}</FixtureVal>')
continue
r, g, b = rgb
if fid in MOVERS:
ch = mover_channels(r, g, b)
elif fid in white_ids:
ch = can_channels(0, 0, 0, white=255)
else:
ch = can_channels(r, g, b)
lines.append(f' <FixtureVal ID="{fid}">{ch}</FixtureVal>')
return "\n".join(lines)
def scene(
fid: int,
name: str,
lit: dict,
*,
white_ids: set[int] | None = None,
fade: int = 0,
) -> str:
return f""" <Function ID="{fid}" Type="Scene" Name="{name}">
<Speed FadeIn="{fade}" FadeOut="0" Duration="{fade}" />
{fixture_vals(lit, white_ids=white_ids)}
</Function>"""
def replace_function(text: str, function_id: int, new_xml: str) -> str:
pattern = re.compile(
rf' <Function ID="{function_id}"[\s\S]*?</Function>\n',
re.MULTILINE,
)
if not pattern.search(text):
raise SystemExit(f"Function ID {function_id} not found")
return pattern.sub(new_xml.rstrip() + "\n", text, count=1)
def all_color(rgb: tuple[int, int, int]) -> dict:
lit = {i: rgb for i in CANS}
lit[8] = rgb
lit[9] = rgb
return lit
def monitor_xml() -> str:
items = []
for fid, (xm, ym) in LAYOUT_M.items():
gx, gy = m_to_grid(xm, ym)
items.append(f' <FxItem ID="{fid}" XPos="{gx}" YPos="{gy}" />')
return f""" <Monitor DisplayMode="1" ShowLabels="1">
<Font>Arial,12,-1,5,50,0,0,0,0,0</Font>
<ChannelStyle>0</ChannelStyle>
<ValueStyle>0</ValueStyle>
<Grid Width="{GRID_W}" Height="{GRID_H}" Depth="5" Units="0" />
{chr(10).join(items)}
</Monitor>"""
def main():
path = Path(__file__).resolve().parents[1] / "shows" / "xchc.qxw"
text = path.read_text()
for i, (name, rgb) in enumerate(COLORS.items()):
white_ids = set(CANS) if name == "White" else None
text = replace_function(text, i, scene(i, name, all_color(rgb), white_ids=white_ids))
for step in range(8):
lit = {}
for ci, can in enumerate(U_WALK):
lit[can] = RAINBOW[(ci + step) % 8]
lit[8] = RAINBOW[(3 + step) % 8]
lit[9] = RAINBOW[(4 + step) % 8]
text = replace_function(text, 10 + step, scene(10 + step, f"Rainbow {step + 1}", lit))
blue, red = (0, 0, 255), (255, 0, 0)
odd_blue, odd_red = {}, {}
for i in CANS:
if i % 2 == 0:
odd_blue[i], odd_red[i] = blue, red
else:
odd_blue[i], odd_red[i] = red, blue
odd_blue[8], odd_blue[9] = blue, red
odd_red[8], odd_red[9] = red, blue
text = replace_function(text, 20, scene(20, "Odd Blue Even Red", odd_blue))
text = replace_function(text, 21, scene(21, "Odd Red Even Blue", odd_red))
off = {i: None for i in list(CANS) + list(MOVERS)}
text = replace_function(text, 23, scene(23, "Test Off", off))
text = replace_function(text, 72, scene(72, "Soft Blackout", off, fade=4000))
for i, can in enumerate(U_WALK):
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
lit[can] = (255, 255, 255)
text = replace_function(
text, 33 + i, scene(33 + i, f"Scanner {i + 1}", lit, white_ids={can})
)
for mid, name, ids in ((99, "Scanner Movers", {8, 9}), (100, "Scanner Off", set())):
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
for m in ids:
lit[m] = (255, 255, 255)
block = scene(mid, name, lit)
if f'Function ID="{mid}"' in text:
text = replace_function(text, mid, block)
else:
text = text.replace(
' <Function ID="41" Type="Chaser" Name="Scanner">',
block + '\n <Function ID="41" Type="Chaser" Name="Scanner">',
1,
)
scanner_steps = "\n".join(
f' <Step Number="{i}" FadeIn="0" Hold="400" FadeOut="0">{sid}</Step>'
for i, sid in enumerate([*range(33, 41), 99, 100])
)
text = replace_function(
text,
41,
f""" <Function ID="41" Type="Chaser" Name="Scanner">
<Speed FadeIn="0" FadeOut="0" Duration="400" />
<Direction>Forward</Direction>
<RunOrder>Loop</RunOrder>
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common" />
{scanner_steps}
</Function>""",
)
for n in range(1, 9):
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
for can in U_WALK[:n]:
lit[can] = (255, 255, 255)
if n >= 3:
lit[8] = lit[9] = (255, 255, 255)
white = {c for c in U_WALK[:n]}
text = replace_function(
text, 41 + n, scene(41 + n, f"Fill {n}", lit, white_ids=white)
)
for i, ring in enumerate(RINGS):
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
white = {f for f in ring if f in CANS}
for fid in ring:
lit[fid] = (255, 255, 255)
text = replace_function(
text, 51 + i, scene(51 + i, f"Center {i + 1}", lit, white_ids=white)
)
for i, (ids, name) in enumerate(
[
({0, 7}, "Pairs 1"),
({1, 6}, "Pairs 2"),
({2, 5}, "Pairs 3"),
({3, 4, 8, 9}, "Pairs 4"),
]
):
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
white = {f for f in ids if f in CANS}
for fid in ids:
lit[fid] = (255, 255, 255)
text = replace_function(text, 56 + i, scene(56 + i, name, lit, white_ids=white))
lbrr = {fid: None for fid in list(CANS) + list(MOVERS)}
lrbr = {fid: None for fid in list(CANS) + list(MOVERS)}
for fid in LEFT:
lbrr[fid], lrbr[fid] = (0, 0, 255), (255, 0, 0)
for fid in RIGHT:
lbrr[fid], lrbr[fid] = (255, 0, 0), (0, 0, 255)
text = replace_function(text, 61, scene(61, "Left Blue Right Red", lbrr))
text = replace_function(text, 62, scene(62, "Left Red Right Blue", lrbr))
for step in range(3):
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
white = set()
for can in CANS:
if can % 3 == step:
lit[can] = (255, 255, 255)
white.add(can)
if step == 0:
lit[8] = (255, 255, 255)
elif step == 1:
lit[9] = (255, 255, 255)
else:
lit[8] = lit[9] = (255, 200, 140)
text = replace_function(
text, 64 + step, scene(64 + step, f"Theater {step + 1}", lit, white_ids=white)
)
collapse_steps = "\n".join(
f' <Step Number="{i}" FadeIn="200" Hold="300" FadeOut="0">{sid}</Step>'
for i, sid in enumerate([54, 53, 52, 51, 23])
)
text = replace_function(
text,
68,
f""" <Function ID="68" Type="Chaser" Name="Collapse In">
<Speed FadeIn="200" FadeOut="0" Duration="500" />
<Direction>Forward</Direction>
<RunOrder>SingleShot</RunOrder>
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common" />
{collapse_steps}
</Function>""",
)
chase_steps = "\n".join(
f' <Step Number="{i}" FadeIn="0" Hold="300" FadeOut="0">{sid}</Step>'
for i, sid in enumerate([*range(33, 41), 99, 23])
)
text = replace_function(
text,
69,
f""" <Function ID="69" Type="Chaser" Name="Chase Out">
<Speed FadeIn="0" FadeOut="0" Duration="400" />
<Direction>Forward</Direction>
<RunOrder>SingleShot</RunOrder>
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common" />
{chase_steps}
</Function>""",
)
text = replace_function(
text, 70, scene(70, "Home Soft", all_color((255, 180, 80)), fade=2500)
)
text = re.sub(
r' <Monitor DisplayMode="1" ShowLabels="1">[\s\S]*?</Monitor>',
lambda _m: monitor_xml(),
text,
count=1,
)
text = text.replace("<Name>BCC145 Line</Name>", "<Name>BCC145 U</Name>", 1)
path.write_text(text)
print("Updated", path)
print("Y=0 row of 4; +Y toward audience (in front of the 4)")
for fid in sorted(LAYOUT_M):
x, y = LAYOUT_M[fid]
label = f"Can #{fid + 1}" if fid < 8 else f"Mover #{fid - 7}"
print(f" {label:10} x={x:+.1f} y={y:.1f}")
if __name__ == "__main__":
main()
+305
View File
@@ -0,0 +1,305 @@
#!/usr/bin/env python3
"""Generate shows/simple.qxw — per-mover position + shared and individual RGBW."""
from __future__ import annotations
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "shows" / "simple.qxw"
# Fixture IDs match shows/xchc.qxw
CANS = list(range(8)) # BCC145 #1–#8
M1, M2 = 8, 9
MOVERS = [M1, M2]
# Can 8ch: Dim=0, R=2, G=3, B=4, W=5
# Mover 43ch: Center Bright=8; RGBW heads 1–7
MOVER_R = [10, 14, 18, 22, 26, 30, 34]
MOVER_G = [11, 15, 19, 23, 27, 31, 35]
MOVER_B = [12, 16, 20, 24, 28, 32, 36]
MOVER_W = [13, 17, 21, 25, 29, 33, 37]
COLORS = [
("R", 2, MOVER_R, "4294901760", "Red"),
("G", 3, MOVER_G, "4278255360", "Green"),
("B", 4, MOVER_B, "4278190335", "Blue"),
("W", 5, MOVER_W, "4294967295", "None"),
]
def appearance(
fg: str = "Default",
bg: str = "Default",
frame: str = "Sunken",
) -> str:
return f""" <Appearance>
<FrameStyle>{frame}</FrameStyle>
<ForegroundColor>{fg}</ForegroundColor>
<BackgroundColor>{bg}</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>"""
def slider(
wid: int,
caption: str,
x: int,
y: int,
w: int,
h: int,
channels: list[tuple[int, int]],
*,
value: int = 0,
fg: str = "Default",
cng: str = "None",
) -> str:
ch_xml = "\n".join(
f' <Channel Fixture="{fid}">{ch}</Channel>' for fid, ch in channels
)
return f""" <Slider Caption="{caption}" ID="{wid}" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
{appearance(fg=fg)}
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="{cng}" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="{value}">
{ch_xml}
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>"""
def xypad(wid: int, caption: str, fid: int, x: int, y: int, w: int, h: int) -> str:
return f""" <XYPad Caption="{caption}" ID="{wid}" InvertedAppearance="0">
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
{appearance()}
<Fixture ID="{fid}" Head="0">
<Axis ID="X" LowLimit="0" HighLimit="1" Reverse="False"/>
<Axis ID="Y" LowLimit="0" HighLimit="1" Reverse="False"/>
</Fixture>
<Window hMin="0" hMax="255" vMin="0" vMax="255"/>
<Pan Position="128"/>
<Tilt Position="128"/>
</XYPad>"""
def label_frame(caption: str, x: int, y: int, w: int, h: int) -> str:
return f""" <Frame Caption="{caption}">
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
<AllowChildren>True</AllowChildren>
<AllowResize>True</AllowResize>
<ShowHeader>True</ShowHeader>
<ShowEnableButton>False</ShowEnableButton>
<ShowIntensityButton>False</ShowIntensityButton>
<Mixing>False</Mixing>
</Frame>"""
def fixture_xml() -> str:
parts = []
for i in range(8):
parts.append(
f""" <Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>{i}</ID>
<Name>BCC145 #{i + 1}</Name>
<Universe>0</Universe>
<Address>{87 + i * 8}</Address>
<Channels>8</Channels>
</Fixture>"""
)
for i, addr in enumerate((0, 44)):
parts.append(
f""" <Fixture>
<Manufacturer>Small Eye 7</Manufacturer>
<Model>Mover</Model>
<Mode>43 Channel</Mode>
<ID>{8 + i}</ID>
<Name>Small Eye 7 #{i + 1}</Name>
<Universe>0</Universe>
<Address>{addr}</Address>
<Channels>43</Channels>
</Fixture>"""
)
return "\n".join(parts)
def main() -> None:
pad_w, pad_h = 240, 240
sl_w, sl_h = 44, 240
ind_w, ind_h = 36, 160
gap = 8
widgets: list[str] = []
wid = 0
max_x = 0
max_y = 0
def place_slider(caption, x, y, w, h, channels, value=0, fg="Default", cng="None"):
nonlocal wid, max_x, max_y
widgets.append(
slider(wid, caption, x, y, w, h, channels, value=value, fg=fg, cng=cng)
)
wid += 1
max_x = max(max_x, x + w)
max_y = max(max_y, y + h)
y0 = 28
x = 10
widgets.append(xypad(wid, "M1 Position", M1, x, y0, pad_w, pad_h))
wid += 1
x += pad_w + gap
widgets.append(xypad(wid, "M2 Position", M2, x, y0, pad_w, pad_h))
wid += 1
x += pad_w + gap + 12
max_x = max(max_x, x)
max_y = max(max_y, y0 + pad_h)
place_slider("C Dim", x, y0, sl_w, sl_h, [(f, 0) for f in CANS], 255, "4294967295")
x += sl_w + 2
for name, can_ch, _mover_chs, fg, cng in COLORS:
place_slider(
f"C {name}",
x,
y0,
sl_w,
sl_h,
[(f, can_ch) for f in CANS],
fg=fg,
cng=cng,
)
x += sl_w + 2
x += 14
place_slider("M Dim", x, y0, sl_w, sl_h, [(f, 8) for f in MOVERS], 255, "4294967295")
x += sl_w + 2
for name, _can_ch, mover_chs, fg, cng in COLORS:
place_slider(
f"M {name}",
x,
y0,
sl_w,
sl_h,
[(f, c) for f in MOVERS for c in mover_chs],
fg=fg,
cng=cng,
)
x += sl_w + 2
y1 = y0 + pad_h + 36
x = 10
widgets.append(label_frame("Cans individual RGBW", x, y1 - 28, 200, 24))
for i, fid in enumerate(CANS):
col_x = x + i * (4 * (ind_w + 2) + 10)
for j, (name, can_ch, _m, fg, cng) in enumerate(COLORS):
place_slider(
f"{i + 1}{name}",
col_x + j * (ind_w + 2),
y1,
ind_w,
ind_h,
[(fid, can_ch)],
fg=fg,
cng=cng,
)
mx = x + 8 * (4 * (ind_w + 2) + 10) + 16
widgets.append(label_frame("Movers individual RGBW", mx, y1 - 28, 220, 24))
for mi, (fid, label) in enumerate(((M1, "M1"), (M2, "M2"))):
col_x = mx + mi * (4 * (ind_w + 2) + 14)
for j, (name, _can_ch, mover_chs, fg, cng) in enumerate(COLORS):
place_slider(
f"{label}{name}",
col_x + j * (ind_w + 2),
y1,
ind_w,
ind_h,
[(fid, c) for c in mover_chs],
fg=fg,
cng=cng,
)
total_w = max_x + 16
total_h = max_y + 16
qxw = f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Workspace>
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="VirtualConsole">
<Creator>
<Name>Q Light Controller Plus</Name>
<Version>4.12.7</Version>
<Author>Jimmy</Author>
</Creator>
<Engine>
<InputOutputMap>
<Universe Name="Universe 1" ID="0">
<Output Plugin="ArtNet" UID="192.168.1.92" Line="7">
<PluginParameters outputIP="192.168.1.228" outputUni="0"/>
</Output>
</Universe>
<Universe Name="Universe 2" ID="1"/>
<Universe Name="Universe 3" ID="2"/>
<Universe Name="Universe 4" ID="3"/>
</InputOutputMap>
{fixture_xml()}
<FixtureGroup ID="0">
<Name>BCC145 U</Name>
<Size X="8" Y="1"/>
<Head X="0" Y="0" Fixture="0">0</Head>
<Head X="1" Y="0" Fixture="1">0</Head>
<Head X="2" Y="0" Fixture="2">0</Head>
<Head X="3" Y="0" Fixture="3">0</Head>
<Head X="4" Y="0" Fixture="4">0</Head>
<Head X="5" Y="0" Fixture="5">0</Head>
<Head X="6" Y="0" Fixture="6">0</Head>
<Head X="7" Y="0" Fixture="7">0</Head>
</FixtureGroup>
<FixtureGroup ID="1">
<Name>Small Eye Movers</Name>
<Size X="2" Y="1"/>
<Head X="0" Y="0" Fixture="8">0</Head>
<Head X="1" Y="0" Fixture="9">0</Head>
</FixtureGroup>
</Engine>
<VirtualConsole>
<Frame Caption="">
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
{"\n".join(widgets)}
</Frame>
<Properties>
<Size Width="{total_w}" Height="{total_h}"/>
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
</Properties>
</VirtualConsole>
<SimpleDesk>
<Engine/>
</SimpleDesk>
</Workspace>
"""
OUT.parent.mkdir(parents=True, exist_ok=True)
OUT.write_text(qxw)
print(f"Wrote {OUT} ({total_w}x{total_h}, {wid} widgets)")
if __name__ == "__main__":
main()
+268
View File
@@ -0,0 +1,268 @@
#!/usr/bin/env python3
"""Merge Patterns + Movers into one SoloFrame and one Speed dial in xchc.qxw."""
from __future__ import annotations
import re
from pathlib import Path
def btn(
widget_id: int,
caption: str,
func_id: int,
x: int,
y: int,
w: int,
h: int,
bg: str,
fg: str = "4294967295",
) -> str:
return f""" <Button Caption="{caption}" ID="{widget_id}" Icon="">
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>{fg}</ForegroundColor>
<BackgroundColor>{bg}</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<Function ID="{func_id}"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
</Button>"""
ROOT = Path(__file__).resolve().parents[1]
def main():
path = ROOT / "shows" / "xchc.qxw"
text = path.read_text()
# Combined looks: can colour chase + figure-of-8 movement
combos = [
(101, "Colour + F8", 9, 77),
(102, "Rainbow + F8", 18, 77),
(103, "OddEven + F8", 22, 77),
(104, "Center + F8", 55, 77),
(105, "Theater + F8", 67, 77),
]
combo_xml = []
for fid, name, a, b in combos:
block = f""" <Function ID="{fid}" Type="Collection" Name="{name}">
<Step Number="0">{a}</Step>
<Step Number="1">{b}</Step>
</Function>
"""
if f'Function ID="{fid}"' in text:
text = re.sub(
rf' <Function ID="{fid}"[\s\S]*?</Function>\n',
block,
text,
count=1,
)
else:
combo_xml.append(block.rstrip())
if combo_xml:
text = text.replace(
' <Monitor DisplayMode="1"',
"\n".join(combo_xml) + "\n <Monitor DisplayMode=\"1\"",
1,
)
# Build unified Show SoloFrame
# Row 0: colour / spatial patterns (cans+movers already in scenes)
# Row 1: combined flight looks
# Row 2: mover-only + exits
w, h = 150, 56
gap_x, gap_y = 8, 8
x0, y0 = 10, 28
def cell(col, row):
return x0 + col * (w + gap_x), y0 + row * (h + gap_y)
buttons = []
# Row 0 — parcans + movers colour/spatial
row0 = [
(0, "Colour", 9, "4282664004"),
(28, "Rainbow", 18, "4280427042"),
(37, "Odd Even", 22, "4284752486"),
(47, "Scanner", 41, "4292033564"),
(48, "Fill", 50, "4278218076"),
(49, "Center Out", 55, "4280817043"),
]
for i, (wid, cap, fid, bg) in enumerate(row0):
x, y = cell(i, 0)
buttons.append(btn(wid, cap, fid, x, y, w, h, bg))
row1 = [
(50, "Pairs", 60, "4294946560", "4278190080"),
(51, "Left Right", 63, "4279648704", "4294967295"),
(52, "Theater", 67, "4285143962", "4294967295"),
(200, "Colour+F8", 101, "4282664004", "4294967295"),
(201, "Rainbow+F8", 102, "4280427042", "4294967295"),
(202, "Center+F8", 104, "4280817043", "4294967295"),
]
for i, (wid, cap, fid, bg, fg) in enumerate(row1):
x, y = cell(i, 1)
buttons.append(btn(wid, cap, fid, x, y, w, h, bg, fg))
row2 = [
(100, "Figure of 8", 77, "4282664004"),
(203, "OddEven+F8", 103, "4284752486"),
(204, "Theater+F8", 105, "4285143962"),
(53, "Collapse In", 68, "4281545523"),
(54, "Chase Out", 69, "4284900966"),
(55, "Home Fade", 71, "4286611584"),
]
for i, (wid, cap, fid, bg) in enumerate(row2):
x, y = cell(i, 2)
buttons.append(btn(wid, cap, fid, x, y, w, h, bg))
# Home Fade for whole stage uses can Home Fade 71; keep mover Home Fade via MIB/Soft BO
row3 = [
(101, "Ring Collapse", 85, "4281545523"),
(114, "Ring Chase", 94, "4284900966"),
(116, "Move in Black", 98, "4279900698"),
(56, "Soft Blackout", 72, "4278190080"),
(38, "Red Test", 32, "4286578688"),
]
for i, (wid, cap, fid, bg) in enumerate(row3):
x, y = cell(i, 3)
buttons.append(btn(wid, cap, fid, x, y, w, h, bg))
frame_w = x0 + 6 * (w + gap_x) + 10
frame_h = y0 + 4 * (h + gap_y) + 16
show_frame = f""" <SoloFrame Caption="Show">
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<WindowState Visible="True" X="10" Y="10" Width="{frame_w}" Height="{frame_h}"/>
<AllowChildren>True</AllowChildren>
<AllowResize>True</AllowResize>
<ShowHeader>True</ShowHeader>
<Mixing>False</Mixing>
{chr(10).join(buttons)}
</SoloFrame>"""
# Replace Patterns SoloFrame
text = re.sub(
r' <SoloFrame Caption="Patterns">[\s\S]*?</SoloFrame>',
show_frame,
text,
count=1,
)
# Remove Movers SoloFrame (buttons now in Show)
text = re.sub(
r' <SoloFrame Caption="Movers">[\s\S]*?</SoloFrame>\n',
"",
text,
count=1,
)
# Merge mover speed targets into main Speed dial; drop Mover Speed dial
text = re.sub(
r' <SpeedDial Caption="Mover Speed" ID="102">[\s\S]*?</SpeedDial>\n',
"",
text,
count=1,
)
speed_extra = """ <Function FadeIn="6" FadeOut="0" Duration="6">74</Function>
<Function FadeIn="0" FadeOut="0" Duration="6">76</Function>
<Function FadeIn="6" FadeOut="0" Duration="6">101</Function>
<Function FadeIn="6" FadeOut="0" Duration="6">102</Function>
<Function FadeIn="6" FadeOut="0" Duration="6">103</Function>
<Function FadeIn="6" FadeOut="0" Duration="6">104</Function>
<Function FadeIn="0" FadeOut="0" Duration="6">105</Function>
"""
if 'Function FadeIn="6" FadeOut="0" Duration="6">74</Function>' not in text:
text = text.replace(
' <Function FadeIn="0" FadeOut="0" Duration="6">69</Function>\n </SpeedDial>',
' <Function FadeIn="0" FadeOut="0" Duration="6">69</Function>\n'
+ speed_extra
+ " </SpeedDial>",
1,
)
# Make Speed dial visible next to Show
text = text.replace(
'<SpeedDial Caption="Speed" ID="3">\n <WindowState Visible="False" X="720" Y="20" Width="90" Height="250"/>',
f'<SpeedDial Caption="Speed" ID="3">\n <WindowState Visible="True" X="{frame_w + 20}" Y="10" Width="100" Height="{frame_h}"/>',
1,
)
# All Dim also drives mover dimmers
if "<Channel Fixture=\"8\">8</Channel>" not in text.split('Caption="All Dim"', 1)[1][:800]:
text = text.replace(
""" <Level LowLimit="0" HighLimit="255" Value="174">
<Channel Fixture="0">0</Channel>
<Channel Fixture="1">0</Channel>
<Channel Fixture="2">0</Channel>
<Channel Fixture="3">0</Channel>
<Channel Fixture="4">0</Channel>
<Channel Fixture="5">0</Channel>
<Channel Fixture="6">0</Channel>
<Channel Fixture="7">0</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="1 R\"""",
""" <Level LowLimit="0" HighLimit="255" Value="174">
<Channel Fixture="0">0</Channel>
<Channel Fixture="1">0</Channel>
<Channel Fixture="2">0</Channel>
<Channel Fixture="3">0</Channel>
<Channel Fixture="4">0</Channel>
<Channel Fixture="5">0</Channel>
<Channel Fixture="6">0</Channel>
<Channel Fixture="7">0</Channel>
<Channel Fixture="8">8</Channel>
<Channel Fixture="9">8</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="1 R\"""",
1,
)
# Relabel / place XY pad under Show
text = text.replace(
'Caption="Mover Position"',
'Caption="Position"',
1,
)
text = text.replace(
'<XYPad Caption="Position" ID="103" InvertedAppearance="0">\n <WindowState Visible="True" X="720" Y="180" Width="320" Height="320"/>',
f'<XYPad Caption="Position" ID="103" InvertedAppearance="0">\n <WindowState Visible="True" X="10" Y="{frame_h + 20}" Width="320" Height="300"/>',
1,
)
# Shift mover sliders under Show, right of XY pad
slider_y = frame_h + 20
old_xs = [1050 + i * 46 for i in range(10)]
new_xs = [340 + i * 46 for i in range(10)]
for ox, nx in zip(old_xs, new_xs):
text = text.replace(
f'Visible="True" X="{ox}" Y="180" Width="44" Height="320"',
f'Visible="True" X="{nx}" Y="{slider_y}" Width="44" Height="300"',
1,
)
path.write_text(text)
print(f"Unified Show controls in {path}")
print(f" SoloFrame {frame_w}x{frame_h} with pattern + F8 combos + exits")
print(" One Speed dial; Position pad + mover sliders below")
if __name__ == "__main__":
main()
+269
View File
@@ -0,0 +1,269 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Workspace>
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="VirtualConsole">
<Creator>
<Name>Q Light Controller Plus</Name>
<Version>4.12.7</Version>
<Author>Jimmy</Author>
</Creator>
<Engine>
<InputOutputMap>
<Universe Name="Universe 1" ID="0">
<Output Plugin="E1.31" UID="10.1.1.222" Line="1">
<PluginParameters UniverseChannels="8" multicast="0" ucastIP="10.1.1.159" universe="1"/>
</Output>
</Universe>
<Universe Name="Universe 2" ID="1"/>
<Universe Name="Universe 3" ID="2"/>
<Universe Name="Universe 4" ID="3"/>
</InputOutputMap>
<Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>0</ID>
<Name>BCC145</Name>
<Universe>0</Universe>
<Address>0</Address>
<Channels>8</Channels>
</Fixture>
<ChannelsGroup ID="0" Name="Red" Value="0">0,2</ChannelsGroup>
<ChannelsGroup ID="1" Name="Green" Value="0">0,3</ChannelsGroup>
<ChannelsGroup ID="2" Name="Blue" Value="0">0,4</ChannelsGroup>
<ChannelsGroup ID="3" Name="White" Value="0">0,5</ChannelsGroup>
<ChannelsGroup ID="4" Name="Dimmer" Value="0">0,0</ChannelsGroup>
<!-- 8ch: 0 dimmer, 1 strobe, 2 R, 3 G, 4 B, 5 W, 6 macro (0=RGBW mix), 7 speed -->
<Function Type="Scene" Name="Red" ID="0" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,255,3,0,4,0,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Orange" ID="1" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,255,3,127,4,0,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Yellow" ID="2" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,255,3,255,4,0,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Green" ID="3" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,0,3,255,4,0,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Cyan" ID="4" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,0,3,255,4,255,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Blue" ID="5" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,0,3,0,4,255,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Violet" ID="6" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,127,3,0,4,255,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Magenta" ID="7" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,255,3,0,4,255,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="White" ID="8" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,0,3,0,4,0,5,255,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Blackout" ID="9" Path="Colors">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0</FixtureVal>
</Function>
<Function Type="Scene" Name="Built-in Gradient" ID="10">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">0,255,1,0,2,0,3,0,4,0,5,0,6,225,7,80</FixtureVal>
</Function>
<Function Type="Chaser" Name="Color Transition" ID="11">
<Speed FadeIn="3000" FadeOut="0" Duration="4000"/>
<Direction>Forward</Direction>
<RunOrder>Loop</RunOrder>
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common"/>
<Step Number="0" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">0</Step>
<Step Number="1" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">1</Step>
<Step Number="2" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">2</Step>
<Step Number="3" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">3</Step>
<Step Number="4" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">4</Step>
<Step Number="5" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">5</Step>
<Step Number="6" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">6</Step>
<Step Number="7" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">7</Step>
</Function>
</Engine>
<VirtualConsole>
<Frame Caption="">
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<Button Icon="" Caption="Color Transition">
<Function ID="11"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="20" Y="20" Width="180" Height="70" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4282664004</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Built-in Gradient">
<Function ID="10"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="210" Y="20" Width="180" Height="70" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4280427042</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Blackout">
<Function ID="9"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="400" Y="20" Width="120" Height="70" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4278190080</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Red">
<Function ID="0"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="20" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4294901760</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Orange">
<Function ID="1"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="110" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4278190080</ForegroundColor>
<BackgroundColor>4294944000</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Yellow">
<Function ID="2"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="200" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4278190080</ForegroundColor>
<BackgroundColor>4294967040</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Green">
<Function ID="3"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="290" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4278190080</ForegroundColor>
<BackgroundColor>4278255360</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Cyan">
<Function ID="4"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="380" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4278190080</ForegroundColor>
<BackgroundColor>4278255615</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Blue">
<Function ID="5"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="470" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4278190335</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Violet">
<Function ID="6"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="560" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4286578687</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="Magenta">
<Function ID="7"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="650" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4294902015</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button Icon="" Caption="White">
<Function ID="8"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="740" Y="110" Width="80" Height="50" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4278190080</ForegroundColor>
<BackgroundColor>4294967295</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
</Frame>
<Properties>
<Size Width="1920" Height="1080"/>
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
</Properties>
</VirtualConsole>
<SimpleDesk>
<Engine/>
</SimpleDesk>
</Workspace>
+115
View File
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Workspace>
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="SimpleDesk">
<Creator>
<Name>Q Light Controller Plus</Name>
<Version>4.12.7</Version>
<Author>Jimmy</Author>
</Creator>
<Engine>
<InputOutputMap>
<Universe Name="Universe 1" ID="0">
<Output Plugin="ArtNet" UID="192.168.1.92" Line="7">
<PluginParameters outputIP="192.168.1.228"/>
</Output>
</Universe>
<Universe Name="Universe 2" ID="1"/>
<Universe Name="Universe 3" ID="2"/>
<Universe Name="Universe 4" ID="3"/>
</InputOutputMap>
<Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>0</ID>
<Name>BCC145 #1</Name>
<Universe>0</Universe>
<Address>71</Address>
<Channels>8</Channels>
</Fixture>
<Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>1</ID>
<Name>BCC145 #2</Name>
<Universe>0</Universe>
<Address>79</Address>
<Channels>8</Channels>
</Fixture>
<Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>2</ID>
<Name>BCC145 #3</Name>
<Universe>0</Universe>
<Address>87</Address>
<Channels>8</Channels>
</Fixture>
<Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>3</ID>
<Name>BCC145 #4</Name>
<Universe>0</Universe>
<Address>95</Address>
<Channels>8</Channels>
</Fixture>
<Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>4</ID>
<Name>BCC145 #5</Name>
<Universe>0</Universe>
<Address>103</Address>
<Channels>8</Channels>
</Fixture>
<Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>5</ID>
<Name>BCC145 #6</Name>
<Universe>0</Universe>
<Address>111</Address>
<Channels>8</Channels>
</Fixture>
<Fixture>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Mode>8 Channel</Mode>
<ID>6</ID>
<Name>BCC145 #7</Name>
<Universe>0</Universe>
<Address>119</Address>
<Channels>8</Channels>
</Fixture>
<Monitor DisplayMode="1" ShowLabels="0">
<Font>Arial,12,-1,5,50,0,0,0,0,0</Font>
<ChannelStyle>0</ChannelStyle>
<ValueStyle>0</ValueStyle>
<Grid Width="5" Height="3" Depth="5" Units="0"/>
</Monitor>
</Engine>
<VirtualConsole>
<Frame Caption="">
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Frame>
<Properties>
<Size Width="1920" Height="1080"/>
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
</Properties>
</VirtualConsole>
<SimpleDesk>
<Engine/>
</SimpleDesk>
</Workspace>
+1259
View File
File diff suppressed because it is too large Load Diff
+487
View File
@@ -0,0 +1,487 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Workspace>
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="VirtualConsole">
<Creator>
<Name>Q Light Controller Plus</Name>
<Version>4.12.7</Version>
<Author>Jimmy</Author>
</Creator>
<Engine>
<InputOutputMap>
<Universe Name="Universe 1" ID="0">
<Output Plugin="ArtNet" UID="192.168.1.92" Line="7">
<PluginParameters outputIP="192.168.1.228" outputUni="0"/>
</Output>
</Universe>
<Universe Name="Universe 2" ID="1"/>
<Universe Name="Universe 3" ID="2"/>
<Universe Name="Universe 4" ID="3"/>
</InputOutputMap>
<Fixture>
<Manufacturer>Small Eye 7</Manufacturer>
<Model>Mover</Model>
<Mode>43 Channel</Mode>
<ID>0</ID>
<Name>Small Eye 7 #1</Name>
<Universe>0</Universe>
<Address>0</Address>
<Channels>43</Channels>
</Fixture>
<Fixture>
<Manufacturer>Small Eye 7</Manufacturer>
<Model>Mover</Model>
<Mode>43 Channel</Mode>
<ID>1</ID>
<Name>Small Eye 7 #2</Name>
<Universe>0</Universe>
<Address>44</Address>
<Channels>43</Channels>
</Fixture>
<Function ID="0" Type="Scene" Name="Figure of 8 Look">
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
<FixtureVal ID="0">4,0,5,0,6,230,7,70,8,255,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0</FixtureVal>
<FixtureVal ID="1">4,0,5,0,6,230,7,70,8,255,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0</FixtureVal>
</Function>
<Function ID="1" Type="Sequence" Name="Figure of 8 Colour Focus" BoundScene="0">
<Speed FadeIn="188" FadeOut="0" Duration="188"/>
<Direction>Forward</Direction>
<RunOrder>Loop</RunOrder>
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common"/>
<Step Number="0" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,14,60,18,60,22,60,26,60,30,60,34,60:1:5,0,6,230,7,70,8,255,10,255,14,60,18,60,22,60,26,60,30,60,34,60</Step>
<Step Number="1" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,24,14,60,15,6,18,60,19,6,22,60,23,6,26,60,27,6,30,60,31,6,34,60,35,6:1:5,0,6,230,7,70,8,255,10,255,11,24,14,60,15,6,18,60,19,6,22,60,23,6,26,60,27,6,30,60,31,6,34,60,35,6</Step>
<Step Number="2" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,48,14,60,15,11,18,60,19,11,22,60,23,11,26,60,27,11,30,60,31,11,34,60,35,11:1:5,0,6,230,7,70,8,255,10,255,11,48,14,60,15,11,18,60,19,11,22,60,23,11,26,60,27,11,30,60,31,11,34,60,35,11</Step>
<Step Number="3" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,72,14,60,15,17,18,60,19,17,22,60,23,17,26,60,27,17,30,60,31,17,34,60,35,17:1:5,0,6,230,7,70,8,255,10,255,11,72,14,60,15,17,18,60,19,17,22,60,23,17,26,60,27,17,30,60,31,17,34,60,35,17</Step>
<Step Number="4" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,96,14,60,15,23,18,60,19,23,22,60,23,23,26,60,27,23,30,60,31,23,34,60,35,23:1:5,0,6,230,7,70,8,255,10,255,11,96,14,60,15,23,18,60,19,23,22,60,23,23,26,60,27,23,30,60,31,23,34,60,35,23</Step>
<Step Number="5" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,120,14,60,15,28,18,60,19,28,22,60,23,28,26,60,27,28,30,60,31,28,34,60,35,28:1:5,0,6,230,7,70,8,255,10,255,11,120,14,60,15,28,18,60,19,28,22,60,23,28,26,60,27,28,30,60,31,28,34,60,35,28</Step>
<Step Number="6" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,143,14,60,15,34,18,60,19,34,22,60,23,34,26,60,27,34,30,60,31,34,34,60,35,34:1:5,0,6,230,7,70,8,255,10,255,11,143,14,60,15,34,18,60,19,34,22,60,23,34,26,60,27,34,30,60,31,34,34,60,35,34</Step>
<Step Number="7" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,167,14,60,15,39,18,60,19,39,22,60,23,39,26,60,27,39,30,60,31,39,34,60,35,39:1:5,0,6,230,7,70,8,255,10,255,11,167,14,60,15,39,18,60,19,39,22,60,23,39,26,60,27,39,30,60,31,39,34,60,35,39</Step>
<Step Number="8" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,191,14,60,15,45,18,60,19,45,22,60,23,45,26,60,27,45,30,60,31,45,34,60,35,45:1:5,0,6,230,7,70,8,255,10,255,11,191,14,60,15,45,18,60,19,45,22,60,23,45,26,60,27,45,30,60,31,45,34,60,35,45</Step>
<Step Number="9" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,215,14,60,15,51,18,60,19,51,22,60,23,51,26,60,27,51,30,60,31,51,34,60,35,51:1:5,0,6,230,7,70,8,255,10,255,11,215,14,60,15,51,18,60,19,51,22,60,23,51,26,60,27,51,30,60,31,51,34,60,35,51</Step>
<Step Number="10" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,239,14,60,15,56,18,60,19,56,22,60,23,56,26,60,27,56,30,60,31,56,34,60,35,56:1:5,0,6,230,7,70,8,255,10,255,11,239,14,60,15,56,18,60,19,56,22,60,23,56,26,60,27,56,30,60,31,56,34,60,35,56</Step>
<Step Number="11" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,247,11,255,14,58,15,60,18,58,19,60,22,58,23,60,26,58,27,60,30,58,31,60,34,58,35,60:1:5,0,6,230,7,70,8,255,10,247,11,255,14,58,15,60,18,58,19,60,22,58,23,60,26,58,27,60,30,58,31,60,34,58,35,60</Step>
<Step Number="12" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,223,11,255,14,52,15,60,18,52,19,60,22,52,23,60,26,52,27,60,30,52,31,60,34,52,35,60:1:5,0,6,230,7,70,8,255,10,223,11,255,14,52,15,60,18,52,19,60,22,52,23,60,26,52,27,60,30,52,31,60,34,52,35,60</Step>
<Step Number="13" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,199,11,255,14,47,15,60,18,47,19,60,22,47,23,60,26,47,27,60,30,47,31,60,34,47,35,60:1:5,0,6,230,7,70,8,255,10,199,11,255,14,47,15,60,18,47,19,60,22,47,23,60,26,47,27,60,30,47,31,60,34,47,35,60</Step>
<Step Number="14" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,175,11,255,14,41,15,60,18,41,19,60,22,41,23,60,26,41,27,60,30,41,31,60,34,41,35,60:1:5,0,6,230,7,70,8,255,10,175,11,255,14,41,15,60,18,41,19,60,22,41,23,60,26,41,27,60,30,41,31,60,34,41,35,60</Step>
<Step Number="15" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,151,11,255,14,36,15,60,18,36,19,60,22,36,23,60,26,36,27,60,30,36,31,60,34,36,35,60:1:5,0,6,230,7,70,8,255,10,151,11,255,14,36,15,60,18,36,19,60,22,36,23,60,26,36,27,60,30,36,31,60,34,36,35,60</Step>
<Step Number="16" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,128,11,255,14,30,15,60,18,30,19,60,22,30,23,60,26,30,27,60,30,30,31,60,34,30,35,60:1:5,0,6,230,7,70,8,255,10,128,11,255,14,30,15,60,18,30,19,60,22,30,23,60,26,30,27,60,30,30,31,60,34,30,35,60</Step>
<Step Number="17" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,104,11,255,14,24,15,60,18,24,19,60,22,24,23,60,26,24,27,60,30,24,31,60,34,24,35,60:1:5,0,6,230,7,70,8,255,10,104,11,255,14,24,15,60,18,24,19,60,22,24,23,60,26,24,27,60,30,24,31,60,34,24,35,60</Step>
<Step Number="18" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,80,11,255,14,19,15,60,18,19,19,60,22,19,23,60,26,19,27,60,30,19,31,60,34,19,35,60:1:5,0,6,230,7,70,8,255,10,80,11,255,14,19,15,60,18,19,19,60,22,19,23,60,26,19,27,60,30,19,31,60,34,19,35,60</Step>
<Step Number="19" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,56,11,255,14,13,15,60,18,13,19,60,22,13,23,60,26,13,27,60,30,13,31,60,34,13,35,60:1:5,0,6,230,7,70,8,255,10,56,11,255,14,13,15,60,18,13,19,60,22,13,23,60,26,13,27,60,30,13,31,60,34,13,35,60</Step>
<Step Number="20" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,32,11,255,14,8,15,60,18,8,19,60,22,8,23,60,26,8,27,60,30,8,31,60,34,8,35,60:1:5,0,6,230,7,70,8,255,10,32,11,255,14,8,15,60,18,8,19,60,22,8,23,60,26,8,27,60,30,8,31,60,34,8,35,60</Step>
<Step Number="21" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,8,11,255,14,2,15,60,18,2,19,60,22,2,23,60,26,2,27,60,30,2,31,60,34,2,35,60:1:5,0,6,230,7,70,8,255,10,8,11,255,14,2,15,60,18,2,19,60,22,2,23,60,26,2,27,60,30,2,31,60,34,2,35,60</Step>
<Step Number="22" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,16,15,60,16,4,19,60,20,4,23,60,24,4,27,60,28,4,31,60,32,4,35,60,36,4:1:5,0,6,230,7,70,8,255,11,255,12,16,15,60,16,4,19,60,20,4,23,60,24,4,27,60,28,4,31,60,32,4,35,60,36,4</Step>
<Step Number="23" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,40,15,60,16,9,19,60,20,9,23,60,24,9,27,60,28,9,31,60,32,9,35,60,36,9:1:5,0,6,230,7,70,8,255,11,255,12,40,15,60,16,9,19,60,20,9,23,60,24,9,27,60,28,9,31,60,32,9,35,60,36,9</Step>
<Step Number="24" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,64,15,60,16,15,19,60,20,15,23,60,24,15,27,60,28,15,31,60,32,15,35,60,36,15:1:5,0,6,230,7,70,8,255,11,255,12,64,15,60,16,15,19,60,20,15,23,60,24,15,27,60,28,15,31,60,32,15,35,60,36,15</Step>
<Step Number="25" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,88,15,60,16,21,19,60,20,21,23,60,24,21,27,60,28,21,31,60,32,21,35,60,36,21:1:5,0,6,230,7,70,8,255,11,255,12,88,15,60,16,21,19,60,20,21,23,60,24,21,27,60,28,21,31,60,32,21,35,60,36,21</Step>
<Step Number="26" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,112,15,60,16,26,19,60,20,26,23,60,24,26,27,60,28,26,31,60,32,26,35,60,36,26:1:5,0,6,230,7,70,8,255,11,255,12,112,15,60,16,26,19,60,20,26,23,60,24,26,27,60,28,26,31,60,32,26,35,60,36,26</Step>
<Step Number="27" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,135,15,60,16,32,19,60,20,32,23,60,24,32,27,60,28,32,31,60,32,32,35,60,36,32:1:5,0,6,230,7,70,8,255,11,255,12,135,15,60,16,32,19,60,20,32,23,60,24,32,27,60,28,32,31,60,32,32,35,60,36,32</Step>
<Step Number="28" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,159,15,60,16,37,19,60,20,37,23,60,24,37,27,60,28,37,31,60,32,37,35,60,36,37:1:5,0,6,230,7,70,8,255,11,255,12,159,15,60,16,37,19,60,20,37,23,60,24,37,27,60,28,37,31,60,32,37,35,60,36,37</Step>
<Step Number="29" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,183,15,60,16,43,19,60,20,43,23,60,24,43,27,60,28,43,31,60,32,43,35,60,36,43:1:5,0,6,230,7,70,8,255,11,255,12,183,15,60,16,43,19,60,20,43,23,60,24,43,27,60,28,43,31,60,32,43,35,60,36,43</Step>
<Step Number="30" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,207,15,60,16,49,19,60,20,49,23,60,24,49,27,60,28,49,31,60,32,49,35,60,36,49:1:5,0,6,230,7,70,8,255,11,255,12,207,15,60,16,49,19,60,20,49,23,60,24,49,27,60,28,49,31,60,32,49,35,60,36,49</Step>
<Step Number="31" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,231,15,60,16,54,19,60,20,54,23,60,24,54,27,60,28,54,31,60,32,54,35,60,36,54:1:5,0,6,230,7,70,8,255,11,255,12,231,15,60,16,54,19,60,20,54,23,60,24,54,27,60,28,54,31,60,32,54,35,60,36,54</Step>
<Step Number="32" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,255,15,60,16,60,19,60,20,60,23,60,24,60,27,60,28,60,31,60,32,60,35,60,36,60:1:5,0,6,230,7,70,8,255,11,255,12,255,15,60,16,60,19,60,20,60,23,60,24,60,27,60,28,60,31,60,32,60,35,60,36,60</Step>
<Step Number="33" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,231,12,255,15,54,16,60,19,54,20,60,23,54,24,60,27,54,28,60,31,54,32,60,35,54,36,60:1:5,0,6,230,7,70,8,255,11,231,12,255,15,54,16,60,19,54,20,60,23,54,24,60,27,54,28,60,31,54,32,60,35,54,36,60</Step>
<Step Number="34" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,207,12,255,15,49,16,60,19,49,20,60,23,49,24,60,27,49,28,60,31,49,32,60,35,49,36,60:1:5,0,6,230,7,70,8,255,11,207,12,255,15,49,16,60,19,49,20,60,23,49,24,60,27,49,28,60,31,49,32,60,35,49,36,60</Step>
<Step Number="35" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,183,12,255,15,43,16,60,19,43,20,60,23,43,24,60,27,43,28,60,31,43,32,60,35,43,36,60:1:5,0,6,230,7,70,8,255,11,183,12,255,15,43,16,60,19,43,20,60,23,43,24,60,27,43,28,60,31,43,32,60,35,43,36,60</Step>
<Step Number="36" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,159,12,255,15,37,16,60,19,37,20,60,23,37,24,60,27,37,28,60,31,37,32,60,35,37,36,60:1:5,0,6,230,7,70,8,255,11,159,12,255,15,37,16,60,19,37,20,60,23,37,24,60,27,37,28,60,31,37,32,60,35,37,36,60</Step>
<Step Number="37" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,135,12,255,15,32,16,60,19,32,20,60,23,32,24,60,27,32,28,60,31,32,32,60,35,32,36,60:1:5,0,6,230,7,70,8,255,11,135,12,255,15,32,16,60,19,32,20,60,23,32,24,60,27,32,28,60,31,32,32,60,35,32,36,60</Step>
<Step Number="38" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,112,12,255,15,26,16,60,19,26,20,60,23,26,24,60,27,26,28,60,31,26,32,60,35,26,36,60:1:5,0,6,230,7,70,8,255,11,112,12,255,15,26,16,60,19,26,20,60,23,26,24,60,27,26,28,60,31,26,32,60,35,26,36,60</Step>
<Step Number="39" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,88,12,255,15,21,16,60,19,21,20,60,23,21,24,60,27,21,28,60,31,21,32,60,35,21,36,60:1:5,0,6,230,7,70,8,255,11,88,12,255,15,21,16,60,19,21,20,60,23,21,24,60,27,21,28,60,31,21,32,60,35,21,36,60</Step>
<Step Number="40" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,64,12,255,15,15,16,60,19,15,20,60,23,15,24,60,27,15,28,60,31,15,32,60,35,15,36,60:1:5,0,6,230,7,70,8,255,11,64,12,255,15,15,16,60,19,15,20,60,23,15,24,60,27,15,28,60,31,15,32,60,35,15,36,60</Step>
<Step Number="41" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,40,12,255,15,9,16,60,19,9,20,60,23,9,24,60,27,9,28,60,31,9,32,60,35,9,36,60:1:5,0,6,230,7,70,8,255,11,40,12,255,15,9,16,60,19,9,20,60,23,9,24,60,27,9,28,60,31,9,32,60,35,9,36,60</Step>
<Step Number="42" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,16,12,255,15,4,16,60,19,4,20,60,23,4,24,60,27,4,28,60,31,4,32,60,35,4,36,60:1:5,0,6,230,7,70,8,255,11,16,12,255,15,4,16,60,19,4,20,60,23,4,24,60,27,4,28,60,31,4,32,60,35,4,36,60</Step>
<Step Number="43" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,8,12,255,14,2,16,60,18,2,20,60,22,2,24,60,26,2,28,60,30,2,32,60,34,2,36,60:1:5,0,6,230,7,70,8,255,10,8,12,255,14,2,16,60,18,2,20,60,22,2,24,60,26,2,28,60,30,2,32,60,34,2,36,60</Step>
<Step Number="44" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,32,12,255,14,8,16,60,18,8,20,60,22,8,24,60,26,8,28,60,30,8,32,60,34,8,36,60:1:5,0,6,230,7,70,8,255,10,32,12,255,14,8,16,60,18,8,20,60,22,8,24,60,26,8,28,60,30,8,32,60,34,8,36,60</Step>
<Step Number="45" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,56,12,255,14,13,16,60,18,13,20,60,22,13,24,60,26,13,28,60,30,13,32,60,34,13,36,60:1:5,0,6,230,7,70,8,255,10,56,12,255,14,13,16,60,18,13,20,60,22,13,24,60,26,13,28,60,30,13,32,60,34,13,36,60</Step>
<Step Number="46" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,80,12,255,14,19,16,60,18,19,20,60,22,19,24,60,26,19,28,60,30,19,32,60,34,19,36,60:1:5,0,6,230,7,70,8,255,10,80,12,255,14,19,16,60,18,19,20,60,22,19,24,60,26,19,28,60,30,19,32,60,34,19,36,60</Step>
<Step Number="47" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,104,12,255,14,24,16,60,18,24,20,60,22,24,24,60,26,24,28,60,30,24,32,60,34,24,36,60:1:5,0,6,230,7,70,8,255,10,104,12,255,14,24,16,60,18,24,20,60,22,24,24,60,26,24,28,60,30,24,32,60,34,24,36,60</Step>
<Step Number="48" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,128,12,255,14,30,16,60,18,30,20,60,22,30,24,60,26,30,28,60,30,30,32,60,34,30,36,60:1:5,0,6,230,7,70,8,255,10,128,12,255,14,30,16,60,18,30,20,60,22,30,24,60,26,30,28,60,30,30,32,60,34,30,36,60</Step>
<Step Number="49" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,151,12,255,14,36,16,60,18,36,20,60,22,36,24,60,26,36,28,60,30,36,32,60,34,36,36,60:1:5,0,6,230,7,70,8,255,10,151,12,255,14,36,16,60,18,36,20,60,22,36,24,60,26,36,28,60,30,36,32,60,34,36,36,60</Step>
<Step Number="50" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,175,12,255,14,41,16,60,18,41,20,60,22,41,24,60,26,41,28,60,30,41,32,60,34,41,36,60:1:5,0,6,230,7,70,8,255,10,175,12,255,14,41,16,60,18,41,20,60,22,41,24,60,26,41,28,60,30,41,32,60,34,41,36,60</Step>
<Step Number="51" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,199,12,255,14,47,16,60,18,47,20,60,22,47,24,60,26,47,28,60,30,47,32,60,34,47,36,60:1:5,0,6,230,7,70,8,255,10,199,12,255,14,47,16,60,18,47,20,60,22,47,24,60,26,47,28,60,30,47,32,60,34,47,36,60</Step>
<Step Number="52" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,223,12,255,14,52,16,60,18,52,20,60,22,52,24,60,26,52,28,60,30,52,32,60,34,52,36,60:1:5,0,6,230,7,70,8,255,10,223,12,255,14,52,16,60,18,52,20,60,22,52,24,60,26,52,28,60,30,52,32,60,34,52,36,60</Step>
<Step Number="53" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,247,12,255,14,58,16,60,18,58,20,60,22,58,24,60,26,58,28,60,30,58,32,60,34,58,36,60:1:5,0,6,230,7,70,8,255,10,247,12,255,14,58,16,60,18,58,20,60,22,58,24,60,26,58,28,60,30,58,32,60,34,58,36,60</Step>
<Step Number="54" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,239,14,60,16,56,18,60,20,56,22,60,24,56,26,60,28,56,30,60,32,56,34,60,36,56:1:5,0,6,230,7,70,8,255,10,255,12,239,14,60,16,56,18,60,20,56,22,60,24,56,26,60,28,56,30,60,32,56,34,60,36,56</Step>
<Step Number="55" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,215,14,60,16,51,18,60,20,51,22,60,24,51,26,60,28,51,30,60,32,51,34,60,36,51:1:5,0,6,230,7,70,8,255,10,255,12,215,14,60,16,51,18,60,20,51,22,60,24,51,26,60,28,51,30,60,32,51,34,60,36,51</Step>
<Step Number="56" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,191,14,60,16,45,18,60,20,45,22,60,24,45,26,60,28,45,30,60,32,45,34,60,36,45:1:5,0,6,230,7,70,8,255,10,255,12,191,14,60,16,45,18,60,20,45,22,60,24,45,26,60,28,45,30,60,32,45,34,60,36,45</Step>
<Step Number="57" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,167,14,60,16,39,18,60,20,39,22,60,24,39,26,60,28,39,30,60,32,39,34,60,36,39:1:5,0,6,230,7,70,8,255,10,255,12,167,14,60,16,39,18,60,20,39,22,60,24,39,26,60,28,39,30,60,32,39,34,60,36,39</Step>
<Step Number="58" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,143,14,60,16,34,18,60,20,34,22,60,24,34,26,60,28,34,30,60,32,34,34,60,36,34:1:5,0,6,230,7,70,8,255,10,255,12,143,14,60,16,34,18,60,20,34,22,60,24,34,26,60,28,34,30,60,32,34,34,60,36,34</Step>
<Step Number="59" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,120,14,60,16,28,18,60,20,28,22,60,24,28,26,60,28,28,30,60,32,28,34,60,36,28:1:5,0,6,230,7,70,8,255,10,255,12,120,14,60,16,28,18,60,20,28,22,60,24,28,26,60,28,28,30,60,32,28,34,60,36,28</Step>
<Step Number="60" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,96,14,60,16,23,18,60,20,23,22,60,24,23,26,60,28,23,30,60,32,23,34,60,36,23:1:5,0,6,230,7,70,8,255,10,255,12,96,14,60,16,23,18,60,20,23,22,60,24,23,26,60,28,23,30,60,32,23,34,60,36,23</Step>
<Step Number="61" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,72,14,60,16,17,18,60,20,17,22,60,24,17,26,60,28,17,30,60,32,17,34,60,36,17:1:5,0,6,230,7,70,8,255,10,255,12,72,14,60,16,17,18,60,20,17,22,60,24,17,26,60,28,17,30,60,32,17,34,60,36,17</Step>
<Step Number="62" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,48,14,60,16,11,18,60,20,11,22,60,24,11,26,60,28,11,30,60,32,11,34,60,36,11:1:5,0,6,230,7,70,8,255,10,255,12,48,14,60,16,11,18,60,20,11,22,60,24,11,26,60,28,11,30,60,32,11,34,60,36,11</Step>
<Step Number="63" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,24,14,60,16,6,18,60,20,6,22,60,24,6,26,60,28,6,30,60,32,6,34,60,36,6:1:5,0,6,230,7,70,8,255,10,255,12,24,14,60,16,6,18,60,20,6,22,60,24,6,26,60,28,6,30,60,32,6,34,60,36,6</Step>
</Function>
<Function ID="2" Type="Scene" Name="Blackout">
<Speed FadeIn="4000" FadeOut="0" Duration="4000"/>
<FixtureVal ID="0">0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,0,42,0</FixtureVal>
<FixtureVal ID="1">0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,0,42,0</FixtureVal>
</Function>
<Function ID="3" Type="EFX" Name="Figure of 8">
<Fixture>
<ID>0</ID>
<Direction>Forward</Direction>
<Intensity>255</Intensity>
</Fixture>
<Fixture>
<ID>1</ID>
<Direction>Forward</Direction>
<Intensity>255</Intensity>
</Fixture>
<PropagationMode>Parallel</PropagationMode>
<Speed Duration="12000" FadeOut="0" FadeIn="0"/>
<Direction>Forward</Direction>
<RunOrder>Loop</RunOrder>
<Algorithm>Eight</Algorithm>
<Width>28</Width>
<Height>22</Height>
<Rotation>0</Rotation>
<Axis Name="X">
<Offset>128</Offset>
<Frequency>1</Frequency>
<Phase>0</Phase>
</Axis>
<Axis Name="Y">
<Offset>80</Offset>
<Frequency>1</Frequency>
<Phase>0</Phase>
</Axis>
</Function>
<Function ID="4" Type="Collection" Name="Figure of 8">
<Step Number="0">0</Step>
<Step Number="1">1</Step>
<Step Number="2">3</Step>
</Function>
<Monitor DisplayMode="1" ShowLabels="1">
<Font>Arial,12,-1,5,50,0,0,0,0,0</Font>
<ChannelStyle>0</ChannelStyle>
<ValueStyle>0</ValueStyle>
<Grid Width="5" Height="3" Depth="5" Units="0"/>
<FxItem ID="0" XPos="1.5" YPos="0.5"/>
<FxItem ID="1" XPos="3.5" YPos="0.5"/>
</Monitor>
</Engine>
<VirtualConsole>
<Frame Caption="">
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SoloFrame Caption="Cues">
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<WindowState Visible="True" X="20" Y="20" Width="400" Height="90"/>
<AllowChildren>True</AllowChildren>
<AllowResize>True</AllowResize>
<ShowHeader>False</ShowHeader>
<Mixing>False</Mixing>
<Button ID="0" Icon="" Caption="Figure of 8">
<Function ID="4"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="10" Y="10" Width="220" Height="70" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4282664004</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
<Button ID="1" Icon="" Caption="Blackout">
<Function ID="2"/>
<Action>Toggle</Action>
<Intensity Adjust="False">100</Intensity>
<WindowState X="240" Y="10" Width="140" Height="70" Visible="True"/>
<Appearance>
<FrameStyle>None</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>4278190080</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
</Button>
</SoloFrame>
<SpeedDial Caption="Speed" ID="2">
<WindowState Visible="True" X="1000" Y="120" Width="100" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<Visibility>108</Visibility>
<AbsoluteValue Minimum="50" Maximum="20000"/>
<Time>12000</Time>
<Function FadeIn="6" FadeOut="0" Duration="6">1</Function>
<Function FadeIn="0" FadeOut="0" Duration="6">3</Function>
</SpeedDial>
<XYPad Caption="Position" ID="3" InvertedAppearance="0">
<WindowState Visible="True" X="20" Y="120" Width="390" Height="390"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>Default</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<Fixture ID="0" Head="0">
<Axis ID="X" LowLimit="0" HighLimit="1" Reverse="False"/>
<Axis ID="Y" LowLimit="0" HighLimit="1" Reverse="False"/>
</Fixture>
<Fixture ID="1" Head="0">
<Axis ID="X" LowLimit="0" HighLimit="1" Reverse="False"/>
<Axis ID="Y" LowLimit="0" HighLimit="1" Reverse="False"/>
</Fixture>
<Window hMin="100" hMax="156" vMin="58" vMax="102"/>
<Pan Position="128"/>
<Tilt Position="80"/>
<Preset ID="0">
<Type>EFX</Type>
<Name>Figure of 8</Name>
<FuncID>3</FuncID>
</Preset>
</XYPad>
<Slider Caption="Pan" ID="4" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="430" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4294944000</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="0">
<Channel Fixture="0">0</Channel>
<Channel Fixture="1">0</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="Tilt" ID="5" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="480" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4278255615</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="0">
<Channel Fixture="0">2</Channel>
<Channel Fixture="1">2</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="Zoom" ID="6" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="530" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4294967040</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="0">
<Channel Fixture="0">5</Channel>
<Channel Fixture="1">5</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="Focus" ID="7" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="580" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4294902015</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="70">
<Channel Fixture="0">7</Channel>
<Channel Fixture="1">7</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="Dim" ID="8" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="630" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4294967295</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="255">
<Channel Fixture="0">8</Channel>
<Channel Fixture="1">8</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="R" ID="9" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="680" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4294901760</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="Red" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="0">
<Channel Fixture="0">10</Channel>
<Channel Fixture="1">10</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="G" ID="10" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="730" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4278255360</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="Green" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="0">
<Channel Fixture="0">11</Channel>
<Channel Fixture="1">11</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="B" ID="11" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="780" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4278190335</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="Blue" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="0">
<Channel Fixture="0">12</Channel>
<Channel Fixture="1">12</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="Outer" ID="12" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="830" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4288256409</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="60">
<Channel Fixture="0">14</Channel>
<Channel Fixture="0">15</Channel>
<Channel Fixture="0">16</Channel>
<Channel Fixture="0">18</Channel>
<Channel Fixture="0">19</Channel>
<Channel Fixture="0">20</Channel>
<Channel Fixture="0">22</Channel>
<Channel Fixture="0">23</Channel>
<Channel Fixture="0">24</Channel>
<Channel Fixture="0">26</Channel>
<Channel Fixture="0">27</Channel>
<Channel Fixture="0">28</Channel>
<Channel Fixture="0">30</Channel>
<Channel Fixture="0">31</Channel>
<Channel Fixture="0">32</Channel>
<Channel Fixture="0">34</Channel>
<Channel Fixture="0">35</Channel>
<Channel Fixture="0">36</Channel>
<Channel Fixture="1">14</Channel>
<Channel Fixture="1">15</Channel>
<Channel Fixture="1">16</Channel>
<Channel Fixture="1">18</Channel>
<Channel Fixture="1">19</Channel>
<Channel Fixture="1">20</Channel>
<Channel Fixture="1">22</Channel>
<Channel Fixture="1">23</Channel>
<Channel Fixture="1">24</Channel>
<Channel Fixture="1">26</Channel>
<Channel Fixture="1">27</Channel>
<Channel Fixture="1">28</Channel>
<Channel Fixture="1">30</Channel>
<Channel Fixture="1">31</Channel>
<Channel Fixture="1">32</Channel>
<Channel Fixture="1">34</Channel>
<Channel Fixture="1">35</Channel>
<Channel Fixture="1">36</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
<Slider Caption="Rotate" ID="13" WidgetStyle="Slider" InvertedAppearance="false">
<WindowState Visible="True" X="880" Y="120" Width="50" Height="380"/>
<Appearance>
<FrameStyle>Sunken</FrameStyle>
<ForegroundColor>4291611852</ForegroundColor>
<BackgroundColor>Default</BackgroundColor>
<BackgroundImage>None</BackgroundImage>
<Font>Default</Font>
</Appearance>
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
<Reset/>
<Level LowLimit="0" HighLimit="255" Value="230">
<Channel Fixture="0">6</Channel>
<Channel Fixture="1">6</Channel>
</Level>
<Playback>
<Function>4294967295</Function>
</Playback>
</Slider>
</Frame>
<Properties>
<Size Width="1920" Height="1080"/>
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
</Properties>
</VirtualConsole>
<SimpleDesk>
<Engine/>
</SimpleDesk>
</Workspace>
+2584
View File
File diff suppressed because it is too large Load Diff
+279
View File
@@ -0,0 +1,279 @@
import {
Card,
CardBody,
CardHeader,
H1,
H2,
Stack,
Table,
Text,
useHostTheme,
} from "cursor/canvas";
/** Y=0 = row of 4; +Y toward audience. Side cans on walls at ±3.5 m. */
const WALL = 3.5;
const FIXTURES: {
key: string;
label: string;
kind: "can" | "mover";
x: number;
y: number;
}[] = [
{ key: "c3", label: "#3", kind: "can", x: -1.8, y: 0.0 },
{ key: "c4", label: "#4", kind: "can", x: -0.6, y: 0.0 },
{ key: "c5", label: "#5", kind: "can", x: 0.6, y: 0.0 },
{ key: "c6", label: "#6", kind: "can", x: 1.8, y: 0.0 },
{ key: "c2", label: "#2", kind: "can", x: -WALL, y: 1.2 },
{ key: "c7", label: "#7", kind: "can", x: WALL, y: 1.2 },
{ key: "m1", label: "M1", kind: "mover", x: -0.3, y: 1.1 },
{ key: "m2", label: "M2", kind: "mover", x: 0.3, y: 1.1 },
{ key: "c1", label: "#1", kind: "can", x: -WALL, y: 2.4 },
{ key: "c8", label: "#8", kind: "can", x: WALL, y: 2.4 },
];
const BUILDING_W = 7;
const DEPTH = 2.4;
export default function StageMap() {
const theme = useHostTheme();
const pad = 0.55;
const x0 = -BUILDING_W / 2 - pad;
const x1 = BUILDING_W / 2 + pad;
const y0 = -0.45;
const y1 = DEPTH + 0.55;
const vbW = x1 - x0;
const vbH = y1 - y0;
const px = 88;
const svgW = vbW * px;
const svgH = vbH * px;
const sx = (x: number) => ((x - x0) / vbW) * svgW;
const sy = (y: number) => ((y1 - y) / vbH) * svgH;
const dim = theme.text.tertiary;
const ink = theme.text.primary;
const accent = theme.accent.primary;
const canFill = theme.fill.tertiary;
const stroke = theme.stroke.primary;
const onAccent = theme.text.onAccent;
function DimH(
xA: number,
xB: number,
y: number,
label: string,
side: "above" | "below" = "above",
) {
const ya = sy(y);
const x1p = sx(Math.min(xA, xB));
const x2p = sx(Math.max(xA, xB));
const mid = (x1p + x2p) / 2;
const ty = side === "above" ? ya - 8 : ya + 14;
return (
<g stroke={dim} fill={dim} strokeWidth={1}>
<line x1={x1p} y1={ya} x2={x2p} y2={ya} />
<line x1={x1p} y1={ya - 4} x2={x1p} y2={ya + 4} />
<line x1={x2p} y1={ya - 4} x2={x2p} y2={ya + 4} />
<text x={mid} y={ty} textAnchor="middle" fontSize={11} fill={dim} stroke="none">
{label}
</text>
</g>
);
}
function DimV(
yA: number,
yB: number,
x: number,
label: string,
side: "left" | "right" = "right",
) {
const xa = sx(x);
const y1p = sy(Math.max(yA, yB));
const y2p = sy(Math.min(yA, yB));
const mid = (y1p + y2p) / 2;
const tx = side === "right" ? xa + 8 : xa - 8;
return (
<g stroke={dim} fill={dim} strokeWidth={1}>
<line x1={xa} y1={y1p} x2={xa} y2={y2p} />
<line x1={xa - 4} y1={y1p} x2={xa + 4} y2={y1p} />
<line x1={xa - 4} y1={y2p} x2={xa + 4} y2={y2p} />
<text
x={tx}
y={mid + 4}
textAnchor={side === "right" ? "start" : "end"}
fontSize={11}
fill={dim}
stroke="none"
>
{label}
</text>
</g>
);
}
return (
<Stack gap={20} style={{ padding: 20, maxWidth: 960 }}>
<Stack gap={6}>
<H1>Stage map</H1>
<Text tone="secondary">
Building {BUILDING_W} m wide · walls at ±{WALL} m · Y = 0 at row of 4 ·
+Y toward audience
</Text>
</Stack>
<Card>
<CardHeader>Plan (audience at bottom)</CardHeader>
<CardBody>
<svg
width="100%"
viewBox={`0 0 ${svgW} ${svgH}`}
style={{ display: "block", maxWidth: svgW, background: theme.bg.editor }}
>
<rect
x={sx(-BUILDING_W / 2)}
y={sy(DEPTH)}
width={BUILDING_W * px}
height={DEPTH * px}
fill="none"
stroke={stroke}
strokeWidth={2}
/>
{/* Wall labels */}
<text
x={sx(-WALL) + 4}
y={sy(1.8)}
fontSize={10}
fill={dim}
stroke="none"
transform={`rotate(-90 ${sx(-WALL) + 4} ${sy(1.8)})`}
>
3.5 m from centre
</text>
<text
x={sx(WALL) - 4}
y={sy(1.8)}
fontSize={10}
fill={dim}
stroke="none"
textAnchor="end"
transform={`rotate(90 ${sx(WALL) - 4} ${sy(1.8)})`}
>
3.5 m from centre
</text>
{DimH(0, -WALL, 1.8, "3.5 m", "above")}
{DimH(0, WALL, 1.8, "3.5 m", "below")}
<line
x1={sx(0)}
y1={sy(-0.15)}
x2={sx(0)}
y2={sy(DEPTH + 0.2)}
stroke={dim}
strokeWidth={1}
strokeDasharray="3 5"
/>
<text x={sx(0) + 6} y={sy(-0.05)} fontSize={10} fill={dim} stroke="none">
centre
</text>
<text
x={sx(0)}
y={sy(DEPTH + 0.38)}
textAnchor="middle"
fontSize={12}
fill={ink}
fontWeight={600}
stroke="none"
>
AUDIENCE
</text>
<text
x={sx(0)}
y={sy(-0.28)}
textAnchor="middle"
fontSize={11}
fill={dim}
stroke="none"
>
row of 4
</text>
{DimH(-3.5, 3.5, DEPTH + 0.32, "7.0 m building", "below")}
{DimH(0, 0.6, 0, "0.6", "above")}
{DimH(0, 1.8, 0, "1.8", "above")}
{DimH(0, -0.6, 0, "0.6", "below")}
{DimH(0, -1.8, 0, "1.8", "below")}
{DimH(0, 0.3, 1.1, "0.3", "above")}
{DimV(0, 1.1, 2.4, "1.1 m movers")}
{DimV(0, 1.2, 2.4, "1.2 m")}
{DimV(0, 2.4, -2.4, "2.4 m", "left")}
{FIXTURES.map((f) => {
const cx = sx(f.x);
const cy = sy(f.y);
const r = f.kind === "mover" ? 14 : 12;
return (
<g key={f.key}>
{f.kind === "mover" ? (
<rect
x={cx - r}
y={cy - r}
width={r * 2}
height={r * 2}
rx={3}
fill={accent}
stroke={stroke}
strokeWidth={1}
/>
) : (
<circle
cx={cx}
cy={cy}
r={r}
fill={canFill}
stroke={stroke}
strokeWidth={1.5}
/>
)}
<text
x={cx}
y={cy + 4}
textAnchor="middle"
fontSize={11}
fontWeight={600}
fill={f.kind === "mover" ? onAccent : ink}
stroke="none"
>
{f.label}
</text>
</g>
);
})}
</svg>
</CardBody>
</Card>
<Stack gap={12}>
<H2>Coordinates</H2>
<Table
headers={["Fixture", "Type", "X (m)", "Y (m)", "Notes"]}
rows={[
["#3", "Can", "−1.8", "0.0", "Row of 4"],
["#4", "Can", "−0.6", "0.0", "Row of 4"],
["#5", "Can", "+0.6", "0.0", "Row of 4"],
["#6", "Can", "+1.8", "0.0", "Row of 4"],
["#2", "Can", "−3.5", "1.2", "Side · 3.5 m from centre · 1.2 m in front of the 4"],
["#7", "Can", "+3.5", "1.2", "Side · 3.5 m from centre · 1.2 m in front of the 4"],
["M1", "Mover", "−0.3", "1.1", "0.3 m off centre · 1.1 m in front of the 4"],
["M2", "Mover", "+0.3", "1.1", "0.3 m off centre · 1.1 m in front of the 4"],
["#1", "Can", "−3.5", "2.4", "Side · 3.5 m from centre · front left · 2.4 m in front"],
["#8", "Can", "+3.5", "2.4", "Side · 3.5 m from centre · front right · 2.4 m in front"],
]}
/>
<Text tone="secondary" size="small">
Source: integrate_u_patterns.py LAYOUT_M
</Text>
</Stack>
</Stack>
);
}
+67
View File
@@ -0,0 +1,67 @@
{
"units": "metres",
"building_width": 7.0,
"origin": "Y=0 at row of 4; +Y toward audience; X=0 centre",
"fixtures": {
"#1": {
"x": -3.5,
"y": 2.4,
"label": "#1",
"kind": "can"
},
"#2": {
"x": -3.5,
"y": 1.2,
"label": "#2",
"kind": "can"
},
"#3": {
"x": -1.8,
"y": 0.0,
"label": "#3",
"kind": "can"
},
"#4": {
"x": -0.6,
"y": 0.0,
"label": "#4",
"kind": "can"
},
"#5": {
"x": 0.6,
"y": 0.0,
"label": "#5",
"kind": "can"
},
"#6": {
"x": 1.8,
"y": 0.0,
"label": "#6",
"kind": "can"
},
"#7": {
"x": 3.5,
"y": 1.2,
"label": "#7",
"kind": "can"
},
"#8": {
"x": 3.5,
"y": 2.4,
"label": "#8",
"kind": "can"
},
"M1": {
"x": -0.3,
"y": 1.1,
"label": "M1",
"kind": "mover"
},
"M2": {
"x": 0.3,
"y": 1.1,
"label": "M2",
"kind": "mover"
}
}
}
+97
View File
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="840" height="350" viewBox="0 0 840.0 350.0">
<title>XCHC stage map — 7 m building</title>
<desc>Y=0 row of 4; +Y toward audience. Sides on walls ±3.5 m. Movers ±0.3 m, 1.1 m in front of row of 4.</desc>
<rect width="100%" height="100%" fill="#1a1a1a"/>
<rect x="70.0" y="60.0" width="700.0" height="240.0" fill="none" stroke="#888" stroke-width="2"/>
<line x1="420.0" y1="320.0" x2="420.0" y2="35.0" stroke="#555" stroke-dasharray="4 6"/>
<text x="426.0" y="305.0" fill="#888" font-size="12" font-family="system-ui,sans-serif">centre</text>
<text x="420.0" y="20.0" text-anchor="middle" fill="#eee" font-size="14" font-weight="600" font-family="system-ui,sans-serif">AUDIENCE</text>
<text x="420.0" y="332.0" text-anchor="middle" fill="#888" font-size="12" font-family="system-ui,sans-serif">row of 4</text>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="70.0" y1="25.0" x2="770.0" y2="25.0"/>
<line x1="70.0" y1="21.0" x2="70.0" y2="29.0"/>
<line x1="770.0" y1="21.0" x2="770.0" y2="29.0"/>
<text x="420.0" y="39.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">7.0 m building</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="420.0" y1="300.0" x2="480.0" y2="300.0"/>
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
<line x1="480.0" y1="296.0" x2="480.0" y2="304.0"/>
<text x="450.0" y="292.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.6 m</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="420.0" y1="300.0" x2="600.0" y2="300.0"/>
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
<line x1="600.0" y1="296.0" x2="600.0" y2="304.0"/>
<text x="510.0" y="314.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.8 m</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="360.0" y1="300.0" x2="420.0" y2="300.0"/>
<line x1="360.0" y1="296.0" x2="360.0" y2="304.0"/>
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
<text x="390.0" y="314.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.6 m</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="240.0" y1="300.0" x2="420.0" y2="300.0"/>
<line x1="240.0" y1="296.0" x2="240.0" y2="304.0"/>
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
<text x="330.0" y="292.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.8 m</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="420.0" y1="190.0" x2="450.0" y2="190.0"/>
<line x1="420.0" y1="186.0" x2="420.0" y2="194.0"/>
<line x1="450.0" y1="186.0" x2="450.0" y2="194.0"/>
<text x="435.0" y="182.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.3 m</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="70.0" y1="120.0" x2="420.0" y2="120.0"/>
<line x1="70.0" y1="116.0" x2="70.0" y2="124.0"/>
<line x1="420.0" y1="116.0" x2="420.0" y2="124.0"/>
<text x="245.0" y="112.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">3.5 m</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="420.0" y1="100.0" x2="770.0" y2="100.0"/>
<line x1="420.0" y1="96.0" x2="420.0" y2="104.0"/>
<line x1="770.0" y1="96.0" x2="770.0" y2="104.0"/>
<text x="595.0" y="114.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">3.5 m</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="640.0" y1="190.0" x2="640.0" y2="300.0"/>
<line x1="636.0" y1="190.0" x2="644.0" y2="190.0"/>
<line x1="636.0" y1="300.0" x2="644.0" y2="300.0"/>
<text x="648.0" y="249.0" text-anchor="start" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.1 m movers</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="640.0" y1="180.0" x2="640.0" y2="300.0"/>
<line x1="636.0" y1="180.0" x2="644.0" y2="180.0"/>
<line x1="636.0" y1="300.0" x2="644.0" y2="300.0"/>
<text x="648.0" y="244.0" text-anchor="start" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.2 m</text>
</g>
<g stroke="#888" fill="#888" stroke-width="1">
<line x1="200.0" y1="60.0" x2="200.0" y2="300.0"/>
<line x1="196.0" y1="60.0" x2="204.0" y2="60.0"/>
<line x1="196.0" y1="300.0" x2="204.0" y2="300.0"/>
<text x="192.0" y="184.0" text-anchor="end" font-size="11" stroke="none" font-family="system-ui,sans-serif">2.4 m</text>
</g>
<circle cx="70.0" cy="60.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
<text x="70.0" y="64.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#1</text>
<circle cx="70.0" cy="180.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
<text x="70.0" y="184.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#2</text>
<circle cx="240.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
<text x="240.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#3</text>
<circle cx="360.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
<text x="360.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#4</text>
<circle cx="480.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
<text x="480.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#5</text>
<circle cx="600.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
<text x="600.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#6</text>
<circle cx="770.0" cy="180.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
<text x="770.0" y="184.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#7</text>
<circle cx="770.0" cy="60.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
<text x="770.0" y="64.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#8</text>
<rect x="376.0" y="176.0" width="28" height="28" rx="3" fill="#3b82f6" stroke="#ccc"/>
<text x="390.0" y="194.0" text-anchor="middle" fill="#fff" font-size="11" font-weight="600" font-family="system-ui,sans-serif">M1</text>
<rect x="436.0" y="176.0" width="28" height="28" rx="3" fill="#3b82f6" stroke="#ccc"/>
<text x="450.0" y="194.0" text-anchor="middle" fill="#fff" font-size="11" font-weight="600" font-family="system-ui,sans-serif">M2</text>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

+294
View File
@@ -0,0 +1,294 @@
#!/usr/bin/env python3
"""Art-Net tester for Small Eye 7 Mover channels 5 / 6 / 7.
Pan/tilt (1–4) already look right. This script lights the centre LED, then
isolates:
CH5 pan/tilt speed — head should move fast at 0, crawl at 255
CH6 zoom — beam should grow/shrink
CH7 lens rotate — front glass spins only in 128–188 or 194–255,
and often only when zoom is fully in (narrow)
Quit with Ctrl+C (sends blackout). Stop QLC+ output first so the two
sources do not fight.
Example:
python3 test_small_eye.py --ip 192.168.1.228 --address 1
"""
from __future__ import annotations
import argparse
import socket
import sys
import threading
import time
ARTNET_PORT = 6454
HEADER = b"Art-Net\x00"
OP_DMX = 0x5000
PROT_VER = 14
# 1-based fixture channels (43ch pixel mode)
CH_PAN = 1
CH_TILT = 3
CH_SPEED = 5
CH_ZOOM = 6
CH_ROTATE = 7
CH_FOCUS = 8
CH_DIMMER = 9
CH_STROBE = 10
CH_RED = 11
CH_GREEN = 12
CH_BLUE = 13
CH_WHITE = 14
FIXTURE_CHANNELS = 43
def build_artdmx(channels: bytes, universe: int = 0, sequence: int = 1) -> bytes:
data = bytearray(channels)
n = len(data)
if n < 2:
data.extend(b"\x00" * (2 - n))
n = 2
if n & 1:
data.append(0)
n += 1
if n > 512:
data = data[:512]
n = 512
pkt = bytearray(18 + n)
pkt[0:8] = HEADER
pkt[8:10] = bytes((OP_DMX & 0xFF, OP_DMX >> 8))
pkt[10] = 0
pkt[11] = PROT_VER
pkt[12] = sequence & 0xFF
pkt[13] = 0
pkt[14] = universe & 0xFF
pkt[15] = 0
pkt[16] = (n >> 8) & 0xFF
pkt[17] = n & 0xFF
pkt[18 : 18 + n] = data
return bytes(pkt)
class ArtNetSender:
def __init__(self, dest: str, universe: int = 0, hz: float = 40.0):
self.dest = dest
self.universe = universe
self.period = 1.0 / hz
self.frame = bytearray(512)
self.sequence = 1
self._lock = threading.Lock()
self._running = True
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self._thread = threading.Thread(target=self._loop, daemon=True)
self._thread.start()
def _loop(self):
while self._running:
with self._lock:
pkt = build_artdmx(self.frame, self.universe, self.sequence)
self.sequence = 1 if self.sequence >= 255 else self.sequence + 1
try:
self.sock.sendto(pkt, (self.dest, ARTNET_PORT))
except OSError as exc:
print(f"Art-Net send failed: {exc}", file=sys.stderr)
time.sleep(self.period)
def set_slot(self, dmx_addr: int, value: int):
"""dmx_addr is 1-based DMX."""
with self._lock:
self.frame[dmx_addr - 1] = max(0, min(255, int(value)))
def blackout(self):
with self._lock:
self.frame[:] = b"\x00" * 512
def close(self):
self.blackout()
time.sleep(self.period * 3)
self._running = False
self._thread.join(timeout=1.0)
self.sock.close()
class SmallEye:
def __init__(self, sender: ArtNetSender, address: int):
self.artnet = sender
self.address = address
def set(self, channel: int, value: int):
self.artnet.set_slot(self.address + channel - 1, value)
def park_light(self, pan=128, tilt=80, dimmer=255, white=255, rgb=40):
"""Still, visible beam. Strobe open, pixels off except centre RGBW."""
for ch in range(1, FIXTURE_CHANNELS + 1):
self.set(ch, 0)
self.set(CH_PAN, pan)
self.set(CH_TILT, tilt)
self.set(CH_SPEED, 0)
self.set(CH_ZOOM, 0)
self.set(CH_ROTATE, 0)
self.set(CH_FOCUS, 128)
self.set(CH_DIMMER, dimmer)
self.set(CH_STROBE, 0)
self.set(CH_RED, rgb)
self.set(CH_GREEN, rgb)
self.set(CH_BLUE, rgb)
self.set(CH_WHITE, white)
def say(msg: str):
print(f"\n=== {msg} ===", flush=True)
def hold(seconds: float, label: str = ""):
if label:
print(f" {label}", flush=True)
end = time.monotonic() + seconds
while time.monotonic() < end:
time.sleep(0.05)
def sweep(fixture: SmallEye, channel: int, start: int, stop: int, seconds: float):
steps = max(1, int(seconds * 40))
for i in range(steps + 1):
value = int(start + (stop - start) * i / steps)
fixture.set(channel, value)
time.sleep(seconds / steps)
def wait_enter(enabled: bool, prompt: str):
if enabled:
input(f" {prompt} [Enter] ")
def test_speed(fixture: SmallEye, hold_s: float, pause: bool):
say("CH5 pan/tilt SPEED")
print("Watch the HEAD (yoke), not the lens.")
print("CH5=0 should be fast, CH5=255 should crawl.")
fixture.park_light()
wait_enter(pause, "Ready to wiggle pan")
for speed in (0, 80, 160, 255):
fixture.set(CH_SPEED, speed)
print(f" CH5 = {speed:3d} sweeping pan 40 → 220")
sweep(fixture, CH_PAN, 40, 220, hold_s)
sweep(fixture, CH_PAN, 220, 40, hold_s)
fixture.set(CH_PAN, 128)
fixture.set(CH_SPEED, 0)
def test_zoom(fixture: SmallEye, hold_s: float, pause: bool):
say("CH6 ZOOM")
print("Watch the SPOT size on the wall. Should grow then shrink.")
fixture.park_light()
fixture.set(CH_ROTATE, 0)
wait_enter(pause, "Ready for zoom sweep")
print(" CH6 0 → 255")
sweep(fixture, CH_ZOOM, 0, 255, hold_s * 2)
hold(1.5, "CH6 = 255 (hold)")
print(" CH6 255 → 0")
sweep(fixture, CH_ZOOM, 255, 0, hold_s * 2)
hold(1.5, "CH6 = 0 (hold, narrow)")
def test_rotate(fixture: SmallEye, hold_s: float, pause: bool):
say("CH7 LENS ROTATE")
print("Watch the FRONT GLASS. Index 0–127 does not spin.")
print("Spin is 128–188 (CCW) and 194–255 (CW). 189–193 is stop.")
print("If nothing moves, zoom is probably too wide — trying both extremes.")
fixture.park_light()
wait_enter(pause, "Ready for rotate")
points = [
(0, "index 0°"),
(64, "index mid"),
(127, "index 60°"),
(160, "SPIN CCW"),
(191, "stop band"),
(220, "SPIN CW"),
(255, "SPIN CW fast"),
(0, "back to index 0"),
]
for zoom in (0, 255):
fixture.set(CH_ZOOM, zoom)
fixture.set(CH_ROTATE, 0)
print(f"\n zoom CH6 = {zoom}")
hold(1.0)
for value, label in points:
fixture.set(CH_ROTATE, value)
hold(hold_s, f"CH7 = {value:3d} {label}")
fixture.set(CH_ROTATE, 0)
fixture.set(CH_ZOOM, 0)
def test_hunt(fixture: SmallEye, hold_s: float, pause: bool):
say("HUNT: put spin values on CH5, then CH6, then CH7")
print("Whichever channel actually spins the glass is lens rotate.")
fixture.park_light()
wait_enter(pause, "Ready to hunt rotate")
for candidate in (CH_SPEED, CH_ZOOM, CH_ROTATE):
fixture.park_light()
# Narrow zoom on the other two optics channels
if candidate != CH_ZOOM:
fixture.set(CH_ZOOM, 0)
print(f"\n putting spin (160, then 220) on CH{candidate}")
fixture.set(candidate, 160)
hold(hold_s, f"CH{candidate} = 160 CCW")
fixture.set(candidate, 220)
hold(hold_s, f"CH{candidate} = 220 CW")
fixture.set(candidate, 0)
def parse_args():
p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
p.add_argument("--ip", default="192.168.1.228", help="Art-Net destination (QLC uses 192.168.1.228)")
p.add_argument("--universe", type=int, default=0, help="Art-Net universe (default 0)")
p.add_argument("--address", type=int, default=1, help="Fixture DMX start address, 1-based")
p.add_argument("--hold", type=float, default=3.0, help="Seconds to hold each rotate/speed step")
p.add_argument("--pause", action="store_true", help="Wait for Enter before each test")
p.add_argument(
"--only",
choices=("speed", "zoom", "rotate", "hunt", "all"),
default="all",
help="Run one test (default all)",
)
return p.parse_args()
def main():
args = parse_args()
if not 1 <= args.address <= 512:
sys.exit("address must be 1–512")
print(
f"Art-Net → {args.ip} universe {args.universe} "
f"fixture start {args.address} (43ch)"
)
print("Stop QLC+ Art-Net output first.")
sender = ArtNetSender(args.ip, universe=args.universe)
fixture = SmallEye(sender, args.address)
try:
fixture.park_light()
hold(2.0, "centre LED on, head still")
tests = {
"speed": lambda: test_speed(fixture, args.hold, args.pause),
"zoom": lambda: test_zoom(fixture, args.hold, args.pause),
"rotate": lambda: test_rotate(fixture, args.hold, args.pause),
"hunt": lambda: test_hunt(fixture, args.hold, args.pause),
}
order = ("speed", "zoom", "rotate", "hunt") if args.only == "all" else (args.only,)
for name in order:
tests[name]()
say("done — blackout")
except KeyboardInterrupt:
print("\nstopped")
finally:
sender.close()
if __name__ == "__main__":
main()
-1191
View File
File diff suppressed because it is too large Load Diff