diff options
author | CoprDistGit <infra@openeuler.org> | 2023-03-09 16:10:32 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-03-09 16:10:32 +0000 |
commit | 7dc2fa9497a81c9d56747ba3ecb7222f51c3d56d (patch) | |
tree | a88674dd1799ebac17469912bba1ed103b365f7a | |
parent | 5fbb3b98a838f545ca36f0317fcf119dd60cb60e (diff) |
automatic import of python-pywizlight
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-pywizlight.spec | 1072 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 1074 insertions, 0 deletions
@@ -0,0 +1 @@ +/pywizlight-0.5.14.tar.gz diff --git a/python-pywizlight.spec b/python-pywizlight.spec new file mode 100644 index 0000000..7ad5be9 --- /dev/null +++ b/python-pywizlight.spec @@ -0,0 +1,1072 @@ +%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 + + +<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> +[](#contributors-) +<!-- ALL-CONTRIBUTORS-BADGE:END --> + + +[](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 + +<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> +<!-- prettier-ignore-start --> +<!-- markdownlint-disable --> +<table> + <tr> + <td align="center"><a href="http://mtnspring.org"><img src="https://avatars.githubusercontent.com/u/223277?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Seth Nickell</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=snickell" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/daanzu"><img src="https://avatars.githubusercontent.com/u/4319503?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Zurow</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=daanzu" title="Documentation">π</a></td> + <td align="center"><a href="https://github.com/eibanez"><img src="https://avatars.githubusercontent.com/u/438494?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eduardo Ibanez</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=eibanez" title="Documentation">π</a></td> + <td align="center"><a href="https://github.com/angadsingh"><img src="https://avatars.githubusercontent.com/u/1623026?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Angad Singh</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=angadsingh" title="Code">π»</a></td> + <td align="center"><a href="http://fabian-affolter.ch/blog/"><img src="https://avatars.githubusercontent.com/u/116184?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fabian Affolter</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=fabaff" title="Documentation">π</a> <a href="https://github.com/sbidy/pywizlight/commits?author=fabaff" title="Code">π»</a></td> + <td align="center"><a href="https://redaxmedia.com"><img src="https://avatars.githubusercontent.com/u/1835397?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Henry Ruhs</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=redaxmedia" title="Code">π»</a></td> + <td align="center"><a href="https://www.panu.it/"><img src="https://avatars.githubusercontent.com/u/2248402?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alberto Panu</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=bigjohnson" title="Code">π»</a></td> + </tr> + <tr> + <td align="center"><a href="https://github.com/skitterrusty"><img src="https://avatars.githubusercontent.com/u/71942600?v=4?s=100" width="100px;" alt=""/><br /><sub><b>skitterrusty</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=skitterrusty" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/mots"><img src="https://avatars.githubusercontent.com/u/26517?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mathias Roth</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=mots" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/durnezj"><img src="https://avatars.githubusercontent.com/u/11504333?v=4?s=100" width="100px;" alt=""/><br /><sub><b>durnezj</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=durnezj" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/Dirty-No"><img src="https://avatars.githubusercontent.com/u/54525684?v=4?s=100" width="100px;" alt=""/><br /><sub><b>NoΓ«lle</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=Dirty-No" title="Documentation">π</a></td> + <td align="center"><a href="https://linkedin.com/in/scriptsrc"><img src="https://avatars.githubusercontent.com/u/8009126?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Patrick Kelley</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=scriptsrc" title="Documentation">π</a></td> + <td align="center"><a href="http://ellismichael.com"><img src="https://avatars.githubusercontent.com/u/1312141?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ellis Michael</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=emichael" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/SvbZ3r0"><img src="https://avatars.githubusercontent.com/u/57280279?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gughan Ravikumar</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=SvbZ3r0" title="Code">π»</a></td> + </tr> + <tr> + <td align="center"><a href="https://github.com/CharlotteCross1998"><img src="https://avatars.githubusercontent.com/u/29734551?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Charlotte</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=CharlotteCross1998" title="Code">π»</a></td> + <td align="center"><a href="https://akx.github.io/"><img src="https://avatars.githubusercontent.com/u/58669?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aarni Koskela</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=akx" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/UH-60"><img src="https://avatars.githubusercontent.com/u/4968133?v=4?s=100" width="100px;" alt=""/><br /><sub><b>UH-60</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=UH-60" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/bdraco"><img src="https://avatars.githubusercontent.com/u/663432?v=4?s=100" width="100px;" alt=""/><br /><sub><b>J. Nick Koston</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=bdraco" title="Code">π»</a></td> + </tr> +</table> + +<!-- markdownlint-restore --> +<!-- prettier-ignore-end --> + +<!-- ALL-CONTRIBUTORS-LIST:END --> + +## 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("<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 + +`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 + + +<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> +[](#contributors-) +<!-- ALL-CONTRIBUTORS-BADGE:END --> + + +[](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 + +<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> +<!-- prettier-ignore-start --> +<!-- markdownlint-disable --> +<table> + <tr> + <td align="center"><a href="http://mtnspring.org"><img src="https://avatars.githubusercontent.com/u/223277?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Seth Nickell</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=snickell" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/daanzu"><img src="https://avatars.githubusercontent.com/u/4319503?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Zurow</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=daanzu" title="Documentation">π</a></td> + <td align="center"><a href="https://github.com/eibanez"><img src="https://avatars.githubusercontent.com/u/438494?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eduardo Ibanez</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=eibanez" title="Documentation">π</a></td> + <td align="center"><a href="https://github.com/angadsingh"><img src="https://avatars.githubusercontent.com/u/1623026?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Angad Singh</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=angadsingh" title="Code">π»</a></td> + <td align="center"><a href="http://fabian-affolter.ch/blog/"><img src="https://avatars.githubusercontent.com/u/116184?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fabian Affolter</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=fabaff" title="Documentation">π</a> <a href="https://github.com/sbidy/pywizlight/commits?author=fabaff" title="Code">π»</a></td> + <td align="center"><a href="https://redaxmedia.com"><img src="https://avatars.githubusercontent.com/u/1835397?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Henry Ruhs</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=redaxmedia" title="Code">π»</a></td> + <td align="center"><a href="https://www.panu.it/"><img src="https://avatars.githubusercontent.com/u/2248402?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alberto Panu</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=bigjohnson" title="Code">π»</a></td> + </tr> + <tr> + <td align="center"><a href="https://github.com/skitterrusty"><img src="https://avatars.githubusercontent.com/u/71942600?v=4?s=100" width="100px;" alt=""/><br /><sub><b>skitterrusty</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=skitterrusty" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/mots"><img src="https://avatars.githubusercontent.com/u/26517?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mathias Roth</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=mots" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/durnezj"><img src="https://avatars.githubusercontent.com/u/11504333?v=4?s=100" width="100px;" alt=""/><br /><sub><b>durnezj</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=durnezj" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/Dirty-No"><img src="https://avatars.githubusercontent.com/u/54525684?v=4?s=100" width="100px;" alt=""/><br /><sub><b>NoΓ«lle</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=Dirty-No" title="Documentation">π</a></td> + <td align="center"><a href="https://linkedin.com/in/scriptsrc"><img src="https://avatars.githubusercontent.com/u/8009126?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Patrick Kelley</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=scriptsrc" title="Documentation">π</a></td> + <td align="center"><a href="http://ellismichael.com"><img src="https://avatars.githubusercontent.com/u/1312141?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ellis Michael</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=emichael" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/SvbZ3r0"><img src="https://avatars.githubusercontent.com/u/57280279?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gughan Ravikumar</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=SvbZ3r0" title="Code">π»</a></td> + </tr> + <tr> + <td align="center"><a href="https://github.com/CharlotteCross1998"><img src="https://avatars.githubusercontent.com/u/29734551?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Charlotte</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=CharlotteCross1998" title="Code">π»</a></td> + <td align="center"><a href="https://akx.github.io/"><img src="https://avatars.githubusercontent.com/u/58669?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aarni Koskela</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=akx" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/UH-60"><img src="https://avatars.githubusercontent.com/u/4968133?v=4?s=100" width="100px;" alt=""/><br /><sub><b>UH-60</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=UH-60" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/bdraco"><img src="https://avatars.githubusercontent.com/u/663432?v=4?s=100" width="100px;" alt=""/><br /><sub><b>J. Nick Koston</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=bdraco" title="Code">π»</a></td> + </tr> +</table> + +<!-- markdownlint-restore --> +<!-- prettier-ignore-end --> + +<!-- ALL-CONTRIBUTORS-LIST:END --> + +## 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("<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 + +`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 + + +<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> +[](#contributors-) +<!-- ALL-CONTRIBUTORS-BADGE:END --> + + +[](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 + +<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> +<!-- prettier-ignore-start --> +<!-- markdownlint-disable --> +<table> + <tr> + <td align="center"><a href="http://mtnspring.org"><img src="https://avatars.githubusercontent.com/u/223277?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Seth Nickell</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=snickell" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/daanzu"><img src="https://avatars.githubusercontent.com/u/4319503?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Zurow</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=daanzu" title="Documentation">π</a></td> + <td align="center"><a href="https://github.com/eibanez"><img src="https://avatars.githubusercontent.com/u/438494?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eduardo Ibanez</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=eibanez" title="Documentation">π</a></td> + <td align="center"><a href="https://github.com/angadsingh"><img src="https://avatars.githubusercontent.com/u/1623026?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Angad Singh</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=angadsingh" title="Code">π»</a></td> + <td align="center"><a href="http://fabian-affolter.ch/blog/"><img src="https://avatars.githubusercontent.com/u/116184?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fabian Affolter</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=fabaff" title="Documentation">π</a> <a href="https://github.com/sbidy/pywizlight/commits?author=fabaff" title="Code">π»</a></td> + <td align="center"><a href="https://redaxmedia.com"><img src="https://avatars.githubusercontent.com/u/1835397?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Henry Ruhs</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=redaxmedia" title="Code">π»</a></td> + <td align="center"><a href="https://www.panu.it/"><img src="https://avatars.githubusercontent.com/u/2248402?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alberto Panu</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=bigjohnson" title="Code">π»</a></td> + </tr> + <tr> + <td align="center"><a href="https://github.com/skitterrusty"><img src="https://avatars.githubusercontent.com/u/71942600?v=4?s=100" width="100px;" alt=""/><br /><sub><b>skitterrusty</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=skitterrusty" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/mots"><img src="https://avatars.githubusercontent.com/u/26517?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mathias Roth</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=mots" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/durnezj"><img src="https://avatars.githubusercontent.com/u/11504333?v=4?s=100" width="100px;" alt=""/><br /><sub><b>durnezj</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=durnezj" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/Dirty-No"><img src="https://avatars.githubusercontent.com/u/54525684?v=4?s=100" width="100px;" alt=""/><br /><sub><b>NoΓ«lle</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=Dirty-No" title="Documentation">π</a></td> + <td align="center"><a href="https://linkedin.com/in/scriptsrc"><img src="https://avatars.githubusercontent.com/u/8009126?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Patrick Kelley</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=scriptsrc" title="Documentation">π</a></td> + <td align="center"><a href="http://ellismichael.com"><img src="https://avatars.githubusercontent.com/u/1312141?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ellis Michael</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=emichael" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/SvbZ3r0"><img src="https://avatars.githubusercontent.com/u/57280279?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gughan Ravikumar</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=SvbZ3r0" title="Code">π»</a></td> + </tr> + <tr> + <td align="center"><a href="https://github.com/CharlotteCross1998"><img src="https://avatars.githubusercontent.com/u/29734551?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Charlotte</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=CharlotteCross1998" title="Code">π»</a></td> + <td align="center"><a href="https://akx.github.io/"><img src="https://avatars.githubusercontent.com/u/58669?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aarni Koskela</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=akx" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/UH-60"><img src="https://avatars.githubusercontent.com/u/4968133?v=4?s=100" width="100px;" alt=""/><br /><sub><b>UH-60</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=UH-60" title="Code">π»</a></td> + <td align="center"><a href="https://github.com/bdraco"><img src="https://avatars.githubusercontent.com/u/663432?v=4?s=100" width="100px;" alt=""/><br /><sub><b>J. Nick Koston</b></sub></a><br /><a href="https://github.com/sbidy/pywizlight/commits?author=bdraco" title="Code">π»</a></td> + </tr> +</table> + +<!-- markdownlint-restore --> +<!-- prettier-ignore-end --> + +<!-- ALL-CONTRIBUTORS-LIST:END --> + +## 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("<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 + +`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 <Python_Bot@openeuler.org> - 0.5.14-1 +- Package Spec generated @@ -0,0 +1 @@ +e9a773920864a91b4369c96dee167aa6 pywizlight-0.5.14.tar.gz |