diff --git a/docs/stage-light-dimmer.md b/docs/stage-light-dimmer.md new file mode 100644 index 0000000..484c18e --- /dev/null +++ b/docs/stage-light-dimmer.md @@ -0,0 +1,268 @@ +# Stage light dimmer — driving an old filament fixture from HA over Zigbee + +**Short answer: a SONOFF MINI Extreme ZBDIM (400 W halogen rating) wired inline +into a short Schuko extension lead, paired to the existing Zigbee2MQTT instance. +Roughly €25, appears in HA as a normal dimmable `light` with no HA config at +all.** The only reason this needs a document is that the lamp has to be verified +*before* anything is bought — the wattage decides whether this is a €25 job or a +€100 one, and getting it wrong is the one path here with a real fire risk. + +This is guidance, not automation — **nothing under this repo touches the fixture, +the dimmer, or the Zigbee pairing.** Same convention as `network-integration.md`: +you do this by hand, at move-in, after Phase 1 is up. + +## 0. Prerequisite + +Phase 1 must be running first: the Docker stack from +`tools/setup-container-host.sh`, with Mosquitto, Home Assistant, and +Zigbee2MQTT talking to the Haozee CC2652P dongle (`docs/project-plan.md:16`). +Nothing below works until `docker logs zigbee2mqtt` shows a healthy coordinator. + +Everything in this doc stays on the Zigbee backbone rather than adding a WiFi +dimmer, for the reasons in `docs/components.md:208`. + +## 1. Verify the lamp before buying anything + +The fixture as measured in 2026: **19.6 cm lens diameter, ~15 Ω cold across the +lamp's own terminals, no transformer, no cooling fan.** That works out to roughly +a 250 W mains filament lamp. Re-verify at move-in — the fixture may have been +relamped, and the whole plan hangs on this number. + +### 1a. Read the lamp first + +The wattage is usually stamped on the pinch, base, or glass, and the fixture +nameplate states max lamp wattage and voltage. A type code is enough — CP60 / +CP61 / CP62 = 1000 W, CP95 = 500 W, HPL 575 = 575 W. **If you can read it, skip +to §2** — a printed number beats every estimate below. + +### 1b. Or measure it running — better than any estimate + +Not required, but it ends the guessing completely and costs almost nothing. A +plug-in energy meter (~€10, rated 16 A / 3680 W, so fine up to a 2 kW lamp) +reports true wattage directly: no tungsten coefficient, no lead nulling, no +arithmetic. A clamp meter (~€15) on the live lead does the same job. + +Worth owning regardless — it's the same instrument you'll want the first time an +automation's power figures look wrong anywhere else in this project. + +### 1c. Otherwise, estimate from cold resistance + +Disconnected from mains, probe **across the lamp's own two pins** — not at the +plug. The plug reading includes the fixture's switch, wiring, and socket +contacts, which added ~4–5 Ω of error last time and made the lamp look half its +actual size. + + P ≈ V² / (R_cold × k) → at 230 V: P ≈ 3530 / R_cold + +`k` is tungsten's hot/cold resistance ratio, ~15 for theatre halogen (range +13–17). Expect ±25% overall. + +| Cold reading | Likely lamp | | Cold reading | Likely lamp | +|---|---|---|---|---| +| ~18 Ω | 200 W | | ~5.4 Ω | 650 W | +| ~15 Ω | 250 W | | ~4.7 Ω | 750 W | +| ~12 Ω | 300 W | | ~3.5 Ω | 1000 W | +| ~7 Ω | 500 W | | ~1.8 Ω | 2000 W | +| open / ∞ | blown filament — **or a discharge lamp, see §1c** | + +Null your leads first (short the probes, subtract that reading). Irrelevant at +15 Ω, critical below 5 Ω where lead resistance is a large fraction of the total. + +A reading that wanders means bad probe contact, or that you're measuring a +winding rather than a filament. A good filament reads stable. + +### 1d. Optional cross-check: fixture size + +A sanity check on the estimate, not a rule. Lens diameter tracks wattage across +*professional theatrical* ranges, but older and budget fixtures routinely pair a +large lens with a modest lamp — lens size is set by the beam optics you want, not +the power. **Where this table disagrees with a terminal measurement, the +measurement wins.** + +| Fresnel lens Ø | Typical lamp | | PAR can Ø | Typical lamp | +|---|---|---|---|---| +| 75 mm (3") | 150–300 W | | PAR36 · 114 mm | 6–12 V + **transformer** | +| 125 mm (5") | 500–650 W | | PAR56 · 178 mm | 300–500 W | +| 150 mm (6") | 1000 W | | PAR64 · 204 mm | 500–1000 W | +| 200 mm (8") | 2000 W | | | | + +This fixture's 196 mm lens sits on PAR64, which would normally imply 500–1000 W, +while the terminal reading says ~250 W. That conflict is exactly what the caveat +above covers — but it's also why §1a/§1b are worth doing rather than trusting +either number alone. + +### 1e. Three things that stop this plan dead + +**Discharge lamp.** If the lamp or fixture says HMI, MSR, CSI, CDM, or HQI, or +there's a ballast/igniter in the base — **it cannot be phase-dimmed at all.** +Attempting it destroys the lamp and possibly the ballast. On/off relay only. + +**Transformer in the fixture.** Confirm by pulling the lamp and re-measuring at +the plug: open circuit means the path was the filament and you're fine; a +remaining reading of tens of ohms means there's a winding in there. That's an +inductive load, generic dimmer modules are not automatically safe on it, and the +lamp is low-voltage rather than mains. Stop and reassess. + +**Cooling fan.** If the fixture has one, it is usually wired in parallel with the +lamp downstream of the dimmer. Dim the circuit and the fan stalls while the lamp +still throws full heat. It must be fed from unswitched mains, ahead of the +dimmer. + +## 2. Bill of materials — ~€25 + +| Item | Price | Note | +|---|---|---| +| [SONOFF MINI Extreme ZBDIM](https://www.amazon.de/SONOFF-elektronische-Halogenlampen-Neutralleiter-Leistungsmessung/dp/B0GFN145VT) | €15–20 | 400 W halogen, Zigbee 3.0, Z2M-supported, power monitoring, acts as a router | +| Short Schuko extension lead | ~€5 | Gets cut in half | +| Surface junction box (Abzweigdose) | ~€3 | Houses the module | +| Inline fuse holder + 2 A fuse | ~€3 | The module has no internal fuse | + +At 250 W into a 400 W rating you sit at ~62% load — the headroom you want for +cold-filament inrush. + +**Do not buy a plug-in Zigbee dimmer.** The whole category caps around 200 W +because a plug body has nowhere to dump triac heat. The +[AduroSmart ERIA dimmable plug](https://www.amazon.de/AduroSmart-Steckdose-Dimmbar-kompatibel-81855/dp/B08PKQVQTQ) +is the only real Schuko option and it's rated 200 W — *under* this lamp's draw. + +[Candeo C204](https://www.amazon.de/Candeo-Dimmermodul-erforderlich-kompatibel-Smartthings/dp/B091GTK61Y) +(~€35) is an equally valid module if the SONOFF is unavailable. Same 400 W +halogen rating, same build job, no power monitoring. + +## 3. Build the inline dimmer + +Cut the extension lead, wire the module in a junction box: Schuko plug in, Schuko +socket out. The module needs neutral, which an extension lead has. + +- Proper enclosure, no exposed conductors. +- Strain relief on **both** cable entries. +- Fuse in the live leg, upstream of the module. +- Don't bury the box anywhere unventilated. Thermal is the dominant failure mode. + +If cutting mains cable isn't something you want to do, this is a 15-minute job +for an electrician — and there's no off-the-shelf product that avoids it, given +the 200 W plug ceiling above. + +## 4. Pair with Zigbee2MQTT + +`tools/setup-container-host.sh:503` sets `permit_join: false`, which is the right +default and means pairing is a deliberate act: + +1. Z2M web UI → **Permit join**, scoped to the coordinator. +2. Power the module. It should appear within ~30 s. +3. Let permit-join time out. Don't leave it open. +4. **Rename it immediately** — `stage_lamp` or similar. Otherwise + `light.0x00124b00...` ends up baked into every automation you write. + +`tools/setup-container-host.sh:502` already sets `homeassistant: true`, so MQTT +discovery creates the HA `light` entity automatically. **No HA YAML, no manual +entity definition, nothing to commit to this repo** — the pairing lives in Z2M's +`database.db`, which the restic backups already cover +(`docs/project-plan.md:459`). + +If Z2M reports the device as unsupported, pull a newer image rather than writing +a converter — the compose file already tracks `koenkk/zigbee2mqtt:latest` +(`tools/setup-container-host.sh:1184`). + +## 5. Configure + +One setting genuinely matters: + +- **`power_on_behavior` → `off`.** Defaults are often `previous` or `on`, which + means a power blip or a Z2M container restart brings a 250 W stage lamp to full + brightness in an empty room. + +Three worth doing: + +- **Tune `min_brightness` by walking it down.** The default is set to stop LEDs + flickering at the bottom of the range, and a filament doesn't need that + protection — it dims smoothly to near-zero. But don't just set it to 1: at very + low phase angles the triac stops latching reliably, which shows up as flicker + or dropout rather than a dim glow. On the Z2M device page, lower it a step at a + time until the lamp goes unstable, then back off one step. That point is the + real bottom of the usable range, and it's fixture-specific — worth writing the + final value down. +- **Cap `max_brightness` at 90%.** Filament life is brutally sensitive to + voltage: roughly `life ∝ V⁻¹³` against `light ∝ V³·⁴`. Running at 90% buys + about **4× the lamp life for ~30% less light** — a strong trade on a fixture + whose lamp type may well be discontinued (§6), and this is a mood/accent light + rather than something being asked to actually illuminate a room. Back off to + 95% (≈2× life, ~15% less light) if it turns out dimmer than you want. Rules of + thumb, not exact, but the direction is very strong. +- **Pass `transition: 2` in `light.turn_on` calls.** Ramping over a couple of + seconds cuts the cold-filament inrush, which is the biggest single wear event + on the lamp and the main stress on the triac. + +Optional and situational: + +- **`switch_type`** — only relevant if a physical wall switch is wired to the + module's input. Irrelevant for an inline extension-lead build; set it if the + fixture ever gets a permanent installation. +- **Edge mode**, if the module exposes it. Trailing edge (Phasenabschnitt) and + leading edge (Phasenanschnitt) both work fine on a pure resistive filament, so + leave the default alone. It only becomes a real decision if a transformer ever + enters the picture (§1e), where leading edge is the more tolerant of the two. +- **Surface the power reading in HA.** The ZBDIM's power monitoring arrives as + its own sensor entity. A dashboard card, or a template alert if draw exceeds + the expected figure, is cheap early warning on a failing lamp or a wrong + relamp — and it's the only thing here that would catch someone plugging a + bigger fixture into this dimmer. +- **Don't bother with a dimming curve.** Filament light output is very nonlinear + against phase angle, so the HA brightness slider won't feel perceptually even. + Correcting it is fiddly and buys little on a fixture like this; live with it + unless it actually bothers you. + +## 6. First run + +- Non-flammable surface, module in open air, not boxed into anything yet. +- RCD-protected circuit, ideally on a 6 A or 10 A MCB rather than 16 A. +- Stay with it for the first 30 minutes and sweep the full dim range rather than + parking at one level — **mid-dim is peak triac dissipation, not full-on**. +- **Check the power reading against the ~250 W estimate.** This is what the + SONOFF's power monitoring is for; it replaces the resistance estimate with a + direct measurement. Materially higher than expected → stop, reassess headroom. +- Check the fixture's clearance. Old stage cans run 200 °C+ housings and want + ~0.5 m from anything flammable. If the triac ever fails short, the lamp sits at + 100% indefinitely — fine for the fixture, less fine for a curtain. + +Worth doing once while the lamp is out: clean the lamp socket contacts. The +~4–5 Ω gap between the plug and terminal readings in 2026 was fixture wiring and +contacts, dissipating several watts as heat inside an already-hot fixture. + +Two more that aren't required but pay for themselves: + +- **Buy a spare lamp at the same time.** Theatre lamp types get discontinued and + an old fixture is worth nothing without one. Record the exact type code once + you've read it in §1a. +- **Label the finished dimmer box** with both numbers — lamp draw and module + rating (250 W / 400 W). Future-you plugging a different fixture into a box that + looks like a generic extension lead is the most plausible way this ends up + overloaded. + +## 7. If the lamp turns out bigger than ~400 W + +Everything above is void; a 1 kW lamp pulls ~4.3 A steady and 50 A of cold +inrush, well past any in-wall module. Two routes, both built around a used +theatrical dimmer pack (€50–100 for 4×1200 W), which handles inrush, fusing, +heatsinking, and EMI properly: + +| | Approach | Cost | Note | +|---|---|---|---| +| **B** | Zigbee 0–10 V dimmer (YSRSAI YSR-Mini-01 or Lonsonho VM-Zigbee-S02, ~€20–25) into the pack's **0–10 V analog input** | €75–125 | Stays on the Zigbee backbone. Most analog packs already have this input. | +| **C** | ESP32 + RS485 module (~€10) running [andyboeh/esphome-dmx512](https://github.com/andyboeh/esphome-dmx512) driving the pack over DMX512 | €60–110 | Cheapest, fits the existing `firmware/` ESPHome pattern, but breaks the Zigbee-only lighting rule in `docs/components.md:208`. | + +Prefer **B** — €20 more to keep lighting on one backbone is noise, and either +way you get three spare channels for future fixtures. + +## 8. Troubleshooting + +| Symptom | Likely cause | +|---|---| +| Device never appears in Z2M | Permit-join timed out; module has no neutral; too far from coordinator for its first hop | +| Appears in Z2M, not in HA | `homeassistant: true` missing, or Mosquitto auth failing — check `docker logs zigbee2mqtt` | +| Lamp stuck at full, unresponsive | Triac failed short. Unplug at the wall. Usually means the load exceeded rating — re-measure before replacing | +| Buzzing or humming from the lamp | Normal for phase-cut dimming of big filaments (magnetostriction). Worse at mid-dim. A dimmer pack's choke fixes it; an inline module won't | +| Flicker at low brightness | Raise `min_brightness` | +| Module warm to the touch | Expected. Hot enough to be uncomfortable means it's under-rated for the load | +| Resistance readings that don't reconcile | A parallel path can never *raise* total resistance. If pulling the lamp makes the reading go **down**, the two measurements weren't the same configuration — re-probe both at the lamp terminals | +| Lamp reads open but fixture still conducts | The lamp is blown *and* there's a fan or transformer across the input. Both §1e cases at once — replace the lamp, then re-read §1e before wiring anything |