WiZ (Signify, LAN)
Local JSON-RPC driver for Signify WiZ Wi-Fi smart bulbs, plugs and ceiling fixtures over UDP port 38899. One GEM device row is one bulb. The cloud is bypassed entirely — every command goes directly to the bulb on the LAN.
Prerequisites
- A Wi-Fi-connected WiZ bulb, plug or fixture commissioned in the WiZ mobile app and joined to the same LAN as the GEM controller.
- A reserved DHCP lease (or static IP) for the bulb. WiZ devices do not advertise mDNS by default, so the GEM device row stores an IP, not a host name.
- UDP/38899 reachable from the GEM host to the bulb's IP. Most home IoT VLAN isolation drops outbound UDP/38899 by default — if commands time out, check the firewall first.
- Firmware modern enough to expose
getPilot/setPilot. Every WiZ-branded device shipped since 2018 supports this. Earlier Philips-branded WiZ stock may need a firmware update via the WiZ app.
Setup
- In the WiZ mobile app, open the bulb and note its IP from the device info screen. (Alternatively, look it up in your router's DHCP lease table.)
- Reserve a DHCP lease for that MAC so the IP does not change.
- On the Devices page choose System → Devices → Add Device and pick the driver
wiz_lan:ip— bulb IP from step 1.port— defaults to 38899; leave as-is unless you have a UDP proxy.status_interval— defaults to 30000 ms.
- Save the device. On connect the driver issues
getPilotand folds the result into device attributes (power_state,state,level,color_temp,rgb_hex,scene_id,color_mode). - (Optional) Run
get_scenesto print the WiZ built-in scene table, then useset_scenewith an id to fire dynamic scenes (Sunset = 3, Fireplace = 5, Daylight = 12, etc.).
Device attributes
| Attribute | Required | Description |
|---|---|---|
ip | yes | LAN IP of the WiZ device. |
port | no | UDP port; default 38899 — hardcoded on the bulb, only change for a UDP proxy. |
status_interval | no | getPilot poll cadence in milliseconds; default 30000. |
request_timeout | no | Per-request UDP timeout in milliseconds; default 3000. |
Polled state attributes
Every getPilot poll (and the connect-time read) refreshes these device attributes. Use them for zone/device tiles, attribute triggers, and history:
| Attribute | Type | Meaning |
|---|---|---|
state | string | on / off. |
power_state | string | on / off — written alongside state so power-state triggers fire. |
level | int | Brightness 10..100. |
color_temp | int | Color temperature in Kelvin (meaningful in color-temperature mode). |
rgb_hex | string | Last RGB color as 6-char hex (color mode). |
scene_id | int | Active WiZ scene id (0 = none). |
color_mode | string | Derived hint: scene, color, or ct. |
Zones & control
This driver controls a single bulb at the device level — it does not manage zones itself, so there is nothing to address per zone. Polled state (the attributes above) lands on the device, and you can drive the bulb directly with device commands.
To place the bulb on a UI page with the standard light controls (on/off, dimmer, color, color-temperature), create one zone bound to this device under Zones:
- Subsystem — a default GEM install ships a Lights subsystem (
lights); use it. The driver hintslighting, which does not match the seededlightsname exactly, so the zone editor will not pre-select a subsystem for you — choose Lights yourself (or create alightingsubsystem under Subsystems if you prefer to keep WiZ bulbs separate). - Address — leave blank. One device row equals one bulb. (Multi-bulb groups are managed inside the WiZ app and are not exposed to local control.)
The zone's on/off, brightness, color and color-temperature controls dispatch to the bulb's on / off / set_level / set_color / set_ct commands.
Supported commands
| Command | Args | What it does |
|---|---|---|
on | — | Turn bulb on. |
off | — | Turn bulb off. |
toggle | — | Read current state and flip it (WiZ has no native toggle). |
set_level | level | Brightness 1..100; clamped to 10..100 on the wire (WiZ rejects <10). |
set_ct | ct | Color temperature in Kelvin 2200..6500. |
set_color | color | RGB; accepts "ff8800" (6-char hex) or {r,g,b}. C/W channels are forced to 0. |
set_scene | scene_id | Fire WiZ built-in scene 1..32. |
set_speed | speed | Set dynamic scene speed 0..200. |
get_status | — | getPilot and refresh attributes. |
get_info | — | getSystemConfig (firmware, mac, module name). |
get_scenes | — | Return the WiZ scene-id reference table. |
raw_command | method, params | Send an arbitrary WiZ method; params is a JSON object string. |
Brightness floor
WiZ rejects dimming values below 10. To turn the bulb off use the off command — set_level 0 clamps to 10 and the bulb stays on. (There is no set_state command; off is the off path.)
Known limitations
- No native toggle; the driver emulates by reading state and flipping it (one extra round-trip).
- Plugs (Smart Plug) honor only
state; brightness/color/temp writes are silently ignored by the firmware. - Discovery via UDP broadcast is intentionally not implemented — manually enter the bulb IP.
- The driver does not bind WiZ's push/heartbeat port (UDP 38900), so the
firstBeat/syncPilotdatagrams the bulb broadcasts there are not consumed. External changes (made from the WiZ app or a wall switch) are picked up by the periodicgetPilotpoll instead — within onestatus_interval(default 30 s). - Multi-bulb groups, WiZ Mote remote pairing, on-bulb automation / schedule CRUD are out of scope.
Troubleshooting
Connect succeeds but every command times out — UDP/38899 is being firewalled. Check VLAN/IoT isolation rules between the GEM host and the bulb subnet.
set_level has no effect when the bulb is off — WiZ requires state=on before brightness/color/temp writes take effect. The driver sends state=on alongside brightness writes; if commands still no-op, the firmware is below 1.18 — update via the WiZ app.
set_color works but the white channel stays lit — some WiZ models keep the C/W channels lit alongside RGB at low color saturation. Re-send set_color (it already forces c=0,w=0), or zero them explicitly with raw_command — method setPilot, params {"r":255,"g":136,"b":0,"c":0,"w":0}.
State stops updating after an app interaction — the WiZ app sometimes locks the bulb to push a sequence of updates. Wait 5–10 s; the driver retries on the next poll.
Color temperature out of range error — most WiZ tunable-white bulbs accept 2200..6500 K. Some plain-white SKUs are 2700..6500 K. The driver clamps to 2200..6500 but the bulb may reject the outer edges silently — try 2700..6500 if the lower end no-ops.