When evaluating Raspberry Pi projects for home automation, the most common point of failure isn't the code—it is the physical interface between the Pi's 3.3V logic and the 5V or 12V relays switching your mains loads. A poorly wired relay module will cause GPIO brownouts, corrupt your SD card, or silently fail to trigger your HVAC dampers and lighting circuits.
This guide walks through building a robust, fail-safe 4-channel MQTT relay node. We are targeting the Raspberry Pi 5 (4GB variant) running Raspberry Pi OS Bookworm (64-bit). By using an optocoupler-isolated relay module and the updated Paho MQTT v2.0 Python API, this build ensures electrical isolation and reliable 24/7 operation.
Hardware Spec Sheet & Parts List
Sourcing the exact variants matters. Generic relay modules often lack the flyback diodes necessary to protect the Pi's power rail from inductive kickback when the relay coils de-energize.
| Component | Exact Variant / Specification | Approx. Cost (2026) |
|---|---|---|
| Microcontroller | Raspberry Pi 5 (4GB RAM) | $60.00 |
| Power Supply | Official 27W USB-C PD Power Supply (5V/5A) | $12.00 |
| Relay Module | 4-Channel 5V Relay with Optocoupler (SRD-05VDC-SL-C) | $8.50 |
| Cooling | Raspberry Pi 5 Active Cooler | $5.00 |
| Storage | 32GB SanDisk High Endurance microSD (UHS-I) | $9.00 |
| Wiring | 22 AWG stranded silicone jumper wires (Female-to-Female) | $6.00 |
Pin Mapping & Wiring Guide
The Raspberry Pi 5 GPIO header operates at 3.3V. The standard SRD-05VDC-SL-C relay module requires 5V for the coil, but its optocoupler inputs can be safely driven by 3.3V logic if wired correctly.
| Pi 5 Pin (BCM) | Physical Pin | Relay Module Pin | Function |
|---|---|---|---|
| GPIO 17 | 11 | IN1 | Relay 1 Control (Active LOW) |
| GPIO 27 | 13 | IN2 | Relay 2 Control (Active LOW) |
| GPIO 22 | 15 | IN3 | Relay 3 Control (Active LOW) |
| GPIO 23 | 16 | IN4 | Relay 4 Control (Active LOW) |
| 3.3V Power | 1 | VCC | Optocoupler Logic Power |
| 5V Power | 2 | JD-VCC | Relay Coil Power (Jumper Removed) |
| Ground | 6 | GND | Common Ground |
The Python MQTT Controller Code
This script uses gpiozero for hardware abstraction and paho-mqtt for broker communication. It is written for the Paho MQTT v2.0 API, which requires explicit callback versioning. The code includes automatic reconnection logic and graceful GPIO cleanup on exit.
import time
import signal
import sys
from gpiozero import OutputDevice
import paho.mqtt.client as mqtt
# --- PIN DEFINITIONS & CONFIG ---
# Active LOW relays: active_high=False means pin goes LOW to energize coil
RELAY_PINS = {
'home/lights/living_room': OutputDevice(17, active_high=False, initial_value=False),
'home/lights/kitchen': OutputDevice(27, active_high=False, initial_value=False),
'home/hvac/damper_1': OutputDevice(22, active_high=False, initial_value=False),
'home/hvac/damper_2': OutputDevice(23, active_high=False, initial_value=False)
}
BROKER_IP = '192.168.1.50'
BROKER_PORT = 1883
CLIENT_ID = 'pi5_relay_node_01'
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code == 0:
print(f'Connected to broker. Subscribing to {len(RELAY_PINS)} topics.')
for topic in RELAY_PINS.keys():
client.subscribe(topic, qos=1)
else:
print(f'Connection failed with reason code: {reason_code}')
def on_message(client, userdata, msg):
topic = msg.topic
payload = msg.payload.decode('utf-8').strip().upper()
if topic in RELAY_PINS:
relay = RELAY_PINS[topic]
if payload in ['ON', '1', 'TRUE']:
relay.on()
print(f'[ACTUATED] {topic} -> ON')
elif payload in ['OFF', '0', 'FALSE']:
relay.off()
print(f'[ACTUATED] {topic} -> OFF')
else:
print(f'[IGNORED] Invalid payload for {topic}: {payload}')
def graceful_exit(signum, frame):
print('\nShutting down: Turning off all relays and cleaning up GPIO...')
for relay in RELAY_PINS.values():
relay.off()
relay.close()
client.loop_stop()
client.disconnect()
sys.exit(0)
# Register signal handlers for safe shutdown
signal.signal(signal.SIGINT, graceful_exit)
signal.signal(signal.SIGTERM, graceful_exit)
# Initialize MQTT Client (Paho v2.0 API)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.on_message = on_message
# Enable automatic reconnection (waits 1s to 120s between attempts)
client.reconnect_delay_set(min_delay=1, max_delay=120)
try:
print(f'Attempting connection to {BROKER_IP}:{BROKER_PORT}...')
client.connect(BROKER_IP, BROKER_PORT, keepalive=60)
client.loop_forever()
except Exception as e:
print(f'Fatal MQTT Error: {e}')
for relay in RELAY_PINS.values():
relay.off()
relay.close()
Debugging: "Connection Refused" & Hardware Faults
When deploying Raspberry Pi projects for home automation, network and broker errors are the most frequent roadblocks. If your script crashes on startup, you will likely see this exact error string in your terminal:
ConnectionRefusedError: [Errno 111] Connection refused
Here are the ranked causes and the first three things to check when it fails:
- Mosquitto Broker Binding (Most Likely): Recent versions of Eclipse Mosquitto (v2.0+) default to binding only to
localhostfor security. If your broker is running on a separate Home Assistant server, it will refuse external connections. Fix: SSH into your broker, edit/etc/mosquitto/conf.d/default.conf, and addlistener 1883andallow_anonymous true(or configure ACLs), then restart the service. - Pi 5 Wi-Fi Power Save Mode: The Pi 5's Wi-Fi chip aggressively enters power-save mode, causing dropped MQTT keep-alive packets and subsequent broker disconnects. Fix: Disable Wi-Fi power management by running
sudo iwconfig wlan0 power offand making it persistent via NetworkManager. - Firewall Blocking Port 1883: If your broker is running on a Ubuntu/Debian host, UFW may be blocking the port. Fix: Run
sudo ufw allow 1883/tcpon the broker machine.
Hardware Fault Check: If the script runs but a relay clicks weakly or not at all, measure the voltage between the JD-VCC and GND pins on the relay module while triggering the channel. If it reads below 4.7V, your 5V power rail is sagging. Upgrade to a higher-amperage 5V supply or power the relay coils from a dedicated 5V buck converter.
Extending and Simplifying the Build
Depending on your infrastructure, you may want to adjust the complexity of this node.
How to Simplify: If you don't want to maintain a separate MQTT broker and write custom Python scripts, flash Home Assistant OS directly onto the Pi 5. Home Assistant includes a built-in Mosquitto broker add-on and can read the GPIO pins natively via the raspberrypi_gpio integration in YAML, eliminating the need for the Python script entirely.
How to Extend: Add a DS18B20 1-Wire temperature sensor to GPIO 4 (Physical Pin 7) with a 4.7kΩ pull-up resistor to 3.3V. Enable the 1-Wire interface in raspi-config. You can then modify the Python script to read the /sys/bus/w1/devices/ directory and publish temperature data to an home/sensors/temp MQTT topic, allowing your home automation hub to trigger the HVAC damper relays based on real-time thermal thresholds.
FAQ: Raspberry Pi Projects for Home Automation
Are Raspberry Pi projects for home automation reliable enough for 24/7 use?
Yes, but only if you mitigate the two primary failure vectors: SD card corruption and thermal throttling. The Pi 5 runs significantly hotter than the Pi 4; the Active Cooler listed in the parts list is mandatory for 24/7 enclosed operation. To prevent SD card corruption from continuous MQTT logging and OS writes, use a "High Endurance" microSD card (designed for dashcams and security cameras) and move your Docker containers or heavy logs to a USB 3.0 SSD or configure a RAM disk for temporary files.
How do I integrate Raspberry Pi home automation projects with Apple HomeKit?
The Pi itself does not natively speak the HomeKit Accessory Protocol (HAP) out of the box in a way that is easy to manage. The standard approach is to run Home Assistant on the Pi (or use the Pi as an MQTT node talking to a central Home Assistant server). Home Assistant includes a built-in "HomeKit Bridge" integration that exposes your MQTT relays and sensors to Apple Home over your local network, allowing Siri control without relying on cloud servers.
What is the best power supply for Raspberry Pi projects in home automation?
Always use the Official Raspberry Pi 27W USB-C PD Power Supply for the Pi 5. Third-party phone chargers often suffer from voltage drop under transient loads (like when the Wi-Fi chip transmits or a relay coil energizes). If the Pi 5 detects the supply cannot negotiate the 5A PD profile, it will artificially limit USB port current to 600mA, which will starve external peripherals like SSDs or Zigbee USB dongles commonly used in home automation setups.






