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.

Build Spec Sheet
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
⚠️ Mains Voltage Safety Warning: If you are using the relay contacts (COM, NO, NC) to switch 120V/240V AC mains appliances, ensure the Pi is housed in a non-conductive, enclosed project box. Never work on mains wiring while the circuit is energized. De-energize the breaker, verify dead with a CAT III multimeter, and consult local electrical codes. If you are unsure, stick to switching low-voltage DC loads like 12V LED strips.

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.

  1. 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:5000 to a URL like https://pi-relay.yourdomain.com.
  2. 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).
  3. Set the Webhook URL: Point the IFTTT webhook to https://pi-relay.yourdomain.com/api/relay/1/on using the GET method.
  4. 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:

  1. Missing Group Membership: The standard user (usually pi) has not been added to the gpio user group, which is required to access /dev/gpiomem without root privileges.
  2. 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.
  3. Legacy Library Conflict: You have an older version of RPi.GPIO installed via pip that is conflicting with the system-level lgpio backend required by the Pi 5.

The First Three Things to Check When It Fails

  1. Verify User Groups: Run groups in the terminal. If gpio is missing, execute sudo usermod -aG gpio $USER, then log out and log back in to apply the group change.
  2. Check for Port Collisions: If Flask throws an Address already in use error, run sudo lsof -i :5000 to find the PID of the zombie process and kill it with sudo kill -9 [PID].
  3. Inspect the Relay Jumper: Most 2-channel relay modules have a physical jumper cap labeled JD-VCC and VCC. 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.