UPDATED: Automating Unifi WiFi SSID password changes and QR code generation

It’s the up address of whatever web server you out the qr code on. If you’re using my code without (much) modification, that would be your HA IP.

thank you …for some reason the automation isnt running the script …my password doesnt change for the wifi …could firewall rules block it from running …I made sure to create a new local admin user in unifi and tested the user name and password

I think your idea is really good.
I have implemented everything as you have described, but am slowly despairing.
I have the Unifi controller with version 7.3.83 as docker on a Unraid system.
The script also runs until the QR code is saved.
After that it should log on to the Unifi controller and change the password.
But what does not work.

Does anyone have the same problem or can help me?

Sorry, I don’t know if it works with the Unifi controller. This code was written and developed for a Dream Machine Pro…

That’s probably because the login & API endpoints for a UDM or UDM pro are different from the standard Unifi controller endpoints. You’ll need to make a few changes:

  1. Line 16: change https://${3}/api/auth/login to https://${3}/api/login
  2. Line 22: change https://${3}/proxy/network/api/s/default/rest/wlanconf/${4} to https://${3}/api/s/default/rest/wlanconf/${4}
  3. BaseURL: this script requires the format https://<ip-address>:<port>. Adjust the port to 8443 instead of 443 (UDM, UMD pro only). This assumes 8443 is mapped to 8443 in your Docker config.
1 Like

You’re the man! Thanks for the assist. :slight_smile:

Thanks @exx for you works !
I don’t have a UDM (PRO) but I was able to make it work by adapting the code with the indications of @rootnegativ1.
I’ll share the code here too if it can be useful to others.

Some explanations: according to the unifi wiki, I think it is useless to get the CSRF Token if you don’t have a UDM or a UDM Pro. I also took care to remove the change function to lighten the code. I also removed the EOF
in the configuration.yaml file, you have to use double quotes for the SSID of the WiFi, if ever there are SSID with the space character:

#!/bin/sh

cookie=$(mktemp)
headers=$(mktemp)

curl_cmd="curl --silent --output /dev/null --cookie ${cookie} --cookie-jar ${cookie} --insecure"

# generate new password
NEW_PWD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)

# generate QR code
wget --output-document="/config/www/${5}.png" "http://api.qrserver.com/v1/create-qr-code/?data=WIFI:T:WPA;S:${5};P:${NEW_PWD};H:;&size=100x100"

# authenticate against unifi controller
${curl_cmd} -H 'Content-Type: application/json' -D ${headers} -d "{\"username\":\"${1}\", \"password\":\"${2}\"}" https://${3}/api/login

# change wifi password
${curl_cmd} -k -X PUT https://${3}/api/s/default/rest/wlanconf/${4} -H "Content-Type: application/json" -d "{\"_id\":\"${4}\",\"x_passphrase\":\"${NEW_PWD}\"}"

configuration.yaml:

shell_command:
    unifi_wlanchange: /bin/bash /config/scripts/wifichange.sh change {{ username }} {{ password }} {{ baseurl }} {{ network_id }} "{{ ssid }}"
1 Like

Excellent work!!! Glad to hear you were able to get it doing what you needed!!

If this was implemented in the UniFi integration, how would you prefer this to be exposed?

First, allow me to say how humbled I am that you would include a one-off feature that I (mostly) wrote into the main integration. I’m honored.

Beyond that, I’m not sure what the best way to expose it in the integration would be. I’m a pretty terrible UI developer, just ask anyone who’s seen my dashboard… Lol

That aside, perhaps another screen added to the config wizard that has a checkbox for if you want to do this or not, then a box for the time you want it to happen, and then perhaps a drop down for the SSID you want to do this to? It would then create a camera entity named like “myssid_qrcode_camera” or something that users could then add to their dashboard? I suppose you’d also need another input field for how many characters they wanted it to be, and perhaps one for if they want special characters included (some devices have trouble, though I’m not sure that would be applicable in this instance?) Not sure. Just spitballing. I’m sure you will come up with something excellent. :slight_smile:

Thanks again, this is just too cool!

1 Like

you could do it in two parts:

  1. create a camera entity for each wlan which includes some of the class attributes from aiounifi including _id, name, and x_passphrase. Then use the python module qrcode to generate a png for the camera. Not really sure where to store the png file…
  2. create a service called unifi.set_wifi_password
    Service data attribute Optional Description
    id no 24 character string identifying the wireless network
    random no BOOLEAN should the password be randomized
    password yes STRING user provided password
    if random is set true, then override any user provided password with one that is randomly generated. This could simply be a bunch of random characters, or something like Diceware passphrases using the python module xkcdpass
1 Like

I don’t think it’s a one-off feature, it provides real value. Being done through alternative means than an official integration doesn’t diminish the value you’ve provided here!

1 Like

Thanks, yes I was thinking something similar.

Great suggestions on the service however I ponder if its unnecessarily complex adding a service for this rather than just a button to set a new randomised password, the whole thing with the QR code is to not need to know the password right?

1 Like

Looking at generating a QR code, is it only “WPA” as well as passphrase that’s relevant? There are no other variants to care about?

Basing it on what has been done for fritzconnection fritzconnection/fritzwlan.py at 4b00d5df06564dd9b8353c505397dae2448b7fe7 · kbr/fritzconnection · GitHub

Great catch!

According to the standard:

Authentication type; can be WEP or WPA or WPA2-EAP, or nopass for no password. Or, omit for no password.

Since I wrote this for me, and then published it for home users, WPA was used. WPA covers WPA, WPA2, and WPA3. I don’t know anyone who uses WEP anymore (it’s old and busted), and EAP is enterprise and uses RADIUS, which is also uncommon in home networks.

If it’s not too much difficulty, including the various types may be nice. I would think that information can be gotten from interrogating the SSID on the dream machine, rather than asking the user. Otherwise, I think WPA will catch greater than 99% of use cases.

1 Like

Good evening everyone,

Thank you, @exx, for your excellent scripts and Youtube videos!
I am still pretty green with HomeAssistant so I apologize if this question is very basic.

I tried going through all of the steps and I am not able to get the password to change on my dream machine pro or the image to update.
The only log file I see has the below information. Is there a way to get better logging?

Any help would be much appreciated!

wifiPW: Error executing script. Unexpected error for call_service at pos 1: No closing quotation
8:54:48 PM – (ERROR) Automation - message first occurred at 5:04:32 PM and shows up 6 times
Error getting new camera image from guestqrcode: Server disconnected without sending a response.
8:54:06 PM – (ERROR) Generic Camera - message first occurred at 5:04:42 PM and shows up 23 times

Looks like you’re missing a quotation mark somewhere maybe?

Can someone help me with this setup? I followed the steps several times and I can’t get it to update the password and or produce a QR code.

You’re going to need to be a bit more specific…

Yes more information might help lol. I have this setup but its not working. Is there anything I can check for why its failing? Not sure how to troubleshoot this process.