Files
fasthue/README.md
T
2026-08-09 16:38:29 +02:00

219 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 /srv/fasthue /etc/fasthue
sudo chown fasthue:fasthue /srv/fasthue /etc/fasthue
# Copy this project into /srv/fasthue, then:
sudo -u fasthue python3 -m venv /srv/fasthue/.venv
sudo -u fasthue /srv/fasthue/.venv/bin/pip install -r /srv/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=/srv/fasthue
Environment=FASTHUE_SECRETS_FILE=/etc/fasthue/secrets.yaml
RuntimeDirectory=fasthue
RuntimeDirectoryMode=0750
ExecStart=/srv/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