BLOG / TUTORIALS / Raspberry Pi Home Automation: Build a Sm…
Стаття блогу

Raspberry Pi Home Automation: Build a Smart Home Hub from Scratch

Viktor Build ~9 min read

Build a complete smart home hub with your Raspberry Pi. This guide covers MQTT broker setup, DHT22 and PIR sensors, relay control, and a Node-RED dashboard — all fully local.

You want to build a smart home system, and you’ve heard the Raspberry Pi is a good place to start. You’re right. In this guide, I’ll walk you through building a complete raspberry pi home automation hub from scratch using MQTT, temperature and motion sensors, and relay modules to control lights or appliances. By the end, you’ll have a working system that you can monitor and control from any device on your home network.

Why Build Your Own Smart Home Hub?

Off-the-shelf smart home systems like Philips Hue or TP-Link Kasa are convenient, but they lock you into their ecosystem, often require cloud accounts, and give you no control over the data your devices generate. Building your own hub means:

  • Full local control — no internet required for core operations
  • Privacy — your sensor data never leaves your home
  • Flexibility — mix and match any sensor or actuator you can wire up
  • Learning — you’ll understand exactly how MQTT, GPIO, and relay logic work under the hood

I’ve been building these systems for years, and the recipe hasn’t changed much: a Raspberry Pi running an MQTT broker, a few ESP8266 or Arduino nodes for sensors, and a web dashboard to tie it all together. We’ll cover the full stack.

What You’ll Need

Before we get into wiring and code, here’s the complete parts list. Most of these are available from any electronics distributor for under $50 total (excluding the Pi).

Hardware

Component Purpose Approx Cost
Raspberry Pi 3B+, 4, or Zero 2 W Central hub / MQTT broker $15–$45
16GB+ microSD card OS + data storage $8
DHT22 temperature/humidity sensor Temp + humidity monitoring $8
HC-SR501 PIR motion sensor Motion detection $4
2-channel 5V relay module Switch lights/appliances $6
Breadboard + jumper wires Prototyping $5
10kΩ resistor (for DHT22 pull-up) Signal stability $1
USB micro power supply (5V 2.5A) Power the Pi $10

Software

  • Raspberry Pi OS Lite (64-bit) — headless, minimal install
  • Mosquitto — MQTT broker
  • Node-RED — visual flow editor for dashboards and logic
  • Mosquitto clients — for testing MQTT from the command line

Step 1: Set Up the Raspberry Pi as an MQTT Broker

MQTT is a lightweight publish/subscribe messaging protocol perfect for IoT. The broker lives on your Pi and relays messages between sensors (publishers) and your dashboard or scripts (subscribers).

Install Raspberry Pi OS

Flash Raspberry Pi OS Lite (64-bit) to your microSD card using the Raspberry Pi Imager. Enable SSH and set a hostname like smarthub during the flash process.

Boot the Pi, find its IP address (check your router’s DHCP list or use arp -a), and SSH in:

ssh pi@192.168.1.100

Update the system:

sudo apt update && sudo apt upgrade -y

Install Mosquitto MQTT Broker

sudo apt install -y mosquitto mosquitto-clients

Mosquitto starts automatically. Test it by publishing a test message from one terminal window:

mosquitto_pub -h localhost -t "test/topic" -m "Hello from Pi"

In another terminal, subscribe:

mosquitto_sub -h localhost -t "test/topic"

You should see the message appear. If you do, the broker is working.

Secure the Broker (Optional but Recommended)

Edit the Mosquitto config:

sudo nano /etc/mosquitto/mosquitto.conf

Add these lines:

listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd

Create a password for user maker:

sudo mosquitto_passwd -c /etc/mosquitto/passwd maker

Restart Mosquitto:

sudo systemctl restart mosquitto

Now all MQTT clients need the username and password to connect.

Step 2: Wire the Sensors and Relay to the Pi

We’ll wire the DHT22, PIR sensor, and relay module to the Pi’s GPIO pins. Disconnect power while wiring.

Wiring Table

Component Pi GPIO Pin Notes
DHT22 VCC Pin 1 (3.3V)
DHT22 DATA Pin 7 (GPIO 4) Add 10kΩ pull-up between DATA and VCC
DHT22 GND Pin 6 (GND)
PIR VCC Pin 2 (5V)
PIR OUT Pin 11 (GPIO 17)
PIR GND Pin 14 (GND)
Relay IN1 Pin 13 (GPIO 27) Controls relay channel 1
Relay IN2 Pin 15 (GPIO 22) Controls relay channel 2
Relay VCC Pin 4 (5V)
Relay GND Pin 20 (GND)

Important note about relay modules: Many relay modules have an active-low trigger pin. That means writing GPIO 27 LOW closes the relay (turns on the connected appliance). Always check your module’s datasheet.

Step 3: Write the Python Code That Publishes Sensor Data

We’ll write a Python script that reads the DHT22 and PIR sensor every 5 seconds and publishes the data to MQTT topics.

Install required libraries:

sudo apt install -y python3-pip
pip3 install adafruit-circuitpython-dht
sudo apt install -y libgpiod2

Create the script:

nano ~/sensor_publisher.py
import time
import board
import adafruit_dht
import RPi.GPIO as GPIO
import paho.mqtt.client as mqtt

# MQTT config
MQTT_BROKER = "localhost"
MQTT_PORT = 1883
MQTT_USER = "maker"
MQTT_PASS = "your_password"
TOPIC_TEMP = "home/sensor/temperature"
TOPIC_HUM = "home/sensor/humidity"
TOPIC_MOTION = "home/sensor/motion"

# Sensor pins
DHT_PIN = board.D4
PIR_PIN = 17

# Init sensors
dht_device = adafruit_dht.DHT22(DHT_PIN)
GPIO.setmode(GPIO.BCM)
GPIO.setup(PIR_PIN, GPIO.IN)

# MQTT connect
client = mqtt.Client()
client.username_pw_set(MQTT_USER, MQTT_PASS)
client.connect(MQTT_BROKER, MQTT_PORT, 60)
client.loop_start()

print("Sensor publisher started...")

try:
    while True:
        try:
            temperature = dht_device.temperature
            humidity = dht_device.humidity
            if temperature is not None and humidity is not None:
                client.publish(TOPIC_TEMP, f"{temperature:.1f}")
                client.publish(TOPIC_HUM, f"{humidity:.1f}")
                print(f"Published temp={temperature:.1f}C humidity={humidity:.1f}%")
        except RuntimeError as e:
            print(f"DHT read error: {e}")

        motion = GPIO.input(PIR_PIN)
        client.publish(TOPIC_MOTION, "ON" if motion else "OFF")
        print(f"Motion: {'ON' if motion else 'OFF'}")

        time.sleep(5)

except KeyboardInterrupt:
    print("Exiting...")
    GPIO.cleanup()
    client.loop_stop()
    client.disconnect()

Run it:

python3 ~/sensor_publisher.py

In another terminal, verify the data is flowing:

mosquitto_sub -h localhost -u maker -P your_password -t "home/sensor/#"

You should see messages like 23.5, 45.2, OFF scrolling by.

Step 4: Control Relays via MQTT

Now let’s add relay control. We’ll create a second script that subscribes to commands and toggles the relays.

nano ~/relay_controller.py
import RPi.GPIO as GPIO
import paho.mqtt.client as mqtt

RELAY1_PIN = 27
RELAY2_PIN = 22

MQTT_BROKER = "localhost"
MQTT_PORT = 1883
MQTT_USER = "maker"
MQTT_PASS = "your_password"
TOPIC_RELAY1 = "home/relay/1/set"
TOPIC_RELAY2 = "home/relay/2/set"

GPIO.setmode(GPIO.BCM)
GPIO.setup(RELAY1_PIN, GPIO.OUT, initial=GPIO.HIGH)  # HIGH = relay off
GPIO.setup(RELAY2_PIN, GPIO.OUT, initial=GPIO.HIGH)

def on_message(client, userdata, msg):
    payload = msg.payload.decode()
    topic = msg.topic

    if topic == TOPIC_RELAY1:
        GPIO.output(RELAY1_PIN, GPIO.LOW if payload == "ON" else GPIO.HIGH)
        print(f"Relay 1 set to {payload}")
    elif topic == TOPIC_RELAY2:
        GPIO.output(RELAY2_PIN, GPIO.LOW if payload == "ON" else GPIO.HIGH)
        print(f"Relay 2 set to {payload}")

client = mqtt.Client()
client.username_pw_set(MQTT_USER, MQTT_PASS)
client.on_message = on_message
client.connect(MQTT_BROKER, MQTT_PORT, 60)
client.subscribe([(TOPIC_RELAY1, 0), (TOPIC_RELAY2, 0)])
client.loop_forever()

Run it in a second SSH session:

python3 ~/relay_controller.py

Now publish a command to turn on the light:

mosquitto_pub -h localhost -u maker -P your_password -t "home/relay/1/set" -m "ON"

You should hear the relay click, and the script prints confirmation.

Step 5: Build a Dashboard with Node-RED

Node-RED runs on the Pi and gives you a visual web interface to build dashboards without writing HTML. It runs as a service and is perfect for this.

Install Node-RED:

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

Enable it as a service:

sudo systemctl enable nodered.service
sudo systemctl start nodered.service

Access it at http://192.168.1.100:1880 (replace with your Pi’s IP). Install the dashboard nodes:

  • Click the hamburger menu → Manage paletteInstall
  • Search for node-red-dashboard and install

Now build the flow:

  1. Drag in three MQTT input nodes: subscribe to home/sensor/temperature, home/sensor/humidity, and home/sensor/motion
  2. Drag in two MQTT output nodes: set topic to home/relay/1/set and home/relay/2/set
  3. Drag in dashboard widgets:
    • For temperature and humidity: ui_gauge nodes
    • For motion: ui_text node showing ON/OFF
    • For relays: ui_switch nodes (type on/off, payload ON/OFF)
  4. Wire them up: MQTT input → gauge/text; switch → MQTT output

Deploy the flow. Open the dashboard UI at http://192.168.1.100:1880/ui (or the port you configured). You’ll see live sensor data and toggles for your relays.

Step 6: Automate with Rules

Node-RED makes it easy to add automation. For example, turn on a relay when motion is detected after sunset. Here’s a simple rule flow:

  1. Add a function node that checks if motion is ON and time is between 18:00 and 06:00.
  2. Wire motion MQTT input → function node → MQTT output to relay topic.

The function code:

var hour = new Date().getHours();
if (msg.payload === "ON" && (hour >= 18 || hour < 6)) {
    return { payload: "ON" };
} else {
    return null;
}

Deploy and test — walk in front of the PIR sensor and the relay should fire only in darkness hours.

Troubleshooting Common Issues

DHT22 returns None repeatedly

  • Check the 10kΩ pull-up resistor between DATA and 3.3V
  • Try a slower reading interval (2–3 seconds minimum)
  • Some DHT22 clones are finicky; try a genuine Aosong part

Relay doesn’t click when publishing ON

  • Double-check the pin number in the relay script
  • Some modules are active-low, some active-high. Try publishing OFF to see if the relay toggles
  • Use a multimeter to measure voltage between the relay’s trigger pin and GND when you publish

MQTT connection refused

  • Ensure you created the password file and set allow_anonymous false
  • Check that port 1883 is not blocked by a firewall
  • Verify the username and password in your Python scripts

Node-RED dashboard can’t connect to MQTT

  • Add an MQTT broker node in Node-RED (not the MQTT input nodes directly)
  • Input nodes connect to a broker config node pointing to localhost:1883 with your credentials

Going Further

This system is the foundation. From here you can:

  • Add more sensors: light sensors (LDR), soil moisture, air quality (PMS5003)
  • Control more relays: wire up a multi-channel relay board for lamps, fans, or aquarium pumps
  • Add remote access: set up a WireGuard VPN to your home network instead of exposing MQTT to the internet
  • Log data: write sensor readings to a CSV file or InfluxDB for historical graphs
  • Integrate voice control: connect your MQTT topics to a local voice assistant like Mycroft or Rhasspy

For inspiration, check out some of my other builds: GPS Module + Arduino: Does a Cheap Sensor Actually Work? or I Turned My Old Fan Into a Remote Control Fan (ESP8266 + Relay). Both use similar MQTT patterns but with different hardware.

Conclusion

You’ve just built a complete raspberry pi home automation hub that reads temperature, humidity, and motion data, publishes it over MQTT, and lets you control relays from a web dashboard. The stack — Mosquitto for messaging, Python for sensor logic, and Node-RED for the UI — scales from a single room to an entire house.

The best part? Everything runs locally, no cloud dependency, no monthly fees, and full control over your code and data. If you get stuck, the community on Discord is always helpful. Now go wire up that lamp.

Приєднуйся до спільноти в Discord

Задавай питання, ділися своїми збірками та спілкуйся з іншими мейкерами.

Приєднатися до Discord — безкоштовно

Сподобався туторіал?

Підтримай канал на Patreon і отримай ранній доступ до проєктів та багато іншого.

Підтримати на Patreon →