Project Overview and Hardware Requirements

Getting a Raspberry Pi to talk directly to Google Home used to mean relying on flaky IFTTT applets or running a massive Home Assistant instance just to toggle a single relay. In 2026, the most reliable, lightweight method for exposing custom Pi GPIO pins to Google Assistant is using a dedicated IoT middleware API like Sinric Pro. This approach bypasses the heavy compilation requirements of the native Matter SDK while keeping latency under 200ms.

Difficulty: Intermediate | Time: 45 minutes | Cost: ~$65 USD

Exact Parts List

  • Microcontroller: Raspberry Pi 5 (4GB variant) running Raspberry Pi OS (64-bit, Bookworm). Note: Code is backward compatible with Pi 4 Model B.
  • Relay Module: 5V 2-Channel Relay Module with Optocoupler Isolation (e.g., Elegoo or HiLetgo variants).
  • Power Supply: Official 27W USB-C Power Supply (5.1V / 5A) for Pi 5.
  • Wiring: 22 AWG solid copper hookup wire (for GPIO), 14 AWG stranded (for AC load side).
  • Load: 120V/240V AC desk lamp or soldering fume extractor.

Choosing Your Bridge: Middleware Comparison

Before writing code, you need to understand how the Pi actually reaches Google's servers. Google Home does not natively scan your local network for raw Python scripts. You must bridge the Pi to Google via a recognized protocol or cloud API. Below is a data-dense comparison of the four primary methods available to embedded developers today.

Integration Method Avg Latency Setup Complexity Offline Capability Best Use Case
Matter Protocol (Native) < 50ms High (C++ SDK compile) Full Local Commercial products, Thread border routers
Sinric Pro (Cloud API) 120 - 250ms Low (Python pip install) None (Cloud dependent) Custom workbench tools, rapid prototyping
Home Assistant (Bridge) 150 - 300ms Medium (YAML config) Partial (LAN only) Whole-home automation, complex logic
Local UDP / MQTT < 20ms High (Custom Google Action) Full Local Enterprise internal tools, isolated networks

For this build, we are using Sinric Pro. It provides a free tier for up to 3 devices, requires no local server infrastructure, and links directly to the Google Home Developer Console via their official Action.

Wiring the Relay Module to the Raspberry Pi 5

⚠️ HIGH VOLTAGE SAFETY WARNING: The load side of the relay module will carry mains voltage (120V-240V AC). De-energize the circuit at the breaker before making any AC connections. Verify the circuit is dead with a non-contact voltage tester (NCVT) and a multimeter. If you are not comfortable terminating mains wiring, use a pre-wired smart plug teardown or stick to 12V DC loads.

The Raspberry Pi 5 uses the new RP1 I/O controller chip. This means the physical pinout remains the same as the Pi 4, but the underlying software addressing has changed. We will use BCM (Broadcom) numbering in our code.

Pin Mapping Table

Raspberry Pi 5 Pin (BCM) Physical Pin # Relay Module Pin Wire Color (Recommended)
5V (Power) 2 or 4 VCC Red
GND 6 GND Black
GPIO 17 11 IN1 (Relay 1) Yellow
GPIO 27 13 IN2 (Relay 2) Blue
  1. Connect the 5V and GND pins from the Pi to the relay module's VCC and GND headers.
  2. Connect GPIO 17 to IN1 and GPIO 27 to IN2.
  3. On the AC load side, cut the hot/live wire of your desk lamp. Connect one cut end to the relay's COM (Common) terminal and the other to the NO (Normally Open) terminal.
  4. Double-check that the neutral wire remains uninterrupted and properly wire-nutted.

Python Implementation for Google Home Integration

This code targets the Raspberry Pi 5 (4GB) running the 64-bit Bookworm OS.

Critical Pi 5 Note: The legacy RPi.GPIO library is deprecated and will throw hardware address errors on the Pi 5. We are using gpiozero, which automatically utilizes the modern lgpio backend required by the RP1 chip. For deeper reading on Pi 5 I/O changes, refer to the official gpiozero documentation.

Prerequisites

Install the required libraries via terminal:

sudo apt update
sudo apt install python3-gpiozero python3-full
python3 -m venv ~/google_home_env
source ~/google_home_env/bin/activate
pip install sinricpro websockets

Complete Compilable Code

Save the following as pi_google_bridge.py. You will need to generate an App Key, App Secret, and two Device IDs from the Google Home Developer Console (linked via the Sinric Pro dashboard).

import asyncio
import logging
from gpiozero import OutputDevice
from sinricpro import SinricPro
from sinricpro.devices import SinricProSwitch

# Configure logging for debugging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger('PiGoogleBridge')

# --- Hardware Pin Definitions (BCM Numbering) ---
RELAY_1_PIN = 17
RELAY_2_PIN = 27

# Initialize relays. 
# active_high=False is required for most optocoupler relay modules (they trigger on LOW).
relay_1 = OutputDevice(RELAY_1_PIN, active_high=False, initial_value=False)
relay_2 = OutputDevice(RELAY_2_PIN, active_high=False, initial_value=False)

