Dominic Böttger

← Back to blog

Published on January 3, 2026 by Dominic Böttger · 6 min read

That Surface Pro 6 gathering dust in your drawer? It’s actually an excellent candidate for a Home Assistant voice satellite. Originally designed for Microsoft Teams conference rooms, the Surface Pro features high-quality digital MEMS microphones with hardware beamforming - making it surprisingly well-suited for voice assistant duties.

Why the Surface Pro 6 Excels as a Voice Satellite

The Surface Pro 6 was built with video conferencing in mind. Microsoft equipped it with features that translate perfectly to voice assistant use:

Conference-Grade Microphone Array

The Surface Pro features a dual far-field microphone array with several advantages:

These features were designed so Microsoft Teams could pick up voices clearly across a conference room - the same qualities that make wake word detection reliable from across your living room.

Additional Benefits

Architecture Overview

The setup uses the Wyoming protocol to connect your Surface to Home Assistant:

┌─────────────────────────────────────────────────────────────┐
│                     Surface Pro 6                           │
│  ┌─────────────────┐     ┌──────────────────────────────┐  │
│  │ wyoming-        │────▶│ wyoming-satellite            │  │
│  │ openwakeword    │     │ (streams audio to/from HA)   │  │
│  │ (local wake     │     └──────────────────────────────┘  │
│  │  word detection)│                  │                    │
│  └─────────────────┘                  │                    │
└───────────────────────────────────────┼────────────────────┘
                                        │ TCP/10700

┌───────────────────────────────────────────────────────────┐
│                   Home Assistant                           │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐    │
│  │   Whisper   │  │   Piper     │  │ Conversation    │    │
│  │   (STT)     │  │   (TTS)     │  │ Agent           │    │
│  └─────────────┘  └─────────────┘  └─────────────────┘    │
└───────────────────────────────────────────────────────────┘

Prerequisites

Before starting, ensure you have:

  1. Surface Pro 6 running Linux with the linux-surface kernel
  2. Home Assistant with Whisper and Piper add-ons installed
  3. Network connectivity between Surface and Home Assistant

If you haven’t set up Linux on your Surface yet, check out my article on fixing Surface Pro touch after suspend.

Step 1: Install Wyoming Satellite

First, clone and set up the Wyoming Satellite on your Surface:

# Create installation directory
sudo mkdir -p /opt/wyoming-satellite
sudo chown $USER:$USER /opt/wyoming-satellite
cd /opt/wyoming-satellite

# Clone the repository
git clone https://github.com/rhasspy/wyoming-satellite.git .

# Create virtual environment and install
python3 -m venv .venv
.venv/bin/pip install --upgrade pip wheel
.venv/bin/pip install -e .

# Install WebRTC for noise suppression
.venv/bin/pip install webrtc-noise-gain

Download Notification Sounds

mkdir -p sounds
wget -O sounds/awake.wav \
  "https://github.com/rhasspy/wyoming-satellite/raw/master/sounds/awake.wav"
wget -O sounds/done.wav \
  "https://github.com/rhasspy/wyoming-satellite/raw/master/sounds/done.wav"

Step 2: Install Wyoming openWakeWord

Install the local wake word detection service:

# Create installation directory
sudo mkdir -p /opt/wyoming-openwakeword
sudo chown $USER:$USER /opt/wyoming-openwakeword
cd /opt/wyoming-openwakeword

# Clone and install
git clone https://github.com/rhasspy/wyoming-openwakeword.git .
python3 -m venv .venv
.venv/bin/pip install --upgrade pip wheel
.venv/bin/pip install -e .

Step 3: Find Your Audio Devices

Identify the correct ALSA device names:

# List recording devices
arecord -L | grep -A1 "^plughw"

# List playback devices
aplay -L | grep -A1 "^plughw"

On the Surface Pro 6, the internal audio is typically plughw:CARD=PCH,DEV=0.

Step 4: Create Systemd Services

openWakeWord Service

Create /etc/systemd/system/wyoming-openwakeword.service:

[Unit]
Description=Wyoming openWakeWord
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=dob
Group=dob
ExecStart=/opt/wyoming-openwakeword/.venv/bin/python3 -m wyoming_openwakeword \
    --uri "tcp://0.0.0.0:10400" \
    --preload-model hey_jarvis \
    --threshold 0.3 \
    --trigger-level 1 \
    --debug
WorkingDirectory=/opt/wyoming-openwakeword
Restart=always
RestartSec=1

[Install]
WantedBy=default.target

Configuration options:

Wyoming Satellite Service

Create /etc/systemd/system/wyoming-satellite.service:

[Unit]
Description=Wyoming Satellite
Wants=network-online.target
After=network-online.target wyoming-openwakeword.service

