pywizlight
A Python connector for WiZ devices.
Wiz Ligt API Documentation
https://docs.pro.wizconnected.com/#introduction
Install
pip install pywizlight
Note: Requires Python version >=3.11.
Fedora/CentOS
On a Fedora-based system or on a CentOS/RHEL 8 machine which has EPEL enabled, as
pywizlight is present in the
Fedora Package Collection.
sudo dnf -y install python3-pywizlight
NixOS
For NixOS and Nix the latest release of pywizlight is usually available in the unstable
channel. Stable releases might ship older versions of pywizlight.
nix-env -iA nixos.python37Packages.pywizlight
Contributors
CLI Usage
pywizlight includes a command-line interface for easy bulb control:
# Discover bulbs (uses 192.168.1.255 by default)
python -m pywizlight.cli discover
# Discover with custom broadcast address
python -m pywizlight.cli discover --broadcast 192.168.0.255
# Turn bulb on (full brightness)
python -m pywizlight.cli on 192.168.1.10
# Turn on with specific brightness and color temperature
python -m pywizlight.cli on 192.168.1.10 --brightness 128 --kelvin 3000
# Set RGB color
python -m pywizlight.cli color 192.168.1.10 255,0,0 # Red
# Set predefined scene
python -m pywizlight.cli scene 192.168.1.10 4 # Party scene
# Adjust brightness only
python -m pywizlight.cli brightness 192.168.1.10 128
# Turn bulb off
python -m pywizlight.cli off 192.168.1.10
# Get bulb status
python -m pywizlight.cli status 192.168.1.10
Available Commands
discover- Find bulbs on the networkon- Turn bulb on with optional settings (brightness, color temp, RGB, scene)off- Turn bulb offcolor- Set RGB colorscene- Set predefined scene (1-35)brightness- Set brightness level (0-255)status- Get current bulb state
Use --help with any command for detailed options:
python -m pywizlight.cli on --help
Example
import asyncio
from pywizlight import wizlight, PilotBuilder, discovery
async def main():
"""Sample code to work with bulbs."""
# Discover all bulbs in the network via broadcast datagram (UDP)
# function takes the discovery object and returns a list of wizlight objects.
bulbs = await discovery.discover_lights(broadcast_space="192.168.1.255")
# Print the IP address of the bulb on index 0
print(f"Bulb IP address: {bulbs[0].ip}")
# Iterate over all returned bulbs
for bulb in bulbs:
print(bulb.__dict__)
# Turn off all available bulbs
# await bulb.turn_off()
# Set up a standard light
light = wizlight("192.168.1.27")
# Set up the light with a custom port
#light = wizlight("your bulb's IP address", port=12345)
# The following calls need to be done inside an asyncio coroutine
# to run them from normal synchronous code, you can wrap them with
# asyncio.run(..).
# Turn the light on into "rhythm mode"
await light.turn_on(PilotBuilder())
# Set bulb brightness
await light.turn_on(PilotBuilder(brightness = 255))
# Set bulb brightness (with async timeout)
timeout = 10
await asyncio.wait_for(light.turn_on(PilotBuilder(brightness = 255)), timeout)
# Set bulb to warm white
await light.turn_on(PilotBuilder(warm_white = 255))
# Set RGB values
# red to 0 = 0%, green to 128 = 50%, blue to 255 = 100%
await light.turn_on(PilotBuilder(rgb = (0, 128, 255)))
# Get the current color temperature, RGB values
state = await light.updateState()
print(state.get_colortemp())
red, green, blue = state.get_rgb()
print(f"red {red}, green {green}, blue {blue}")
# Start a scene
await light.turn_on(PilotBuilder(scene = 4)) # party
# Get the name of the current scene
state = await light.updateState()
print(state.get_scene())
# Get the features of the bulb
bulb_type = await bulbs[0].get_bulbtype()
print(bulb_type.features.brightness) # returns True if brightness is supported
print(bulb_type.features.color) # returns True if color is supported
print(bulb_type.features.color_tmp) # returns True if color temperatures are supported
print(bulb_type.features.effect) # returns True if effects are supported
print(bulb_type.kelvin_range.max) # returns max kelvin in INT
print(bulb_type.kelvin_range.min) # returns min kelvin in INT
print(bulb_type.name) # returns the module name of the bulb
# Turn the light off
await light.turn_off()
# Do operations on multiple lights in parallel
#bulb1 = wizlight("<your bulb1 ip>")
#bulb2 = wizlight("<your bulb2 ip>")
# --- DEPRECATED in 3.10 see [#140](https://github.com/sbidy/pywizlight/issues/140)
# await asyncio.gather(bulb1.turn_on(PilotBuilder(brightness = 255)),
# bulb2.turn_on(PilotBuilder(warm_white = 255)))
# --- For >3.10 await asyncio.gather() from another coroutine
# async def turn_bulbs_on(bulb1, bulb2):
# await asyncio.gather(bulb1.turn_on(PilotBuilder(warm_white=255)), bulb2.turn_on(PilotBuilder(warm_white=255)))
# def main:
# asyncio.run(async turn_bulbs_on(bulb1, bulb2))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
CLI Reference
The CLI provides intuitive commands for bulb control:
$ python -m pywizlight.cli --help
Usage: cli.py [OPTIONS] COMMAND [ARGS]...
Command-line tool to interact with Wizlight bulbs.
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
brightness Set bulb brightness (0-255).
color Set bulb to RGB color (format: 'r,g,b' e.g., '255,0,0').
discover Discover bulbs in the local network.
off Turn bulb off.
on Turn bulb on with optional color/brightness settings.
scene Set bulb to a predefined scene (1-35).
status Get bulb status and current settings.
Updated Examples
# Discover bulbs with default broadcast
$ python -m pywizlight.cli discover
Searching for bulbs on 192.168.1.255...
Found 2 bulb(s):
IP: 192.168.1.10, MAC: a8bb50a4f94d
IP: 192.168.1.11, MAC: a8bb50a4f95e
# Turn on bulb with warm white
$ python -m pywizlight.cli on 192.168.1.10 --kelvin 3000 --brightness 200
✓ Turned on 192.168.1.10
# Set RGB color
$ python -m pywizlight.cli color 192.168.1.10 255,0,0
✓ Set 192.168.1.10 to RGB(255,0,0)
# Get detailed status
$ python -m pywizlight.cli status 192.168.1.10
Bulb 192.168.1.10 status:
Power: ON
Brightness: 200
Color Temp: 3000K
Run python -m pywizlight.cli COMMAND --help for detailed command options.
Discovery
The discovery works with a UDP Broadcast request and collects all bulbs in the network.
Bulb paramters (UDP RAW)
- sceneId - calls one of the predefined scenes (int from 1 to 35) List of names in code
- speed - sets the color changing speed in percent
- dimming - sets the dimmer of the bulb in percent
- temp - sets the color temperature in kelvins
- r - red color range 0-255
- g - green color range 0-255
- b - blue color range 0-255
- c - cold white range 0-255
- w - warm white range 0-255
- id - the bulb id
- state - whether it's on or off
- schdPsetId - rhythm id of the room
Async I/O
For async I/O this component uses Python's built-in asyncio DatagramTransport, which allows completely non-blocking UDP transport.
Classes
wizlight(ip): Creates an instance of a WiZ Light Bulb. Constructed with the IP addCancel changesress of the bulb.
Instance variables
First you need to fetch the state by calling light.updateState().
After that all states can be fetched from light.state, which is a PilotParser object.
PilotParser.get_brightness()gets the value of the brightness 0-255
PilotParser.get_rgb() gets the rgbW color state of the bulb
PilotParser.get_colortemp() gets the color temperature of the bulb
PilotParser.get_warm_white/get_cold_white() gets the current warm/cold setting (not supported by original Philips Wiz bulbs)
PilotParser.get_scene() gets the current scene name
PilotParser.get_state() returns True/False. True = on, False = off
Methods
getBulbConfig(self) returns the hardware configuration of the bulb
updateState(self) gets the current bulb state from the light using sendUDPMessage and sets it to self.state
lightSwitch(self) toggles the light bulb on or off like a switch
getMAC(self) returns the MAC address of the bulb. Can be used as a unique ID
sendUDPMessage(self, message, timeout = 60, send_interval = 0.5, max_send_datagrams = 100): sends the UDP message to the bulb. Since UDP can lose packets, and your light might be a long distance away from the router, we continuously keep sending the UDP command datagram until there is a response from the bulb. In tests this worked way better than just sending once and waiting for a timeout. You can set the async operation timeout using timeout, set the time interval to sleep between continuous UDP sends using send_interval and the maximum number of continuous pings to send using max_send_datagrams. It is already hardcoded to a lower value for setPilot (set light state) vs getPilot (fetch light state) to avoid flickering the light.
turn_off(self) turns the light off
turn_on(PilotBuilder) turns the light on. This takes a PilotBuilder object, which can be used to set all the parameters programmatically - rgb, color temperature, brightness, etc. To set the light to rhythm mode, create an empty PilotBuilder.
get_power(self) returns the current power consumption of a Smart Plug with Metering.
Bulb methods (UDP native):
- getSystemConfig - gets the current system configuration - no parameters required
- syncPilot - sent by the bulb as heartbeats
- getPilot - gets the current bulb state - no parameters required
- setPilot - used to tell the bulb to change color/temp/state
- Pulse - Gradually fades the current light state in or out based on the delta value (+/- 1–100) and a specified duration (in ms). If the duration is set longer than 2 minutes, the pulsing effect will loop continuously
- Registration - used to "register" with the bulb: This notifies the bulb if you want it to send you heartbeat sync packets
Sync functions:
- syncUserConfig
- syncPilot - {"method":"syncPilot","env":"pro","params":{"mac":"ABCABCABC","rssi":-71,"src":"udp","state":true,"sceneId":0,"temp":6500,"dimming":62}}
- syncSchdPset
- syncBroadcastPilot
- syncSystemConfig
- syncConfig
- syncAlarm
Set functions:
- pulse - {"method":"pulse", "params":{"delta":-15,"duration":300}}
- registration - {"method":"registration","id":105, "params":{"phoneIp":"10.0.0.0","phoneMac":"aaaaaaaaaaaa","register":true}}
- setUserConfig
- setSystemConfig
- setDevInfo
- setSchd
- setSchdPset
- setWifiConfig
- reset
- setFavs
- setState
- setPilot
Get functions
- getPilot
- getUserConfig
- getSystemConfig
- getWifiConfig
- reboot
- getDevInfo
Error States and Returns
- Parse error
- Invalid Request
- Method not found
- Invalid params
- Internal error
- Success
Example UDP requests
Send message to the bulb:
{"method":"setPilot","params":{"r":255,"g":255,"b":255,"dimming":50}}
Response: {"method":"setPilot","env":"pro","result":{"success":true}}
Get state of the bulb:
{"method":"getPilot","params":{}}
Responses:
custom color mode:
{'method': 'getPilot', 'env': 'pro', 'result': {'mac': 'a8bb50a4f94d', 'rssi': -60, 'src': '', 'state': True, 'sceneId': 0, 'temp': 5075, 'dimming': 47}}
scene mode:
{'method': 'getPilot', 'env': 'pro', 'result': {'mac': 'a8bb50a4f94d', 'rssi': -65, 'src': '', 'state': True, 'sceneId': 12, 'speed': 100, 'temp': 4200, 'dimming': 47}}
rhythm mode:
{'method': 'getPilot', 'env': 'pro', 'result': {'mac': 'a8bb50a4f94d', 'rssi': -63, 'src': '', 'state': True, 'sceneId': 14, 'speed': 100, 'dimming': 100, 'schdPsetId': 9}}
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pywizlight-0.6.6.tar.gz.
File metadata
- Download URL: pywizlight-0.6.6.tar.gz
- Upload date:
- Size: 48.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6c57ee128a5867548181ae9b0a0d8b4333863734a7f80375d42fcda97293100
|
|
| MD5 |
64050a8cb52fa0960206e3128fc68f62
|
|
| BLAKE2b-256 |
791a974d1313525cd7098ab4a14efb2420a3e64a26f71366abd778bc64d7c010
|
Provenance
The following attestation bundles were made for pywizlight-0.6.6.tar.gz:
Publisher:
pythonpublish.yml on sbidy/pywizlight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pywizlight-0.6.6.tar.gz -
Subject digest:
b6c57ee128a5867548181ae9b0a0d8b4333863734a7f80375d42fcda97293100 - Sigstore transparency entry: 2343509718
- Sigstore integration time:
-
Permalink:
sbidy/pywizlight@c6ce9d97677aab1da3a693973fb3487383f5d235 -
Branch / Tag:
refs/tags/v0.6.6 - Owner: https://github.com/sbidy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pythonpublish.yml@c6ce9d97677aab1da3a693973fb3487383f5d235 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pywizlight-0.6.6-py3-none-any.whl.
File metadata
- Download URL: pywizlight-0.6.6-py3-none-any.whl
- Upload date:
- Size: 64.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71afd52e1c60ab1002afea9068d3c41243d792c3f824b0eb74f2a3f0fdd96d04
|
|
| MD5 |
6c61624f65f7516de702fd70557d62f2
|
|
| BLAKE2b-256 |
7163eb4a4d70539f934a46ae85285a890ef6e9ec3731cf192582a27d725ed5ac
|
Provenance
The following attestation bundles were made for pywizlight-0.6.6-py3-none-any.whl:
Publisher:
pythonpublish.yml on sbidy/pywizlight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pywizlight-0.6.6-py3-none-any.whl -
Subject digest:
71afd52e1c60ab1002afea9068d3c41243d792c3f824b0eb74f2a3f0fdd96d04 - Sigstore transparency entry: 2343509727
- Sigstore integration time:
-
Permalink:
sbidy/pywizlight@c6ce9d97677aab1da3a693973fb3487383f5d235 -
Branch / Tag:
refs/tags/v0.6.6 - Owner: https://github.com/sbidy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pythonpublish.yml@c6ce9d97677aab1da3a693973fb3487383f5d235 -
Trigger Event:
release
-
Statement type: