Custom Home Automation with Node-RED

Custom Home Automation with Node-RED

I spent months wrestling with proprietary home automation platforms—locked ecosystems, cloud dependencies, vendor lock-in. Then I discovered Node-RED, and everything changed. It's a visual programming tool that lets you wire together automation logic without touching a line of code. Within a week, I had more control over my home than I ever did with commercial hubs.

If you're tired of limitations and want to build automation that works exactly the way you want it, this is your guide.

Why Node-RED Changed My Approach to Home Automation

Before Node-RED, I was juggling Zigbee hubs, MQTT brokers, and multiple cloud services. The friction was real. Node-RED sits in the middle and glues everything together. It runs on Docker, Raspberry Pi, or any Linux box. The visual editor means I can build complex workflows in minutes—and I can see exactly what's happening at every step.

The biggest win: I'm not locked into anyone's ecosystem. My philips Hue lights talk to MQTT. My smart thermostat works through an HTTP API. My door sensors use Zigbee. All of it flows through Node-RED as a single source of truth.

Setting Up Node-RED in Docker

I run Node-RED in a Docker container on my homelab server alongside other services. Here's my full Docker Compose setup:

version: '3.8'

services:
  node-red:
    image: nodered/node-red:latest
    container_name: node-red
    restart: unless-stopped
    ports:
      - "1880:1880"
    volumes:
      - /data/node-red:/data
      - /etc/localtime:/etc/localtime:ro
    environment:
      - TZ=UTC
      - NODE_RED_ENABLE_PROJECTS=true
    networks:
      - homelab
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:1880/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    restart: unless-stopped
    ports:
      - "1883:1883"
      - "9001:9001"
    volumes:
      - /data/mosquitto/config:/mosquitto/config
      - /data/mosquitto/data:/mosquitto/data
      - /data/mosquitto/log:/mosquitto/log
    networks:
      - homelab

networks:
  homelab:
    driver: bridge

Deploy this with docker-compose up -d. Node-RED will be accessible at http://your-server:1880. Mosquitto runs as your MQTT broker on port 1883.

Tip: Create the data directories on your host before running the compose file: mkdir -p /data/node-red /data/mosquitto/{config,data,log}. Node-RED will persist your flows and settings across restarts.

Installing Essential Nodes

Out of the box, Node-RED comes with basic nodes. I immediately add community nodes for more power. Access the palette manager from the hamburger menu → Manage Palette.

Here are the nodes I install on every setup:

Search for each in the palette manager and click "Install". This takes less than a minute per node.

Building Your First Automation: Motion-Triggered Lights

Let me walk you through a real automation I use daily. When motion is detected in my living room after sunset, lights turn on at 40% brightness. After 5 minutes of no motion, they fade down.

Here's the flow exported as a JSON blob. Import this into Node-RED by copying it, then Ctrl+I and pasting:

[
  {
    "id": "motion_sensor",
    "type": "mqtt in",
    "topic": "home/living_room/motion",
    "qos": 0,
    "x": 100,
    "y": 100
  },
  {
    "id": "check_time",
    "type": "function",
    "func": "const hour = new Date().getHours();\nmsg.payload = (hour >= 19 || hour < 7) ? true : false;\nreturn msg;",
    "x": 300,
    "y": 100
  },
  {
    "id": "conditional_switch",
    "type": "switch",
    "property": "payload",
    "propertyType": "msg",
    "rules": [{"t": "true"}],
    "checkall": "false",
    "x": 500,
    "y": 100
  },
  {
    "id": "light_control",
    "type": "mqtt out",
    "topic": "home/living_room/light/brightness",
    "qos": 0,
    "retain": false,
    "x": 700,
    "y": 100
  },
  {
    "id": "set_brightness",
    "type": "function",
    "func": "msg.payload = 40;\nreturn msg;",
    "x": 600,
    "y": 100
  }
]

This is just the trigger. In the real flow, I also add a delay node set to 5 minutes, followed by another MQTT node that publishes 0 (off) to turn off the lights. The beauty is I can see every message flowing through the system in real time.

Watch out: Node-RED flows block the event loop if you run heavy processing. If you're doing intensive calculations, offload to an external function or use a dedicated service. I learned this the hard way when one poorly-written function caused dashboard delays.

Connecting to Home Assistant and Other Services

Many of us run Home Assistant. Node-RED plays beautifully with it. You can integrate via MQTT (if HA has the integration enabled) or directly through webhooks.

To trigger a Home Assistant automation from Node-RED, use an HTTP POST node pointing to your Home Assistant webhook. Configure it like this in a function node:

msg.url = "http://home-assistant.local:8123/api/webhook/node_red_trigger_abc123";
msg.method = "POST";
msg.headers = {
  "Content-Type": "application/json"
};
msg.payload = {
  "action": "activate_scene",
  "scene_name": "movie_time"
};
return msg;

Then pipe that into an HTTP Request node. Home Assistant receives the webhook and executes your automation. This decouples Node-RED from HA, so if one goes down, the other continues independently.

Building a Dashboard

The node-red-dashboard module gives you a web interface to control and monitor your home. I use it to see all sensor states at a glance, control lights manually, and trigger scenes.

Add a dashboard gauge for temperature:

The dashboard is mobile-responsive. I access it from my phone to check heating status or unlock doors remotely. No special app—just a responsive web interface.

Storage and Data Retention with InfluxDB

After a week of automation, you'll want historical data. I store temperature, humidity, and motion events in InfluxDB, then visualize them in Grafana.

Add the InfluxDB node to your flow. Configure it with:

Pass JSON like this into the InfluxDB node:

msg.payload = {
  temperature: 22.5,
  humidity: 45,
  location: "living_room"
};
return msg;

InfluxDB stores it with a timestamp. Months of data let me spot patterns—like how my heating cycles or when humidity spikes near the bathroom.

Next Steps: Advanced Automations

Once you master the basics, Node-RED scales. I've built workflows that:

The key is starting small. Pick one real problem in your home—lights that never turn off, a room that's always too cold, alerts you need but don't get—and build a flow to solve it. You'll learn the patterns, and soon you'll be automating things you didn't know you could.

Ready to go deeper? Export your flows as JSON, version-control them in Git, and treat your home automation like you treat code. I keep mine in a private Gitea repo so I can roll back changes if something breaks. And always test on a single device before rolling out to your whole house.

```