You cannot flash the proprietary Google Home OS onto a Raspberry Pi. However, you can build a fully functional, always-listening Google Assistant voice satellite using the Google Assistant Embedded API (gRPC). This setup turns your Pi into a custom smart speaker that responds to "Hey Google," controls your smart home, and answers queries exactly like a commercial Google Nest Audio.

This guide targets the Raspberry Pi 5 (8GB variant) running Raspberry Pi OS (64-bit, Bookworm). We will use the Seeed Studio ReSpeaker 2-Mic HAT for I2S audio input/output and map a physical GPIO LED to indicate listening states. Expect to spend about $125 on parts and 2 to 3 hours on the bench.

Project Spec Sheet:
Difficulty: Intermediate | Time: 2-3 Hours | Cost: ~$125
Target Board: Raspberry Pi 5 (8GB) | OS: Raspberry Pi OS 64-bit (Bookworm)

Hardware BOM & Pin Mapping

The Raspberry Pi 5 requires a robust power delivery system to handle continuous audio processing and I2S streaming without brownouts. Do not use a standard 15W phone charger.

Component Exact Variant / Spec Est. Cost
Microcontroller Raspberry Pi 5 (8GB RAM) $80.00
Audio HAT Seeed Studio ReSpeaker 2-Mics Pi HAT (V2.0) $35.00
Power Supply Official 27W USB-C PD Power Supply (5V/5A) $12.00
Storage 32GB microSD (SanDisk Extreme A2) $9.00
Indicator 5mm Blue LED + 330Ω Resistor $0.10
Bench Tip: The Pi 5 will throttle or reset under audio processing loads if the power supply cannot negotiate the 5V/5A PD contract. If you see the lightning bolt icon on your display, your power delivery is failing.

GPIO & I2S Pin Mapping

The ReSpeaker HAT sits directly on the 40-pin header, but it consumes specific BCM GPIO pins for the I2S audio bus. We will use a free pin for our status LED.

BCM GPIO Function Physical Pin Notes
GPIO 17Status LED11Connect via 330Ω resistor to LED Anode
GPIO 18I2S PCM_CLK12ReSpeaker HAT (Bit Clock)
GPIO 19I2S PCM_FS35ReSpeaker HAT (Frame Sync)
GPIO 20I2S PCM_DIN38ReSpeaker HAT (Data In / Mic)
GPIO 21I2S PCM_DOUT40ReSpeaker HAT (Data Out / Speaker)

Google Cloud & API Configuration

Before writing code, you must register the Pi as an embedded device in the Google Cloud Platform (GCP). The Google Assistant SDK requires OAuth 2.0 credentials and a registered device_model_id.

  1. Enable the API: Go to the GCP Console, create a new project (e.g., pi-voice-satellite), and enable the Google Assistant API.
  2. Configure OAuth: Navigate to APIs & Services > Credentials. Create an OAuth Client ID (select "Other" or "Desktop App"). Download the JSON file and rename it to client_secret.json.
  3. Register the Device: Use the Google Assistant SDK registration tool to generate a device_model_id. You will need this exact string in your Python code.
  4. Generate User Credentials: Run the google-oauthlib-tool on the Pi to exchange the client secret for a local credentials.json token. This token grants the Pi permission to act on your Google account.

Python Assistant Implementation

We will use the google-assistant-grpc package alongside sounddevice for low-latency audio streaming and gpiozero for the LED indicator. Install the dependencies in a virtual environment:

sudo apt install portaudio19-dev libffi-dev libssl-dev
python3 -m venv ~/assistant-env
source ~/assistant-env/bin/activate
pip install google-assistant-grpc sounddevice gpiozero

Below is the complete, runnable script. It establishes a gRPC channel, streams microphone chunks to Google's servers, and plays back the synthesized response.

import sounddevice as sd
import grpc
import json
import os
from gpiozero import LED
from google.assistant.embedded.v1alpha2 import embedded_assistant_pb2
from google.assistant.embedded.v1alpha2 import embedded_assistant_pb2_grpc

# --- Pin Definitions & Config ---
STATUS_LED = LED(17) # BCM GPIO 17
SAMPLE_RATE = 16000
BLOCK_SIZE = 512
DEVICE_MODEL_ID = 'your-registered-model-id-123'
PROJECT_ID = 'pi-voice-satellite'
CREDENTIALS_PATH = os.path.expanduser('~/.config/google-oauthlib-tool/credentials.json')

def load_credentials():
    """Loads the local OAuth2 token generated by google-oauthlib-tool."""
    try:
        with open(CREDENTIALS_PATH, 'r') as f:
            creds = json.load(f)
            return creds['access_token']
    except (FileNotFoundError, KeyError) as e:
        print(f"[FATAL] Credential error: {e}. Run google-oauthlib-tool to refresh.")
        exit(1)

def audio_generator():
    """Yields raw audio chunks from the ReSpeaker I2S microphone."""
    stream = sd.RawInputStream(samplerate=SAMPLE_RATE, blocksize=BLOCK_SIZE,
                               dtype='int16', channels=1)
    with stream:
        while True:
            data, overflowed = stream.read(BLOCK_SIZE)
            if overflowed:
                print("[WARN] Audio buffer overflowed")
            yield data

