neopi 0.1.0__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 (66) hide show
  1. neopi-0.1.0/PKG-INFO +372 -0
  2. neopi-0.1.0/README.md +355 -0
  3. neopi-0.1.0/pyproject.toml +37 -0
  4. neopi-0.1.0/setup.cfg +4 -0
  5. neopi-0.1.0/src/neopi/__init__.py +3 -0
  6. neopi-0.1.0/src/neopi/__main__.py +7 -0
  7. neopi-0.1.0/src/neopi/animations/__init__.py +79 -0
  8. neopi-0.1.0/src/neopi/animations/aurora_borealis.py +46 -0
  9. neopi-0.1.0/src/neopi/animations/blinking_ornaments_1.py +95 -0
  10. neopi-0.1.0/src/neopi/animations/blinking_ornaments_2.py +123 -0
  11. neopi-0.1.0/src/neopi/animations/breathing_wreath.py +111 -0
  12. neopi-0.1.0/src/neopi/animations/chase.py +91 -0
  13. neopi-0.1.0/src/neopi/animations/color_waves.py +71 -0
  14. neopi-0.1.0/src/neopi/animations/counterflow_waves.py +90 -0
  15. neopi-0.1.0/src/neopi/animations/fire_and_ice_bounce.py +54 -0
  16. neopi-0.1.0/src/neopi/animations/fire_and_ice_duality.py +153 -0
  17. neopi-0.1.0/src/neopi/animations/fireflies.py +108 -0
  18. neopi-0.1.0/src/neopi/animations/garland_wave.py +63 -0
  19. neopi-0.1.0/src/neopi/animations/ghost_procession.py +52 -0
  20. neopi-0.1.0/src/neopi/animations/gift_unwrapping.py +120 -0
  21. neopi-0.1.0/src/neopi/animations/glowing_train.py +68 -0
  22. neopi-0.1.0/src/neopi/animations/hearth_glow.py +68 -0
  23. neopi-0.1.0/src/neopi/animations/hue_room_bloom.py +56 -0
  24. neopi-0.1.0/src/neopi/animations/hue_room_chase.py +50 -0
  25. neopi-0.1.0/src/neopi/animations/hue_room_color_wash.py +49 -0
  26. neopi-0.1.0/src/neopi/animations/hue_room_mirror_pulse.py +53 -0
  27. neopi-0.1.0/src/neopi/animations/hue_room_mosaic.py +68 -0
  28. neopi-0.1.0/src/neopi/animations/hue_room_twinkle.py +42 -0
  29. neopi-0.1.0/src/neopi/animations/hue_room_waves.py +51 -0
  30. neopi-0.1.0/src/neopi/animations/marching_stripes.py +76 -0
  31. neopi-0.1.0/src/neopi/animations/peppermint_swirl.py +86 -0
  32. neopi-0.1.0/src/neopi/animations/pumpkin_lanterns.py +50 -0
  33. neopi-0.1.0/src/neopi/animations/rainbow_cycle.py +26 -0
  34. neopi-0.1.0/src/neopi/animations/shooting_star_chase.py +101 -0
  35. neopi-0.1.0/src/neopi/animations/snowfall.py +128 -0
  36. neopi-0.1.0/src/neopi/animations/sparkle.py +109 -0
  37. neopi-0.1.0/src/neopi/animations/starry_candle_procession.py +146 -0
  38. neopi-0.1.0/src/neopi/animations/toy_train_parade.py +134 -0
  39. neopi-0.1.0/src/neopi/animations/twinkle.py +100 -0
  40. neopi-0.1.0/src/neopi/animations/vampire_drips.py +51 -0
  41. neopi-0.1.0/src/neopi/animations/witches_cauldron.py +57 -0
  42. neopi-0.1.0/src/neopi/animations/witching_hour.py +59 -0
  43. neopi-0.1.0/src/neopi/app.py +1289 -0
  44. neopi-0.1.0/src/neopi/cli.py +103 -0
  45. neopi-0.1.0/src/neopi/config.py +182 -0
  46. neopi-0.1.0/src/neopi/hue.py +457 -0
  47. neopi-0.1.0/src/neopi/paths.py +18 -0
  48. neopi-0.1.0/src/neopi/presets.py +1030 -0
  49. neopi-0.1.0/src/neopi/py.typed +1 -0
  50. neopi-0.1.0/src/neopi/static/hue.js +75 -0
  51. neopi-0.1.0/src/neopi/static/index.html +340 -0
  52. neopi-0.1.0/src/neopi/static/main.js +1098 -0
  53. neopi-0.1.0/src/neopi/static/style.css +1325 -0
  54. neopi-0.1.0/src/neopi/type_defs.py +10 -0
  55. neopi-0.1.0/src/neopi/utils.py +162 -0
  56. neopi-0.1.0/src/neopi.egg-info/PKG-INFO +372 -0
  57. neopi-0.1.0/src/neopi.egg-info/SOURCES.txt +64 -0
  58. neopi-0.1.0/src/neopi.egg-info/dependency_links.txt +1 -0
  59. neopi-0.1.0/src/neopi.egg-info/entry_points.txt +2 -0
  60. neopi-0.1.0/src/neopi.egg-info/requires.txt +12 -0
  61. neopi-0.1.0/src/neopi.egg-info/top_level.txt +1 -0
  62. neopi-0.1.0/tests/test_color_utils.py +62 -0
  63. neopi-0.1.0/tests/test_hue.py +223 -0
  64. neopi-0.1.0/tests/test_hue_animations.py +122 -0
  65. neopi-0.1.0/tests/test_preview_api.py +28 -0
  66. neopi-0.1.0/tests/test_refactored.py +79 -0
