# FastHue A local, iPhone-first Philips Hue dashboard and command-line client. It works with a Hue Bridge or Hue Bridge Pro on the same network. ## Dashboard The dashboard fills an iPhone screen with eight dark controls in a 2 × 4 grid. - A blue edge means at least one light in that room or zone is on. - The subtitle is the active Hue scene, when one is active. - Tap a button to activate the next configured scene. - Press and hold a button for about 0.65 seconds to turn its lights off. ### Start it First register the app with the bridge (you only need to do this once): ```sh python3 hue.py register ``` Press the physical button on the bridge when prompted. Then install the small web app dependencies and run it: ```sh python3 -m venv .venv .venv/bin/pip install -r requirements.txt .venv/bin/python app.py ``` On the iPhone, open `http://YOUR-COMPUTER-IP:5000/?key=YOUR_API_KEY` in Safari. The key is saved only for that browser session and removed from the displayed URL. The iPhone and computer must be on the same local network. ## Configure buttons and scenes `hue.yaml` controls the dashboard. The `buttons` entries define button order, the target room/zone, and the ordered scenes to cycle through: ```yaml buttons: 1: name: Ground floor scenes: - Sunset allure - Relax ``` Each button name must match a `rooms` or `zones` entry. Scene names must match scenes for that same group in the main `scenes` catalog. The app expects exactly eight buttons. ## Command line client ```sh # Find local bridges python3 hue.py discover # List rooms, zones, and scenes python3 hue.py list # Activate a scene or control a group directly python3 hue.py scene "Evening relax" python3 hue.py on "Living room" python3 hue.py off "zone:Downstairs" ``` Credentials are saved with owner-only permissions in `secrets.yaml`: ```yaml bridge: 192.168.1.10 app_key: your-hue-application-key. # the hue bride api key api_key: your-dashboard-api-key # the key for this services api ``` The file is ignored by Git and should not be shared. `hue.py register` creates or updates it, including a random dashboard API key. You can override values for either tool with environment variables: ```sh FASTHUE_API_KEY=YOUR_DASHBOARD_KEY HUE_BRIDGE=192.168.1.10 HUE_APP_KEY=YOUR_HUE_KEY .venv/bin/python app.py ``` The reverse-proxy path is configured separately in `config.yaml`: ```yaml url_prefix: /hue ``` Set it to an empty value when FastHue is served at `/`. ## HTTP API Every API request needs the single `api_key` from `secrets.yaml` as a Bearer token. Override it with `FASTHUE_API_KEY` or `--api-key` when necessary. ```sh export FASTHUE_API_KEY='the-api_key-from-secrets.yaml' curl -H "Authorization: Bearer $FASTHUE_API_KEY" http://localhost:5000/api/groups curl -X POST -H "Authorization: Bearer $FASTHUE_API_KEY" \ http://localhost:5000/api/groups/GROUP_UUID/next-scene curl -X POST -H "Authorization: Bearer $FASTHUE_API_KEY" \ http://localhost:5000/api/groups/GROUP_UUID/off curl -X POST -H "Authorization: Bearer $FASTHUE_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Relax"}' \ 'http://localhost:5000/api/groups/Ground%20floor/scene' ``` `GET /api/groups` returns each configured group ID, its power state, and its active scene. Use those IDs for the `next-scene` and `off` endpoints. The `scene` endpoint uses the URL-encoded room or zone name (not its UUID), and activates the named scene only when it belongs to that group. Keep this service on a trusted network; the included Flask server uses HTTP, so place it behind an HTTPS reverse proxy if it needs to cross an untrusted network. ## Deploy with Gunicorn and Nginx These instructions target a Linux host running systemd. Gunicorn listens on a Unix socket; Nginx is the only public-facing process. Install the project and dependencies under a service account, then place its credentials outside the web root: ```sh sudo useradd --system --create-home --shell /usr/sbin/nologin fasthue sudo mkdir -p /opt/fasthue /etc/fasthue sudo chown fasthue:fasthue /opt/fasthue /etc/fasthue # Copy this project into /opt/fasthue, then: sudo -u fasthue python3 -m venv /opt/fasthue/.venv sudo -u fasthue /opt/fasthue/.venv/bin/pip install -r /opt/fasthue/requirements.txt sudo install -o fasthue -g fasthue -m 600 secrets.yaml /etc/fasthue/secrets.yaml ``` Create `/etc/systemd/system/fasthue.service`: ```ini [Unit] Description=FastHue dashboard After=network-online.target Wants=network-online.target [Service] Type=exec User=fasthue # Use your Nginx worker group (commonly www-data; use nginx on some distros). Group=www-data WorkingDirectory=/opt/fasthue Environment=FASTHUE_SECRETS_FILE=/etc/fasthue/secrets.yaml RuntimeDirectory=fasthue RuntimeDirectoryMode=0750 ExecStart=/opt/fasthue/.venv/bin/gunicorn --workers 1 --umask 007 --bind unix:/run/fasthue/fasthue.sock --factory app:create_gunicorn_app Restart=on-failure RestartSec=3 [Install] WantedBy=multi-user.target ``` Enable it: ```sh sudo systemctl daemon-reload sudo systemctl enable --now fasthue sudo systemctl status fasthue ``` Configure Nginx with a TLS-enabled virtual host (replace the hostname and certificate paths). This example publishes FastHue at `/hue`: ```nginx server { listen 443 ssl http2; server_name hue.example.com; ssl_certificate /etc/letsencrypt/live/hue.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/hue.example.com/privkey.pem; location = /hue { return 302 /hue/; } location /hue/ { # The trailing slash strips /hue before proxying to Flask. proxy_pass http://unix:/run/fasthue/fasthue.sock:/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Prefix /hue; proxy_set_header Authorization $http_authorization; } } ``` The `www-data` group in the systemd unit and `--umask 007` make the socket readable by Nginx. If your Nginx workers use another group, replace `www-data` in the unit with that group. Test and reload Nginx with `sudo nginx -t && sudo systemctl reload nginx`. Use the HTTPS URL on the iPhone with `/hue/?key=YOUR_API_KEY` once per browser session. Set `url_prefix` in `config.yaml` to another leading-slash prefix when needed, and use the same value in Nginx's `location` and `X-Forwarded-Prefix`. Keep `secrets.yaml` readable only by the service account. The bridge typically has a locally issued TLS certificate, so certificate verification is disabled by default. Add `--verify-tls` only when your computer trusts that certificate. ## Files - `app.py` — Flask dashboard and Hue API integration - `hue.py` — dependency-free command-line client and registration tool - `config.yaml` — reverse-proxy settings - `hue.yaml` — button, group, and scene configuration - `static/` and `templates/` — phone interface