Skip to content

Instantly share code, notes, and snippets.

@jcconnell
Last active November 8, 2024 10:39
Show Gist options
  • 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!

@knyckis
Copy link

knyckis commented Nov 8, 2024

Redid this process today and can confirm that it still worked like a charm! The only thing different per the instructions above is that in finding the wifi id, you now click on the wifi network in question (thus getting to the edit page) and then read off the wifi_id directly from the slightly different url. Reusing the example id:

https://example:8443/manage/default/settings/wifi/000d00c0e0b0e00d00000000

So same same, fundamentally speaking, but looking at little different.

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