Goal: Query Ubiquiti’s cloud portal (unifi.ui.com) using custom API keys to track remote WAN status and local IP addresses of UniFi Express (UX) gateways.
Before jumping into the script code, it is important to understand why command-line scripts are extremely useful for modern smart homes. Beyond convenience for terminal users, these CLI scripts act as a programmatic interface (API bridge) for agentic AI assistants like Antigravity (agy).
By exposing Home Assistant states through standard shell scripts, an AI agent running in your workspace can query, check, and verify live IoT metrics or network states autonomously. This enables the agent to check if the network is healthy, read environment levels, or verify configurations without having to scrape web-based dashboards or utilize complex browser interfaces. It bridges human developer terminal workflows with agentic automation.
Step-by-Step Configuration
1. Generate a UniFi API Key
- Go to UniFi Site Manager.
- Log in and navigate to Settings -> Accounts -> API Tokens.
- Generate a new API Key, copy it, and save it locally:
echo "YOUR_UNIFI_CLOUD_API_KEY" > /home/gvoina/homeassistant/unifi_api_key.txt
2. Create the Status Aggregation Script
Write /home/gvoina/scripts/get_unifi_status.sh to fetch and format UniFi status details:
#!/usr/bin/env bash
set -eo pipefail
KEY_FILE="/home/gvoina/homeassistant/unifi_api_key.txt"
if [[ ! -f "$KEY_FILE" ]]; then
echo "Error: UniFi Cloud API key not found at $KEY_FILE."
exit 1
fi
API_KEY=$(cat "$KEY_FILE" | tr -d '\r\n[:space:]')
# Query the centralized Site Manager hosts and sites endpoints
HOSTS_RESPONSE=$(curl -s -X GET \
-H "X-API-KEY: $API_KEY" \
-H "Accept: application/json" \
"https://api.ui.com/v1/hosts")
SITES_RESPONSE=$(curl -s -X GET \
-H "X-API-KEY: $API_KEY" \
-H "Accept: application/json" \
"https://api.ui.com/v1/sites")
if echo "$HOSTS_RESPONSE" | jq -e '.data' >/dev/null 2>&1 && echo "$SITES_RESPONSE" | jq -e '.data' >/dev/null 2>&1; then
echo "================================================= CONSOLE STATUS (CLOUD API) ================================================="
printf "%-15s | %-12s | %-12s | %-8s | %-8s | %-12s | %-15s | %-10s\n" "Console Name" "Status" "Model" "Clients" "Devices" "WAN Uptime" "ISP" "Local IP"
echo "------------------------------------------------------------------------------------------------------------------------------"
echo "$HOSTS_RESPONSE" | jq -c '.data[]' | while read -r host_row; do
ID=$(echo "$host_row" | jq -r '.id')
NAME=$(echo "$host_row" | jq -r '.reportedState.name // "Unknown"')
STATUS=$(echo "$host_row" | jq -r '.reportedState.state // "offline"')
MODEL=$(echo "$host_row" | jq -r '.reportedState.hardware.shortname // "N/A"')
IP=$(echo "$host_row" | jq -r '.reportedState.ip // "N/A"')
# Match with site details
SITE_MATCH=$(echo "$SITES_RESPONSE" | jq -c ".data[] | select(.hostId == \"$ID\")" | head -n 1 || true)
if [[ -n "$SITE_MATCH" ]]; then
WIFI_CLIENTS=$(echo "$SITE_MATCH" | jq -r '.statistics.counts.wifiClient // 0')
WIRED_CLIENTS=$(echo "$SITE_MATCH" | jq -r '.statistics.counts.wiredClient // 0')
CLIENTS=$((WIFI_CLIENTS + WIRED_CLIENTS))
DEVICES=$(echo "$SITE_MATCH" | jq -r '.statistics.counts.totalDevice // 0')
WAN_UPTIME=$(echo "$SITE_MATCH" | jq -r '.statistics.percentages.wanUptime // "N/A"')
ISP=$(echo "$SITE_MATCH" | jq -r '.statistics.ispInfo.name // "Unknown"')
if [[ "$WAN_UPTIME" =~ ^[0-9.]+$ ]]; then
WAN_UPTIME="${WAN_UPTIME}%"
fi
else
CLIENTS="N/A"
DEVICES="N/A"
WAN_UPTIME="N/A"
ISP="N/A"
fi
printf "%-15s | %-12s | %-12s | %-8s | %-8s | %-12s | %-15s | %-10s\n" "$NAME" "$STATUS" "$MODEL" "$CLIENTS" "$DEVICES" "$WAN_UPTIME" "$ISP" "$IP"
done
echo "=============================================================================================================================="
else
echo "Error: Failed to query UniFi Cloud API."
exit 1
fi
Make the script executable:
chmod +x /home/gvoina/scripts/get_unifi_status.sh