neopi-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,372 @@
1
+ Metadata-Version: 2.4
2
+ Name: neopi
3
+ Version: 0.1.0
4
+ Summary: NeoPixel animation scenes and a friendly Raspberry Pi web controller
5
+ Requires-Python: >=3.9
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: fastapi<1,>=0.110
8
+ Requires-Dist: pydantic<3,>=2
9
+ Requires-Dist: uvicorn[standard]<1,>=0.29
10
+ Provides-Extra: hardware
11
+ Requires-Dist: Adafruit-Blinka>=8; extra == "hardware"
12
+ Requires-Dist: adafruit-circuitpython-neopixel>=6; extra == "hardware"
13
+ Requires-Dist: rpi-ws281x>=5; extra == "hardware"
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest>=8; extra == "dev"
16
+ Requires-Dist: httpx>=0.27; extra == "dev"
17
+
18
+ # NeoPi: NeoPixel Animations and Web Controls
19
+
20
+ NeoPi runs customizable seasonal animations on Raspberry Pi NeoPixel lightstrips and provides a responsive local web dashboard. It also includes a simulator fallback for development without LED hardware.
21
+
22
+ ## Quick Start
23
+
24
+ On a Raspberry Pi with Python 3.9 or newer:
25
+
26
+ ```bash
27
+ python3 -m venv .venv
28
+ source .venv/bin/activate
29
+ python -m pip install -e ".[hardware]"
30
+ neopi setup
31
+ sudo .venv/bin/neopi serve
32
+ ```
33
+
34
+ The setup command asks only for the pixel count, strip color order, and GPIO data pin. Then open `http://<your-pi-hostname>:8000` on a device connected to the same network. The dashboard includes a sampled live preview of the animation being sent to the strip.
35
+
36
+ For development on a computer without LEDs:
37
+
38
+ ```bash
39
+ python -m pip install -e ".[dev]"
40
+ neopi setup
41
+ neopi serve --reload
42
+ ```
43
+
44
+ The simulator is selected automatically off the Pi. To choose it explicitly, set `NEOPI_DRIVER=simulator`.
45
+
46
+ After changing branches or pulling packaging changes, refresh the editable install:
47
+
48
+ ```bash
49
+ python -m pip install -e ".[dev]"
50
+ ```
51
+
52
+ The supported installed entry point is `neopi serve`. To run a small animation loop without the web dashboard, use `python example_serverless.py` from a source checkout.
53
+
54
+ > **Hardware safety:** Long strips need a separate, correctly sized 5 V supply. Connect the Pi and supply grounds together; do not power a long strip from the Pi's 5 V pin. A level shifter, 300–500 ohm data resistor, and 500–1000 µF capacitor at the strip input are strongly recommended. Begin with power disconnected and verify DIN, 5 V, and ground before starting the server.
55
+
56
+ ---
57
+
58
+ ## Repository and Package Architecture
59
+
60
+ NeoPi uses a `src` layout so tests and development commands exercise the same importable package that is installed from a wheel:
61
+
62
+ ```text
63
+ neopi/
64
+ ├── pyproject.toml
65
+ ├── README.md
66
+ ├── example_serverless.py # Small animation loop without the web server
67
+ ├── src/neopi/
68
+ │ ├── app.py # FastAPI application and controller
69
+ │ ├── cli.py # neopi command
70
+ │ ├── config.py # Hardware initialization and simulator
71
+ │ ├── hue.py # Philips Hue synchronization
72
+ │ ├── presets.py # Preset catalog
73
+ │ ├── animations/ # One module per animation
74
+ │ └── static/ # Dashboard assets bundled in the wheel
75
+ └── tests/
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Installation & Requirements
81
+
82
+ To run this server and correctly interface with the physical lightstrip on your Raspberry Pi, you need the following Python libraries installed:
83
+
84
+ 1. **Web Server & API Libraries:**
85
+ * `fastapi` (for the REST/WebSocket API)
86
+ * `uvicorn[standard]` (the ASGI server to run FastAPI)
87
+ * `pydantic` (for data validation)
88
+
89
+ 2. **Hardware Control Libraries:**
90
+ * `adafruit-circuitpython-neopixel` (provides the `neopixel` module to control the LEDs)
91
+ * `Adafruit-Blinka` (provides the `board` module to map the physical Raspberry Pi GPIO pins)
92
+ * `rpi-ws281x` (the underlying hardware driver required for WS2812B/NeoPixels on the Pi)
93
+
94
+ The recommended editable install records and installs these dependencies for you:
95
+
96
+ ```bash
97
+ python -m pip install -e ".[hardware]"
98
+ ```
99
+
100
+ For a regular local installation or a distributable wheel:
101
+
102
+ ```bash
103
+ python -m pip install ".[hardware]"
104
+ python -m pip wheel . --no-deps --wheel-dir dist
105
+ ```
106
+
107
+ The resulting `neopi-*.whl` contains the Python server, built-in animations, and dashboard assets. Once the project is published to a package index, the intended installation command is `python -m pip install "neopi[hardware]"`.
108
+
109
+ To build and publish both the source distribution and wheel from Windows, use the release script. Configure a PyPI token when Twine prompts for credentials:
110
+
111
+ ```bat
112
+ publish.cmd
113
+ ```
114
+
115
+ Configuration and controller state are stored in `~/.config/neopi/`. Set `NEOPI_DATA_DIR` to choose another directory, or override individual files with `NEOPI_CONFIG_FILE`, `NEOPI_SETTINGS_FILE`, and `NEOPI_HUE_SETTINGS_FILE`. Re-run `neopi setup` whenever the strip is replaced or moved to another supported GPIO pin. Controlling NeoPixels on Raspberry Pi commonly requires root privileges, so the production command may need `sudo .venv/bin/neopi serve`.
116
+
117
+ Existing checkout-local `lightstrip_config.json`, `settings.json`, and `hue_settings.json` files are not moved automatically. Copy their contents into `~/.config/neopi/config.json`, `~/.config/neopi/settings.json`, and `~/.config/neopi/hue.json`, respectively, or point the corresponding environment variables at the existing files.
118
+
119
+ ---
120
+
121
+ ## Setting Up as a System Service (Raspberry Pi/Linux)
122
+
123
+ To ensure NeoPi starts automatically when the Raspberry Pi boots and restarts after a failure, configure it as a systemd service.
124
+
125
+ ### 1. Create a Service File
126
+ On your Raspberry Pi, create a new file for your service in the `/etc/systemd/system/` directory:
127
+ ```bash
128
+ sudo nano /etc/systemd/system/neopi.service
129
+ ```
130
+
131
+ ### 2. Add the Configuration
132
+ Replace `yourusername` and the virtual-environment path with the values from your installation.
133
+
134
+ ```ini
135
+ [Unit]
136
+ Description=NeoPi lightstrip server
137
+ After=network.target
138
+
139
+ [Service]
140
+ # The user you are running the script as (e.g., 'pi' or your custom username)
141
+ User=yourusername
142
+
143
+ Environment=NEOPI_DATA_DIR=/home/yourusername/.config/neopi
144
+ ExecStart=/home/yourusername/neopi/.venv/bin/neopi serve
145
+
146
+ # Restart the service automatically if it crashes
147
+ Restart=always
148
+ # Wait 5 seconds before restarting
149
+ RestartSec=5
150
+
151
+ # Forward outputs to the system journal
152
+ StandardOutput=inherit
153
+ StandardError=inherit
154
+
155
+ [Install]
156
+ # Starts the service on boot
157
+ WantedBy=multi-user.target
158
+ ```
159
+ *(Press `Ctrl+O` then `Enter` to save, and `Ctrl+X` to exit nano).*
160
+
161
+ ### 3. Enable and Start the Service
162
+ Reload the systemd daemon to recognize the new file, enable it to start on boot, and start it immediately:
163
+
164
+ ```bash
165
+ # Reload systemd to recognize your new service file
166
+ sudo systemctl daemon-reload
167
+
168
+ # Enable the service to run automatically on boot
169
+ sudo systemctl enable neopi.service
170
+
171
+ # Start the service right now
172
+ sudo systemctl start neopi.service
173
+ ```
174
+
175
+ ### 4. Check the Status and Logs
176
+ To verify that your server is running successfully:
177
+ ```bash
178
+ sudo systemctl status neopi.service
179
+ ```
180
+
181
+ To view the live application logs:
182
+ ```bash
183
+ sudo journalctl -u neopi.service -f
184
+ ```
185
+
186
+ ### 5. If You Need to Stop or Restart the Service
187
+ ```bash
188
+ # To stop the service
189
+ sudo systemctl stop neopi.service
190
+ # To restart the service after installing changes
191
+ sudo systemctl restart neopi.service
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Control Center Web Dashboard Features
197
+
198
+ The NeoPi Control Center is a responsive single-page application for mobile and desktop browsers:
199
+
200
+ 1. **Decoupled Animation Preview and Customization**: Clicking on any card in the library selects it, showing its specific configurable sliders in the "Configure & Play" settings panel without immediately playing it. The user can adjust parameters first, then click "Play Now" or "+ Queue" to execute.
201
+ 2. **Interactive Live Parameter Tuning**: If the selected card is the currently active manual animation, dragging sliders or choosing colors immediately pushes live REST updates to the Raspberry Pi, showing immediate hardware feedback.
202
+ 3. **Dynamic Hover Tooltips**: Every parameter (e.g., frame wait times, segment counts, speeds, spacing) has custom tooltips. Hovering over a slider or input group expands a micro-description explaining exactly how it affects the visual pattern.
203
+ 4. **Customizable Auto-Cycle Queue**: Users can choose to run the lightstrip autonomously using a customized sequence list. Queued patterns can be added, deleted, or reordered instantly. Settings are persisted in the NeoPi data directory so that they survive a system restart.
204
+ 5. **Global Fade Transitions and Cycling Times**: Users can set how long each auto-cycle animation runs (Active Animation Duration) and how long they fade into one another (Transition Fade Time) using global sliders.
205
+ 6. **Restore Defaults Action**: A dedicated action button that instantly restores uvicorn state, cycle modes, parameters, active duration settings, and the default holiday queue back to factory defaults.
206
+ 7. **Full RGBW Color & White Channel Control**: Complete 4-channel LED control is supported. The frontend dynamically renders a companion White intensity slider (0-255) next to the color wheel picker for any pattern with an RGBW color parameter. Color values are serialized and transmitted in an extended 8-character hex format (#RRGGBBWW), allowing granular tuning of white channel intensity alongside RGB colors.
207
+
208
+ ---
209
+
210
+ ## Guiding Principles for Writing Animations
211
+
212
+ To maintain consistency, safety, and visual quality, every animation must adhere to these guidelines:
213
+
214
+ ### 1. Standard Parameters and Signature
215
+ Every animation function must accept at least these two arguments to ensure compatibility with the automated cycle loop and the web control server:
216
+ * `wait` (float): The speed controller. It is the time in seconds to sleep between rendering frames.
217
+ * `duration` (int or float): The total time in seconds the animation should run before returning.
218
+
219
+ Example signature:
220
+ ```python
221
+ def my_new_animation(wait=0.05, duration=10, speed_multiplier=1.0, color=(255, 0, 0, 0)):
222
+ # ... implementation ...
223
+ ```
224
+
225
+ ### 2. Documentation Guidelines
226
+ We use the Google Python Style Guide for docstrings. Every animation module must specify:
227
+ 1. A summary line describing the visual effect.
228
+ 2. A detailed description of the physical look.
229
+ 3. An Args section detailing every parameter.
230
+
231
+ Example:
232
+ ```python
233
+ def starry_sky(wait=0.1, duration=15, star_count=10):
234
+ """Simulates glowing stars fading in and out on a dark blue background.
235
+
236
+ Args:
237
+ wait (float): Time to sleep between frames (seconds).
238
+ duration (int): Total run time of the animation (seconds).
239
+ star_count (int): Maximum number of concurrent stars to render.
240
+ """
241
+ ```
242
+
243
+ ### 3. Parametrization and Avoiding Magic Numbers
244
+ * Never use hardcoded magic numbers for speeds, counts, densities, or colors in the rendering loop.
245
+ * Expose these variables as default argument parameters on the function signature.
246
+ * This enables the FastAPI web server to dynamically inspect the function signature using reflection (inspect module) and automatically render customization sliders on the web control panel.
247
+
248
+ ### 4. RGBW Color Parameter Formatting
249
+ Color parameters can be defined as 3-channel RGB tuples `(R, G, B)` or 4-channel RGBW tuples `(R, G, B, W)`. The backend parses these into hex values for web interface compatibility:
250
+ * Standard 6-character hex (`#RRGGBB`): Default for standard RGB strips.
251
+ * Extended 8-character hex (`#RRGGBBWW`): Utilized for RGBW strips to package both the color and the white channel intensity. The server automatically translates `#RRGGBBWW` strings back into `(R, G, B, W)` tuples for the animation functions, allowing native hardware integration.
252
+
253
+ ---
254
+
255
+ ## Anti-Flickering Guidelines (CRITICAL)
256
+
257
+ To prevent data line interference, voltage drops, and visual flickering on long strips (e.g., our 289-pixel strip), **don't update all pixels in a single frame**.
258
+
259
+ ### Rules for Implementation:
260
+ 1. **Interlacing (Stepped Ranges)**: Stagger updates between frames using a stepped range based on the frame parity.
261
+ ```python
262
+ # Correct way to loop through pixels
263
+ for i in range(frame % 2, NUM_PIXELS, 2):
264
+ pixels[i] = (r, g, b, w)
265
+ ```
266
+ 2. **Conditional Drawing**: If calculating a single moving object (e.g., a train engine or comet head), only write to it if it matches the current frame's parity.
267
+ ```python
268
+ if pixel_index % 2 == frame % 2:
269
+ pixels[pixel_index] = color
270
+ ```
271
+ 3. **No pixels.fill() inside rendering loops**: Avoid filling the entire strip in every frame. Clear old pixels in two staggered passes or clear pixels individually using the interlaced frame parity.
272
+
273
+ ---
274
+
275
+ ## Step-by-Step: Adding a New Animation
276
+
277
+ Adding a new custom animation is clean and straightforward:
278
+
279
+ ### Step 1: Create the Animation File
280
+ Create a new file in `src/neopi/animations/`, e.g., `my_custom_pattern.py`.
281
+ Import necessary items from `neopi.config` and `neopi.utils`:
282
+
283
+ ```python
284
+ import time
285
+ from neopi.config import pixels, NUM_PIXELS
286
+ from neopi.utils import fade_transition
287
+
288
+ @fade_transition() # Optional: Adds standard fade-out/fade-in between animations
289
+ def my_custom_pattern(wait=0.05, duration=10, main_color=(255, 0, 128, 0)):
290
+ """A beautiful neon-pink wave sweeping down the strip.
291
+
292
+ Args:
293
+ wait (float): Time to sleep between frames.
294
+ duration (int): Total run time in seconds.
295
+ main_color (tuple): The RGBW color of the sweeping wave.
296
+ """
297
+ start_time = time.time()
298
+ frame = 0
299
+
300
+ while time.time() - start_time < duration:
301
+ # Use anti-flicker interlaced rendering
302
+ for i in range(frame % 2, NUM_PIXELS, 2):
303
+ # ... rendering logic ...
304
+ pixels[i] = main_color
305
+
306
+ pixels.show()
307
+ time.sleep(wait)
308
+ frame += 1
309
+ ```
310
+
311
+ ### Step 2: Register the Animation
312
+ Open `src/neopi/animations/__init__.py`:
313
+ 1. Import your new function:
314
+ ```python
315
+ from .my_custom_pattern import my_custom_pattern
316
+ ```
317
+ 2. Add it to the central `ANIMATIONS` registry dictionary:
318
+ ```python
319
+ ANIMATIONS = {
320
+ ...
321
+ "my_custom_pattern": my_custom_pattern,
322
+ }
323
+ ```
324
+
325
+ ### Step 3: Run / Verify
326
+ Run the test suite to verify your function executes correctly without syntax or parameter errors:
327
+ ```bash
328
+ python -m pytest
329
+ ```
330
+
331
+ Registering the animation makes it available in the web dashboard. For a minimal serverless installation, import it in `example_serverless.py` and add it to `run_serverless_cycle()`.
332
+
333
+ ---
334
+
335
+ ## Running Without the Web Server
336
+
337
+ The source checkout includes a minimal loop with Rainbow Cycle, Color Waves, and Counterflow Waves:
338
+
339
+ ```bash
340
+ python example_serverless.py
341
+ ```
342
+
343
+ It uses the same NeoPi configuration and hardware driver as the installed package, but it does not start FastAPI, save a queue, or synchronize with Philips Hue. Press `Ctrl+C` to stop and blank the strip. Edit the imported functions and calls in `run_serverless_cycle()` to choose a different small set of animations.
344
+
345
+ ---
346
+
347
+ ## Offline Local Development (Mock Mode)
348
+
349
+ If you are not running the code on a Raspberry Pi (e.g., developing on Windows or macOS), the package will **automatically fall back to Mock mode**:
350
+ * It bypasses the physical `board` and `neopixel` hardware libraries.
351
+ * It initializes a `MockNeoPixel` class that matches the interface of the Adafruit library.
352
+ * This allows you to run, test, and develop the FastAPI Web Server and the responsive dashboard locally on your development machine before deploying.
353
+
354
+ ## Philips Hue room color sync
355
+
356
+ 1. Start the server and open **Hue Room Sync** in the dashboard.
357
+ 2. Enter the Hue Bridge's LAN IP address (reserve it in your router to keep it stable).
358
+ 3. Press the physical bridge link button, then click **Pair Bridge** within its pairing window.
359
+ 4. Load rooms, choose a room or zone, select a palette mode, enable sync, and save. The refresh interval defaults to **10 seconds** and accepts **5–3600 seconds**.
360
+ 5. Open the **Hue** library filter and play or queue any of the seven room-aware animations. In addition to Waves, Chase, and Twinkle, the library includes Color Wash, Bloom, Mirror Pulse, and Mosaic. Adjust **Wait** and **Motion Speed** in Configure & Play independently of the bridge refresh interval.
361
+
362
+ All seven Hue animations continuously read a shared palette and blend toward changed colors without restarting their motion or cycle duration. A background worker reads one bridge snapshot per interval, regardless of bulb count. It samples the selected room's individual powered-on, reachable bulbs, including xy colors, hue/saturation, and white color temperature. Global strip brightness remains separately adjustable.
363
+
364
+ **Inferred scene colors** groups perceptually similar bulb readings and exposes up to five representative colors. A nearly uniform room produces one color, while multicolor scenes retain their major color families and isolated contrasting accents. Representatives are actual bulb readings rather than averaged colors. **Direct bulb colors** preserves the original behavior and exposes every exact unique bulb color in the room's bridge order.
365
+
366
+ If the bridge is unavailable, the room is removed, or all its bulbs are off/unreachable, the last usable palette remains active and status explains the condition. Before the first successful sync, the Hue animations use a violet/green/orange fallback. Disabling sync clears the cached palette. Other animation categories continue using their own colors. For uninterrupted manual playback, disable the existing **Auto-Return to Cycle** option.
367
+
368
+ This integration uses the bridge's local **v1 REST API**, following the [official Hue pairing workflow](https://developers.meethue.com/develop/get-started-2/). Bulbs must belong to a Hue Bridge; direct Bluetooth or Zigbee bulb pairing is not implemented. It samples current bulb states rather than extracting every color from a named Hue scene, and does not change Hue bulb state. A dynamic Hue scene is sampled at your chosen interval. Colors are an RGB approximation and can differ between Hue bulbs and your strip.
369
+
370
+ Pairing credentials and Hue settings stay server-side in the NeoPi data directory, separate from ordinary animation settings. The local v1 transport uses HTTP, so use it on your trusted LAN. Bridge addresses are restricted to LAN IP literals; redirects and system HTTP proxies are disabled. **Restore Defaults** also clears local Hue settings; it does not revoke the previously created application user on the bridge.
371
+
372
+ Regression checks: `python -m pytest`. Hue tests mock bridge responses; physical bridge/LED validation is still needed on the Pi.