# --- Sinric Pro Credentials ---
APP_KEY = 'YOUR_APP_KEY_HERE'
APP_SECRET = 'YOUR_APP_SECRET_HERE'
DEVICE_ID_1 = 'YOUR_DEVICE_ID_1'  # e.g., Workbench Light
DEVICE_ID_2 = 'YOUR_DEVICE_ID_2'  # e.g., Fume Extractor

# --- Callback Functions ---
async def on_power_state_1(device_id: str, state: bool):
    """Handles power state commands for Relay 1."""
    logger.info(f'Device 1 ({device_id}) commanded to: {state}')
    try:
        if state:
            relay_1.on()
        else:
            relay_1.off()
        return True, state
    except Exception as e:
        logger.error(f'Hardware failure on Relay 1: {e}')
        return False, state

async def on_power_state_2(device_id: str, state: bool):
    """Handles power state commands for Relay 2."""
    logger.info(f'Device 2 ({device_id}) commanded to: {state}')
    try:
        if state:
            relay_2.on()
        else:
            relay_2.off()
        return True, state
    except Exception as e:
        logger.error(f'Hardware failure on Relay 2: {e}')
        return False, state

# --- Main Async Loop ---
async def main():
    logger.info('Initializing Sinric Pro connection...')
    sinricpro = SinricPro(APP_KEY, APP_SECRET)
    
    switch_1 = SinricProSwitch(DEVICE_ID_1)
    switch_1.on_power_state(on_power_state_1)
    
    switch_2 = SinricProSwitch(DEVICE_ID_2)
    switch_2.on_power_state(on_power_state_2)
    
    sinricpro.add_device(switch_1)
    sinricpro.add_device(switch_2)
    
    # Connect with automatic reconnection enabled
    await sinricpro.connect(reconnect=True)

if __name__ == '__main__':
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        logger.info('Keyboard interrupt received. Shutting down safely...')
        relay_1.off()
        relay_2.off()
        logger.info('Relays deactivated. Exiting.')
    except Exception as fatal_error:
        logger.critical(f'Fatal system error: {fatal_error}')
        relay_1.off()
        relay_2.off()

Debugging: First Three Things to Check When It Fails

When bridging cloud APIs to local hardware, failures usually happen at the OS, Network, or API layer. If your Google Home voice commands aren't triggering the relays, check these three exact error strings in your terminal output.

1. The Pi 5 Hardware Address Error

Exact Error String: RuntimeError: Cannot determine SOC peripheral base address or ModuleNotFoundError: No module named 'RPi.GPIO'

  • Cause: You are trying to use the legacy RPi.GPIO library, or you are running an outdated 32-bit Buster OS on a Pi 5. The RP1 chip architecture breaks legacy memory mapping.
  • Fix: Ensure you are using the gpiozero library as shown in the code above. Verify your OS is 64-bit Bookworm by running uname -a. If you absolutely must use raw GPIO control, install the modern wrapper via sudo apt install python3-rpi-lgpio.

2. The Cloud Authentication Failure

Exact Error String: sinricpro: Connection failed: 401 Unauthorized or websockets.exceptions.InvalidStatusCode: server rejected WebSocket connection: HTTP 401

  • Cause: Your App Key, App Secret, or Device IDs are incorrect, or you forgot to link the Sinric Pro skill inside the Google Home app on your phone.
  • Fix: Log into the Sinric Pro dashboard and regenerate your App Secret. Copy-paste the new strings directly into the Python script. Open the Google Home app on your phone, go to Settings > Works with Google, and ensure the Sinric Pro action is linked and showing your two devices.

3. The Network Dropout

Exact Error String: websockets.exceptions.ConnectionClosedError: code = 1006 (abnormal closure)

  • Cause: The Pi lost its WiFi/Ethernet connection, or your router's firewall is aggressively dropping idle WebSocket connections.
  • Fix: The reconnect=True parameter in the code handles transient drops. If this error loops continuously, check your router's WebSocket timeout settings, or switch the Pi from 2.4GHz WiFi to a hardwired Ethernet connection for bench stability.

How to Extend or Simplify the Build

Simplifying the Build

If your only goal is to toggle a relay via Google Home and you don't need the Pi for other tasks (like running a camera or local LLM), downgrade to an ESP32. An ESP32-WROOM-32 DevKit costs under $6, consumes milliamps instead of amps, and boots in 2 seconds. You can use the exact same Sinric Pro credentials with the SinricPro Arduino C++ library, eliminating the need for a full Linux OS and Python environment.

Extending the Build

To turn this from a simple switch into a smart environmental controller:

  1. Add a Sensor: Wire an I2C BME280 temperature/humidity sensor to the Pi's SDA (GPIO 2) and SCL (GPIO 3) pins.
  2. Update the Cloud Profile: Change Device 2 in the Sinric Pro dashboard from a 'Switch' to a 'Thermostat' or 'Temperature Sensor'.
  3. Modify the Code: Import the smbus2 library to read the BME280 registers, and use the sinricpro.send_power_state() or equivalent telemetry methods to push temperature data up to Google Home every 60 seconds. This allows you to ask, "Hey Google, what's the temperature at my workbench?"

By understanding the middleware layer and respecting the Pi 5's new I/O architecture, you can build highly reliable voice-controlled bench tools that respond instantly to Google Assistant commands.