Skip to content
D · 06 · TECHNICAL WRITE-UP

Homelab.

The hardware that runs everything else on this site.

Two parts that act like one. A segmented network (OPNsense + UniFi, six VLANs) and a self-learning climate + energy system (Homey Pro v18, 152 devices, BigQuery behind it). The other technical projects on this site run on top of this. Documentation lives in two private repos — this page is the public version.

  • SCOPE A single house · production
  • DEVICES 152 across 31 zones (climate side) · 7 APs · 7 cameras (network side)
  • DATA 5-minute sample cadence → Cloud Run → BigQuery
  • STATUS Production · docs private · this page is the summary
01 · THE NETWORK

Six VLANs, segmented on purpose.

The network exists so the rest of the system can. Every service that runs locally — climate, audio, surveillance, automations — sits on a VLAN that matches its trust level. A misbehaving device gets blast-radiused by its segment, not by the firewall's patience.

VLANPurpose
ManagementNetwork infrastructure itself — firewall, switches, controllers.
SecureHigh-trust devices, including the surveillance recorder. Tight egress.
TrustedPersonal laptops, phones, workstations.
IoTSmart-home devices that should never talk to anything they don't have a reason to talk to.
GuestAnyone visiting. No lateral access.
Management LAN (legacy)Bootstrap-only path that exists so a misconfiguration on a VLAN never locks the network out of itself.

The hardware behind it

LayerDetail
FirewallOPNsense with ISC DHCPv4. KPN delivers WAN as PPPoE over VLAN 6 — that single config is the load-bearing piece between the house and the internet.
SwitchingUniFi Aggregation (10Gb uplink from KPN) → PoE Pro switch (10Gb to Aggregation) → USW24 for distribution (1Gb fiber).
WirelessSeven UniFi access points. Two SSIDs broadcast — one bound to the Trusted VLAN, one to the IoT VLAN — so a smart bulb never lands on the same broadcast domain as a laptop.
CamerasSeven UniFi Protect cameras + one UNVR. Recording stays on the Secure VLAN; egress is firewalled at the network boundary.
Inter-VLAN servicesmDNS reflection, UDP broadcast relay, and IGMP Proxy configured per-VLAN. Required to make AirPlay and multi-brand multiroom discovery work across segments.
02 · CLIMATE + LIGHTING

One Homey Pro, one v18 controller, 152 devices.

The climate side is a self-learning thermostat with real feedback loops, not a thermostat with an app. Lighting and presence run on the same hub through the same scripting layer.

LayerDetail
ControllerCustom Homey Pro v18 — seasonal ranges, cold-feet prevention, comfort-signal model. The previous controllers (v14 → v17) are kept as references so behaviour drift is debuggable.
HeatingFive active floor-heating zones (1e verdieping) via Fibaro Smart Implant. Three pending zones on the ground floor. Heat pump is driven by a Fibaro Q2 wall relay rather than the heat pump's own thermostat.
Air conditioningSix Daikin units. The Daikin cloud API is rate-limited to 200 calls/day per account, which the controller respects — polling cadence is the budget.
Sensors25+ temperature sensors feeding a thermal model. Per-room thermal lag measured (35–55 min total) and used by the controller's lookahead.
Heating-rate ceilingMax measured 1.58°C/hour (Bijkeuken). The controller respects per-room ceilings — anything faster is a sensor reporting wrong, not a comfort win.
Lighting30 flows + 24 HomeyScript scripts. Presence-aware, scene-aware, motion-aware per room. 'Adaptive' in the sense that the rules adapt to the time of day and the mode of the house, not in the sense that an LLM picks the temperature.
03 · ENERGY ARBITRAGE

The house front-runs the grid.

Dynamic Dutch energy prices change every hour and tomorrow's curve lands after 13:00. The controller plans heating, EV charging, and battery dispatch against the next 24 hours — not the current price.

