%global _empty_manifest_terminate_build 0
Name: python-pywizlight
Version: 0.5.14
Release: 1
Summary: A python connector for WiZ light bulbs (e.g SLV Play)
License: MIT
URL: https://github.com/sbidy/pywizlight
Source0: https://mirrors.nju.edu.cn/pypi/web/packages/e9/7b/c7f4b79e88c0ce565c11f90df6a2a714aa1d8154e615217ea77254b0e240/pywizlight-0.5.14.tar.gz
BuildArch: noarch
Requires: python3-click
%description
![Upload Python Package](https://github.com/sbidy/pywizlight/workflows/Upload%20Python%20Package/badge.svg)
[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-)
![Update Docs](https://github.com/sbidy/pywizlight/workflows/Update%20Docs/badge.svg)
[![Lint](https://github.com/sbidy/pywizlight/actions/workflows/lint.yml/badge.svg)](https://github.com/sbidy/pywizlight/actions/workflows/lint.yml)
[![codecov][code-cover-shield]][code-coverage]
# pywizlight
A Python connector for [WiZ](https://www.wizconnected.com/en/consumer/) devices.
## Install
```bash
pip install pywizlight
```
**Note:** Requires Python version `>=3.7`.
### Fedora/CentOS
On a Fedora-based system or on a CentOS/RHEL 8 machine which has EPEL enabled, as
[`pywizlight`](https://src.fedoraproject.org/rpms/python-pywizlight) is present in the
Fedora Package Collection.
```bash
sudo dnf -y install python3-pywizlight
```
### NixOS
For NixOS and Nix the latest release of `pywizlight` is usually available in the [`unstable`](https://search.nixos.org/packages?channel=unstable&query=pywizlight)
channel. Stable releases might ship older versions of `pywizlight`.
```bash
nix-env -iA nixos.python37Packages.pywizlight
```
## Contributors
## Discover bulbs via CLI
To find bulbs via cli you can use the following:
```bash
python -m pywizlight.cli discover
```
## Example
```python
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("")
#bulb2 = wizlight("")
# --- 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
`wizlight` is a command-line tool to perform basic interactions with bulbs.
```console
$ wizlight
Usage: wizlight [OPTIONS] COMMAND [ARGS]...
Simple command-line tool to interact with Wizlight bulbs.
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
discover Discover bulb in the local network.
off Turn the bulb off.
on Turn the bulb on.
state Get the current state from the given bulb.
```
## 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 32) [List of names in code](https://github.com/sbidy/pywizlight/blob/master/pywizlight/scenes.py)
- **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`.
## 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** - uncertain of purpose
- **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}}`
[code-coverage]: https://codecov.io/gh/sbidy/pywizlight
[code-cover-shield]: https://codecov.io/gh/sbidy/pywizlight/branch/master/graph/badge.svg
%package -n python3-pywizlight
Summary: A python connector for WiZ light bulbs (e.g SLV Play)
Provides: python-pywizlight
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-pip
%description -n python3-pywizlight
![Upload Python Package](https://github.com/sbidy/pywizlight/workflows/Upload%20Python%20Package/badge.svg)
[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-)
![Update Docs](https://github.com/sbidy/pywizlight/workflows/Update%20Docs/badge.svg)
[![Lint](https://github.com/sbidy/pywizlight/actions/workflows/lint.yml/badge.svg)](https://github.com/sbidy/pywizlight/actions/workflows/lint.yml)
[![codecov][code-cover-shield]][code-coverage]
# pywizlight
A Python connector for [WiZ](https://www.wizconnected.com/en/consumer/) devices.
## Install
```bash
pip install pywizlight
```
**Note:** Requires Python version `>=3.7`.
### Fedora/CentOS
On a Fedora-based system or on a CentOS/RHEL 8 machine which has EPEL enabled, as
[`pywizlight`](https://src.fedoraproject.org/rpms/python-pywizlight) is present in the
Fedora Package Collection.
```bash
sudo dnf -y install python3-pywizlight
```
### NixOS
For NixOS and Nix the latest release of `pywizlight` is usually available in the [`unstable`](https://search.nixos.org/packages?channel=unstable&query=pywizlight)
channel. Stable releases might ship older versions of `pywizlight`.
```bash
nix-env -iA nixos.python37Packages.pywizlight
```
## Contributors
## Discover bulbs via CLI
To find bulbs via cli you can use the following:
```bash
python -m pywizlight.cli discover
```
## Example
```python
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("")
#bulb2 = wizlight("")
# --- 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
`wizlight` is a command-line tool to perform basic interactions with bulbs.
```console
$ wizlight
Usage: wizlight [OPTIONS] COMMAND [ARGS]...
Simple command-line tool to interact with Wizlight bulbs.
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
discover Discover bulb in the local network.
off Turn the bulb off.
on Turn the bulb on.
state Get the current state from the given bulb.
```
## 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 32) [List of names in code](https://github.com/sbidy/pywizlight/blob/master/pywizlight/scenes.py)
- **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`.
## 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** - uncertain of purpose
- **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}}`
[code-coverage]: https://codecov.io/gh/sbidy/pywizlight
[code-cover-shield]: https://codecov.io/gh/sbidy/pywizlight/branch/master/graph/badge.svg
%package help
Summary: Development documents and examples for pywizlight
Provides: python3-pywizlight-doc
%description help
![Upload Python Package](https://github.com/sbidy/pywizlight/workflows/Upload%20Python%20Package/badge.svg)
[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-)
![Update Docs](https://github.com/sbidy/pywizlight/workflows/Update%20Docs/badge.svg)
[![Lint](https://github.com/sbidy/pywizlight/actions/workflows/lint.yml/badge.svg)](https://github.com/sbidy/pywizlight/actions/workflows/lint.yml)
[![codecov][code-cover-shield]][code-coverage]
# pywizlight
A Python connector for [WiZ](https://www.wizconnected.com/en/consumer/) devices.
## Install
```bash
pip install pywizlight
```
**Note:** Requires Python version `>=3.7`.
### Fedora/CentOS
On a Fedora-based system or on a CentOS/RHEL 8 machine which has EPEL enabled, as
[`pywizlight`](https://src.fedoraproject.org/rpms/python-pywizlight) is present in the
Fedora Package Collection.
```bash
sudo dnf -y install python3-pywizlight
```
### NixOS
For NixOS and Nix the latest release of `pywizlight` is usually available in the [`unstable`](https://search.nixos.org/packages?channel=unstable&query=pywizlight)
channel. Stable releases might ship older versions of `pywizlight`.
```bash
nix-env -iA nixos.python37Packages.pywizlight
```
## Contributors
## Discover bulbs via CLI
To find bulbs via cli you can use the following:
```bash
python -m pywizlight.cli discover
```
## Example
```python
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("")
#bulb2 = wizlight("")
# --- 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
`wizlight` is a command-line tool to perform basic interactions with bulbs.
```console
$ wizlight
Usage: wizlight [OPTIONS] COMMAND [ARGS]...
Simple command-line tool to interact with Wizlight bulbs.
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
discover Discover bulb in the local network.
off Turn the bulb off.
on Turn the bulb on.
state Get the current state from the given bulb.
```
## 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 32) [List of names in code](https://github.com/sbidy/pywizlight/blob/master/pywizlight/scenes.py)
- **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`.
## 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** - uncertain of purpose
- **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}}`
[code-coverage]: https://codecov.io/gh/sbidy/pywizlight
[code-cover-shield]: https://codecov.io/gh/sbidy/pywizlight/branch/master/graph/badge.svg
%prep
%autosetup -n pywizlight-0.5.14
%build
%py3_build
%install
%py3_install
install -d -m755 %{buildroot}/%{_pkgdocdir}
if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
pushd %{buildroot}
if [ -d usr/lib ]; then
find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/lib64 ]; then
find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/bin ]; then
find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/sbin ]; then
find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
fi
touch doclist.lst
if [ -d usr/share/man ]; then
find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
fi
popd
mv %{buildroot}/filelist.lst .
mv %{buildroot}/doclist.lst .
%files -n python3-pywizlight -f filelist.lst
%dir %{python3_sitelib}/*
%files help -f doclist.lst
%{_docdir}/*
%changelog
* Thu Mar 09 2023 Python_Bot - 0.5.14-1
- Package Spec generated