Getting Google Home for Raspberry Pi integration working in 2026 requires a workaround. Google officially deprecated the native Google Assistant SDK for Raspberry Pi, meaning the old "hotword" detection libraries no longer function on modern Raspberry Pi OS Bookworm. The most robust, low-latency method to control Pi GPIO pins via voice commands today is building a lightweight REST API bridge on the Pi, exposing it securely via a Cloudflare Tunnel, and triggering it using Google Home Routines linked to IFTTT webhooks.
This guide walks through building a voice-controlled 2-channel relay bridge on a Raspberry Pi 5, complete with exact pin mappings, production-ready Python code, and the specific debugging steps for the most common Bookworm permission errors.
Difficulty: Intermediate
Time Required: 90 minutes
Estimated Cost: $68 USD
Target Board: Raspberry Pi 5 (8GB variant, SKU: SC1112) running Raspberry Pi OS Bookworm 64-bit
Hardware Selection and Pin Mapping
To switch external loads, we are using an optocoupler-isolated relay module. This protects the Pi 5's sensitive 3.3V logic lines from inductive kickback and electrical noise generated by the relay coils.
Parts List
- Microcontroller: Raspberry Pi 5 (8GB RAM) - Provides the headroom to run the Flask API and Cloudflare daemon simultaneously without thermal throttling.
- Power Supply: Official Raspberry Pi 27W USB-C PD Power Supply (SKU: SC1005) - Required to prevent brownouts when the relay coils energize.
- Relay Module: 5V 2-Channel Relay Module with Optocoupler (Relay model: Songle SRD-05VDC-SL-C).
- Wiring: Female-to-Female Dupont jumper wires (20cm length).
Pin Mapping Table
The Raspberry Pi 5 uses the BCM (Broadcom) GPIO numbering scheme. We will map physical pins to BCM GPIO numbers in the code below.
| Pi 5 Physical Pin | BCM GPIO Number | Relay Module Pin | Function |
|---|---|---|---|
| Pin 11 | GPIO 17 | IN1 | Relay 1 Logic Control |
| Pin 13 | GPIO 27 | IN2 | Relay 2 Logic Control |
| Pin 2 | 5V Power | VCC | Optocoupler LED Power |
| Pin 6 | Ground | GND | Common Ground |
The Python API Bridge Code
We will use Flask to create a lightweight web server and gpiozero to handle the hardware abstraction. Note that most 5V relay modules are Active LOW, meaning the relay engages when the GPIO pin is pulled to ground (0V). The code below accounts for this logic inversion.
Install the dependencies on your Pi via terminal:
sudo apt update
sudo apt install python3-flask python3-gpiozero
Create a file named pi_relay_bridge.py and paste the following complete, compilable code:
from flask import Flask, jsonify
from gpiozero import OutputDevice
import logging
import sys
app = Flask(__name__)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# BCM Pin Definitions
RELAY_1_PIN = 17
RELAY_2_PIN = 27
try:
# active_high=False configures for Active LOW relay modules
# initial_value=False ensures relays are OFF on boot
relay1 = OutputDevice(RELAY_1_PIN, active_high=False, initial_value=False)
relay2 = OutputDevice(RELAY_2_PIN, active_high=False, initial_value=False)
logging.info("GPIO pins initialized successfully.")
except Exception as e:
logging.critical(f"GPIO Initialization Failed: {e}")
sys.exit(1)
@app.route('/api/relay/<int:relay_id>/<state>', methods=['GET'])
def control_relay(relay_id, state):
try:
target_relay = relay1 if relay_id == 1 else relay2 if relay_id == 2 else None
if target_relay is None:
return jsonify({"error": "Invalid relay ID. Use 1 or 2."}), 400
if state == 'on':
target_relay.on()
elif state == 'off':
target_relay.off()
else:
return jsonify({"error": "Invalid state. Use 'on' or 'off'."}), 400
logging.info(f"Relay {relay_id} turned {state}")
return jsonify({"success": True, "relay": relay_id, "state": state})
except Exception as e:
logging.error(f"Hardware control error: {str(e)}")
return jsonify({"error": str(e)}), 500
if __name__ == '__main__':
# Bind to all interfaces so the Cloudflare tunnel can reach it
app.run(host='0.0.0.0', port=5000)
Routing Google Home to Your Pi
Google Home cannot natively route HTTP GET requests to local IP addresses without a Matter/Thread bridge or a middleware hub like Home Assistant. To keep this build standalone, we use a secure tunnel and webhook automation.
- Install Cloudflared: Install the Cloudflare Tunnel daemon on your Pi. This creates a secure outbound connection to a public URL without opening ports on your home router. Follow the official Cloudflare Tunnel documentation to map
http://localhost:5000to a URL likehttps://pi-relay.yourdomain.com. - Configure IFTTT: Create an IFTTT applet. Set the trigger to "Google Assistant" (e.g., "Say 'Turn on the workbench light'"). Set the action to "Webhooks" (Make a web request).
- Set the Webhook URL: Point the IFTTT webhook to
https://pi-relay.yourdomain.com/api/relay/1/onusing the GET method. - Create the 'Off' Routine: Duplicate the IFTTT applet, change the voice phrase to "Turn off the workbench light", and change the webhook URL to end in
/off.
When you speak the phrase, Google processes the intent, fires the IFTTT webhook, routes through Cloudflare, and hits your Pi's Flask API in roughly 800 milliseconds.
Debugging Common Failures
When migrating from older Pi models to the Pi 5 on Bookworm, the underlying GPIO architecture shifted from the legacy RPi.GPIO library to lgpio. This introduces specific permission and binding errors.
Exact Error String: PermissionError: [Errno 13] Permission denied: '/dev/gpiomem'
This error halts the script immediately upon execution when the gpiozero library attempts to map the hardware memory addresses.
Ranked Causes:
- Missing Group Membership: The standard user (usually
pi) has not been added to thegpiouser group, which is required to access/dev/gpiomemwithout root privileges. - Zombie Process Lock: A previous instance of your Python script crashed but left a background process running, holding a lock on the GPIO memory map.
- Legacy Library Conflict: You have an older version of
RPi.GPIOinstalled viapipthat is conflicting with the system-levellgpiobackend required by the Pi 5.
The First Three Things to Check When It Fails
- Verify User Groups: Run
groupsin the terminal. Ifgpiois missing, executesudo usermod -aG gpio $USER, then log out and log back in to apply the group change. - Check for Port Collisions: If Flask throws an
Address already in useerror, runsudo lsof -i :5000to find the PID of the zombie process and kill it withsudo kill -9 [PID]. - Inspect the Relay Jumper: Most 2-channel relay modules have a physical jumper cap labeled
JD-VCCandVCC. If this jumper is missing, the optocoupler LEDs will not receive power, and the Pi's GPIO pins will trigger the logic side, but the physical relay will never click.
How to Extend or Simplify the Build
To Simplify: If you only need to switch a single 120V appliance and don't need the Pi for other compute tasks, abandon the Pi entirely. Buy a Sonoff Basic R4 (an ESP32-based smart relay) for about $8. It natively supports Matter and integrates with Google Home in seconds without writing code.
To Extend: Add an Adafruit BME280 I2C environmental sensor to the Pi. You can expand the Flask API to include a /api/sensors/temp endpoint, and use a secondary IFTTT routine to push that data to a Google Sheet every hour, effectively creating a custom telemetry logger.
Frequently Asked Questions
Can I use Google Home for Raspberry Pi without Home Assistant?
Yes. While Home Assistant is the most common middleware for smart home integration, it is resource-heavy. The method outlined in this guide uses a lightweight Flask API and Cloudflare Tunnels to bridge Google Home directly to the Pi's hardware, bypassing the need for a full home automation server. This is ideal for headless, single-purpose Pi deployments.
Why does my Google Home routine say "device is not responding" but the Pi relay clicks?
This happens because IFTTT webhooks are "fire and forget." Google Home expects a specific JSON response format (like the Google Smart Home API requires) to confirm success. Since our basic Flask script returns a standard JSON object rather than the strict Google Action schema, Google assumes the request timed out or failed, even though the IFTTT webhook successfully triggered the Pi. You can fix this by building a formal Google Cloud Action, but for simple DIY tasks, ignoring the voice prompt error is the standard workaround.
Does the official Google Assistant SDK still work on Raspberry Pi OS Bookworm?
No. Google officially deprecated the google-assistant-library and the embedded Assistant SDK for ARM-based Linux boards. Attempting to install the old hotword detection binaries on a 64-bit Bookworm system will result in missing libssl1.1 dependencies and architecture mismatches. The REST API bridge method is the current standard for custom Pi-to-Google hardware control.






