First of all there is a PHP library from Art-of-WiFi, which was unfortunately too powerful for my purposes.

Anyone who wants to do something more should take a look at this PHP class.

The script I created uses Python3 instead of PHP, which is included on all Linux systems. Also, the script is relatively easy to customize for your own needs.

I could successfully test the script from Unifi version 6 upwards.

Since I don't use a Unifi Cloud Controller (those parts are overpriced and unnecessary) I can't say for sure if it will work with it.

Create a Unifi user with minimal rights

All steps that require elevated privileges are done via SSH, so it is sufficient to create only a readonly user.

Log in to your Unifi controller (usually via port 8443).

Enable the legacy GUI because the new GUI does not allow creating users without email. Since we are creating a pure function user, we don't want that.

Unifi legacy interface

Go to Settings and create a readonly user with no special privileges under "Admins". Remember the password and the username.

Unifi Create readonly user

From this point on you can switch back to the modern interface.

Download script from Github

Download via curl or wget and unzip from github:

wget https://github.com/sowoi/automatically-renew-wifi-key-on-the-unifi-the-controller/archive/refs/tags/v1.0.tar.gz

The zip contains all Python modules that are needed.

If you want to install all Python dependencies yourself:

pip freeze:

  • pexpect 4.8.0
  • ptyprocess 0.7.0
  • requests 2.28.1
  • urllib3 1.26.12

Do not forget to change the shebang in the script!

Create Systemd Timer

[Unit]
Description=Change Wifi key of SSID
Wants=wifichanger.timer

[Service]
Type=oneshot
# This is just an example:
ExecStart=/srv/script/unifi_pexpect.py \
-H <ControllerIP> \
-U ControllerUser \
-P ControllerUser \
-S SSID
# optional if you want to get notified via mail
#-m <mailRecipient> \
#-r <mailSender> 
# optional if remote setup is used-u <SSHuser> -p <SSHpassword>
# use -h or --help to show help
[Unit]
# of course, daily, monthly or any 
# other periodicity is also 
# configurable here
Description=Changes your wifi key quarterly

[Timer]
Unit=wifichanger.service
# You can 
OnCalendar=quarterly

[Install]
WantedBy=timers.target

Options

Options:
-h, --help            show help message and exit

Generic options:
-d, --debug         enable debugging outputs (default: no)

Host options:

SSID options:
-S SSID, --ssid=SSID
defines the SSID name (mandatory)

User options:

Password options:
-U UNIFIUSER, --accountuser=UNIFIUSER
defines your Unifi Controller user (mandatory)
-P UNIFIPASSWORD, --accountpassword=UNIFIPASSWORD
defines your Unifi Controller user (mandatory

Remote options:
-H HOST, --host=HOST
defines the controller hostname or IP (default:
localhost, only mandatory if script is not running
locally)
-u USER, --user=USER
defines SSH user (only mandatory if script is not
running locally)
-p PASSWORD, --password=PASSWORD
defines SSH password. leave blank if ssh key is
available (only mandatory if script is not running
locally)

Mail options:
-m MAILRECIPIENT, --mailrecipient=MAILRECIPIENT
provide an e-mail address to which the change of the
key will be sent.
-r MAILSENDER, --mailsender=MAILSENDER
provide an e-mail address from  which the change of
the key will be sent (mandatory if mailrecipient is
set).

Sample configuration

bin/python3 src/unifi_pexpect.py \
-H <ControllerIP> \
-U <ReadonlyControllerUser> \
-P <ReadonlyControllerPassword> \ 
-m <Recipient-Mail> \
-r <Recipient-Sender> \
-S <SSID> \
-u <SSH-User> \
-p <SSH-Password> \
-d