Enable or disable a UniFi WiFi network via switch in Home Assistant

I created this script to be used from within Home Assistant. It can be used to enable, disable or check the status of a wifi network. Read the details below and check this gist for updates:

Last Updated: 7/28/18

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

Example configuration.yaml:

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

Example Script:

#!/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
4 Likes

Thank you very much… wanted to do that for a long time but didn’t get around to it yet :slight_smile:
Works like a charm!

FYI: You have to disable the manual override for enable in the Unifi UI otherwise you cannot turn on or off with this script. This happened to me because i have guest Wifi only activated on 2.4Ghz and not on 5Ghz. The disable flag for override can stay though.

You might be able to adjust the script to satisfy the 5GHz only requirement.

The URL to modify a specific device would look like:
https://example.com:8443/api/s/default/rest/device/0af00a0bc44810000df4aec0

The data would like like:
–data-binary ‘{“wlan_overrides”:[{“wlan_id”:“b2e8eb39d273a56eb030c460”,“enabled”:false}]}’

The device ID can be found by:

  • Opening DevTools on Chrome
  • Navigate to network tab (watch for network calls here)
  • Open UniFi Controller
  • Goto Devices
  • Click device you want to modify
  • Queue changes you want to make
  • Apply Changes
  • In the network console, you’ll see a new query was made.
  • Right click the query. Choose copy as cURL.
  • In the URL you’ll be able to find the device ID

Thank for creating this. It’s exactly what I need to turn of the kids wifi when required.

Could i please ask for some help with setting it up? Where in the folder structure do I place the unifi_wifi.sh file? In the configuration folder where the configuration.yaml file is? I have added the switch configuration to the configuration.yaml. Just not sure what to do next.

My next question is about curl and the cookie path. Is this something i have to install?

Thanks for your work on this… exactly what I have been looking for.

I’m having trouble in getting it to work though… Unifi Dream Machine, latest software. I get a 'exit -1` error when checking the status. Have exported a cookie from my browser, updated user name, password, wifi id, controller address.

Anything obvious that I’m missing?

Tx,
Jean

Try to print the value of the response to debug the issue.

Something like this at the end of the check_status() function:
echo "$response"

Thanks for the speedy response!

I added the line, here:

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
echo "$response"
fi
}

It gives a blank line in the terminal as a response though :-/

Try modifying the jq command to be jq ".data", then see what the output of check_status() is.

Alternately, here’s how I would try to debug the issue:

I think there have been a few issues in the past with Dream Machines. I’ve never used or interacted with them so I don’t have much insight.

  • Open a new browser tab in Chrome or Safari
  • Open the Inspector and navigate to the Network tab
  • Enter the address of your controller/Dream machine in the address bar and navigate to it
  • Navigate to Settings > WiFi and click the WiFi Name

In the web inspector, you should see a request named wlanconf. Select this request and then choose preview on the right hand side to see an example of the data returned. In the preview, you’ll be able to find a JSON array with the key data. Find the entry where id matches the id of your WiFi network and then look for the enabled field. This is the field that the check_status() function is looking for.

You may need to tweak the jq command in the check_status() function to get the information for the WiFi network you’re interested in.

Thanks again for your response! :slight_smile:

I tried all the steps above… still no output after changing the jq command. Using the web inspector, i found the wlanconf bit, and the enabled field… so it’s all there.

I think that the problem is in the login though… If I let the command create a new cookie, it generates this:

# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

Looks empty to me. So then I went into my browser and exported my browsers cookie (which was not empty) and used that. Same blank response.

Feels like the script is not authenticating so the jq command has nothing to do its job on, hence the blank response… something in unifi_login(). I pasted out the commands and replaced the variables to see if I could tweak anything there but it doesnt seem to give an output.

Anything else that I can try there?

Tx,
Jean

When I last looked at enabling/disabling wifi networks the whole controller reconfigured leading to many things not working for some time, leading to me not wanting to expose it in the unifi integration. Is that still the case?

Did you ever find out where the file should go @jmmitchell81 ?

Cheers in advance!

Unfortunately not. Sorry

Missed the earlier messages about file location. Sorry about that. Here’s what I’m using.

My script lives in: /home/homeassistant/.homeassistant/shell_scripts/unifi_guest.sh

Then I created a switch entity in configuration.yaml:

switch:
  - 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

Then I added the switch to my dashboard. This is all on a Docker installation of Home Assistant.

1 Like

Thanks @jcconnell
Got some free time to check this out again! I’ve followed through and get this…

Logger: homeassistant.components.command_line.switch
Source: components/command_line/switch.py:118
Integration: command_line (documentation, issues)
First occurred: 22:23:06 (3 occurrences)
Last logged: 22:34:24

Command failed: /config/unifi_kids_wifi.sh enable

The only bit I didn’t understand was the curl/cookies part
I’ve put the script in the config folder with the configuration.yaml file

Any help much appreciated!

Will need some more information that what’s provided in that error message to troubleshoot.

Can you goto the directory where you put the script (looks like /config/unifi_kids_wifi.sh from the error), execute the script manually and paste the output here?

Also, since it looks like you’re running Home Assistant via Docker, you’ll want to test executing the script from within the container. To get inside the container, execute this command first: docker exec -it home-assistant bash, then navigate to the config directory.

I’m having the same issue most people here seem to be having.
It’s not working - but what I’m struggling to do mainly is to debug it.

In my home assistant > Configuration > Settings > Logs, I’m seeing errors, but only limited detail:

Logger: homeassistant.components.command_line.switch Source: components/command_line/switch.py:133 Integration: command_line ([documentation](https://www.home-assistant.io/integrations/command_line), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+command_line%22)) First occurred: 6:56:33 PM (2 occurrences) Last logged: 7:13:34 PM

Command failed: /config/unifi_kids_wifi.sh enable

I’ve removed /dev/null within the script, and added echo “$response” at the bottom after the if/else, but I’m not sure how to trigger in a way that I can capture the full log?
Home assistant appears to be repressing the echo commands?

Any ideas, @jcconnell ?

Many thanks

Discovered I can view a small amount of logs - from Supervisor > System > Logs > Core

I added echo commands at the very start of the script, but not seeing them being returned - only Permission Denied.
So I actually think I’ve got a problem even running the script

Can’t quite work out what I’m doing wrong, config looks fine:
image

Script saved in “/config/unifi_kids_wifi.sh”

Why don’t you just use unifi integration and use the switches created by the integration? Much easier

It looks like the user that runs Home Assistant doesn’t have permission to execute the script. Based on your directories, I imagine you’re running a Docker based deployment - is that correct?

You need to give the user homeassistant permission to execute the script. One way to do this is by marking the homeassistant user as the owner of the script. Access a shell prompt on the machine that runs home assistant, navigate to the directory where you stored the script and execute chown homeassistant:homeassistant unifi_kids_wifi.sh. Restart Home Assistant and see if that fixes the issue.

@thundergreen I’m not familiar with that integration. Possible to share a link?

I’ll create switches for WiFi and non WiFi devices if you want and U can use it in automation