# Wave Studio for Windows

This package provides **sACN input for same-PC Vista use**, plus the existing Art-Net receiver for a separate computer. It is a prototype visualizer for cue rehearsal, not a firing controller, certified device emulator, or safety-validation tool. Neither mode transmits DMX or firing commands.

Use **Start-Wave-Studio-sACN.cmd** when Vista and Wave Studio are on the same Windows PC. The older Art-Net receiver and Vista both need UDP 6454; their exclusive binding conflict was observed during this project's Windows troubleshooting. The sACN mode instead listens on UDP 5568 and never opens 6454.

## What is included

- **Start-Wave-Studio-sACN.cmd:** Same-PC launcher. Prompts for Vista's selected interface IPv4, then starts the sACN receiver with the Vista 3 preset.
- **Start-Wave-Studio-grandMA.cmd:** Same as above for grandMA3 or grandMA2 (asks which, then the console interface IPv4); starts the sACN receiver with that console preset so the studio's Vista & MA Receiver dialog opens on the matching tab. The receiver reads E1.31 Final and grandMA2 Draft packets, multicast or unicast.
- **Start-Wave-Studio.cmd:** Art-Net launcher for a separate receiver PC. Retains ArtPollReply discovery.
- **receiver.py:** Art-Net or sACN receiver and loopback-only web server. Uses Python's standard library; no pip packages are needed. `--console vista | grandma3 | grandma2 | other` selects the console preset (hints, status text, dialog tab); the Windows app exposes the same choice as a **Console** drop-down.
- **web folder:** The Wave Studio application, including the six-channel visualization model.
- **START-HERE.md:** This guide.

The package is not a compiled Windows executable. Install Python 3.10 or newer for Windows from https://www.python.org/downloads/windows/ if it is not already installed.

## Layout selection and group dragging

### Current browser defaults and webpage demo

A fresh browser studio starts with **six fixtures**, evenly distributed from
left to right, at the same height. **F01, F03 and F05 are inverted**; the even
fixtures are not. All six start selected, with sequence 001, playback and
Auto-next enabled. The initial view is 100% to spread the row across the stage;
Fit view still restores the wider 55% view. Loading a saved layout replaces
these startup defaults with the saved fixture count, positions and settings.

The webpage demo is now editable, with the same six-unit alternating-invert
layout and an initial wave sequence. Drag a fixture to move it or its selected
group. Drag empty stage space to box-select; Ctrl/Command/Shift-click or the
**Multi-select** touch toggle adds or removes individual selections.
**+ Add flamer**, **− Remove**, **Invert**, **Select all**, and **Undo** control
the demo layout. It supports 1–16 fixtures and internal sequences **001–070**.
Choosing a sequence applies it to the selection and turns off Auto-next, so
the chosen look repeats. The demo resets on reload; use the full studio's
Save layout and Load layout for portable saved work. These browser updates
do not rebuild previously downloaded desktop packages.

### Stage-adjacent playback and row placement

The fader strips now sit directly below the stage's compact playback bar.
The stage and bar remain pinned while you scroll the bank, so a fader can
be adjusted while its visual result stays visible. On smaller screens the
bank scrolls horizontally; setup, cue recording and help are below the strips.

The bar is to the left of **Fixture scale**. Its minimalist arrows mean
**beginning**, **previous cue**, **next cue**, and **end**. Beginning/end pause
at that position; Restart returns to the beginning and plays. Play/Pause,
Loop, Auto-next, Rate and the scrubber are on the same bar.

**Sequence time:** minus/plus buttons and the number field set an absolute
duration from **0.01 to 10.00 seconds**. Each click changes 0.01 s; Shift-click
changes 0.10 s. There is no timing slider or signed offset. Selecting a new
sequence restores its native duration: Sequence 046 defaults to **0.99 s**.
Reset also restores the preset time. The Preset label shows that native reference.
Manual fixtures share the selected preset's clock ratio; the separate 1.10-second
stage gap remains real time. Cue mode uses the captured sequence duration as its
reference (the longest for multiple looks) and scales the shared bank clock,
including timing envelopes. The timeline displays source time. Display refresh
limits very short previews. Neither Live Input nor virtual DMX is retimed.

**Layout zoom:** hold Ctrl while scrolling the mouse wheel over the stage.
Use the minus/plus buttons without a mouse wheel. Fit view restores the wider
55% view. Zoom out further or pan to frame longer flames and larger flame scales.
Zoom is view-only; it does not change saved fixture positions
or DMX values. Intentional zoom-in can crop the artwork.
Hold the **middle mouse button** over the layout and drag to pan the view,
including when starting over a fixture. Panning does not move fixtures or change
selection/DMX. Release to keep the view; Esc or window blur cancels an unfinished
pan. Fit view resets both pan and zoom. Save layout now stores the view position
and zoom as well as fixture coordinates. Older layouts use the centred 55% view.
In manual preview these controls use the preset catalog and shared stage clock.
In fader playback Play/Pause and speed affect the bank clock; navigation and
seeking use the recorded cue selected in the library (falling back to an active
assigned cue). Changing cue releases other playbacks and preserves the chosen
fader level, or uses 100% if it was zero. The master remains unchanged.
The navigation arrows can assign an unassigned library cue to the current cue
fader. Loop edits that fader's loop setting. Auto-next advances the recorded cue
library at each cue's end. These controls do not change incoming live fixture DMX.
The compact timeline shows cue progress in fader mode and preset emission in
manual mode.

**Startup and sequence follow:** a fresh launch starts manual preview at sequence
001 with Play and Auto-next on, progressing through the catalog and wrapping
from 088 to 001. Pause stops progression; turn off Auto-next to stay on one look
(Loop then controls whether it repeats). Loading a saved layout still starts
paused and disconnected.

The sequence library highlights the active fixture's current sequence, including
cue/chase playback and received sequence commands. It scrolls only enough to keep
a newly active row visible. Clicking a visible sequence keeps the list in place,
and favorite/layout edits preserve its scroll position. Search, family filters
and the Favorites tab are not cleared automatically: use All sequences with no
filters to follow the complete catalog. Direct DMX has no catalog sequence.
Selected stage fixtures keep their highlight outline, without a checkmark badge.

**Delete selected**, next to Add flamer, removes the selected group. The Delete
key does the same, except while editing a field or using a dialog. Undo restores
the group in one step. The app still requires one fixture: if every unit is
selected, the active unit is kept. The inspector's Remove button now removes
the same selected group.

Adding a flamer now recenters all units in a straight horizontal row, with a
gap equal to one rendered fixture body width (two body widths center-to-center).
Arrange row uses the same spacing. Dense rows automatically reduce the rendered
fixture size to fit; Fixture scale is a relative size control, not a physical
measurement. Adding and arranging are undoable; manual drag placement remains
available afterward. This graphical spacing is not a real-world safety clearance.

- Click a unit to select it. Selected units have an orange border and check mark; the fixture chips and selection count show the same selection.
- Hold **Ctrl** and click a unit or its F01/F02 chip to add or remove it from the selection. Ctrl-clicking the last selected unit clears the selection.
- Drag any selected unit to move the selected group together. A normal click without dragging selects that unit alone.
- Drag a rectangle on empty stage space to select the units it touches. Hold Ctrl while drawing the rectangle to toggle those units.
- Click empty stage space or **Clear selection** to deselect all. **Select all** selects every unit.
- Group movement preserves spacing and stops the group at the stage boundary.
- **Undo** reverses a group move in one step. **Esc** during a drag cancels it and restores the original positions.
- Arrow keys on a focused selected unit nudge the group; Shift + arrow uses a larger step.
- Preset, Invert, nozzle, virtual arm, angle limits and visual scales apply to
  **all selected fixtures**. The inspector displays the active fixture's values;
  mixed Invert uses an indeterminate checkbox. Unselected fixtures are unchanged.
- X/Y fields translate the selected group while preserving spacing. Patch edits
  apply the universe and shift all selected start addresses by the same offset,
  preserving unique addresses. Invalid/overlapping group patches and invalid
  angle-limit edits are rejected without changing any unit.
- Save layout records fixture positions, not the temporary multi-selection. Loading a layout selects its active fixture.

The Mac package has not been rebuilt for this Windows update. The shared browser UI also recognizes Command-click, but native Mac testing remains pending.

## Ten-fader local playback bank

### Type a fader value

All ten faders and MASTER now have editable **0–255 value boxes** in place of
their previous main readouts. Enter a whole number and press Enter, Tab, or click
away to commit. **0** releases the fader, **255** is full level, and **128** is
approximately 50.2%. The smaller percentage below the box is a reference.
Typing a draft does not change output until committed; Escape cancels.
Blank, nonnumeric, fractional and out-of-range values are rejected without
changing the existing level.

An assigned cue or checked DMX channel is still required before raising a
playback fader. In cue mode, the number scales the cue intensity; in virtual-DMX
mode it writes that exact channel byte. MASTER scales rendered intensity, not
control bytes. Flash holds temporarily override the readout and return to the
underlying fader value on release. Slider dragging and wheel changes keep the
box synchronized. All numeric controls are disabled in direct Live Input.

### Favorites and ordered look cues

Use the star beside any of the 88 library sequences to add or remove it from
Favorites without changing the selected preview. Open the star-icon tab to see
your favorites. Drag a grip to place a look before/after another; insertion lines
show the destination. Up/down buttons provide keyboard and touch alternatives.
Clear the search field before reordering.

Select the target virtual fixtures, enter a chase cue name, and click
**Save order as cue**. The complete favorite list, not just search results, is
copied into a new cue. The first free cue fader receives it at zero; if all faders
are assigned, choose the new cue from any fader dropdown. Existing cues are not
overwritten, and later rearranging/un-starring favorites never changes saved cues.

In Favorites, each look now has a **Duration** field (0.01–10.00 seconds) and a
**Gap** field (0–60.00 seconds), both with hundredth-second precision. Duration
retimes the complete look; Gap is the pause after it. Defaults are the catalog
duration and 1.10-second gap. Reset restores these defaults for that look.
Reordering keeps timing with its look. Saving a cue copies the order and timings.

For an existing saved chase, select it in **Recorded cues**, open **Timing / delay**,
and use **Individual looks**. Each look has its own Duration, Gap and Reset.
Save timing updates that cue and releases assigned faders; closing without saving
discards edits. This does not change the Favorites working list or other cues.

In Virtual faders mode, raising that cue's fader plays the ordered looks in sync
on the target group using those timings. Loop repeats the whole order; flashes start the order
from its first look while held and release back to the underlying fader.
MASTER, delay/fades, one-shot mode, seeking and cue navigation remain available.
An explicit Hold time can truncate/repeat the order; Hold = 0 uses its full length.
The Time control scales the whole bank relative to the first look's configured duration,
including configured gaps. At its default value, per-look timings play as entered.
The timeline shows the current look number and sequence ID.

**Save layout** preserves favorites, their order and all saved chase cues.
Reload the layout file to restore them in a later session; they are not stored
automatically in browser storage. Legacy layouts open with an empty Favorites tab.
Update from selection changes a saved chase's name/fixture targets but retains
its look order; create a new cue from Favorites for a different order.

### Editable labels and virtual rear display

Click either the **Cue** or **DMX channel** label on any fader to rename it.
Enter or moving focus saves; Escape cancels; an empty label restores the default.
Labels are independent per strip, accept 32 characters, and persist with Save
layout. Renaming never changes a cue assignment, channel number or fader level.

Each fader's **Settings** includes **Default DMX label**, **Default cue label**
and **Default mode: DMX / Cue**. Save applies these defaults immediately and
releases that fader to zero; it does not discard its assigned cue. A DMX default
requires an assigned channel. Renaming a strip label also updates that label's
default. Blank labels are not accepted in Settings.

New layouts start with faders **1–6 in DMX mode** and **7–10 in Cue mode**, all
at zero. The strip's DMX checkbox can temporarily override its default mode.
Use **Save layout** to keep your defaults; **Load layout** restores the defaults
with all levels at zero. Older layout files inherit defaults from their existing
saved labels and modes, rather than being changed to the new startup arrangement.

The right column starts with Selected sequence / output and a virtual rear panel.
Nozzle direction precedes Nozzle / selected unit, with Visual flame scale directly
below the nozzle selector.

