You’re a developer. You have smart lights. They turn on when you clap or yell at a cylinder. Congratulations, you’ve automated nothing meaningful.

Real home automation is infrastructure. Let’s build it properly.

The Stack That Works

Home Assistant — The hub. Open source, local-first, integrates with everything. Run it on a Raspberry Pi, a NUC, or a VM.

Zigbee/Z-Wave coordinator — Wireless protocols that don’t depend on WiFi or cloud services. Zigbee2MQTT or ZHA for Zigbee, Z-Wave JS for Z-Wave.

MQTT broker — The message bus. Mosquitto is the standard. Lightweight, fast, reliable.

Node-RED — Visual automation for complex flows. Optional but useful for logic that’s awkward in YAML.

[Sensors][ZigbeeCoordinator][N[oMdQeT-TR]ED][(HcoommeplAesxsilsotgainct)][Automations]

Why Local Matters

Cloud-dependent smart home devices are:

  • Unreliable — Internet outage = dark house
  • Slow — Round trip to server adds latency
  • Ephemeral — Company goes under, devices become bricks
  • Privacy nightmares — Your usage data lives on someone else’s server

Local-first means:

  • Works offline
  • Instant response
  • You control the data
  • Devices work forever (or until hardware dies)

Automation Patterns

Presence-Based

The most valuable automations react to who’s home.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Home Assistant automation
automation:
  - alias: "Welcome Home"
    trigger:
      - platform: state
        entity_id: person.me
        to: "home"
    condition:
      - condition: sun
        after: sunset
    action:
      - service: light.turn_on
        target:
          entity_id: light.living_room
        data:
          brightness_pct: 70
          color_temp: 350

Presence detection options:

  • Phone WiFi/Bluetooth — Home Assistant companion app
  • GPS geofencing — Good for “arriving soon” triggers
  • Motion sensors — Room-level presence
  • mmWave radar — Detects stationary presence (sitting, sleeping)

Layer them. GPS for macro presence, motion for micro.

Time + Context

Simple schedules are table stakes. Context makes them smart.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
automation:
  - alias: "Morning Lights"
    trigger:
      - platform: time
        at: "06:30:00"
    condition:
      - condition: state
        entity_id: binary_sensor.workday
        state: "on"
      - condition: state
        entity_id: person.me
        state: "home"
      - condition: numeric_state
        entity_id: sensor.bedroom_illuminance
        below: 50
    action:
      - service: light.turn_on
        target:
          entity_id: light.bedroom
        data:
          brightness_pct: 30
          transition: 300  # 5 minute fade

This only triggers on workdays, when home, when it’s actually dark. Not a dumb timer.

State Machines

Complex automations need state tracking.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
input_select:
  home_mode:
    options:
      - Home
      - Away
      - Sleep
      - Guest

automation:
  - alias: "Set Sleep Mode"
    trigger:
      - platform: time
        at: "23:00:00"
    condition:
      - condition: state
        entity_id: input_select.home_mode
        state: "Home"
    action:
      - service: input_select.select_option
        target:
          entity_id: input_select.home_mode
        data:
          option: "Sleep"
      - service: light.turn_off
        target:
          entity_id: all
      - service: climate.set_temperature
        target:
          entity_id: climate.thermostat
        data:
          temperature: 68

Mode changes cascade to multiple systems. One trigger, coordinated response.

Sensor Fusion

Combine sensors for reliability.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
binary_sensor:
  - platform: template
    sensors:
      kitchen_occupied:
        friendly_name: "Kitchen Occupied"
        value_template: >
          {{ is_state('binary_sensor.kitchen_motion', 'on') or
             is_state('binary_sensor.kitchen_mmwave', 'on') or
             (states('sensor.kitchen_power') | float > 100) }}
        delay_off:
          minutes: 5

Motion sensor OR mmWave radar OR significant power draw = occupied. Much more reliable than any single sensor.

Hardware Worth Buying

Sensors

Motion: Aqara P1 or Hue motion sensors. Fast, reliable, Zigbee.

Door/window: Aqara contact sensors. Cheap, tiny, last years on a battery.

Temperature/humidity: Aqara or Sonoff SNZB-02. Put one in every room.

mmWave presence: Aqara FP2 or DIY with ESP32 + LD2410. Game changer for room presence.

Actuators

Lights: Anything Zigbee. Hue bulbs are expensive but excellent. IKEA Tradfri is budget-friendly.

Switches: Inovelli or Zooz for Z-Wave. Sonoff for Zigbee. Replace dumb switches, keep existing bulbs.

Outlets: Sonoff S31 (flash with Tasmota) or Zigbee smart plugs.

Locks: Z-Wave locks (Schlage, Yale) for local control. Avoid WiFi-only locks.

Infrastructure

Coordinator: SONOFF Zigbee 3.0 USB Dongle Plus (flash with Zigbee2MQTT firmware) or SkyConnect.

Host: Raspberry Pi 4 (dedicated) or any Linux box. Home Assistant OS is easiest.

Network: Separate IoT VLAN if you’re paranoid (you should be).

The VLAN Setup

IoT devices are security liabilities. Isolate them.

MIHaooiTmneYPTNSSSCCCNohrememaAaaeuoutanamsnntrnswrsreswetototrirrocserraseerodkbspstaakmulaccpd(lunhh(ue1bgt1tv9ssIm9ei2(oa2rc.1Ti.se19n1s62n68.en8.1te.26wt1.8ow.0.ro0/1kr/2.k2414)0))

Firewall rules:

  • IoT devices cannot initiate connections to main network
  • IoT devices can respond to Home Assistant
  • IoT devices have no internet access (optional but recommended)

Your smart bulb doesn’t need to phone home.

Avoiding Common Mistakes

Don’t Over-Automate

The best automation is invisible. If you have to think about it, it’s wrong.

Bad: “When I triple-tap the light switch, set movie mode” Good: “When the TV turns on after sunset, dim the lights”

Handle Edge Cases

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
automation:
  - alias: "Turn off lights when leaving"
    trigger:
      - platform: state
        entity_id: person.me
        to: "not_home"
        for:
          minutes: 10  # Don't trigger on GPS glitches
    condition:
      - condition: state
        entity_id: input_boolean.guest_mode
        state: "off"  # Don't turn off if guests are over
    action:
      - service: light.turn_off
        target:
          entity_id: all

The for clause prevents false triggers. The guest mode check prevents awkward situations.

Build Manual Overrides

Every automation needs an escape hatch.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
automation:
  - alias: "Auto lights with override"
    trigger:
      - platform: state
        entity_id: binary_sensor.motion
        to: "on"
    condition:
      - condition: state
        entity_id: input_boolean.auto_lights
        state: "on"  # Manual override switch
    action:
      - service: light.turn_on
        target:
          entity_id: light.room

A physical button or dashboard toggle to disable automations when they’re in the way.

Test Before Deploying

Home Assistant has a “Developer Tools” section. Use it.

1
2
3
# Test your conditions
{{ is_state('person.me', 'home') and 
   is_state('sun.sun', 'below_horizon') }}

Template editor shows exactly what your conditions evaluate to.

Start Here

  1. This week: Install Home Assistant, add one Zigbee sensor
  2. This month: Presence-based lighting in one room
  3. This quarter: Whole-house presence + climate automation
  4. This year: Full local control, no cloud dependencies

Home automation done right is infrastructure that fades into the background. The house just works. You stop thinking about lights, locks, and thermostats entirely.

That’s the goal.


The best smart home is one where you never open an app. The house knows what you need before you do.