Skip to content

Instantly share code, notes, and snippets.

@jcconnell
Last active December 28, 2023 17:09
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jcconnell/0ee6c9d5b25c572863e8ffa0a144e54b to your computer and use it in GitHub Desktop.
Save jcconnell/0ee6c9d5b25c572863e8ffa0a144e54b to your computer and use it in GitHub Desktop.
A bash script to enable, disable or check the status of a UniFi WiFi network.
#!/bin/bash
unifi_username=USERNAME
unifi_password='PASSWORD'
unifi_controller=https://EXAMPLE.COM:8443
wifi_id=YOUR_WIFI_ID
cookie=/tmp/cookie
curl_cmd="curl -s -S --cookie ${cookie} --cookie-jar ${cookie} --insecure "
unifi_login() {
# authenticate against unifi controller
# Mute response by adding > /dev/null
${curl_cmd} -H "Content-Type: application/json" -X POST -d "{\"password\":\"$unifi_password\",\"username\":\"$unifi_username\"}" $unifi_controller/api/login > /dev/null
}
unifi_logout() {
# logout
${curl_cmd} $unifi_controller/logout
}
enable_wifi() {
# enables guest wifi network
# Mute response by adding > /dev/null
${curl_cmd} "$unifi_controller"'/api/s/default/rest/wlanconf/'"$wifi_id" -X PUT --data-binary '{"_id":"'"$site_id"'","enabled":true}' --compressed > /dev/null
}
disable_wifi() {
# enables guest wifi network
# Mute response by adding > /dev/null
${curl_cmd} "$unifi_controller"'/api/s/default/rest/wlanconf/'"$wifi_id" -X PUT --data-binary '{"_id":"'"$site_id"'","enabled":false}' --compressed > /dev/null
}
check_status() {
# checks wifi network status
# Mute response by adding > /dev/null
response=$(${curl_cmd} "$unifi_controller"'/api/s/default/rest/wlanconf/'"$wifi_id" --compressed)
status=$(echo $response | jq ".data[0].enabled")
if [ "$status" == "true" ]; then
exit 0
elif [ "$status" == "false" ]; then
exit 1
else
echo exit -1
fi
}
unifi_login
if [ "$1" == "enable" ]; then
echo "Enabling WiFi."
enable_wifi
elif [ "$1" == "disable" ]; then
echo "Disabling WiFi."
disable_wifi
elif [ "$1" == "status" ]; then
check_status
else
echo "Must include command line parameter [enable|disable|status]."
fi
unifi_logout
@jcconnell
Copy link
Author

Last Updated: 7/28/18

A bash script to enable, disable or check the status of a UniFi WiFi network.

Requirements:

  • jq
  • curl

User Config:

  • unifi_username: The username for your controller
  • unifi_password: The password for the user. Leave inside the single quotes.
  • unifi_controller: The URL where you access your controller.
  • wifi_id: The ID of the WiFi you'd like to control. Details for acquiring the id below.
  • cookie: Path to the cookie for curl. Make sure the user that runs this script has permissions to this directory/file.

Details:

  • This script is run like the following where parameter can be one of the following (enable | disable | status):
    ./unifi_wifi.sh parameter

Getting your wifi_id:

  • Navigate to your controller and sign in.
  • Navigate to Settings > Wifi Networks.
  • Click Edit next to the SSID you'd like to control.
  • Copy the ID from the end of the URL.
  • In the following example, the ID is ( 000d00c0e0b0e00d00000000 ):
    https://example:8443/manage/site/default/settings/wlans/00bd00a6e0000e9da2cde10c/edit/000d00c0e0b0e00d00000000

Use:

  • Create a new file on your machine. I named mine unifi_wifi.sh.
  • Copy the below contents into your file.
  • Save the file.
  • chmod +x unifi_wifi.sh (Insert your file name there).
  • Use like ./unifi_wifi.sh parameter

@knyckis
Copy link

knyckis commented Apr 11, 2020

Thanks, worked like a charm, and perfect, easy peasy explanation of how to use it at that. Much obliged!

@jcconnell
Copy link
Author

Glad you enjoyed it! I used this as a way to control my Unifi networks from Home Assistant.

@baldrick
Copy link

Excellent mitigation for Unifi UI fail, thanks!

@ReMiOS
Copy link

ReMiOS commented Jan 11, 2021

