Adds support for WiZ Connected (Philips' budget-tier) smart bulbs that
accept JSON commands as UDP datagrams on port 38899 with broadcast LAN
discovery on 255.255.255.255:38899.
Backend:
- WiZClient is a single-pixel UDP adapter: averages the incoming strip
to one RGB triple and pushes it via setPilot with r/g/b params.
Brightness folds into the RGB scaling so we burn one packet per frame
instead of two.
- UDP fire-and-forget tolerates high update rates with no ack overhead,
so the default rate gate is 50 ms (~20 Hz) -- 10x faster than Yeelight.
- supports_fast_send=True with a synchronous send_pixels_fast hot path.
- Broadcast discovery sends the standard registration envelope; bulb
replies are parsed for IP+MAC and surfaced as DiscoveredDevice
entries. Broadcast failures (no network, firewall) yield [] rather
than raising.
- Health check sends getPilot and waits 1.5s for any reply on a
one-shot UDP socket.
- WiZConfig joins the typed config union; Device storage gains a
wiz_min_interval_ms field; full to_dict/from_dict/to_config wiring.
- 36 unit tests cover URL parsing, MAC extraction, strip averaging,
rate limiting, fast-send hot path, provider validate/discover/health,
and Device.to_config round-trip.
Frontend:
- 'wiz' in DEVICE_TYPE_KEYS (next to 'yeelight'), lightbulb icon
(deliberate smart-bulb family grouping with Hue + Yeelight).
- isWizDevice predicate + per-type field show/hide in create and
settings modals.
- Rate-limit number input (default 50 ms) in both modals with hint
text noting the UDP fire-and-forget characteristic.
- Locale strings in en/ru/zh.
WiZ bulbs are reachable from the existing "Scan network" button -- no
new discovery UI affordance was needed.