Compare commits

..
2 Commits
Author SHA1 Message Date
jimmyandCursor 5eb623d6af 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>
2026-09-08 00:59:36 +12:00
jimmyandCursor c92094cc26 Add QLC+ fixture definitions for beamZ BCC145 and Small Eye 7 Mover.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 20:42:19 +12:00
18 changed files with 7955 additions and 1191 deletions
+4
View File
@@ -0,0 +1,4 @@
__pycache__/
*.py[cod]
*.qxw~
.DS_Store
+47
View File
@@ -1,2 +1,49 @@
# 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.
+443
View File
@@ -0,0 +1,443 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE FixtureDefinition>
<FixtureDefinition xmlns="http://www.qlcplus.org/FixtureDefinition">
<Creator>
<Name>Q Light Controller Plus</Name>
<Version>4.12.7</Version>
<Author>Jimmy</Author>
</Creator>
<Manufacturer>Small Eye 7</Manufacturer>
<Model>Mover</Model>
<Type>Moving Head</Type>
<Channel Name="Pan" Preset="PositionPan"/>
<Channel Name="Pan Fine" Preset="PositionPanFine"/>
<Channel Name="Tilt" Preset="PositionTilt"/>
<Channel Name="Tilt Fine" Preset="PositionTiltFine"/>
<Channel Name="Pan/Tilt Speed" Preset="SpeedPanTiltFastSlow"/>
<Channel Name="Zoom" Preset="BeamZoomSmallBig"/>
<Channel Name="Focus" Preset="BeamFocusNearFar"/>
<Channel Name="Center Brightness" Preset="IntensityMasterDimmer"/>
<Channel Name="Center Strobe">
<Group Byte="0">Shutter</Group>
<Capability Min="0" Max="3" Preset="ShutterOpen">Open</Capability>
<Capability Min="4" Max="200" Preset="StrobeSlowToFast">Strobe slow to fast</Capability>
<Capability Min="201" Max="215" Preset="StrobeRandom">Random strobe low</Capability>
<Capability Min="216" Max="234" Preset="StrobeRandom">Random strobe mid</Capability>
<Capability Min="235" Max="255" Preset="StrobeRandom">Random strobe high</Capability>
</Channel>
<Channel Name="Lens Rotate">
<Group Byte="0">Prism</Group>
<Capability Min="0" Max="127">Index 0–60° (no spin)</Capability>
<Capability Min="128" Max="188" Preset="RotationCounterClockwiseFastToSlow">Spin CCW fast to slow</Capability>
<Capability Min="189" Max="193">Stop</Capability>
<Capability Min="194" Max="255" Preset="RotationClockwiseSlowToFast">Spin CW slow to fast</Capability>
</Channel>
<Channel Name="Lens Rotate 35">
<Group Byte="0">Prism</Group>
<Capability Min="0" Max="127">Index 0–60°</Capability>
<Capability Min="128" Max="191" Preset="RotationClockwise">Rotate CW infinite</Capability>
<Capability Min="192" Max="255" Preset="RotationCounterClockwise">Rotate CCW infinite</Capability>
</Channel>
<Channel Name="Dimmer" Preset="IntensityMasterDimmer"/>
<Channel Name="Dimmer Fine" Preset="IntensityMasterDimmerFine"/>
<Channel Name="Strobe">
<Group Byte="0">Shutter</Group>
<Capability Min="0" Max="3" Preset="ShutterOpen">Open</Capability>
<Capability Min="4" Max="200" Preset="StrobeSlowToFast">Strobe slow to fast</Capability>
<Capability Min="201" Max="215" Preset="StrobeRandom">Random strobe low</Capability>
<Capability Min="216" Max="234" Preset="StrobeRandom">Random strobe mid</Capability>
<Capability Min="235" Max="255" Preset="StrobeRandom">Random strobe high</Capability>
</Channel>
<Channel Name="Strobe 35">
<Group Byte="0">Shutter</Group>
<Capability Min="0" Max="3" Preset="ShutterClose">Closed</Capability>
<Capability Min="4" Max="103" Preset="StrobeSlowToFast">Sync strobe 1–25 Hz</Capability>
<Capability Min="104" Max="107" Preset="ShutterOpen">Open</Capability>
<Capability Min="108" Max="207" Preset="StrobeSlowToFast">Pulse strobe 1–25 Hz</Capability>
<Capability Min="208" Max="212" Preset="ShutterOpen">Open</Capability>
<Capability Min="213" Max="225" Preset="StrobeRandom">Random strobe low</Capability>
<Capability Min="226" Max="238" Preset="StrobeRandom">Random strobe mid</Capability>
<Capability Min="239" Max="251" Preset="StrobeRandom">Random strobe high</Capability>
<Capability Min="252" Max="255" Preset="ShutterOpen">Open</Capability>
</Channel>
<Channel Name="Red" Preset="IntensityRed"/>
<Channel Name="Red Fine" Preset="IntensityRedFine"/>
<Channel Name="Green" Preset="IntensityGreen"/>
<Channel Name="Green Fine" Preset="IntensityGreenFine"/>
<Channel Name="Blue" Preset="IntensityBlue"/>
<Channel Name="Blue Fine" Preset="IntensityBlueFine"/>
<Channel Name="White" Preset="IntensityWhite"/>
<Channel Name="White Fine" Preset="IntensityWhiteFine"/>
<Channel Name="Colour Temperature">
<Group Byte="0">Colour</Group>
<Capability Min="0" Max="255">Linear CTO / colour temperature</Capability>
</Channel>
<Channel Name="Colour Macro">
<Group Byte="0">Colour</Group>
<Capability Min="0" Max="9">No function</Capability>
<Capability Min="10" Max="255">Built-in colour macros</Capability>
</Channel>
<Channel Name="Static Effect">
<Group Byte="0">Effect</Group>
<Capability Min="0" Max="9">No function</Capability>
<Capability Min="10" Max="255">Static pixel effect select</Capability>
</Channel>
<Channel Name="Dynamic Effect">
<Group Byte="0">Effect</Group>
<Capability Min="0" Max="9">No function</Capability>
<Capability Min="10" Max="255">Dynamic pixel effect select</Capability>
</Channel>
<Channel Name="Dynamic Effect Speed">
<Group Byte="0">Speed</Group>
<Capability Min="0" Max="127">Forward fast to slow</Capability>
<Capability Min="128" Max="255">Reverse slow to fast</Capability>
</Channel>
<Channel Name="Background Red" Preset="IntensityRed"/>
<Channel Name="Background Green" Preset="IntensityGreen"/>
<Channel Name="Background Blue" Preset="IntensityBlue"/>
<Channel Name="Background White" Preset="IntensityWhite"/>
<Channel Name="Reset">
<Group Byte="0">Maintenance</Group>
<Capability Min="0" Max="199">No function</Capability>
<Capability Min="200" Max="205" Preset="ResetMotors">Reset all (hold ~5 s)</Capability>
<Capability Min="206" Max="255">No function</Capability>
</Channel>
<Channel Name="Function">
<Group Byte="0">Maintenance</Group>
<Capability Min="0" Max="255">Reserved</Capability>
</Channel>
<Channel Name="Pattern Select">
<Group Byte="0">Effect</Group>
<Capability Min="0" Max="255">Pattern / gobo select</Capability>
</Channel>
<Channel Name="Pattern Speed">
<Group Byte="0">Speed</Group>
<Capability Min="0" Max="255">Pattern effect speed</Capability>
</Channel>
<Channel Name="Pattern Fade">
<Group Byte="0">Effect</Group>
<Capability Min="0" Max="255">Pattern fade</Capability>
</Channel>
<Channel Name="Pattern Red" Preset="IntensityRed"/>
<Channel Name="Pattern Green" Preset="IntensityGreen"/>
<Channel Name="Pattern Blue" Preset="IntensityBlue"/>
<Channel Name="Pattern White" Preset="IntensityWhite"/>
<Channel Name="Pattern Dimmer" Preset="IntensityDimmer"/>
<Channel Name="Background Dimmer" Preset="IntensityDimmer"/>
<Channel Name="Pattern Transition">
<Group Byte="0">Effect</Group>
<Capability Min="0" Max="255">Pattern transition</Capability>
</Channel>
<Channel Name="Pattern Angle">
<Group Byte="0">Effect</Group>
<Capability Min="0" Max="255">Pattern angle / translation</Capability>
</Channel>
<Channel Name="Foreground Strobe">
<Group Byte="0">Shutter</Group>
<Capability Min="0" Max="3" Preset="ShutterClose">Closed</Capability>
<Capability Min="4" Max="103" Preset="StrobeSlowToFast">Sync strobe 1–25 Hz</Capability>
<Capability Min="104" Max="107" Preset="ShutterOpen">Open</Capability>
<Capability Min="108" Max="207" Preset="StrobeSlowToFast">Pulse strobe 1–25 Hz</Capability>
<Capability Min="208" Max="212" Preset="ShutterOpen">Open</Capability>
<Capability Min="213" Max="225" Preset="StrobeRandom">Random strobe low</Capability>
<Capability Min="226" Max="238" Preset="StrobeRandom">Random strobe mid</Capability>
<Capability Min="239" Max="251" Preset="StrobeRandom">Random strobe high</Capability>
<Capability Min="252" Max="255" Preset="ShutterOpen">Open</Capability>
</Channel>
<Channel Name="Background Strobe">
<Group Byte="0">Shutter</Group>
<Capability Min="0" Max="3" Preset="ShutterClose">Closed</Capability>
<Capability Min="4" Max="103" Preset="StrobeSlowToFast">Sync strobe 1–25 Hz</Capability>
<Capability Min="104" Max="107" Preset="ShutterOpen">Open</Capability>
<Capability Min="108" Max="207" Preset="StrobeSlowToFast">Pulse strobe 1–25 Hz</Capability>
<Capability Min="208" Max="212" Preset="ShutterOpen">Open</Capability>
<Capability Min="213" Max="225" Preset="StrobeRandom">Random strobe low</Capability>
<Capability Min="226" Max="238" Preset="StrobeRandom">Random strobe mid</Capability>
<Capability Min="239" Max="251" Preset="StrobeRandom">Random strobe high</Capability>
<Capability Min="252" Max="255" Preset="ShutterOpen">Open</Capability>
</Channel>
<Channel Name="Background Select">
<Group Byte="0">Effect</Group>
<Capability Min="0" Max="255">Background pattern select</Capability>
</Channel>
<Channel Name="Red 1" Preset="IntensityRed"/>
<Channel Name="Green 1" Preset="IntensityGreen"/>
<Channel Name="Blue 1" Preset="IntensityBlue"/>
<Channel Name="White 1" Preset="IntensityWhite"/>
<Channel Name="Red 2" Preset="IntensityRed"/>
<Channel Name="Green 2" Preset="IntensityGreen"/>
<Channel Name="Blue 2" Preset="IntensityBlue"/>
<Channel Name="White 2" Preset="IntensityWhite"/>
<Channel Name="Red 3" Preset="IntensityRed"/>
<Channel Name="Green 3" Preset="IntensityGreen"/>
<Channel Name="Blue 3" Preset="IntensityBlue"/>
<Channel Name="White 3" Preset="IntensityWhite"/>
<Channel Name="Red 4" Preset="IntensityRed"/>
<Channel Name="Green 4" Preset="IntensityGreen"/>
<Channel Name="Blue 4" Preset="IntensityBlue"/>
<Channel Name="White 4" Preset="IntensityWhite"/>
<Channel Name="Red 5" Preset="IntensityRed"/>
<Channel Name="Green 5" Preset="IntensityGreen"/>
<Channel Name="Blue 5" Preset="IntensityBlue"/>
<Channel Name="White 5" Preset="IntensityWhite"/>
<Channel Name="Red 6" Preset="IntensityRed"/>
<Channel Name="Green 6" Preset="IntensityGreen"/>
<Channel Name="Blue 6" Preset="IntensityBlue"/>
<Channel Name="White 6" Preset="IntensityWhite"/>
<Channel Name="Red 7" Preset="IntensityRed"/>
<Channel Name="Green 7" Preset="IntensityGreen"/>
<Channel Name="Blue 7" Preset="IntensityBlue"/>
<Channel Name="White 7" Preset="IntensityWhite"/>
<Mode Name="43 Channel">
<Channel Number="0">Pan</Channel>
<Channel Number="1">Pan Fine</Channel>
<Channel Number="2">Tilt</Channel>
<Channel Number="3">Tilt Fine</Channel>
<Channel Number="4">Pan/Tilt Speed</Channel>
<Channel Number="5">Zoom</Channel>
<Channel Number="6">Lens Rotate</Channel>
<Channel Number="7">Focus</Channel>
<Channel Number="8">Center Brightness</Channel>
<Channel Number="9">Center Strobe</Channel>
<Channel Number="10">Red 1</Channel>
<Channel Number="11">Green 1</Channel>
<Channel Number="12">Blue 1</Channel>
<Channel Number="13">White 1</Channel>
<Channel Number="14">Red 2</Channel>
<Channel Number="15">Green 2</Channel>
<Channel Number="16">Blue 2</Channel>
<Channel Number="17">White 2</Channel>
<Channel Number="18">Red 3</Channel>
<Channel Number="19">Green 3</Channel>
<Channel Number="20">Blue 3</Channel>
<Channel Number="21">White 3</Channel>
<Channel Number="22">Red 4</Channel>
<Channel Number="23">Green 4</Channel>
<Channel Number="24">Blue 4</Channel>
<Channel Number="25">White 4</Channel>
<Channel Number="26">Red 5</Channel>
<Channel Number="27">Green 5</Channel>
<Channel Number="28">Blue 5</Channel>
<Channel Number="29">White 5</Channel>
<Channel Number="30">Red 6</Channel>
<Channel Number="31">Green 6</Channel>
<Channel Number="32">Blue 6</Channel>
<Channel Number="33">White 6</Channel>
<Channel Number="34">Red 7</Channel>
<Channel Number="35">Green 7</Channel>
<Channel Number="36">Blue 7</Channel>
<Channel Number="37">White 7</Channel>
<Channel Number="38">Colour Temperature</Channel>
<Channel Number="39">Colour Macro</Channel>
<Channel Number="40">Static Effect</Channel>
<Channel Number="41">Dynamic Effect</Channel>
<Channel Number="42">Reset</Channel>
<Head>
<Channel>10</Channel>
<Channel>11</Channel>
<Channel>12</Channel>
<Channel>13</Channel>
</Head>
<Head>
<Channel>14</Channel>
<Channel>15</Channel>
<Channel>16</Channel>
<Channel>17</Channel>
</Head>
<Head>
<Channel>18</Channel>
<Channel>19</Channel>
<Channel>20</Channel>
<Channel>21</Channel>
</Head>
<Head>
<Channel>22</Channel>
<Channel>23</Channel>
<Channel>24</Channel>
<Channel>25</Channel>
</Head>
<Head>
<Channel>26</Channel>
<Channel>27</Channel>
<Channel>28</Channel>
<Channel>29</Channel>
</Head>
<Head>
<Channel>30</Channel>
<Channel>31</Channel>
<Channel>32</Channel>
<Channel>33</Channel>
</Head>
<Head>
<Channel>34</Channel>
<Channel>35</Channel>
<Channel>36</Channel>
<Channel>37</Channel>
</Head>
</Mode>
<Mode Name="23 Channel">
<Channel Number="0">Pan</Channel>
<Channel Number="1">Pan Fine</Channel>
<Channel Number="2">Tilt</Channel>
<Channel Number="3">Tilt Fine</Channel>
<Channel Number="4">Pan/Tilt Speed</Channel>
<Channel Number="5">Zoom</Channel>
<Channel Number="6">Lens Rotate</Channel>
<Channel Number="7">Focus</Channel>
<Channel Number="8">Center Brightness</Channel>
<Channel Number="9">Center Strobe</Channel>
<Channel Number="10">Red</Channel>
<Channel Number="11">Green</Channel>
<Channel Number="12">Blue</Channel>
<Channel Number="13">White</Channel>
<Channel Number="14">Colour Macro</Channel>
<Channel Number="15">Static Effect</Channel>
<Channel Number="16">Dynamic Effect</Channel>
<Channel Number="17">Dynamic Effect Speed</Channel>
<Channel Number="18">Background Red</Channel>
<Channel Number="19">Background Green</Channel>
<Channel Number="20">Background Blue</Channel>
<Channel Number="21">Background White</Channel>
<Channel Number="22">Reset</Channel>
</Mode>
<Mode Name="35 Channel">
<Channel Number="0">Red</Channel>
<Channel Number="1">Red Fine</Channel>
<Channel Number="2">Green</Channel>
<Channel Number="3">Green Fine</Channel>
<Channel Number="4">Blue</Channel>
<Channel Number="5">Blue Fine</Channel>
<Channel Number="6">White</Channel>
<Channel Number="7">White Fine</Channel>
<Channel Number="8">Colour Temperature</Channel>
<Channel Number="9">Colour Macro</Channel>
<Channel Number="10">Strobe 35</Channel>
<Channel Number="11">Dimmer</Channel>
<Channel Number="12">Dimmer Fine</Channel>
<Channel Number="13">Pan</Channel>
<Channel Number="14">Pan Fine</Channel>
<Channel Number="15">Tilt</Channel>
<Channel Number="16">Tilt Fine</Channel>
<Channel Number="17">Function</Channel>
<Channel Number="18">Reset</Channel>
<Channel Number="19">Zoom</Channel>
<Channel Number="20">Lens Rotate 35</Channel>
<Channel Number="21">Pattern Select</Channel>
<Channel Number="22">Pattern Speed</Channel>
<Channel Number="23">Pattern Fade</Channel>
<Channel Number="24">Pattern Red</Channel>
<Channel Number="25">Pattern Green</Channel>
<Channel Number="26">Pattern Blue</Channel>
<Channel Number="27">Pattern White</Channel>
<Channel Number="28">Pattern Dimmer</Channel>
<Channel Number="29">Background Dimmer</Channel>
<Channel Number="30">Pattern Transition</Channel>
<Channel Number="31">Pattern Angle</Channel>
<Channel Number="32">Foreground Strobe</Channel>
<Channel Number="33">Background Strobe</Channel>
<Channel Number="34">Background Select</Channel>
</Mode>
<Mode Name="51 Channel">
<Channel Number="0">Pan</Channel>
<Channel Number="1">Pan Fine</Channel>
<Channel Number="2">Tilt</Channel>
<Channel Number="3">Tilt Fine</Channel>
<Channel Number="4">Pan/Tilt Speed</Channel>
<Channel Number="5">Zoom</Channel>
<Channel Number="6">Lens Rotate</Channel>
<Channel Number="7">Focus</Channel>
<Channel Number="8">Center Brightness</Channel>
<Channel Number="9">Center Strobe</Channel>
<Channel Number="10">Red</Channel>
<Channel Number="11">Green</Channel>
<Channel Number="12">Blue</Channel>
<Channel Number="13">White</Channel>
<Channel Number="14">Colour Macro</Channel>
<Channel Number="15">Static Effect</Channel>
<Channel Number="16">Dynamic Effect</Channel>
<Channel Number="17">Dynamic Effect Speed</Channel>
<Channel Number="18">Background Red</Channel>
<Channel Number="19">Background Green</Channel>
<Channel Number="20">Background Blue</Channel>
<Channel Number="21">Background White</Channel>
<Channel Number="22">Reset</Channel>
<Channel Number="23">Red 1</Channel>
<Channel Number="24">Green 1</Channel>
<Channel Number="25">Blue 1</Channel>
<Channel Number="26">White 1</Channel>
<Channel Number="27">Red 2</Channel>
<Channel Number="28">Green 2</Channel>
<Channel Number="29">Blue 2</Channel>
<Channel Number="30">White 2</Channel>
<Channel Number="31">Red 3</Channel>
<Channel Number="32">Green 3</Channel>
<Channel Number="33">Blue 3</Channel>
<Channel Number="34">White 3</Channel>
<Channel Number="35">Red 4</Channel>
<Channel Number="36">Green 4</Channel>
<Channel Number="37">Blue 4</Channel>
<Channel Number="38">White 4</Channel>
<Channel Number="39">Red 5</Channel>
<Channel Number="40">Green 5</Channel>
<Channel Number="41">Blue 5</Channel>
<Channel Number="42">White 5</Channel>
<Channel Number="43">Red 6</Channel>
<Channel Number="44">Green 6</Channel>
<Channel Number="45">Blue 6</Channel>
<Channel Number="46">White 6</Channel>
<Channel Number="47">Red 7</Channel>
<Channel Number="48">Green 7</Channel>
<Channel Number="49">Blue 7</Channel>
<Channel Number="50">White 7</Channel>
<Head>
<Channel>23</Channel>
<Channel>24</Channel>
<Channel>25</Channel>
<Channel>26</Channel>
</Head>
<Head>
<Channel>27</Channel>
<Channel>28</Channel>
<Channel>29</Channel>
<Channel>30</Channel>
</Head>
<Head>
<Channel>31</Channel>
<Channel>32</Channel>
<Channel>33</Channel>
<Channel>34</Channel>
</Head>
<Head>
<Channel>35</Channel>
<Channel>36</Channel>
<Channel>37</Channel>
<Channel>38</Channel>
</Head>
<Head>
<Channel>39</Channel>
<Channel>40</Channel>
<Channel>41</Channel>
<Channel>42</Channel>
</Head>
<Head>
<Channel>43</Channel>
<Channel>44</Channel>
<Channel>45</Channel>
<Channel>46</Channel>
</Head>
<Head>
<Channel>47</Channel>
<Channel>48</Channel>
<Channel>49</Channel>
<Channel>50</Channel>
</Head>
</Mode>
<Physical>
<Bulb Type="LED" Lumens="0" ColourTemperature="0"/>
<Dimensions Weight="5.6" Width="242" Height="313" Depth="184"/>
<Lens Name="Other" DegreesMin="5" DegreesMax="45"/>
<Focus Type="Head" PanMax="540" TiltMax="270"/>
<Layout Width="7" Height="1"/>
<Technical PowerConsumption="300" DmxConnector="3-pin"/>
</Physical>
</FixtureDefinition>
+59
View File
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE FixtureDefinition>
<FixtureDefinition xmlns="http://www.qlcplus.org/FixtureDefinition">
<Creator>
<Name>Q Light Controller Plus</Name>
<Version>4.12.7</Version>
<Author>Jimmy</Author>
</Creator>
<Manufacturer>beamZ</Manufacturer>
<Model>BCC145</Model>
<Type>Color Changer</Type>
<Channel Name="Dimmer" Default="255" Preset="IntensityMasterDimmer"/>
<Channel Name="Red" Preset="IntensityRed"/>
<Channel Name="Green" Preset="IntensityGreen"/>
<Channel Name="Blue" Preset="IntensityBlue"/>
<Channel Name="White" Preset="IntensityWhite"/>
<Channel Name="Strobe">
<Group Byte="0">Shutter</Group>
<Capability Min="0" Max="7" Preset="ShutterOpen">No function</Capability>
<Capability Min="8" Max="255" Preset="StrobeSlowToFast">Strobe slow to fast</Capability>
</Channel>
<Channel Name="Macro">
<Group Byte="0">Effect</Group>
<Capability Min="0" Max="50">RGBW mix</Capability>
<Capability Min="51" Max="100">Fixed colour</Capability>
<Capability Min="101" Max="150">Colour jump</Capability>
<Capability Min="151" Max="200">Colour pulse</Capability>
<Capability Min="201" Max="250">Colour gradient</Capability>
<Capability Min="251" Max="253">Sound 1</Capability>
<Capability Min="254" Max="255">Sound 2</Capability>
</Channel>
<Channel Name="Speed">
<Group Byte="0">Speed</Group>
<Capability Min="0" Max="255">Macro speed from slow to fast</Capability>
</Channel>
<Mode Name="4 Channel">
<Channel Number="0">Red</Channel>
<Channel Number="1">Green</Channel>
<Channel Number="2">Blue</Channel>
<Channel Number="3">White</Channel>
</Mode>
<Mode Name="8 Channel">
<Channel Number="0">Dimmer</Channel>
<Channel Number="1">Strobe</Channel>
<Channel Number="2">Red</Channel>
<Channel Number="3">Green</Channel>
<Channel Number="4">Blue</Channel>
<Channel Number="5">White</Channel>
<Channel Number="6">Macro</Channel>
<Channel Number="7">Speed</Channel>
</Mode>
<Physical>
<Bulb Type="LED" Lumens="0" ColourTemperature="0"/>
<Dimensions Weight="1.15" Width="232" Height="225" Depth="110"/>
<Lens Name="Other" DegreesMin="25" DegreesMax="25"/>
<Focus Type="Fixed" PanMax="0" TiltMax="0"/>
<Technical PowerConsumption="56" DmxConnector="3-pin"/>
</Physical>
</FixtureDefinition>
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