def main():
    access_token = load_credentials()
    STATUS_LED.off()
    
    # Setup gRPC Channel
    channel = grpc.secure_channel('embeddedassistant.googleapis.com',
                                  grpc.ssl_channel_credentials())
    assistant = embedded_assistant_pb2_grpc.EmbeddedAssistantStub(channel)
    
    config = embedded_assistant_pb2.AssistantConfig(
        audio_in_config=embedded_assistant_pb2.AudioInConfig(
            encoding=embedded_assistant_pb2.AudioInConfig.Encoding.LINEAR16,
            sample_rate_hertz=SAMPLE_RATE),
        audio_out_config=embedded_assistant_pb2.AudioOutConfig(
            encoding=embedded_assistant_pb2.AudioOutConfig.Encoding.LINEAR16,
            sample_rate_hertz=SAMPLE_RATE),
        device_config=embedded_assistant_pb2.DeviceConfig(
            device_model_id=DEVICE_MODEL_ID)
    )

    print("[INFO] Google Assistant gRPC stream active. Say 'Hey Google'...")
    
    try:
        while True:
            # Create the request generator
            def request_gen():
                yield embedded_assistant_pb2.AssistRequest(config=config)
                for chunk in audio_generator():
                    yield embedded_assistant_pb2.AssistRequest(audio_in=chunk)

            STATUS_LED.on() # Indicate listening/streaming
            
            # Stream to Google and process responses
            for resp in assistant.Assist(request_gen(), metadata=[('authorization', f'Bearer {access_token}')]):
                if resp.event_type == embedded_assistant_pb2.AssistResponse.ON_CONVERSATION_TURN_STARTED:
                    print("[EVENT] Conversation started")
                
                if resp.audio_out.audio_data:
                    # Play audio back through ReSpeaker DAC
                    sd.play(resp.audio_out.audio_data, samplerate=SAMPLE_RATE)
                    sd.wait()
                    
            STATUS_LED.off() # Return to idle
            
    except grpc.RpcError as e:
        print(f"[ERROR] gRPC Failure: {e.code()} - {e.details()}")
    except KeyboardInterrupt:
        print("\n[INFO] Shutting down assistant.")
    finally:
        STATUS_LED.off()
        channel.close()

if __name__ == '__main__':
    main()

Debugging: gRPC & Audio Failures

When building voice satellites, 90% of your debugging time will be spent on authentication tokens and I2S driver conflicts. If the script crashes immediately upon calling assistant.Assist(), check the terminal output.

The Most Common Error

grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.UNAUTHENTICATED, details = "Request had invalid authentication credentials.">

First three things to check when this fails:

  1. Device Model ID Mismatch: The DEVICE_MODEL_ID string in the Python script must exactly match the one you registered in the GCP Console. A single typo triggers an UNAUTHENTICATED state.
  2. Expired OAuth Token: The local credentials.json token expires. Re-run google-oauthlib-tool --refresh --client-secrets client_secret.json --scope https://www.googleapis.com/auth/assistant-sdk-prototype to generate a fresh token.
  3. API Not Enabled: Verify that the Google Assistant API (not just the Cloud Speech-to-Text API) is explicitly enabled in your GCP project dashboard.
Audio Routing Gotcha: If the script runs but you hear no audio output, PulseAudio or PipeWire might be hijacking the ReSpeaker DAC. Run pactl list sinks to verify the Seeed I2S card is the default sink, or temporarily kill the PipeWire daemon (systemctl --user stop pipewire) during testing.

Extending and Simplifying the Build

The continuous streaming model used above consumes significant bandwidth and requires Google's cloud servers to process the wake word. Depending on your deployment environment, you may want to alter this behavior.

  • Simplify (Push-to-Talk): If you want to eliminate the "Hey Google" wake word and save bandwidth, wire a momentary push-button to GPIO 27. Modify the audio_generator() to only yield audio chunks while button.is_pressed is True. This turns the Pi into a high-fidelity walkie-talkie.
  • Extend (Local Wake Word): Integrate Picovoice Porcupine. Porcupine runs locally on the Pi's CPU, listening for a custom wake word (like "Computer"). Once detected, it triggers the gRPC stream to Google. This drastically reduces cloud API calls and improves privacy, as audio is only streamed after the local wake word triggers.

Frequently Asked Questions

Can I run the official Google Home app directly on Raspberry Pi OS?

No. The Google Home app is compiled for Android and iOS ARM architectures and relies on proprietary Google Play Services. While you can run Android emulators on a Pi, the performance is unusable for real-time smart home control. The gRPC Embedded API used in this guide is the only supported, performant method to integrate Google Assistant natively on Linux.

Why does my ReSpeaker HAT show "no soundcard found" on Pi 5?

The Raspberry Pi 5 uses a completely new RP1 I/O controller, which broke older I2S kernel overlays. If aplay -l returns no devices, you are likely using an outdated Seeed kernel driver. You must use the updated seeed-voicecard DKMS package specifically patched for the Pi 5's Bookworm kernel, or manually configure the dtoverlay=seeed-2mic-voicecard in /boot/firmware/config.txt after pulling the latest Seeed Studio GitHub repository.

How do I connect this Pi Google Home to my existing smart home devices?

You do not need to program MQTT or Zigbee bridges into the Python script. Because the Pi authenticates via your personal Google account OAuth token, it automatically inherits your Google Home ecosystem. Simply open the Google Home app on your phone, go to Settings > Assistant > Devices, and your Pi will appear as a new speaker. Any smart lights or thermostats linked to your Google account can be controlled by voice through the Pi immediately.