Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ Fast, **local, cloud-free** control for Philips WiZ smart bulbs. It talks to bul

## Features

Mirrors the original app's capabilities:
Mirrors the original app's capabilities, and adds more:

- **Discovery** — find WiZ bulbs on your network (UDP broadcast), keyed by MAC.
- **Saved lights** — remember bulbs by **MAC** with a friendly name; the IP is re-resolved on discovery, so it survives DHCP changes.
- **Colour** — a **colour wheel** plus direct **RGB / HSV / hex** entry, with per-device colour memory.
- **Colour** — a **colour wheel** plus direct **RGB / HSV / hex** entry, with per-device colour memory and an optional **"Brighter colours"** white-LED blend.
- **White temperature** — tunable white over the bulb's own negotiated range (e.g. **2200–6500 K**).
- **Warm Glow** — a one-knob cosy mode: set brightness and the temperature auto-follows the bulb's dim-to-warm curve (warmer as you dim), with one-tap glow levels.
- **Scenes** — run a bulb's built-in **dynamic scenes** (Party, Ocean, Fireplace, …) with adjustable speed, on bulbs that support them.
- **Brightness** — 0–100% (clamped to the firmware-valid floor; see below).
- **Presets** — seeded RGB + white presets, with apply / match.
- **Sync from light** — read a bulb's current state (`getPilot`) back into the UI.
- **Settings** — accent/highlight colour, auto-sync, and auto-off when the Mac sleeps or shuts down, persisted locally.
- **Sync from light** — read a bulb's current state (`getPilot`) back into the UI, and reflect changes made elsewhere (e.g. the phone app).
- **Settings** — auto-sync on launch; turn the light **off when the Mac sleeps or shuts down** — and optionally **restore it** on wake / startup; open at login; update checks. Persisted locally.

## Screenshots

The native macOS app: a menu-bar dropdown for quick changes, and a full controls window. Each shot is annotated — the numbered callouts are explained beneath it.
The native macOS app: a menu-bar dropdown for quick changes, and a full controls window with four modes — **RGB**, **White**, **Warm Glow**, and **Scenes**. Each shot is annotated — the numbered callouts are explained beneath it.

**Menu-bar dropdown** — click the bulb for instant control, no window needed:

Expand All @@ -31,17 +33,25 @@ The native macOS app: a menu-bar dropdown for quick changes, and a full controls

<img src="assets/screenshot-rgb.png" alt="RGB colour controls (annotated)" width="520">

**Controls — white & presets** — tunable colour temperature and one-tap presets:
**Controls — white** — tunable colour temperature with one-tap white presets:

<img src="assets/screenshot-white.png" alt="White temperature and presets (annotated)" width="520">

**Discover** — find bulbs on your LAN and save them:
**Controls — Warm Glow** — one knob: brightness leads, and the temperature follows the dim-to-warm curve:

<img src="assets/screenshot-discover.png" alt="Discovery sheet (annotated)" width="480">
<img src="assets/screenshot-warmglow.png" alt="Warm Glow controls (annotated)" width="520">

**Settings** — device info, auto-sync, auto-off on sleep/shutdown, and update checks:
**Controls — Scenes** — a bulb's built-in dynamic scenes, with adjustable speed (on bulbs that support them):

<img src="assets/screenshot-settings.png" alt="Settings tab (annotated)" width="500">
<img src="assets/screenshot-scenes.png" alt="Scenes grid (annotated)" width="520">

**Discover** — scan the LAN, then save a new bulb or manage a saved one:

<img src="assets/screenshot-discover.png" alt="Discovery sheet (annotated)" width="500">

**Settings** — device info, auto-sync, sleep / shutdown power behaviour, open-at-login, and updates:

<img src="assets/screenshot-settings.png" alt="Settings tab (annotated)" width="520">

## Install

Expand Down
Binary file modified assets/screenshot-discover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshot-dropdown.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshot-rgb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshot-scenes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshot-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshot-warmglow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/screenshot-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
154 changes: 154 additions & 0 deletions scripts/annotate-screenshots.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#!/bin/bash
# Regenerate the annotated README screenshots in assets/ from the raw captures in
# assets/raw/. Adds numbered yellow badges (right-gutter, with leader lines) + a
# bottom legend, matching the project's screenshot style.
#
# Repeatable: drop a fresh capture into assets/raw/screenshot-<name>.png (or tweak
# the per-image config below) and re-run from the repo root:
#
# ./scripts/annotate-screenshots.sh
#
# Requires ImageMagick v7 (`magick`) and the referenced macOS system fonts.
set -euo pipefail

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" # repo root
RAW="$DIR/assets/raw"
OUT="$DIR/assets"
BADGE_DIR="$(mktemp -d)"
trap 'rm -rf "$BADGE_DIR"' EXIT

YELLOW="#FFD60A"
LIGHT="#EAEAEA"
NUMFONT="/System/Library/Fonts/Supplemental/Arial Bold.ttf" # badge + legend numbers
TEXTFONT="/System/Library/Fonts/SFNS.ttf" # legend body (San Francisco)

