Building a UAP "Dog Whistle": Exploring the Skywatcher Phenomenon
Building our own UAP 'dog whistle' device using a Raspberry Pi Zero, battery, and custom Python code. Inspired by Skywatcher's tech, we're sharing the complete DIY guide.
This guide provides step-by-step instructions for configuring a Raspberry Pi Zero W (or other Pi models) to automatically connect to a Bluetooth speaker at boot, with a watchdog service that will reconnect if the speaker is turned off and back on later.
First, we need to install the necessary Bluetooth packages including the audio utilities:
sudo apt update
sudo apt upgrade -y
sudo apt install -y bluetooth bluez bluez-alsa-utils
The bluez-alsa-utils
package is critical for the audio profiles to work correctly.
Start the Bluetooth service and configure your speaker:
# Start Bluetooth service
sudo systemctl start bluetooth
sudo systemctl enable bluetooth
# Enter Bluetooth control
sudo bluetoothctl
In the bluetoothctl interface, run these commands:
agent on
default-agent
scan on
# Wait for your speaker to appear, then replace XX:XX:XX:XX:XX:XX with your speaker's MAC
pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
connect XX:XX:XX:XX:XX:XX
exit
If you're having trouble connecting, try removing the device first:
remove XX:XX:XX:XX:XX:XX
scan on
# Then pair again
Edit the main Bluetooth configuration file:
sudo nano /etc/bluetooth/main.conf
Add or modify these lines (if they don't exist, add them at the end):
[General]
Class = 0x00041C
Enable = Source,Sink,Media,Socket
This setting ensures the audio profiles are properly enabled.
Create a script that will handle connecting to your Bluetooth speaker:
sudo nano /usr/local/bin/bluetooth-speaker-manager.sh
Paste this script (replace XX:XX:XX:XX:XX
with your speaker's MAC):
#!/bin/bash
SPEAKER_MAC="XX:XX:XX:XX:XX:XX"
LOG_FILE="/tmp/bluetooth-connect.log"
CONNECTED_FLAG="/tmp/bt_speaker_connected"
EVENT_SCRIPT="/usr/local/bin/speaker-connected.sh"
MAX_ATTEMPTS=3
# Function to check if already connected
check_connection() {
if bluetoothctl info $SPEAKER_MAC | grep -q "Connected: yes"; then
return 0 # Connected
else
return 1 # Not connected
fi
}
# Log with timestamp
log_message() {
echo "$(date) - $1" >> $LOG_FILE
}
log_message "Bluetooth speaker manager starting"
# Check if already running
if [ -f /tmp/bt_manager_running ]; then
PID=$(cat /tmp/bt_manager_running)
if ps -p $PID > /dev/null; then
log_message "Already running with PID $PID, exiting"
exit 0
fi
fi
# Set running flag
echo $$ > /tmp/bt_manager_running
# Initial check
if check_connection; then
log_message "Speaker already connected"
# Only run the event script once per connection
if [ ! -f "$CONNECTED_FLAG" ]; then
log_message "Running connected event script"
touch "$CONNECTED_FLAG"
[ -x "$EVENT_SCRIPT" ] && "$EVENT_SCRIPT" &
fi
exit 0
else
# Not connected, remove the flag
rm -f "$CONNECTED_FLAG"
fi
# Make sure Bluetooth is running
if ! systemctl is-active bluetooth >> $LOG_FILE 2>&1; then
log_message "Starting Bluetooth service"
systemctl start bluetooth
sleep 5
fi
# Ensure Bluetooth audio profiles are available
log_message "Ensuring audio profiles are loaded"
sudo hciconfig hci0 class 0x41C
sleep 2
# Reset Bluetooth adapter
log_message "Resetting Bluetooth adapter"
bluetoothctl power off >> $LOG_FILE 2>&1
sleep 3
bluetoothctl power on >> $LOG_FILE 2>&1
sleep 8
# Try to connect - multiple attempts
for attempt in $(seq 1 $MAX_ATTEMPTS); do
log_message "Connection attempt $attempt of $MAX_ATTEMPTS"
# Try to connect
(
echo "power on"
sleep 2
echo "agent on"
sleep 1
echo "default-agent"
sleep 1
echo "connect $SPEAKER_MAC"
sleep 10
echo "quit"
) | bluetoothctl >> $LOG_FILE 2>&1
# Check if successful
if check_connection; then
log_message "Successfully connected to speaker"
touch $CONNECTED_FLAG
# Run the event script when connected
[ -x "$EVENT_SCRIPT" ] && "$EVENT_SCRIPT" &
exit 0
fi
log_message "Attempt $attempt failed, retrying..."
sleep 3
done
log_message "Failed to connect to Bluetooth speaker after $MAX_ATTEMPTS attempts"
rm -f $CONNECTED_FLAG
exit 1
Make the script executable:
sudo chmod +x /usr/local/bin/bluetooth-speaker-manager.sh
Create a script that will run when the speaker connects:
sudo nano /usr/local/bin/speaker-connected.sh
Paste this content:
#!/bin/bash
# This script runs when the Bluetooth speaker connects
# You can customize it to run any audio application you want
LOG_FILE="/tmp/bluetooth-connect.log"
echo "$(date) - Speaker connected event running" >> "$LOG_FILE"
# Example: Play a notification sound to confirm connection
if [ -f /usr/share/sounds/alsa/Front_Center.wav ]; then
aplay /usr/share/sounds/alsa/Front_Center.wav
elif [ -f /usr/share/sounds/freedesktop/stereo/complete.oga ]; then
# Try another common sound file
aplay /usr/share/sounds/freedesktop/stereo/complete.oga
fi
# Example: Start your audio application
# mpg123 /path/to/your/music.mp3 &
# Add any other commands you want to run when connected
exit 0
Make it executable:
sudo chmod +x /usr/local/bin/speaker-connected.sh
Create a systemd service that will continuously check if the speaker is connected and attempt to reconnect if needed:
sudo nano /etc/systemd/system/bluetooth-speaker-watchdog.service
Paste this service definition:
[Unit]
Description=Bluetooth Speaker Connection Watchdog
After=bluetooth.target network.target
Wants=bluetooth.target
Requires=bluetooth.service
[Service]
Type=simple
ExecStartPre=/bin/sleep 30
ExecStart=/bin/bash -c 'while true; do if ! bluetoothctl info XX:XX:XX:XX:XX:XX | grep -q "Connected: yes"; then /usr/local/bin/bluetooth-speaker-manager.sh; fi; sleep 30; done'
Restart=on-failure
RestartSec=30
StandardOutput=journal
[Install]
WantedBy=multi-user.target
Be sure to replace XX:XX:XX:XX:XX
with your speaker's MAC address.
sudo systemctl daemon-reload
sudo systemctl enable bluetooth-speaker-watchdog
sudo systemctl start bluetooth-speaker-watchdog
# Check service status
sudo systemctl status bluetooth-speaker-watchdog
# Check speaker connection
bluetoothctl info XX:XX:XX:XX:XX:XX
# View connection logs
tail -f /tmp/bluetooth-connect.log
If you see "Failed to connect: org.bluez.Error.Failed br-connection-profile-unavailable", make sure you've:
If you see "Failed to connect: org.bluez.Error.Failed br-connection-page-timeout", try:
journalctl -u bluetooth-speaker-watchdog
systemctl is-enabled bluetooth-speaker-watchdog
aplay -l
aplay -D bluealsa:HCI=hci0,DEV=XX:XX:XX:XX:XX:XX /usr/share/sounds/alsa/Front_Center.wav
You can customize the speaker-connected.sh script to do anything you want when the speaker connects, such as:
This setup provides a reliable way to automatically connect to a Bluetooth speaker at boot and reconnect if the connection is lost. The watchdog service ensures the speaker will always be connected when available, and the event script allows you to run custom actions when the connection is established.