[Service]
Type=simple
User=dob
Group=dob
Environment=XDG_RUNTIME_DIR=/run/user/1000
ExecStart=/opt/wyoming-satellite/.venv/bin/python3 -m wyoming_satellite \
    --name "Surface Kiosk" \
    --uri "tcp://0.0.0.0:10700" \
    --mic-command "arecord -D plughw:CARD=PCH,DEV=0 -r 16000 -c 1 -f S16_LE -t raw" \
    --snd-command "aplay -D plughw:CARD=PCH,DEV=0 -r 22050 -c 1 -f S16_LE -t raw" \
    --mic-auto-gain 5 \
    --mic-noise-suppression 2 \
    --wake-uri "tcp://127.0.0.1:10400" \
    --wake-word-name "hey_jarvis" \
    --awake-wav "/opt/wyoming-satellite/sounds/awake.wav" \
    --done-wav "/opt/wyoming-satellite/sounds/done.wav" \
    --debug
WorkingDirectory=/opt/wyoming-satellite
Restart=always
RestartSec=1

[Install]
WantedBy=default.target

Key parameters:

Step 5: Enable and Start Services

# Reload systemd
sudo systemctl daemon-reload

# Enable services to start on boot
sudo systemctl enable wyoming-openwakeword
sudo systemctl enable wyoming-satellite

# Start services
sudo systemctl start wyoming-openwakeword
sudo systemctl start wyoming-satellite

Step 6: Connect to Home Assistant

  1. Go to Settings → Devices & Services → Add Integration
  2. Search for Wyoming
  3. Enter your Surface’s IP address and port 10700
  4. The satellite should appear as “Surface Kiosk”

Configure the Assist Pipeline

  1. Go to Settings → Voice Assistants
  2. Create or edit a pipeline
  3. Set the satellite as a voice assistant device

Testing and Troubleshooting

Check Service Status

systemctl status wyoming-openwakeword wyoming-satellite

View Live Logs

# Watch wake word detection
journalctl -u wyoming-openwakeword -f

# Watch satellite activity
journalctl -u wyoming-satellite -f

Successful Detection Log

When working correctly, you’ll see:

DEBUG:wyoming_openwakeword.handler:Detected hey_jarvis at 26300
DEBUG:root:Detection(name='hey_jarvis', timestamp=26300)
DEBUG:root:Streaming audio
DEBUG:root:Event(type='run-pipeline', data={'start_stage': 'asr'...})

Common Issues

Wake word not detecting:

Audio cutting out:

High latency:

CPU Usage Considerations

Running openWakeWord locally uses approximately 10-15% CPU on the Surface Pro 6’s 8th gen Intel Core. This is acceptable for a dedicated kiosk device, but if you want to minimize power consumption, consider:

  1. Offloading wake word detection to Home Assistant - requires the openWakeWord add-on
  2. Using push-to-talk - disable wake word entirely and trigger via dashboard button

Conclusion

The Surface Pro 6’s conference-grade microphones and touchscreen make it an excellent choice for a Home Assistant voice satellite. The beamforming microphone array picks up wake words reliably from across the room, while the display can serve as an always-on dashboard for your smart home.

Combined with the linux-surface kernel for proper hardware support, you can breathe new life into aging Surface hardware while gaining a capable voice control point for your home automation.


Tested on Surface Pro 6 (i5-8250U), Ubuntu 24.04, linux-surface kernel 6.18.2-surface-1, Wyoming Satellite 1.5.0, Wyoming openWakeWord 1.8.0

Written by Dominic Böttger

← Back to blog
  • Syncing SharePoint and OneDrive on Arch Linux with One Click

    Syncing SharePoint and OneDrive on Arch Linux with One Click

    Set up Microsoft SharePoint and OneDrive sync on Arch Linux using abraunegg/onedrive. Includes a protocol handler script that makes the "Sync" button in SharePoint work natively, with automatic drive detection and systemd background sync.

  • From Sequential to Parallel: Adding Agent Teams to Spec Kit

    From Sequential to Parallel: Adding Agent Teams to Spec Kit

    How we extended Spec Kit with a new /speckit.team-implement command that auto-detects parallel work streams from your task list and spawns specialized AI agent teams to implement features simultaneously -- complete source code, algorithm walkthrough, and usage guide.

  • Building a Private Claude Code Plugin Marketplace for Your Team

    Building a Private Claude Code Plugin Marketplace for Your Team

    Learn how to structure a private Claude Code plugin marketplace for your team, including repository layout, naming conventions, and how to register local or remote marketplaces.

  • Spec Kit + Ralph Loop: Solving AI Context Exhaustion in Large Features

    Spec Kit + Ralph Loop: Solving AI Context Exhaustion in Large Features

    How we combined Spec Kit's structured planning with Ralph Wiggum's fresh context methodology to build an AI-powered development loop that can implement features of any size without context pollution.

  • Mistral Releases Vibe CLI and Devstral 2: Open-Source AI Coding Goes Next Level

    Mistral Releases Vibe CLI and Devstral 2: Open-Source AI Coding Goes Next Level

    Mistral AI launches Vibe CLI and Devstral 2, bringing powerful open-source AI coding assistance to your terminal. Learn how to install and get started with these game-changing tools.

  • Auto Dark Mode on Linux Based on Real Sunrise and Sunset

    Auto Dark Mode on Linux Based on Real Sunrise and Sunset

    Set up automatic theme switching on Linux that follows the real sunrise and sunset times for your location, not just fixed schedules. Complete guide for Hyprland/Omarchy with systemd timers.