# Changelog

All notable changes to clucks.net are documented here.  
Follows [Common Changelog](https://common-changelog.org) and [Semantic Versioning](https://semver.org).  
Written for developers. Contains chickens.

---

## [1.9.0] - 2026-05-04

### Added

- **NET RX / NET TX stat blocks** — NORAD row 3 now shows live network throughput for the streaming host. RX = camera ingest from UniFi, TX = RTMP upload to YouTube. Updates every 5 seconds. Useful for confirming both streams are pushing and the internet hasn't given up.
- **MOON PHASE** — NORAD row 3 now shows current moon phase as emoji + name (e.g. 🌖 WANING GIBBOUS). Pure JS, no API, no network call, never goes OFFLINE. Calculated from orbital mechanics. The hens are unaware.

---

## [1.8.2] - 2026-05-03

### Changed

- **SEO overhaul** — title tags and meta descriptions rewritten across all pages to lead with "Chicken Cam" keyword. Meta descriptions now lead with the value prop (free, ad-free, instant view, no clicking about) rather than hen names. Added Omlet Eglu Cube as explicit keyword target. OG type changed from `website` to `video.other` on index pages.
- **Structured data** — LD+JSON upgraded on index pages. `VideoObject` now includes `uploadDate`, `embedUrl`, `contentUrl`, `keywords`, and `broadcastDisplayName`. `WebSite` schema with `SearchAction` added to main page.
- **Hidden `h1`** — crawler-visible heading added to both index pages (visually hidden, accessible). Previously no `h1` existed on live cam pages.
- **Sitemap** — `/CHANGELOG.md` added; `lastmod` dates updated. Bogus `/run` entry removed (index-run.html has no separate public URL; both index files serve as `https://clucks.net/`).
- **NORAD row 3** — `SOLAR OUTPUT` split into `SOLAR S` (south, 3.6 kWp) and `SOLAR N` (north, 3.2 kWp). IDs `solar-south`, `solar-north`, `battery`. All remain `OFFLINE` pending Teslemetry integration after May 2026 install.
- **about.html** — solar section updated to reference both arrays (3.6 kWp south + 3.2 kWp north = 6.8 kWp total) and heat pump. Solar grid corrected to match. Title reordered for keyword prominence.
- **"rescue hens" corrected** — Run cam OG/LD+JSON previously described the hens as rescue hens. They are not. Fixed.

---

## [1.8.1] - 2026-05-02

### Changed

- **NEXT DOOR ACTION close countdown** — both index pages now count down to **dusk + 15 minutes** instead of exact sunset. Mirrors HA automation change: door close trigger moved from light-level threshold to sunset + 15 min offset. Countdown display, colour thresholds, and "CLOSING SOON" state unchanged.

---

## [1.8.0] - 2026-04-30

### Added

- **Changelog links** — `📋 CHANGELOG` link added to: bottom of the "Meet the flock" popup, bottom of the "About ClucksNet" popup (footer bar below iframe), bottom of `about.html`, and bottom-left link stack on both index pages. Opens `/CHANGELOG.md` in a NORAD-style iframe modal on index pages; direct link on about.html.
- **Changelog overlay modal** — same iframe-in-overlay pattern as the About overlay. Close button top-right, click-outside-to-dismiss. Loads lazily. Available on both index pages.
- **Bottom-left link stack repositioned** — stack order bottom-to-top: ● LIVE · CHANGELOG · WATCH IN HD · ABOUT CLUCKS.NET.
- **Sprinkler control** — viewers can water the hen run from the website. 10 seconds of water, 60-second cooldown, one session at a time, daytime only, temp must be >10°C, no precipitation. Enforced both client-side and server-side because trust nobody, not even yourself.
- **Pre-water confirmation modal** — explains all the rules before firing. Includes prominent note about YouTube's ~30 second stream delay so viewers don't think it's broken. The hens have not been consulted.
- **Weather-gated watering** — checks Open-Meteo WMO weather codes before allowing. Blocks on rain, drizzle, showers, thunderstorm. Snow excluded because if it's snowing it's definitely below 10°C anyway. Basic thermodynamics.
- **SPRINKLER stat block** in NORAD row 3 — shows `READY · TAP TO WATER`, `WATERING... Xs`, `COOLING DOWN Xs`, `TOO COLD`, `RAINING`, or `OFFLINE (NIGHT)`.
- **Total visitor counter** — increments on new/returning visitors (5-min window). Displayed in NORAD panel as `X Online / ### Total`.
- **YouTube channel description** — rewritten for discoverability. Hook-first, humour throughout, correct tech references. Hen names relegated to after the truncation point where they belong.
- **External YouTube description files** — descriptions moved out of `chickencam_daily.py` into separate text files. Edit copy without touching Python. Revolutionary concept.
- **Old broadcast cleanup** — `delete_old_broadcasts()` added to `chickencam_daily.py`. Runs after each nightly rotation, deletes all `complete` broadcasts except today's. YouTube Studio is now peaceful.
- **Random quote panel** — draggable NORAD-style box, bottom of screen, loads a random quote on page load. 700+ quotes covering: anti-news, anti-corporate, Agile/Waterfall/Kanban satire, AI layoff humour, battery hens vs open plan offices, TPS reports, Terraform/IaC jokes, UAP/alien conspiracy (the hens know about the P47s and P52s and aren't talking), and general hen philosophy.
- **Quote word-wrap on mobile** — previously quotes extended into the void on iOS. The void has been addressed.
- **Close buttons** on NORAD panel and quote box — small ✕, reload to restore. The hens remain on screen regardless.

### Changed

- **Viewer display** — was `X ttl (Y YT · Z WEB)`, now `X Online / ### Total`. Label changed from `VIEWERS · 5 MIN` to `VIEWERS / TOTAL`.
- **`chickencam_daily.py`** — description strings removed, replaced with file loader. Script ~80 lines shorter. Tech references corrected throughout.
- **YouTube stream descriptions** — rewritten. Opens with the hook, not the hen names. mediamtx removed and replaced with accurate FFmpeg pipeline description.
- **Wind display** — changed from km/h to mph. This is Yorkshire. The Met Office uses mph. So do we now.

### Fixed

- **Double cooldown countdown** — polling was starting a second countdown on top of the existing one. Fixed with guard flag. Countdowns now singular.
- **Stale water lock** — empty lock file from previous session caused NORAD to show `WATERING...` on page load despite nobody watering anything.

---

## [1.7.0] - 2026-04-28

### Added

- **About page** (`/about`) — full NORAD-aesthetic page covering the flock, the Eglu, the technology stack, radiation monitor, solar plans, and YouTube links. Linked from NORAD panel (ⓘ button) and bottom of page.
- **About overlay** — clicking ⓘ in NORAD panel or `ABOUT CLUCKS.NET` link opens `/about` in an iframe modal. Closes on ✕ or clicking outside. No page navigation.
- **Draggable NORAD panel and PiP** — mouse and touch drag for both the status panel and the PiP window. PiP click-to-swap preserved via drag detection flag.
- **YouTube dynamic links in about.html** — fetches live stream data on load, patches YouTube links. Links are always current after 3am rotation.
- **`/test` directory** — staging area for HTML files before promotion.

### Changed

- **Info button** — icon changed from ⓘ SVG to 🐔 emoji. The about button (new) gets the ⓘ.
- **`ABOUT CLUCKS.NET` link** — moved to bottom-left stack. Stack order bottom-to-top: ● LIVE · ⎋ WATCH IN HD · ABOUT CLUCKS.NET.
- **about.html content** — corrected: hens are not rescue hens (bought point-of-lay, April 2026, wife's birthday), not a smallholding (detached house with garden), mediamtx removed, YouTube CDN pipeline described accurately, Eglu door now HA-controlled, Tessa is ~~chief supervisor~~ absolute dictator, Octopus Intelligent Go with Export mentioned, solar section updated.
- **Mobile responsiveness** — panel reflows to full width, stat blocks wrap, buttons span full width, PiP scales to 40vw.

---

## [1.6.0] - 2026-04-28

### Added

- **Live viewer count** — queries YouTube Data API v3 for concurrent viewers on both streams. Tracks active web visitors via hash (5-min window). Combined display in NORAD panel.
- **NORAD panel layout finalised** — three rows:
  - Row 1: EXT TEMP · INT TEMP · EXT HUMIDITY · INT HUMIDITY · RADIATION · PERIMETER · buttons
  - Row 2: AMBIENT LIGHT · NEXT DOOR ACTION · LAST OPENED · CONDITIONS · WIND · FLOCK STATUS · VIEWERS/TOTAL
  - Row 3: SOLAR OUTPUT · BATTERY · SPRINKLER
- **INT HUMIDITY** — interior humidity added to panel. Colour bands: green 40–70% (ideal), amber 30–40% or 70–85% (watch it), red <30% or >85% (hen health risk). Based on poultry welfare research.
- **Buttons** — reload (↺), fullscreen (⤢), 🐔 (hen info), ⓘ (about). All 38px wide, consistent.

### Fixed

- **Cloudflare caching PHP responses** — PHP endpoints now bypass cache. Viewer count was returning stale `0` despite counter incrementing correctly.
- **Apache vhost** — fully rewritten cleanly after multiple conflicting rules were resolved.

---

## [1.5.0] - 2026-04-27

### Added

- **`live.json` support** — `chickencam_daily.py` writes current video IDs to web server after each rotation. Index pages fetch on load, populate YouTube player IDs dynamically. Fallback IDs hardcoded for resilience.
- **`⎋ LOCATING CAMERA FEEDS`** — hd-link shows this on load, updates to `⎋ WATCH IN HD` with correct URL after `live.json` fetched.
- **HTML update removed from `chickencam_daily.py`** — `live.json` is the single source of truth.
- **PiP camera swap** — click PiP to swap main/PiP cameras. Drag detection prevents swap firing after drag gesture.
- **Stream monitor** — pushes to live edge every 120 seconds. Threshold: >40s behind live edge.

### Changed

- **Resolution** — FFmpeg scale changed from 1280×720 to 1920×1080. HLS containers removed. YouTube-only pipeline now.
- **`docker-compose.yml`** — now contains only the two camera containers. Clean.

---

## [1.4.0] - 2026-04-26

### Added

- **NORAD-style status panel** — fixed top-right, dark background, green border, Share Tech Mono font. Three rows of stat blocks.
- **HA proxy** — PHP script proxying Home Assistant API to frontend. Referrer-gated. Entity whitelist. Exposes: interior temp/humidity, door state, ambient light, last open/close time, radiation CPM, sun state/elevation.
- **Radiation monitor** — GQ GMC-800 Geiger counter connected to HA via USB. Displayed in NORAD panel. Colour: green ≤50 CPM, amber 51–100, red >100. Normal background in North Yorkshire: 10–50 CPM. If it goes red, something interesting has happened.
- **Weather via Open-Meteo** — exterior temp, conditions (WMO codes mapped to readable strings), wind speed+direction (compass), exterior humidity. No API key required.
- **Flock status** — derived from sun elevation: ROOSTING (<-6°), DUSK/DAWN (transitional), SHELTERING (low light, door open), FORAGING (daytime, light >30%).
- **Door countdown** — shows time until door opens (if EGLU SECURED) or time until door closes (if EGLU BREACHED). Sub-1h shows amber.
- **`EGLU BREACHED`** — door open state. Blinks amber. Margo approves of the drama.

### Changed

- **Apache vhost** — all key files whitelisted via RewriteRules. Catch-all 301 redirects everything else to `https://clucks.net/`.

---

## [1.3.0] - 2026-04-25

### Added

- **Dual-camera layout** — main player fullscreen, PiP bottom-right (28vw, min 200px, max 420px, 16:9). PiP has LIVE badge. Click to swap.
- **YouTube IFrame API** — both players initialised. Quality forced to `hd1080` (main) and `hd720` (PiP).
- **`index-eglu.html`** — Eglu Cube cam primary, Run cam PiP.
- **`index-run.html`** — Run cam primary, Eglu Cube cam PiP.

---

## [1.2.0] - 2026-04-24

### Added

- **YouTube streaming pipeline** — UniFi G5 Turret Ultra cameras → RTSPS → Docker (FFmpeg) → RTMP → YouTube. Two containers.
- **FFmpeg command** — libx264, `veryfast` preset, 6000k bitrate, AAC stereo silent audio track (YouTube ingest requirement), 30fps, 1920×1080.
- **`chickencam_daily.py`** — nightly rotation at 3am via cron. Creates fresh YouTube broadcast events, binds to persistent RTMP stream keys, restarts Docker containers, writes `live.json`. OAuth2 via `google-auth-oauthlib`. Stream keys are persistent; broadcast IDs rotate daily.

### Changed

- **HLS streaming abandoned** — self-hosted mediamtx/nginx-rtmp caused stuttering with multiple concurrent viewers. YouTube CDN solves the egress problem entirely. Latency trade-off (~30s vs ~5s) accepted.

---

## [1.1.0] - 2026-04-24

### Added

- **`clucks.net` domain** — Cloudflare DNS, proxied. Apache 2.4 web server. Accessible from Mac via NFS mount.
- **Self-hosted HLS streaming** — mediamtx → nginx-rtmp → HLS. Abandoned in same release due to multi-viewer stuttering. Documented here for posterity and to explain why there are ghost containers in early docker-compose versions.

---

## [1.0.0] - 2026-04-10

### Added

- Four hens (Crumpet, Triborg, Mishelle, Margo Leadbetter). Point-of-lay. Bought as a birthday surprise for wife. They have settled in with considerable confidence and very little gratitude.
- Omlet Eglu Cube with automatic door. Door controlled by Home Assistant based on sunrise/sunset calculations.
- Two UniFi G5 Turret Ultra cameras.
- Tessa (Bichon Frisé). Self-appointed dictator of the run. Not a hen.

---

*"The hens do not know this changelog exists. The hens are fine."*
