phue2 0.0.1.dev279__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. phue2-0.0.1.dev279/.github/workflows/lint.yml +36 -0
  2. phue2-0.0.1.dev279/.github/workflows/publish.yml +26 -0
  3. phue2-0.0.1.dev279/.github/workflows/test.yml +55 -0
  4. phue2-0.0.1.dev279/.gitignore +11 -0
  5. phue2-0.0.1.dev279/.pre-commit-config.yaml +22 -0
  6. phue2-0.0.1.dev279/LICENSE +21 -0
  7. phue2-0.0.1.dev279/PKG-INFO +188 -0
  8. phue2-0.0.1.dev279/README.md +177 -0
  9. phue2-0.0.1.dev279/examples/connect_bridge.py +101 -0
  10. phue2-0.0.1.dev279/examples/flicker.py +54 -0
  11. phue2-0.0.1.dev279/examples/hue-rainbow.py +40 -0
  12. phue2-0.0.1.dev279/examples/random_colors.py +18 -0
  13. phue2-0.0.1.dev279/examples/rgb_colors.py +62 -0
  14. phue2-0.0.1.dev279/examples/sine_wave_lights.py +127 -0
  15. phue2-0.0.1.dev279/examples/tk_gui_complex.py +71 -0
  16. phue2-0.0.1.dev279/examples/tk_gui_hsb.py +119 -0
  17. phue2-0.0.1.dev279/examples/tk_gui_simple.py +33 -0
  18. phue2-0.0.1.dev279/justfile +9 -0
  19. phue2-0.0.1.dev279/pyproject.toml +75 -0
  20. phue2-0.0.1.dev279/src/phue2/__init__.py +37 -0
  21. phue2-0.0.1.dev279/src/phue2/__main__.py +408 -0
  22. phue2-0.0.1.dev279/src/phue2/_internal/__init__.py +1 -0
  23. phue2-0.0.1.dev279/src/phue2/_internal/console.py +175 -0
  24. phue2-0.0.1.dev279/src/phue2/bridge.py +1246 -0
  25. phue2-0.0.1.dev279/src/phue2/exceptions.py +22 -0
  26. phue2-0.0.1.dev279/src/phue2/group.py +118 -0
  27. phue2-0.0.1.dev279/src/phue2/light.py +301 -0
  28. phue2-0.0.1.dev279/src/phue2/scene.py +58 -0
  29. phue2-0.0.1.dev279/src/phue2/sensor.py +307 -0
  30. phue2-0.0.1.dev279/tests/__init__.py +0 -0
  31. phue2-0.0.1.dev279/tests/samples.py +268 -0
  32. phue2-0.0.1.dev279/tests/test_basic_import.py +7 -0
  33. phue2-0.0.1.dev279/tests/test_bridge.py +92 -0
  34. phue2-0.0.1.dev279/tests/test_cli.py +168 -0
  35. phue2-0.0.1.dev279/tests/test_request.py +103 -0
  36. phue2-0.0.1.dev279/uv.lock +1052 -0
@@ -0,0 +1,36 @@
1
+ name: Lint
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ lint:
11
+ name: Lint
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Install uv
17
+ uses: astral-sh/setup-uv@v5
18
+ with:
19
+ enable-cache: true
20
+ version: "0.6.11"
21
+
22
+ - name: Install just
23
+ uses: extractions/setup-just@v2
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version-file: "pyproject.toml"
29
+
30
+ - name: Install dependencies
31
+ run: uv sync
32
+
33
+ - name: Run pre-commit
34
+ uses: pre-commit/action@v3.0.1
35
+ with:
36
+ extra_args: --all-files
@@ -0,0 +1,26 @@
1
+ name: Publish phue2 to PyPI
2
+ on:
3
+ release:
4
+ types: [published]
5
+ workflow_dispatch:
6
+
7
+ jobs:
8
+ pypi-publish:
9
+ name: Upload to PyPI
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write
13
+ steps:
14
+ - name: Checkout
15
+ uses: actions/checkout@v4
16
+ with:
17
+ fetch-depth: 0
18
+
19
+ - name: "Install uv"
20
+ uses: astral-sh/setup-uv@v3
21
+
22
+ - name: Build
23
+ run: uv build --no-cache
24
+
25
+ - name: Publish to PyPi
26
+ run: uv publish -v dist/* --token ${{ secrets.UV_PUBLISH_TOKEN }}
@@ -0,0 +1,55 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ paths:
7
+ - "src/**/*.py"
8
+ - "tests/**/*.py"
9
+ - "pyproject.toml"
10
+ - ".github/workflows/test.yml"
11
+ pull_request:
12
+ branches: [ master ]
13
+ paths:
14
+ - "src/**/*.py"
15
+ - "tests/**/*.py"
16
+ - "pyproject.toml"
17
+ - ".github/workflows/test.yml"
18
+
19
+ env:
20
+ # Enable colored output
21
+ PY_COLORS: 1
22
+
23
+ jobs:
24
+ test:
25
+ name: ${{ matrix.os }} - python:${{ matrix.python-version }}
26
+ runs-on: ${{ matrix.os }}
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ os: [ubuntu-latest, macos-latest]
31
+ python-version: ["3.10", "3.13"]
32
+
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+
36
+ - name: Install uv
37
+ uses: astral-sh/setup-uv@v5
38
+ with:
39
+ enable-cache: true
40
+ version: "0.6.11"
41
+ python-version: ${{ matrix.python-version }}
42
+
43
+ - name: Install just
44
+ uses: extractions/setup-just@v2
45
+ with:
46
+ github-token: ${{ secrets.GITHUB_TOKEN }}
47
+
48
+ - name: Install dependencies
49
+ run: uv sync
50
+
51
+ - name: Build
52
+ run: just build
53
+
54
+ - name: Run tests
55
+ run: just test
@@ -0,0 +1,11 @@
1
+ *.pyc
2
+ *~
3
+ *.swp
4
+ test.py
5
+ *.DS_Store
6
+ dist
7
+ MANIFEST
8
+ __pycache__
9
+ .pytest_cache
10
+ .vscode
11
+ .env
@@ -0,0 +1,22 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/uv-pre-commit
3
+ # uv version.
4
+ rev: 0.6.11
5
+ hooks:
6
+ - id: uv-lock
7
+ - repo: https://github.com/astral-sh/ruff-pre-commit
8
+ # Ruff version.
9
+ rev: v0.9.1
10
+ hooks:
11
+ # Run the linter.
12
+ - id: ruff
13
+ args: [--fix]
14
+ # Run the formatter.
15
+ - id: ruff-format
16
+ - repo: local
17
+ hooks:
18
+ - id: typecheck
19
+ name: typecheck
20
+ entry: just typecheck
21
+ language: system
22
+ pass_filenames: false
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Nathan Nowack
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,188 @@
1
+ Metadata-Version: 2.4
2
+ Name: phue2
3
+ Version: 0.0.1.dev279
4
+ Summary: A Philips Hue Python library
5
+ Author: Nathanaël Lécaudé, Nathan Nowack
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: httpx
10
+ Description-Content-Type: text/markdown
11
+
12
+ # phue2
13
+
14
+ modern Python library to control the Philips Hue lighting system
15
+
16
+ This is a fork of the original [phue library](https://github.com/studioimaginaire/phue) by Nathanaël Lécaudé, modernized with type annotations, improved error handling, and a fully-featured CLI. The library remains MIT licensed.
17
+
18
+ > [!IMPORTANT]
19
+
20
+ > I appreciate the original authors work and if there's any interest in merging these (substantial) changes back into the original library, I'm happy to do so.
21
+
22
+ ## Installation
23
+
24
+ ### Using uv
25
+
26
+ ```bash
27
+ uv add phue2
28
+
29
+ uv pip install phue2
30
+ ```
31
+
32
+ ### Using pip
33
+
34
+ ```bash
35
+ pip install phue2
36
+ ```
37
+
38
+ ## Repository Structure
39
+
40
+ ```
41
+ .
42
+ ├── LICENSE
43
+ ├── README.md
44
+ ├── examples/
45
+ ├── src/
46
+ │ └── phue/
47
+ │ ├── __init__.py
48
+ │ ├── __main__.py # CLI interface
49
+ │ ├── bridge.py # Bridge connection handling
50
+ │ ├── exceptions.py # Custom exceptions
51
+ │ ├── group.py # Group controls
52
+ │ ├── light.py # Light controls
53
+ │ ├── scene.py # Scene handling
54
+ │ └── sensor.py # Sensor controls
55
+ └── tests/ # Tests
56
+ ```
57
+
58
+ ## Requirements
59
+
60
+ - Python 3.10 or higher (not compatible with Python 2.x)
61
+ - httpx (for network requests)
62
+
63
+ ## Features
64
+
65
+ - Fully typed with Python type annotations
66
+ - Robust error handling with custom exceptions
67
+ - Comprehensive test suite
68
+ - Colorful, user-friendly command-line interface
69
+ - Support for Lights, Groups, Scenes, and Sensors
70
+ - Auto-discovery of Hue bridges on the network
71
+ - Simple and intuitive API for controlling Hue devices
72
+
73
+
74
+
75
+ ## Command Line Usage
76
+
77
+ The library includes a command-line interface for controlling your Hue lights:
78
+
79
+ ```bash
80
+ # List all lights
81
+ phue ls
82
+
83
+ # Get details about a specific light
84
+ phue get light "Living Room"
85
+
86
+ # Turn on a light and set brightness
87
+ phue set light "Kitchen" --on --bri 200
88
+
89
+ # List all groups
90
+ phue ls groups
91
+
92
+ # Turn off lights in a group
93
+ phue set group "Downstairs" --off
94
+ ```
95
+
96
+ ## Basic Usage
97
+
98
+ Using the set_light and get_light methods you can control pretty much all the parameters:
99
+
100
+ ```python
101
+ from phue2 import Bridge
102
+
103
+ # Connect to the bridge
104
+ b = Bridge('192.168.1.100')
105
+
106
+ # If the app is not registered and the button is not pressed, press the button and call connect()
107
+ # This only needs to be run a single time
108
+ b.connect()
109
+
110
+ # Get the bridge state (This returns the full dictionary that you can explore)
111
+ b.get_api()
112
+
113
+ # Prints if light 1 is on or not
114
+ b.get_light(1, 'on')
115
+
116
+ # Set brightness of lamp 1 to max
117
+ b.set_light(1, 'bri', 254)
118
+
119
+ # Turn lamp 2 on
120
+ b.set_light(2, 'on', True)
121
+
122
+ # You can also control multiple lamps by sending a list as lamp_id
123
+ b.set_light([1, 2], 'on', True)
124
+
125
+ # You can also use light names instead of the id
126
+ b.get_light('Kitchen')
127
+ b.set_light('Kitchen', 'bri', 254)
128
+
129
+ # Also works with lists
130
+ b.set_light(['Bathroom', 'Garage'], 'on', False)
131
+ ```
132
+
133
+ ### Light Objects
134
+
135
+ If you want to work in a more object-oriented way, you can get Light objects:
136
+
137
+ ```python
138
+ # Get a flat list of light objects
139
+ lights = b.lights
140
+
141
+ # Print light names
142
+ for light in lights:
143
+ print(light.name)
144
+
145
+ # Set brightness of each light to 127
146
+ for light in lights:
147
+ light.brightness = 127
148
+
149
+ # Get a dictionary with the light name as the key
150
+ light_names = b.get_light_objects('name')
151
+
152
+ # Set lights using name as key
153
+ for light_name in ['Kitchen', 'Bedroom', 'Garage']:
154
+ light = light_names.get(light_name)
155
+ if light:
156
+ light.on = True
157
+ light.hue = 15000
158
+ light.saturation = 120
159
+ ```
160
+
161
+ ## Error Handling
162
+
163
+ The library provides custom exceptions for better error handling:
164
+
165
+ ```python
166
+ from phue2 import Bridge, PhueRegistrationException, PhueRequestTimeout
167
+
168
+ try:
169
+ b = Bridge('192.168.1.100')
170
+ b.connect()
171
+ except PhueRegistrationException:
172
+ print("Press the button on the bridge and try again")
173
+ except PhueRequestTimeout:
174
+ print("Could not connect to the bridge - check your network")
175
+ ```
176
+
177
+ ## Acknowledgments
178
+
179
+ This project is a fork of the original [phue](https://github.com/studioimaginaire/phue) library created by Nathanaël Lécaudé.
180
+
181
+ The modernized version was created by [zzstoatzz](https://github.com/zzstoatzz) to add type annotations and a more opinionated CLI.
182
+
183
+ ## License
184
+
185
+ MIT - http://opensource.org/licenses/MIT
186
+
187
+ "Hue Personal Wireless Lighting" is a trademark owned by Koninklijke Philips Electronics N.V., see www.meethue.com for more information.
188
+ I am in no way affiliated with the Philips organization.
@@ -0,0 +1,177 @@
1
+ # phue2
2
+
3
+ modern Python library to control the Philips Hue lighting system
4
+
5
+ This is a fork of the original [phue library](https://github.com/studioimaginaire/phue) by Nathanaël Lécaudé, modernized with type annotations, improved error handling, and a fully-featured CLI. The library remains MIT licensed.
6
+
7
+ > [!IMPORTANT]
8
+
9
+ > I appreciate the original authors work and if there's any interest in merging these (substantial) changes back into the original library, I'm happy to do so.
10
+
11
+ ## Installation
12
+
13
+ ### Using uv
14
+
15
+ ```bash
16
+ uv add phue2
17
+
18
+ uv pip install phue2
19
+ ```
20
+
21
+ ### Using pip
22
+
23
+ ```bash
24
+ pip install phue2
25
+ ```
26
+
27
+ ## Repository Structure
28
+
29
+ ```
30
+ .
31
+ ├── LICENSE
32
+ ├── README.md
33
+ ├── examples/
34
+ ├── src/
35
+ │ └── phue/
36
+ │ ├── __init__.py
37
+ │ ├── __main__.py # CLI interface
38
+ │ ├── bridge.py # Bridge connection handling
39
+ │ ├── exceptions.py # Custom exceptions
40
+ │ ├── group.py # Group controls
41
+ │ ├── light.py # Light controls
42
+ │ ├── scene.py # Scene handling
43
+ │ └── sensor.py # Sensor controls
44
+ └── tests/ # Tests
45
+ ```
46
+
47
+ ## Requirements
48
+
49
+ - Python 3.10 or higher (not compatible with Python 2.x)
50
+ - httpx (for network requests)
51
+
52
+ ## Features
53
+
54
+ - Fully typed with Python type annotations
55
+ - Robust error handling with custom exceptions
56
+ - Comprehensive test suite
57
+ - Colorful, user-friendly command-line interface
58
+ - Support for Lights, Groups, Scenes, and Sensors
59
+ - Auto-discovery of Hue bridges on the network
60
+ - Simple and intuitive API for controlling Hue devices
61
+
62
+
63
+
64
+ ## Command Line Usage
65
+
66
+ The library includes a command-line interface for controlling your Hue lights:
67
+
68
+ ```bash
69
+ # List all lights
70
+ phue ls
71
+
72
+ # Get details about a specific light
73
+ phue get light "Living Room"
74
+
75
+ # Turn on a light and set brightness
76
+ phue set light "Kitchen" --on --bri 200
77
+
78
+ # List all groups
79
+ phue ls groups
80
+
81
+ # Turn off lights in a group
82
+ phue set group "Downstairs" --off
83
+ ```
84
+
85
+ ## Basic Usage
86
+
87
+ Using the set_light and get_light methods you can control pretty much all the parameters:
88
+
89
+ ```python
90
+ from phue2 import Bridge
91
+
92
+ # Connect to the bridge
93
+ b = Bridge('192.168.1.100')
94
+
95
+ # If the app is not registered and the button is not pressed, press the button and call connect()
96
+ # This only needs to be run a single time
97
+ b.connect()
98
+
99
+ # Get the bridge state (This returns the full dictionary that you can explore)
100
+ b.get_api()
101
+
102
+ # Prints if light 1 is on or not
103
+ b.get_light(1, 'on')
104
+
105
+ # Set brightness of lamp 1 to max
106
+ b.set_light(1, 'bri', 254)
107
+
108
+ # Turn lamp 2 on
109
+ b.set_light(2, 'on', True)
110
+
111
+ # You can also control multiple lamps by sending a list as lamp_id
112
+ b.set_light([1, 2], 'on', True)
113
+
114
+ # You can also use light names instead of the id
115
+ b.get_light('Kitchen')
116
+ b.set_light('Kitchen', 'bri', 254)
117
+
118
+ # Also works with lists
119
+ b.set_light(['Bathroom', 'Garage'], 'on', False)
120
+ ```
121
+
122
+ ### Light Objects
123
+
124
+ If you want to work in a more object-oriented way, you can get Light objects:
125
+
126
+ ```python
127
+ # Get a flat list of light objects
128
+ lights = b.lights
129
+
130
+ # Print light names
131
+ for light in lights:
132
+ print(light.name)
133
+
134
+ # Set brightness of each light to 127
135
+ for light in lights:
136
+ light.brightness = 127
137
+
138
+ # Get a dictionary with the light name as the key
139
+ light_names = b.get_light_objects('name')
140
+
141
+ # Set lights using name as key
142
+ for light_name in ['Kitchen', 'Bedroom', 'Garage']:
143
+ light = light_names.get(light_name)
144
+ if light:
145
+ light.on = True
146
+ light.hue = 15000
147
+ light.saturation = 120
148
+ ```
149
+
150
+ ## Error Handling
151
+
152
+ The library provides custom exceptions for better error handling:
153
+
154
+ ```python
155
+ from phue2 import Bridge, PhueRegistrationException, PhueRequestTimeout
156
+
157
+ try:
158
+ b = Bridge('192.168.1.100')
159
+ b.connect()
160
+ except PhueRegistrationException:
161
+ print("Press the button on the bridge and try again")
162
+ except PhueRequestTimeout:
163
+ print("Could not connect to the bridge - check your network")
164
+ ```
165
+
166
+ ## Acknowledgments
167
+
168
+ This project is a fork of the original [phue](https://github.com/studioimaginaire/phue) library created by Nathanaël Lécaudé.
169
+
170
+ The modernized version was created by [zzstoatzz](https://github.com/zzstoatzz) to add type annotations and a more opinionated CLI.
171
+
172
+ ## License
173
+
174
+ MIT - http://opensource.org/licenses/MIT
175
+
176
+ "Hue Personal Wireless Lighting" is a trademark owned by Koninklijke Philips Electronics N.V., see www.meethue.com for more information.
177
+ I am in no way affiliated with the Philips organization.
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Example showing how to connect to a Philips Hue bridge.
4
+ This is a good first script to run when setting up phue.
5
+ """
6
+
7
+ import json
8
+ import logging
9
+ import os
10
+ import sys
11
+
12
+ from phue2 import Bridge, Light, PhueRegistrationException, console
13
+
14
+ logging.basicConfig(level=logging.WARNING, format="%(levelname)s: %(message)s")
15
+
16
+
17
+ def light_formatter(light: Light) -> str:
18
+ """Format a light for display in a table."""
19
+ status = "ON" if light.on else "OFF"
20
+ return f"{light.name:<25} - Status: {status}"
21
+
22
+
23
+ def main():
24
+ """Connect to the Hue bridge and save credentials."""
25
+ console.header("Philips Hue Bridge Setup")
26
+
27
+ config_path = os.path.expanduser("~/.python_hue")
28
+
29
+ if os.path.exists(config_path):
30
+ try:
31
+ with open(config_path) as f:
32
+ config = json.loads(f.read())
33
+ if config:
34
+ console.info("Found existing Hue bridge configuration.")
35
+
36
+ for ip_address in config:
37
+ if "username" in config[ip_address]:
38
+ console.info(f"Trying saved bridge at {ip_address}...")
39
+ try:
40
+ bridge = Bridge(ip=ip_address)
41
+ lights = bridge.lights
42
+ console.success(f"Connected to bridge at {ip_address}")
43
+ console.table(lights, light_formatter)
44
+ return
45
+ except Exception as e:
46
+ console.error(f"Couldn't connect to {ip_address}")
47
+ console.info(f"Error details: {e}")
48
+
49
+ console.warning("Couldn't connect with any saved bridges.")
50
+ except (json.JSONDecodeError, FileNotFoundError):
51
+ console.error("Config file exists but is invalid.")
52
+
53
+ console.section("Bridge Connection Setup")
54
+ console.info("You'll need to provide your bridge IP address.")
55
+ console.info(
56
+ "You can find it in the Hue app (Settings > My Bridge) or your router."
57
+ )
58
+
59
+ ip_address = input("\nEnter your bridge IP address: ")
60
+ if not ip_address:
61
+ console.error("No IP address provided. Exiting.")
62
+ sys.exit(1)
63
+
64
+ while True:
65
+ console.section("Link Button Authentication")
66
+ console.warning("You need to press the link button on your Hue bridge.")
67
+ console.box(
68
+ "IMPORTANT",
69
+ [
70
+ "You only have 30 seconds to press the button!",
71
+ "Get ready to walk over to your bridge...",
72
+ ],
73
+ )
74
+
75
+ input("\nPress Enter when you're ready to go press the button...")
76
+
77
+ try:
78
+ console.info("Attempting to register with the bridge...")
79
+ bridge = Bridge(ip=ip_address)
80
+ console.success("Connected and saved credentials!")
81
+
82
+ console.section("Your Hue Lights")
83
+ console.table(bridge.lights, light_formatter)
84
+
85
+ console.success("Setup complete! You can now control your Hue lights.")
86
+ break
87
+
88
+ except PhueRegistrationException:
89
+ console.error("Link button was not pressed in time.")
90
+ console.warning("Let's try again. Remember, you only have 30 seconds!")
91
+
92
+ except Exception as e:
93
+ console.error(f"Connection failed: {e}")
94
+ retry = input("\nTry again? (y/n): ")
95
+ if retry.lower() != "y":
96
+ console.error("Exiting. Please try again later.")
97
+ sys.exit(1)
98
+
99
+
100
+ if __name__ == "__main__":
101
+ main()
@@ -0,0 +1,54 @@
1
+ """
2
+ This script will have all lights flicker randomly.
3
+
4
+ WARNING: If you have not previously connected to the bridge, run connect_bridge.py first.
5
+ """
6
+
7
+ import random
8
+ from time import sleep
9
+
10
+ from phue2 import Bridge
11
+
12
+ b = Bridge()
13
+ b.connect()
14
+ lights = b.lights
15
+
16
+
17
+ def select_multiple_lights() -> list[int]:
18
+ """
19
+ Selects a random number of lights from the list of lights every time, resulting in a 'flickering' look.
20
+ """
21
+ return random.choices(range(1, len(lights) + 1), k=random.randint(1, len(lights)))
22
+
23
+
24
+ def multi_modal():
25
+ """
26
+ Generates a random transition time between 0.2 and 0.7 seconds folowing a multi-modal distribution.
27
+ This results in really fast transitions, but also slow transitions.
28
+ """
29
+ return [
30
+ 2 + int(random.betavariate(1, 9) * 5),
31
+ 2 + int(random.betavariate(9, 1) * 5),
32
+ ][bool(random.getrandbits(1))]
33
+
34
+
35
+ def candle_flicker():
36
+ """
37
+ Sends a command to change a certain number of lights a different color temperature every time. ct_inc was finicky, so I've used ct instead.
38
+ All inputs use a beta distribution, as it looked more natural. A similar look can be achieved using a triangular distribution as well.
39
+ """
40
+ b.set_light(
41
+ select_multiple_lights(),
42
+ {
43
+ "transitiontime": multi_modal(),
44
+ "on": True,
45
+ "bri": 1 + int(random.betavariate(2, 5) * 253),
46
+ "ct": 153 + int(random.betavariate(9, 4) * 347),
47
+ },
48
+ )
49
+
50
+
51
+ if __name__ == "__main__":
52
+ while True:
53
+ candle_flicker()
54
+ sleep(random.random())