SystemRole
TibberDynamic energy prices (tomorrow's prices land after 13:00). The controller plans heating + EV charging against the price curve, not against the clock.
EnphaseSolar production + house battery. JWT-token refresh handled by the integration; the battery dispatches against the same price curve the heating reads.
ZaptecEV wall-charging, driven by Tibber pricing. Charge during low-price windows by default; override by hand when needed.
Load sheddingenergie_loadshed.js — the moment grid draw approaches the contract cap, the controller sheds the lowest-priority loads (deferred-acceptable ones first) instead of tripping the main.
EVsVehicle state-of-charge reports into the same data plane; charging syncs against the same price + load curve.
04 · AUDIO

Multi-brand audio — on one fabric.

Multi-brand audio on a segmented network is mostly a multicast problem. mDNS reflection, IGMP Querier and STP priority are the unglamorous primitives that make multiroom "just work" across VLANs.

BrandDetail
Primary multiroom stackA paired set that needs PTP sync — EEE disabled at the switch port to keep the clock stable — plus a vendor API exposed on a fixed port. Does multiroom and Apple AirPlay across rooms.
Second multiroom brandConfigured with STP priority + IGMP Querier so multicast discovery survives the VLAN-segmented network.
WiFi-only pairDeliberately kept on the same VLAN as the controller, on 5GHz, so the vendor's auto-pairing works at all.
05 · DATA PIPELINE

Homey Pro → Cloud Run → BigQuery.

The same data plane behind every interesting decision in the house. 152 devices × 5-minute cadence = a real time-series, validated on ingest and persisted long-term for analysis.

LayerDetail
CaptureHomey Pro polls 152 devices every 5 minutes — sensors, switches, climate units, EV chargers, the lot.
Validate + ingestCloud Run worker validates the payload, drops malformed rows, and inserts into BigQuery (home_data.measurements).
AnalyseBigQuery is the long-term store. Thermal-model fitting, energy-arbitrage backtests, lighting-pattern analysis — all SQL against the same table.
Loop backLessons from the offline analysis become controller-version bumps (v17 → v18). The production loop stays simple; the analysis loop stays curious.
06 · NOTABLE DESIGN CHOICES

The lessons the network learned the hard way.

Segment before you optimise
Six VLANs. The IoT VLAN exists so a smart appliance with questionable firmware physically cannot pivot to a workstation. Every other 'smart home' problem is easier once that's true.
Keep a bootstrap path
The management LAN on the untagged native subnet stays around. Not for production — for the day a VLAN change is wrong and the firewall has to be reached without the VLAN config that's broken.
OPNsense, single owner
ISC DHCPv4 is on; Kea and Dnsmasq are off. One DHCP service, one source of truth. Configurations that 'mostly' work because multiple services are mostly-coordinating are how networks rot in private.
Inter-VLAN services are explicit, not implicit
mDNS reflection, UDP broadcast relay, IGMP Proxy. Each one written down per-VLAN, because every audio brand needs a slightly different one and forgetting one breaks the multiroom in a subtle way.
Climate is a controller, not a chatbot
The v18 thermostat is a deterministic model with seasonal ranges and cold-feet prevention. No LLM picks the setpoint. AI lives in the offline analytics layer that explains why a zone behaved oddly — not in the production loop.
Energy arbitrage uses tomorrow's prices
Tibber publishes the next day's price curve after 13:00. Heating windows + EV charging schedule against the next 24h, not the current hour. The house front-runs the grid.
Daikin's rate limit is the polling budget
200 calls/day per Daikin account. The controller treats that as a hard budget, not a guideline — adapts polling cadence per unit so the cap is never hit and the API stays responsive.
Logs are the ground truth
Every measurement, every controller decision, every device state lands in BigQuery via the sensor_uploader pipeline. Every weird behaviour can be back-traced. The data plane is the debugger.
WHY THIS EXISTS

Half of it is craft for craft's sake — running a real network at home is a privilege and a hobby. The other half is operational: if Luminary needs a fresh checkout to deploy from, or Shop Life needs a private WhatsApp webhook to land, or Bedtime Stories needs a place to render that isn't metered — the homelab is the floor everything else stands on. Worth writing down for that reason alone.