# annotate NAME BG CROP_H RPAD BADGE_R BADGE_X LEG_X LEG_Y0 LEG_DY PT BADGES LEGEND
# reads $RAW/NAME.png, writes $OUT/NAME.png
# CROP_H : crop the window to this height first (0 = keep full) — trims empty space
# RPAD : right gutter (px) added for the badges
# BADGES : newline "num target_x target_y" — badge sits at (BADGE_X, target_y),
# a leader runs horizontally from (target_x, target_y) to it
# LEGEND : newline "num|text" (blank num => unnumbered continuation line)
annotate() {
local name="$1" bg="$2" croph="$3" rpad="$4" br="$5" bx="$6" lx="$7" ly0="$8" dy="$9" pt="${10}" badges="${11}" legend="${12}"
local input="$RAW/$name.png" output="$OUT/$name.png"
local W H; read W H < <(magick identify -format "%w %h\n" "$input")
[ "$croph" -eq 0 ] && croph="$H"
local nleg; nleg=$(grep -c . <<< "$legend")
local NW=$((W + rpad)) NH=$((ly0 + nleg * dy + 24))

local args=( "$input" -gravity NorthWest -crop "${W}x${croph}+0+0" +repage
-background "$bg" -extent "${NW}x${NH}" )

# Leader lines first (the badge circle is drawn on top, hiding the stub).
args+=( -stroke "$YELLOW" -strokewidth 3 -fill none )
while IFS= read -r b; do
[ -z "$b" ] && continue
set -- $b; args+=( -draw "line $2,$3 $bx,$3" )
done <<< "$badges"

# Badges: pre-render each glyph (circle + centered number), composite on top.
args+=( -stroke none )
local d=$((br * 2))
while IFS= read -r b; do
[ -z "$b" ] && continue
set -- $b
local bf="$BADGE_DIR/${name}_$1.png"
[ -f "$bf" ] || magick -size "${d}x${d}" xc:none \
-fill "$YELLOW" -draw "circle $br,$br $br,1" \
-gravity center -font "$NUMFONT" -pointsize $((br * 6 / 5)) -fill black -annotate +0+0 "$1" \
"$bf"
args+=( "(" "$bf" ")" -geometry "+$((bx - br))+$(($3 - br))" -composite )
done <<< "$badges"

# Legend (yellow number + light body text), one line per entry.
local i=0
while IFS= read -r l; do
[ -z "$l" ] && continue
local num="${l%%|*}" text="${l#*|}" y=$((ly0 + i * dy))
args+=( -font "$NUMFONT" -pointsize "$pt" -fill "$YELLOW" -annotate "+${lx}+${y}" "$num" )
args+=( -font "$TEXTFONT" -pointsize "$pt" -fill "$LIGHT" -annotate "+$((lx + 38))+${y}" "$text" )
i=$((i + 1))
done <<< "$legend"

args+=( "$output" )
magick "${args[@]}"
echo "wrote $output ($(magick identify -format '%wx%h' "$output"))"
}

# ---- Menu-bar dropdown (RGB) ----
annotate screenshot-dropdown "#1F1F1F" 0 58 18 731 40 372 46 25 \
"1 690 55
2 668 148
3 658 213
4 658 280" \
"1|Open the full controls, or close the popover
2|Power, and the mode: RGB / White / Warm Glow / Scenes
3|Brightness — drag to 0 to turn off
4|Colour — drag the hue"

# ---- Controls — colour (RGB) ----
annotate screenshot-rgb "#1E1E1E" 1530 70 24 1257 50 1574 56 30 \
"1 1155 222
2 980 347
3 890 700
4 1020 1175
5 1170 1465" \
"1|Pick a saved light and Connect / Disconnect; Discover scans the LAN
2|Power, and the colour mode (RGB / White / Warm Glow / Scenes)
3|Colour wheel — drag to set hue and saturation
4|RGB / HSV / hex entry — fine-tune the exact colour
5|\"Brighter colours\" mixes in the white LEDs — brighter, a little less saturated"

# ---- Controls — white & presets ----
annotate screenshot-white "#1E1E1E" 970 70 24 1273 50 1014 56 30 \
"1 980 347
2 1190 480
3 1190 600
4 595 800" \
"1|Mode — here White (tunable colour temperature)
2|Brightness
3|Temperature — warm ↔ cool
4|Presets — tap to apply; \"Save current…\" adds one"

# ---- Controls — Warm Glow ----
annotate screenshot-warmglow "#1E1E1E" 860 70 24 1265 50 904 56 30 \
"1 980 347
2 1190 480
3 1190 560
4 595 750" \
"1|Mode — Warm Glow (an overlay on white)
2|Brightness — the only control you set
3|Temperature follows brightness automatically — warmer as you dim
4|Warm Glow presets — one-tap cosy levels"

# ---- Controls — Scenes ----
annotate screenshot-scenes "#1E1E1E" 1530 70 24 1267 50 1574 56 30 \
"1 980 347
2 885 500" \
"1|Mode — Scenes (shown only for bulbs that support them)
2|Tap a scene to run it; the active one is ringed (brightness + speed sit below)"

# ---- Discover ----
annotate screenshot-discover "#1E1E1E" 0 70 18 993 40 520 46 25 \
"1 905 52
2 875 242
3 470 400" \
"1|Scan the LAN for bulbs; Done closes the sheet
2|A saved light shows its status — Disconnect, or its row menu to Rename / Remove
3|Newly found bulbs appear here — Save one to keep it"

# ---- Settings ----
annotate screenshot-settings "#1E1E1E" 1300 70 24 1259 50 1344 56 30 \
"1 1180 366
2 1180 729
3 1180 843
4 1180 957
5 1180 1142" \
"1|Device — signal, MAC, firmware, model and its capabilities
2|Auto-sync from the light when the app launches
3|When the Mac sleeps / shuts down — turn the light off, and optionally restore it
4|Open at login (needed to restore the light after a shutdown)
5|Updates — automatic, or check now"

echo "done."