The rear panel follows the menu hierarchy and four buttons documented in the
[Explo X2 Wave Flamer v2.0 manual, §§3.5.2–4.3](https://explo.at/wp-content/uploads/2025/06/X2-Wave-Flamer-v2.0-ENG-2.pdf).
It is a **partial visual emulation**, not an exact firmware replica or hardware
configuration tool. Status comes only from the app, never from real sensor feedback.

At the home screen, **E / −** places selected local units in virtual Test mode;
**Mode / OK** then opens the menu. **+ / −** browse; **OK** opens an item, starts
editing, or confirms a value. **Test / ESC** cancels an edit or goes back.
The screen also accepts arrow keys, Enter, Escape and hover-wheel navigation.
At home, Light / + toggles the simulated backlight. Menu inactivity for 60 seconds
or changing selection cancels an unfinished edit.

Under **Edit Wave Flamer settings**, MODUS (Test/Armed), Invert and POS MIN/MAX
update all selected virtual units. Under **Edit DMX settings**, Startadresse
updates the virtual patch while preserving selected fixtures' address spacing.
Crossed limits, out-of-range addresses and overlapping patches are rejected.
Live Input allows browsing but not menu edits. Mode changes are also blocked
while the selected fixtures are owned by virtual DMX.

All documented menu entries are browsable, but hardware-only functions are
explicitly unavailable: no pump, radio, calibration, pressure, system test,
Sleep, firmware reset, alternate protocol or hardware ignition-time changes.
These pages do not pretend to control or report the physical unit.

### Multi-selection and hover-wheel controls

With two or more selected fixtures, the next fader-level or flash operation
captures that group. Cue playback uses the active fixture's recorded look (or
the cue's first look when absent) on every selected unit, synchronized. Chase
assignments apply the same phase to the group. Unselected units are not targeted
by that operation. With one/no selected fixture, saved cue targets are retained.
Selection changes alone do not rewrite running targets or saved cues.

Virtual DMX identifies the parameter from the fader channel's existing fixture
patch, then mirrors that parameter offset to each selected fixture's own patch,
including other universes. Actual patches and incoming Live Input are unchanged.
The underlying fader group returns when a flash is released.

Every assignment title is **Cue**; optional chase remains in the dropdown.
DMX dropdown options are numbers only: **0** is unassigned, **1–512** are channels.
Hover over a numerical DMX box and scroll down for the next unused number,
or up for the previous one. Used channels are skipped to preserve unique mappings.
Hover over a fader and scroll up/down to raise/lower by **1% by default**.
Open that fader's **Settings → Wheel step (%)** to set its own increment from
0.1% to 100%. Hold Shift for one tenth of that increment, with a minimum of 0.1%.
Levels clamp at 0–100%. Each fader's increment is independent and saved with the
layout. The master keeps its existing 1% wheel step. In DMX-priority mode the step
is still percentage points of the fader, not raw DMX bytes.
MASTER also supports wheel adjustment by 1%. No click or focus is required.
Ctrl-wheel is left to layout/browser zoom. Live Input disables local controls.

### Use faders with virtual units, without Vista

Click **Virtual faders** in the top control-source bar, or **Enable virtual
faders** above the bank. This exits direct live input and console mapping and
enables mouse, touch and keyboard control of the bank. On entry from another
mode, all ten fader levels start at zero and MASTER starts at 100%.
Your virtual arm settings are preserved, not automatically armed.

On the first use with an empty cue library, selected units and their current
presets are captured onto the first free Cue-mode fader, normally **fader 7**,
still at zero. Uncheck DMX on any faders whose channels overlap the fixture's
patch before raising the cue fader; otherwise the fixture follows the virtual
DMX frame, even with those DMX faders at zero. To keep a cue-only setup on reload,
set those faders' Default mode to Cue in Settings and save your layout.
If no units are selected, select units and click **Use selected** on a cue fader.
Faders 1–10 each have this shortcut: it records a new cue, assigns it to that
specific fader and resets that fader to zero. Other cues remain in the library.
Existing cues, assignments and timing are not overwritten by entering the mode.

Every fader has the same cue/chase dropdown. There is no fixed selected-intensity
or chase strip. MASTER affects rendered brightness for all local playbacks.
Cue-controlled units must have **Virtual armed state** checked to render flames;
DMX-controlled units instead use their virtual CH6 value. Flash buttons remain momentary.
No USB adapter, DMX receiver, Vista connection or physical fixture is required
for this local workflow. The same on-screen controls work in the browser preview.

The bank sits below the manual playback timeline. It is an independent visual
playback system inspired by a console workflow, not a Vista EX hardware emulator.
The visible slogan above the workspace has been removed.

### Fader assignments

- **Faders 1–10:** choose Unassigned, Multi-unit chase or a recorded cue.
  Record selected captures selected fixture presets onto the first empty cue
  fader. Use selected records directly onto a specific fader. All start at zero.
- **DMX priority checkbox:** unchecked plays the dropdown assignment; checked
  bypasses it and drives the assigned channel in a virtual, in-memory DMX frame.
  The editable 0–255 value now represents that virtual channel byte rather than
  cue intensity. Switching resets the fader to zero.
- **Virtual universe:** Virtual U1 matches stored fixture port-address 0.
  Channels without checked faders are zero. Any checked channel that overlaps a
  fixture's six-channel patch gives that whole fixture to virtual DMX, overriding
  cue playback for that fixture. Other fixtures can continue playing cues.

Virtual DMX uses the existing angle/speed/trigger/opening-time/program/mode
decoder. A single channel is not a complete six-channel fixture command. The
monitor shows the selected fixture's six values and decoder status. Initial
high triggers are ignored until a low value is seen. MASTER scales rendered
brightness, not control bytes. A DMX flash at 100% writes 255 to its channel;
that byte might select a mode/program rather than control intensity.
The virtual frame never leaves the app. **Live Input** remains a separate path
that follows received Vista fixture commands with the local faders disabled,
regardless of the saved priority checkboxes.

Recording captures fixture IDs and their preset numbers. It does not capture
position, Invert, angle limits or patch addresses; those remain the fixture's
current settings. Choose a recorded cue in the library to rename/update it from
the current selection or delete it. Updating or deleting a cue releases its
assigned faders. Up to 64 cues can be stored.

### Flash buttons and settings

Each strip has a play-symbol button above its fader and a small white-sun button
below. Both intentionally use the requested **momentary** behavior: press and
hold to play the assignment at 100% visual intensity by default, then release to
disengage. If the fader is already raised, release returns to its normal playback
level rather than blacking it out. Keyboard Space/Enter can also be held.

**Settings** changes that fader's flash level from 0–100%. Cue flashes bypass
cue delays/fades, not MASTER. Cue faders offer loop or one-shot playback;
holding a flash repeats its cue while held.

Window focus loss, pointer cancellation or Escape releases held flashes. Hiding
the browser tab releases the whole bank; no chase or cue restarts automatically
when the tab becomes visible. **Release all** resets every fader to zero,
including virtual DMX channels.

### Chase setup

Choose **Multi-unit chase** in any fader's dropdown, then open its **Settings**.
The chase configuration is shared by all chase assignments. Adjust:

- **Speed:** 20–300 BPM, one step per beat.
- **Direction:** forward, reverse or bounce.
- **Units per step:** 1–16, capped to the target count.
- **Gate:** emission allowed during 5–100% of each step. Preset off-times still
  apply, and long presets can be cut short at the step boundary.
- **Preset:** choose any of the 88 visual presets.
- **Targets:** all units dynamically ordered left to right, or an explicit
  comma-separated fixture order such as `1, 3, 2, 4`. **Use current selection
  order** fills this list from the selection.
- **Loop:** repeat continuously while raised, or run one pass. A held chase flash
  repeats while held.

If playbacks target the same fixture, highest visual intensity wins; the most
recently started playback wins ties. This is a simplified per-fixture rule,
not a complete Vista tracking or attribute-merging implementation.

### Manual preview, live Vista and saving

Raising a cue/chase fader or pressing a flash selects **Fader playback** and pauses
the manual timeline. Units not targeted by an active playback stay dark. Uncheck
Fader playback or choose **Manual preview** to return to the timeline.

Selecting live Vista input releases and disables all local faders and flash
buttons. Live input is never mixed with this local bank. The receiver still sends
no DMX or firing commands.

**Save layout** includes cues, fader assignments, flash levels and chase settings
as optional playback data in layout version 4. **Load layout** always returns to
manual preview with cue/chase levels at zero and no held buttons. Earlier layout
files still load, with an empty cue library. Earlier app releases will ignore the
new playback data and may discard it when saving, so use this version for cue work.

Current verification covers browser interactions, the playback engine and
synthetic sACN integration in the development environment. Native Windows/Vista
acceptance testing remains required. The package still uses Python 3.10+ and is
not a rebuilt version of the previously quarantined EXE.

## Cue timing, master and F1–F12

Choose a cue in **Recorded cues**, then **Timing / delay**. Set start delay,
fade-in, hold and fade-out in seconds (0–600). Delay runs once when a fader starts.
Fade-in + hold + fade-out form each repeat when that fader is set to Loop.
Hold = 0 uses the longest captured preset duration plus its catalog gap.
Preset motion repeats within this envelope; the envelope does not stretch its motion.
Lowering the cue fader to zero uses its fade-out time from the current level.
Flash buttons bypass these times and release immediately; **Release all** is
also immediate. Editing cue timing releases assigned faders.

The separate **MASTER** scales all local cue, chase and flash brightness, for
selected and unselected units alike. **Zero** suppresses the whole bank.
This master does not affect the manual timeline or direct fixture-DMX input.
Flashes bypass cue timing, but never this master. There is no separate fixed
selected-intensity fader.

Each **F1–F12** macro has an **Assign** button. Assign one local action: set a
fader level, hold a fader flash, release a fader, release all, set the bank
master, select all units or clear selection. A flash macro uses its target
fader's flash level and stops on button release. Other actions run once on press.
These are single actions, not multi-step macro scripts or imported Vista macros.
Enable **Keyboard F1–F12** to use computer function keys while this page has focus.
Shortcuts are suppressed in editing fields and open dialogs; OS/browser-reserved
keys may not reach the page. The on-screen buttons remain available.

Saving a layout now includes timings, macro assignments and console mappings.
Loading resets playback levels, restores the master to 100%, and leaves mapping
disconnected. Virtual arm settings are saved with each fixture.

## Map Vista controls to the local bank

This is a configurable **incoming sACN channel map**, not a USB console driver.
Vista remains the software controlling your EX. A supported path for other
control surfaces depends on their host software producing the same channel
values; universal Vista-console compatibility has not been verified.

1. Launch `Start-Wave-Studio-sACN.cmd` and open its localhost page. Use a copy
   of your Vista show on an isolated rehearsal network with real effect hardware
   disconnected. Do not route these control-channel values to real fixtures.
2. In Vista, arrange a dedicated rehearsal sACN universe for control values.
   In Wave Studio open **Console mapping**, choose that universe and enter
   unique channel addresses for the controls you want. The receiver must
   subscribe to that universe; its launcher defaults to 1–4.
3. Assign controls in Vista to produce the matching channel values. For initial
   verification use generic dimmer channels; faders need proportional 0–255
   output and momentary buttons need high on press and low on release.
   This package does not create Vista playback assignments or macros for you.
   A physical EX user key is not automatically delivered as a keyboard F-key.
4. Use **Save mappings**, then **Connect local sACN controls**. Close the dialog.
   Lower each mapped control to zero/low once, then raise the master, selected
   intensity and the desired playback fader. If master is unmapped, raise
   the on-screen MASTER manually: connecting intentionally sets it to zero.
5. Record/assign cues in Wave Studio before using cue faders. Watch the received
   frame counter, slider levels and visual result. For buttons, values below
   128 release; 128–255 press. Faders scale 0–255 to 0–100%.

Channel 0 means unmapped. **Fill channels 1–43** provides this editable starter
map; it is not a built-in Vista fixture profile:

| Channels | Wave Studio controls |
|---|---|
| 1–10 | Faders 1–10 |
| 11 | Bank master |
| 12–21 | Upper play flash buttons 1–10 |
| 22–31 | Lower sun flash buttons 1–10 |
| 32–43 | User macros F1–F12 |

An Invert checkbox reverses a mapped channel, including its low/high sense.
Duplicate mapped channels are rejected. Changes apply only after Save mappings;
connect uses the last saved map. Set levels back through low after reconnect,
source handover, signal loss, or window focus loss. Loss of data for 2.5 seconds,
stream termination, malformed input, and disconnection release the bank and set
its master to zero. Mapping does not process incoming control frames while
the browser tab is hidden. Return controls to low before resuming.

**Console mapping** and **Live sACN** are different, mutually exclusive modes:
the first drives the local bank; the second interprets each virtual fixture's
six-channel input. Choosing Manual preview or unchecking Fader playback
disconnects mapping. Unmapped controls can still be adjusted on screen.
Changing an on-screen mapped control does not move a motorized hardware fader
or transmit feedback to Vista.

## Three red fixture indicators

Each virtual enclosure has three small red dots in a vertical row.
In local preview they show the active fixture's **Virtual armed** setting;
when armed, brightness follows its current visual intensity. Disarmed units
have dim, unlit dots and render no flame. This toggle edits all selected units.
In direct live input the setting is read-only: dots use the received arm-channel
value and go dark when data is stale or the channel is outside the supported
model's armed range. The inspector labels which source is being shown.

These indicators are simulated/received-data displays, not feedback from a
physical unit, not an interlock, and not confirmation that equipment is safe.

## Layout grid and selected-unit spacing

**Snap to grid**, next to **Fit view**, shows a 5% layout grid. Dragging snaps
the active unit to grid coordinates while preserving offsets within the selected
group. Arrow-key nudges use grid steps while snapping is enabled.
The grid follows the view's zoom and pan; it is not a physical distance or
safety-clearance scale. Turning snapping on does not move units by itself.

Select two or more units to enable **Spacing**. Slide left to bring them closer,
or right to distribute them farther apart with equal horizontal gaps. Their
left-to-right order and individual heights are retained; unselected units stay
in place. Free spacing preserves the group's horizontal center where possible,
shifting only as needed to stay within the layout. With snapping enabled,
gaps use whole grid cells and placement aligns to the grid.
The slider spans the available layout width; 0% gap stacks the selected units.
Each completed spacing gesture or group move supports **Undo**. Escape cancels
an in-progress gesture. Save layout retains the resulting fixture positions;
the snap toggle is a session-only editing aid.

## Nozzle artwork and fader channel dropdowns

The website demo and virtual studio share a flame renderer refined against the
uploaded X2 Wave Flamer reference footage. It uses a fast-growing, narrow stem,
warm gold core, a stronger orange body and perimeter, and detached
burning caps that rise and cool after cutoff. Emitted material retains its
original direction during head movement rather than forming long hairlike trails.
Attack and burnoff are visual approximations of the footage, not calibrated
combustion, manufacturer response specifications, or a pixel-perfect reproduction.
Broad, smoothly varying billows and rounded moving caps soften the flame motion.
Catalog pulse durations and DMX trigger logic are unchanged.

### Compact mobile faders

On phones, choose **Virtual faders** and use the **Stage** tab to see faders
directly under the stage layout and above the three-row sequence library.
The **Faders** tab shows the same controls and levels without the stage.
Six faders appear by default, fitting across the screen without horizontal
scrolling at widths of 320 pixels and above. Use **+** and **−** to show one
through ten faders; when more than six are shown, swipe sideways for the rest.
Removing the last visible fader releases its level and held flashes, but retains
its assignment. Adding it back does not restore the previous level.
Use **Assignments** to reveal channel numbers, DMX priority, editable labels,
cue selection and capture buttons. The three-dot button opens each fader's
settings. Mobile fader visibility resets to six on a fresh page load and does
not delete saved assignments. The mobile master stays hidden; the desktop
retains all ten faders, the master and its existing layout.

Choose **Indoor** or **Outdoor** in the nozzle selector to update all selected units.
Outdoor uses approximately 1.9 times the indoor visual flame height.
The latest browser preview retains the requested **doubled nominal flame length**
for both nozzles and preserves their relative height ratio. The reference-based update
adds more irregular body width and a short travelling burnoff beyond the jet. This
applies to the studio and landing-page demo, without changing DMX values.
The names are rendering presets, not manufacturer-approved venue classifications;
no exact height, fuel behavior, wind response or safety clearance is implied.
Nozzle selection persists in Save layout, supports Undo, applies to manual,
cue and live-input visualization, and does not modify any DMX value.
New fixtures inherit the active fixture's nozzle; older layouts without this
field use Outdoor. The landing-page demo has its own nozzle selector for
comparing the two appearances.

Every fader has an editable **DMX** dropdown. Choose or type a whole channel
number from 1–512; blank or `0` removes the mapping (displayed as 0).
New layouts default to fader 1 = channel 1 through fader 6 = channel 6;
these six faders start in DMX mode. Faders 7–10 start in Cue mode with unassigned
channels, and the other mapping targets start unassigned.
Existing saved mappings are retained when loading a layout.
Duplicate channel assignments are rejected, including conflicts with master,
flash and macro mappings. Edits apply on Enter or leaving the field.

These fields are used as virtual output addresses when the adjacent **DMX
priority** checkbox is checked. An unchecked fader uses its cue/chase dropdown;
optional Console mapping can also use its channel as an incoming fader control.
Checked virtual-channel faders ignore direct incoming fader/flash mappings.
The website stores the assignments and simulates the virtual frame, but does
not receive live sACN; use the local receiver and Live Input for Vista data.
Editing a checked fader's address resets that fader to zero. Editing while
Console mapping is connected disconnects and releases mapped playback; reconnect
and pass through zero/low again. Offline edits to unchecked cue faders preserve
their current levels.

## Physical DMX output: not implemented

Both this download and the hosted browser version remain visualizers.
Neither drives a USB-to-DMX adapter, sends fixture DMX, or controls real flame
hardware. There is no arbitrary-fixture output library in this release.

The reported name “ChromaQ 512” is not sufficient to select a USB driver.
Chroma-Q describes the [Vista UD512](https://chroma-q.com/products/vista-ud512-usb-to-dmx-interface)
as a USB-to-DMX interface designed for Vista, and lists
[Vista channel-license dongles](https://chroma-q.com/products/vista-3-by-chroma-q-dongles)
separately. No supported third-party control API was verified for the reported
device. A photo of its product label or exact model, and vendor confirmation of
an appropriate integration path, are required before implementing direct output.
Do not replace Vista's driver or connect untested software to real effects.

The new engine, browser controls and synthetic local sACN mapping have development
tests. Actual EX/Vista-on-Windows hardware acceptance remains outstanding.
This ZIP is still a Python source package, not a replacement compiled EXE.

## First launch

1. Extract the entire ZIP to a folder such as `Documents\Wave Studio`. Do not run the launcher inside the ZIP.
2. Disconnect real flame hardware from the rehearsal network. This application sends no DMX or firing commands, but Vista could still transmit to any physical devices on the same network.
3. Double-click `Start-Wave-Studio-sACN.cmd`. Enter the IPv4 address selected in Vista's Network preferences, or press Enter for the Windows default interface. Keep the console window open.
4. Use the local browser page it opens: `http://127.0.0.1:8765`.
5. If the browser does not open, enter that address manually. Use a current version of Edge or Chrome.
6. If Windows Firewall asks, allow Python on the appropriate trusted/private network. Do not disable the firewall or grant unnecessary public-network access.
7. Close the console or press Ctrl+C to stop the receiver. Wave Studio clears live effects when the connection is lost.

The sACN receiver listens on UDP 5568 and joins universe multicast groups, as defined in [ANSI E1.31-2018, §§9 and 13](https://github.com/k-yle/sACN/blob/main/docs/E1.31-2018.pdf). The optional Art-Net mode uses UDP 6454, defined by the [Art-Net specification](https://art-net.org.uk/downloads/art-net.pdf). In both modes the web interface binds only to your own computer, not to the LAN.

### Updating an older installation

Save your fixture layout to JSON and stop the old receiver with Ctrl+C before launching this version. Extract the new ZIP into a fresh folder, launch its `Start-Wave-Studio-sACN.cmd`, then load your saved layout. Do not run two receivers at once; refresh an existing browser tab to load the updated app.

## Same-PC Vista: sACN setup

This mode does **not** advertise an Art-Net node. Add a Streaming ACN output manually instead of waiting for “Wave Studio” to appear in Connect Universes.

1. Keep real flame hardware disconnected from the rehearsal network. Use a rehearsal copy of your Vista show; do not change a production show.
2. In Vista's Network preferences, note the selected interface's IPv4 address. Start `Start-Wave-Studio-sACN.cmd` and enter exactly that address. For the setup previously shown in this project, that was `192.168.137.1`; use it only if Vista still shows that address. Do not switch to an unrelated public Wi-Fi network to make the test work.
3. Check the console says **sACN input: UDP 5568**, lists universes **1, 2, 3, 4**, and says Art-Net port 6454 is not opened.
4. In Vista's **Connect Universes**, click **Add Network Connection** and choose **Streaming ACN / sACN**. Set the streaming universe to **1** and priority to **100**. Associate your internal Vista universe with that output and enable its output checkbox. Labels can vary by Vista version; the documented workflow adds an sACN multicast output and then assigns its Vista universe ([Vista user guide, sACN section](https://www.stars-europe.com/pdf/produits/LECONSOLE4+.pdf)).
5. In the local Wave Studio page, the live button should identify **sACN**. Set each virtual fixture's **sACN universe** to **1** and its one-based DMX start address to match Vista. For two six-channel fixtures, use addresses 1 and 7.
6. Click **Live sACN**. Confirm the received packet counter increases and channel values follow Vista before trying visual triggers. Use the six-channel profile below.
7. If Windows Firewall asks, allow Python's input on UDP 5568 on the appropriate trusted/private rehearsal network. Do not disable the firewall or expose the localhost web server.

Vista sends sACN using multicast, not a discovered receiver list; its support discussion explicitly states that Vista does not support unicast sACN output ([Vista support discussion](https://vistaforum.chroma-q.com/t/weird-issue-with-vista-not-outputting-sacn-unless-i-open-up-sacnview-first/3236)). Do not enter `127.0.0.1` as a Vista unicast destination or switch the sACN setup to Art-Net broadcast.

### Universe numbering and saved layouts

The browser displays **one-based sACN universes** in sACN mode. Enter 1 for sACN universe 1, with no manual subtraction.

Layout JSON retains the existing zero-based universe slot for compatibility: stored slot 0 displays as sACN universe 1, slot 1 displays as sACN universe 2, and so on. A layout previously patched to Art-Net port-address 1 will therefore display sACN universe 2; change its patch in the browser if you want sACN universe 1. Fixture positions, Invert and DMX start addresses remain unchanged. Loading a layout still returns to manual preview.

The receiver subscribes to universes 1–4 by default. To change subscriptions, stop it and run:

```text
py -3 receiver.py --protocol sacn --interface 192.168.137.1 --universes 1,2,5
```

Replace the example IP with Vista's current selected local interface. You can subscribe to up to 16 universes in this implementation's supported range **1–32768**; E1.31 itself allows 1–63999 ([ANSI E1.31-2018, §6.2.7](https://github.com/k-yle/sACN/blob/main/docs/E1.31-2018.pdf)). Changing a browser fixture patch does not change multicast subscriptions; the browser warns about unsubscribed universes.

### sACN behavior and diagnostic counters

- **Port separation:** Opens UDP 5568 only. It does not bind, share or steal Vista's UDP 6454.
- **Multicast interface:** `--interface` chooses which local IPv4 interface joins the selected multicast groups. A blank launcher answer uses the OS default, which can be wrong on PCs with multiple adapters.
- **No application output:** Sends no sACN, Art-Net discovery, DMX or firing packets. The OS manages multicast membership traffic.
- **Source identity:** Tracks sender CID and IP, rather than treating every program on the same PC as one sender.
- **Priority:** A higher universe priority can take over. Competing equal- or lower-priority sources are counted and ignored while the selected source is active. This is not a complete standards-compliant HTP/LTP merger.
- **Takeover and recovery:** Source changes, signal loss and termination require a low trigger before a subsequent high trigger can start a new visual effect.
- **Sequence handling:** Uses the E1.31 signed-difference rule, including zero and 255-to-zero wrap; duplicates and slightly stale packets are discarded ([ANSI E1.31-2018, §6.7.2](https://github.com/k-yle/sACN/blob/main/docs/E1.31-2018.pdf)).
- **Stream termination:** An active sender's termination packet immediately clears that universe's virtual effects, without waiting for the 2.5-second timeout. It does not clear other universes.
- **Preview data:** Accepted for visualization only. It never creates physical output.
- **Synchronization:** Not implemented. Data frames render on arrival; synchronization addresses are ignored, as allowed for nonsynchronizing receivers in [ANSI E1.31-2018, §6.2.4](https://github.com/k-yle/sACN/blob/main/docs/E1.31-2018.pdf).
- **Start codes:** Accepts null-start-code levels only. Alternate start codes, including per-address priority, are not supported.
- **Monitor counters:** “UDP received” counts all datagrams delivered to this socket. “DMX packets” counts accepted level frames. Rejected packets include invalid/unsupported frames and stale sequences. Filtered packets include unsubscribed universes or excluded senders. Source conflicts and stream terminations have separate counters.

If **UDP received stays at zero**, check the Vista sACN output assignment, selected interface, subscriptions and firewall. Same-PC multicast also depends on sender/OS loopback behavior; removing the Art-Net port conflict is not a guarantee that every Vista/Windows version will deliver multicast locally. If UDP increases but accepted DMX does not, capture the counter values and console text for troubleshooting. Do not run another sACN monitor on UDP 5568 at the same time unless its port-sharing behavior is understood.

## Art-Net connection: separate receiver computer

Your existing Vista output dongle supplies the output license; Vista supports Art-Net network output without an additional USB-to-DMX cable for this path ([Vista documentation](https://chroma-q.com/assets/uploads/product_downloads/de7aa34640637afbd8048c273eea050a.pdf), [Vista license information](https://chroma-q.com/products/vista-3-by-chroma-q-dongles)).

1. Open a separate rehearsal show or a copy of your show in Vista.
2. Patch each fixture using a profile whose channel order matches the six-channel standard Explo mapping below. Do not assume an existing library profile has the correct footprint, CH5 version, or trigger behavior.
3. If you cannot identify a matching X2 profile, use six consecutive generic DMX channels per virtual fixture for an initial input test. A native Vista fixture-library file is not included.
4. In Vista's **Connect Universes** window, look for **Wave Studio** after Vista polls the network. Connect your internal universe to the appropriate advertised virtual port. Discovery identifies a node; it does not automatically patch your individual flame fixtures or route your show.
5. The receiver advertises raw port-addresses **0, 1, 2, 3** by default. Make the selected port match the fixture's Wave Studio port-address. If discovery is unavailable, use explicit Art-Net broadcast as a fallback; Vista 3 R4 added Net, Sub-Net and Universe fields to the connection window ([Vista R4 release notes](https://www.vistabychromaq.com/wordpress/wp-content/uploads/2023/10/Vista-by-Chroma-Q-Vista-3-R4.0-Release-Notes.pdf)).
6. In Wave Studio, select each fixture and set its **Port-address** and **DMX address**, then click **Update fixture patch**.
7. Select **Live Art-Net**. Confirm the six values in the monitor respond to Vista before testing triggers.

### Discovery settings

Discovery is enabled as soon as the receiver starts, even before the browser enters live mode. Valid ArtPoll requests receive delayed unicast ArtPollReply responses on UDP 6454, following the packet structure in the [Art-Net specification](https://art-net.org.uk/downloads/art-net.pdf).

- **Node identity:** Wave Studio, with the description “Wave Studio - Virtual DMX receiver.” These are virtual receiver ports, not physical DMX outputs.
- **Default ports:** 0, 1, 2, 3. Choose up to 16 advertised raw port-addresses with `py -3 receiver.py --universes 0,1,16,256`.
- **Additional ports:** The implementation splits ports into bound replies of up to four ports sharing Net/Sub-Net. Vista R4 documents support for Art-Net 4 multi-port binding at one IP address ([Vista R4 release notes](https://www.vistabychromaq.com/wordpress/wp-content/uploads/2023/10/Vista-by-Chroma-Q-Vista-3-R4.0-Release-Notes.pdf)).
- **Fixed advertisement:** Changing a fixture's browser patch does not change the advertised ports. Restart with an updated `--universes` list; ArtAddress remote reconfiguration is ignored. ArtDmx input is still accepted for other valid port-addresses.
- **Network address:** Normally selected from the OS route to the polling controller. Use `--advertise-ip 192.168.1.60` only with an IPv4 address actually assigned to the receiver computer on the rehearsal network.
- **Disable discovery:** `py -3 receiver.py --no-discovery` restores DMX reception with no outbound Art-Net packets.
- **Monitor:** Live mode displays the advertised ports and discovery-reply counter. A rising counter confirms replies were sent, not that Vista accepted them or routed DMX.

This prototype uses the official **OemUnknown (0x00FF)** identifier, not an Explo or Chroma-Q product identity ([Art-Net OEM code table](https://art-net.org.uk/oem-code-zone/)). It has no registered product OEM code and is not a certified implementation; the protocol publisher requires OEM registration for implementations, which must be addressed before product distribution ([Art-Net registration guidance](https://art-net.org.uk/)).

### Universe numbering

Wave Studio displays the raw 15-bit Art-Net port-address, not Vista's internal universe label. The packing is `Net × 256 + Sub-Net × 16 + Universe`, with Net 0–127 and Sub-Net/Universe 0–15 ([Art-Net specification](https://art-net.org.uk/downloads/art-net.pdf)).

| Vista Art-Net output settings | Wave Studio port-address |
|---|---:|
| Net 0 / Sub-Net 0 / Universe 0 | 0 |
| Net 0 / Sub-Net 0 / Universe 1 | 1 |
| Net 0 / Sub-Net 1 / Universe 0 | 16 |
| Net 1 / Sub-Net 0 / Universe 0 | 256 |

Port-address 0 is accepted here for compatibility with existing zero-based workflows, although the current Art-Net specification deprecates it; use port-address 1 if preferred, with matching output settings on both ends ([Art-Net specification](https://art-net.org.uk/downloads/art-net.pdf)).

Do not subtract one from every universe number automatically. Compare the actual Art-Net fields. For a straightforward two-fixture test, patch F01 at channels 1–6 and F02 at channels 7–12 in the same port-address.

### Same PC versus a second PC

Do not use this Art-Net receiver alongside Vista on the same Windows PC. Troubleshooting confirmed that Vista and Python alternately owned wildcard UDP 6454, while the receiver requests exclusive access. Use the sACN launcher for the same-PC path.

If the receiver reports that UDP 6454 is already in use, do not kill Vista or change production networking just to force it. Run the receiver on a second Windows computer on the same isolated rehearsal network, keep Vista on the first computer, and open the receiver's local page on the second computer. Broadcast traffic must reach that network segment; alternatively, use explicitly addressed unicast if your Vista output configuration provides it.

## Six-channel visualization profile

This implementation targets **Customer: Explo / Protocol: DMX512 / CH5 version: new** in the v2.0 manual, not Easy DMX or the Pyroemotions variant ([Explo manual, §4.3 and §11](https://explo.at/wp-content/uploads/2025/06/X2-Wave-Flamer-v2.0-ENG-2.pdf)).

| Offset | Function | Implemented interpretation |
|---:|---|---|
| +0 | Angle | 0–255 maps to −105° through +105°. |
| +1 | Speed | 0 and 255 follow the received angle; 1 stops direct head motion; 2–254 use an approximate visual speed curve. |
| +2 | Trigger | A transition into 254–255 triggers a virtual effect after a lower value has been received while in the armed-value range. Holding high does not retrigger. |
| +3 | Opening time | For direct control: 1–254 means value × 10 ms. Values 0 and 255 use gated continuous previews capped at 8 s and 2.5 s, respectively. |
| +4 | Program | 0–2 selects direct control. 3–226 selects presets 1–88 using the exact ranges in the separate sequence sheet. Values 227–255 are unsupported and do not trigger an effect. |
| +5 | Mode | 50–200 allows visual emission. Other values show test mode and clear the effect. |

The channel functions, angle mapping, trigger reset, opening-time caps, mode range, and profile variants follow [Explo manual §11.2](https://explo.at/wp-content/uploads/2025/06/X2-Wave-Flamer-v2.0-ENG-2.pdf); the exact program intervals come from the [X2 sequence / DMX values sheet](https://explo.at/wp-content/uploads/2025/06/X2-Wave-Flame-Sequences-DMX-Values.pdf). The intermediate motor-speed curve, visual cancellation policy and low-before-high reconnect policy are implementation choices, not calibrated or certified hardware behavior.

### Visual-only first cue

With no real flame hardware connected, use this fixture-relative value set:

| Channel | Initial value | Purpose |
|---|---:|---|
| 1 | 128 | Approximately centered direct-angle value |
| 2 | 0 | Maximum/follow-target setting |
| 3 | 0 | Reset trigger |
| 4 | 0 | Not used to override a catalog sequence's duration |
| 5 | 131 | Select preset 51 |
| 6 | 128 | Within the visual armed-value range |

After these values appear in the live monitor, change channel 3 to 255. The virtual fixture should play preset 51 once; return channel 3 below 254 before the next trigger. The program value 131 belongs to preset 51's 131–132 interval ([manufacturer sequence sheet](https://explo.at/wp-content/uploads/2025/06/X2-Wave-Flame-Sequences-DMX-Values.pdf)).

Each fixture has its own trigger clock, so Vista can stagger or synchronize fixtures independently. Invert mirrors the virtual fixture's positions left to right; it does not alter incoming channel values or send a parameter change to hardware.

## Live mode behavior and limits

- **Network output:** Art-Net mode sends only ArtPollReply responses. sACN mode sends no application UDP packets. Neither mode transmits DMX or hardware-control commands. Browser data is delivered by a local HTTP event stream.
- **Independent cues:** Each fixture starts on its own received trigger. New triggers while that fixture's current effect is still active are ignored, not queued.
- **Catalog sequences:** Once started, a sequence completes its catalog duration even if the trigger falls. Test-mode values, signal loss, patch changes and connection loss clear the visual effect.
- **Signal loss:** No valid data for a fixture's universe for 2.5 seconds clears its effect. Reconnection requires a low trigger before the next high trigger; arriving while already high does not start an effect.
- **Incomplete frames:** A packet that does not contain all six channels for a fixture clears that fixture's live effect instead of treating missing slots as valid data.
- **Multiple senders:** In Art-Net mode, the first active source IP owns a universe until absent for 2.5 seconds. sACN additionally uses CID and universe priority as described above. HTP/LTP merge is not implemented.
- **Packet sequence:** Art-Net rejects duplicate or stale nonzero sequence numbers; its zero disables checking. sACN follows its separate ordering rule, where zero is a normal sequence number.
- **ArtSync:** Not implemented. ArtDmx frames are applied as received; this is not a synchronized multi-universe receiver.
- **Manual controls:** Live mode does not use the manual loop, tour, playback-speed or scrub settings. Switch back to Manual preview to use them.
- **Layout files:** Save layout includes patch addresses, positions, presets and Invert. Loading a layout returns to manual preview, never live output. Version 1 and 2 files remain supported and receive automatically assigned patches.
- **Browser tab:** Keep the live browser tab visible for rehearsal. Browsers can throttle background rendering; this is not a timecode-locked visualization engine.
- **Not supported:** Direct USB/XLR DMX input, Easy DMX, legacy CH5, Pyroemotions control, custom device programs, native Vista fixture-library export, hardware arming delay, pressure, fuel, interlocks or calibrated motor mechanics.
- **Real-device differences:** Actual device pressure build-up and firmware-specific timing are not simulated. The manual describes an initial pressure build-up period and older-chip sequence-select timing differences ([Explo manual §11.2.6–11.3](https://explo.at/wp-content/uploads/2025/06/X2-Wave-Flamer-v2.0-ENG-2.pdf)).

The visual model retains the existing artistic flame width, burst separation, and catalog movement assumptions. It is not a prediction of physical flame envelope, clearance, or exact head travel.

## Troubleshooting

- **The hosted preview will not connect:** Expected. Use the page opened by the Windows launcher. No cloud-to-PC connection is provided.
- **“Python not found”:** Install Python 3.10+ from the official Windows downloads page and rerun the launcher. No administrator launch should be needed for the application itself.
- **“Address already in use”:** Check web port 8765 and the selected input port: 5568 for sACN or 6454 for Art-Net. Stop the old receiver and other sACN monitors. Do not change protocol ports arbitrarily or force shared bindings. To change only the web port use `py -3 receiver.py --protocol sacn --port 8766`.
- **Wave Studio does not appear in Vista:** Expected in sACN mode; add Streaming ACN manually. In Art-Net mode on a separate computer, confirm discovery is enabled and check network/firewall settings for UDP 6454.
- **Replies increase but no node appears:** A sent reply is not proof of Vista compatibility. Check for stale discovery entries, the selected network interface and Vista version. Test broadcast routing while troubleshooting discovery.
- **“Connected” but no DMX packets:** Check Vista's output license and universe routing. Discovering the node does not connect an internal Vista universe automatically.
- **Packets arrive but the fixture waits:** Compare Net/Sub-Net/Universe and the one-based start address. Confirm the packet includes all six required channels.
- **Channel values change but no flame:** Check channel 6, channel 5 range and the low-to-high trigger transition. A held high value, an unsupported program value, or a busy fixture will not start a new sequence.
- **Values move differently than expected:** Check Vista's fixture personality and channel order. Use six generic channels to isolate mapping problems. Intermediate pan-speed values are approximate here.
- **Source conflicts increase:** Another controller is transmitting the same universe. Isolate the rehearsal network or restrict the receiver to Vista's source IP.
- **Packet counter is not zero after reconnect:** It counts accepted packets since the receiver process started, not since the current tab connected.
- **Layout changes disappear:** Use Save layout before closing the browser. No layout is silently persisted.
- **Launcher is blocked by organizational policy:** Have your IT administrator review the included text source. Do not bypass endpoint-security policies.

### Optional command-line restrictions

Run from the extracted folder:

```text
py -3 receiver.py --source-ip 192.168.1.50
py -3 receiver.py --bind 192.168.1.60
py -3 receiver.py --port 8766 --no-browser
py -3 receiver.py --universes 0,1,16,256
py -3 receiver.py --advertise-ip 192.168.1.60
py -3 receiver.py --no-discovery
py -3 receiver.py --protocol sacn --interface 192.168.137.1 --universes 1,2,3,4
py -3 receiver.py --protocol sacn --source-ip 192.168.137.1
```

Replace the example addresses with your actual Vista sender and receiver addresses. `--source-ip` accepts DMX and discovery polls only from that sender; `--bind` chooses the receiver's local network interface. If specifying both `--bind` and `--advertise-ip`, use the same local address. The web interface always stays on loopback.

## Verification status

The included implementation was tested with synthetic ArtDmx and ArtPoll packets, packet-field and discovery-routing tests, protocol/trigger unit tests, and Chromium browser integration in a Linux sandbox. Discovery testing covers ordinary and targeted polls, multi-port binding, disabled discovery, source restrictions, reply rate limiting, unicast replies to UDP 6454 and ignoring received reply packets. Multi-fixture routing, invert, trigger reset, signal loss, bad packets, reconnect suppression, patch validation, layout migration, manual-mode regression and responsive UI were also exercised.

sACN testing additionally covers malformed lengths/vectors, short frames, supported universes, sequence zero/wrap/duplicates, priority/CID takeover, preview frames, stream termination, multicast delivery with UDP 6454 already occupied, and multicast-to-browser integration. These tests use a synthetic sender in Linux, not Vista itself.

The previous Art-Net mode was tried on your Windows PC and its same-PC port conflict was confirmed. The **new sACN mode has not yet been tested on your Windows/Vista installation**, and neither mode is validated against a real X2. The first live Vista sACN session remains an acceptance test, not a guaranteed plug-and-play certification.