worked great until ....
after a upgrade to UniFi controller v6.0.43.0 i get "curl: (7) Failed to connect to 10.0.0.1 port 8443: Connection refused"

@alexlmiller
Copy link

Hey JC - I'm trying to do the same thing as you (control WiFi via Home Assistant) but can't get the script to work with my UDM running Unifi-OS. I found a separate guide that said all the network requests need to have /proxy/network as part of the base URL (which I added) but everything still 404s when I try to make any of the calls.

Any ideas how if there's something else it may need to do in order to work on UnifiOS?

@ReMiOS
Copy link

ReMiOS commented Jan 20, 2021

Port 8443 is not used anymore (command "netstat -tlnp" does not show this port listening)
As of Unifi-OS v2 regular https port 443 is used

API Reference: https://ubntwiki.com/products/software/unifi-controller/api
From the API Reference: All API endpoints need to be prefixed with /proxy/network
From the API Reference: The login endpoint is /api/auth/login

Also i've found some changes in the path: /v2/api instead of /api

But nothing i try works ....

@jcconnell
Copy link
Author

Just wanted to follow up that this is still working for me. I host my controller on a GCP free tier instance similarly to how it is described here: https://metis.fi/en/2018/02/unifi-on-gcp/.

I'd suggest checking:

Here is a Home Assistant config snippet:

- platform: command_line
    switches:
      guest_wifi:
        command_on: '/config/shell_scripts/unifi_guest.sh enable'
        command_off: '/config/shell_scripts/unifi_guest.sh disable'
        command_state: '/config/shell_scripts/unifi_guest.sh status'
        friendly_name: Guest WiFi

@alexlmiller
Copy link

So my issue (making it work with Dream Machine line) ended up being that the UnifiOS based stuff request a CSRF token for any PUT or POST command (this was especially maddening because it doesn't require CSRF for GETs and it only returns 404 errors instead of something useful like a 401 or a status message)

I forked a basic python client that was written for for the UDMP and added the relevant calls and logic here: https://gist.github.com/alexlmiller/586f74bbef395e1a34b2dfd06541102b

@ReMiOS
Copy link

ReMiOS commented Jan 26, 2021

On a v2 Unifi OS the port 8443 is not used anymore (command "netstat -tlnp" does not show this port listening)

API Reference: https://ubntwiki.com/products/software/unifi-controller/api
From the API Reference: All API endpoints need to be prefixed with /proxy/network
From the API Reference: The login endpoint is /api/auth/login

i am running the script as user 'root', so rights to '/tmp/cookie' is no issue

# curl -s -S --cookie /tmp/cookie --cookie-jar /tmp/cookie --insecure -H "Content-Type: application/json" -X POST -d "{"password":"your-password","username":"your-username"}" https://<ip-address-controller>/api/login
# curl -s -S --cookie /tmp/cookie --cookie-jar /tmp/cookie --insecure -H "Content-Type: application/json" -X POST -d "{"password":"your-password","username":"your-username"}" https://<ip-address-controller>/proxy/network/api/auth/login

But any url replies with "Not Found" (instead of "Unauthorised" when i use a wrong password)

The script from alexmiller works, so i think an "X-CSRF-Token" header has to be used.

@djspike77
Copy link

Hi,

Tried installing your script using of course the latest version of the controller.

Getting this error:

./unifi_wifi.sh status
parse error: Invalid numeric literal at line 1, column 10
exit -1

<!doctype html>

<script type="text/javascript" src="/vendor.0306759b.chunk.js"></script><script type="text/javascript" src="/main.d8e6c715.js"></script>

May I ask for help?

@funkybunch
Copy link

Something I came across while adding this is it only works as-written if you use want to control a network on the default site. If you use a different site, you will need to also grab that out of the same URL you use to find the network ID.

When you click edit on a wireless network in the Unifi Controller, it will look something like this in the new settings page:

/manage/site/<site_name>/v2/settings/wifi/network/form/<network_id>

You'll need to replace default in the API endpoint URLs with site_name from the URL above, otherwise you'll get a api.err.NoSiteContext error.

Hope this helps.

@s3frank
Copy link

s3frank commented Jun 22, 2023

Thanks for this. Very handy!
After reading a bit more and also the API I was fascinated with controlling the LED of my APs.
In the UI it can be turned on and off and recently even change color and brightness.
But I don't see how to do this in the API.

Any thoughts?

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment