How to Change the Fan Speed on Ubiquiti XG 8 PoE

Introduction

The Ubiquiti Switch Pro XG 8 PoE runs quite hot at factory settings. This isn't likely to cause any issues but if you'd like to reduce temperatures there is no fan control in the UI. This guide shows how you can adjust the fan speed and persist the changes on reboot by using a bash script.

Fan Control Configuration

The fan configuration is stored on the device at /usr/share/fanctrl/ubnt-fanctrl-ed76.conf. You will need to SSH in to modify it, and restart the fan control process afterwards for changes to take effect.

How the configuration file works

Each sensor entry under sensors monitors a temperature source (CPU and SFP). The params array contains the parameters as defined in the component section.

Param Description
setpoint Target temperature in degrees Celsius.
Kp Proportional gain. Controls how aggressively the fan reacts to the current temperature difference from the setpoint.
Ki Integral gain. Corrects for sustained temperature drift over time.
Kd Derivative gain. Responds to the rate of temperature change.
setpoint-interval Time in seconds between setpoint adjustments.
min-output Minimum PWM duty cycle percentage that the fan will run at.

tjmax is the maximum junction temperature — if a sensor reaches this value, the fan runs at full speed regardless of the PID output.

// ubnt-fanctrl-ed76.conf

{
  "component": ["setpoint", "Kp", "Ki", "Kd", "setpoint-interval", "min-output"],
  "sensors": {
    "CPU": {
      "params": [55, -1.0, -0.1, 0.0, 1, 30],
      "sensor": "/sys/class/hwmon/hwmon0/device/temp1_input",
      "sensor_scale": 1000,
      "tjmax": 100
    },
    "SFP": {
      "params": [55, -1.0, -0.1, 0.0, 1, 30],
      "sensor": "/sys/class/hwmon/hwmon0/device/temp3_input",
      "sensor_scale": 1000,
      "tjmax": 100
    }
  },
  "fan_settings": {
    "pwm_min": 0,
    "pwm_sensor": "/sys/class/hwmon/hwmon0/device/pwm1",
    "rpm_sensor": "/sys/class/hwmon/hwmon0/device/fan1_input"
  },
  "settings": {
    "silent_operation": 0,
    "sampling_time": 5,
    "shutdown_duty": 30
  }
}

Automating Fan Speed

Enabling SSH access

To automate the fan speed changes, you need to enable SSH access on your switch. To do this log into your gateway's management console, go to 'UniFi Devices' then 'Device Updates and Settings' on the left sidebar and expand 'Device SSH Settings'. Check 'Device SSH Authentication' and set up an authentication method.

Script

This script uses sshpass to non-interactively SSH into the switch and transfer the modified configuration file. It then restarts the fan control process by killing any running instance of it, which will cause it to automatically restart with the new configuration.

# change-fan-speed.sh

parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )

echo "transferring ubnt-fanctrl-ed76.conf"
sshpass -p $SWITCH_PASS scp -O -o StrictHostKeyChecking=no $parent_path/files/ubnt-fanctrl-ed76.conf $SWITCH_USER@$SWITCH_IP:/usr/share/fanctrl/ubnt-fanctrl-ed76.conf

echo "restarting fanctrl"
sshpass -p $SWITCH_PASS ssh -o StrictHostKeyChecking=no $SWITCH_USER@$SWITCH_IP 'pkill -f fanctrl; exit'

echo "done"
# .env

SWITCH_USER=
SWITCH_PASS=
SWITCH_IP=

Run on switch restart

You can create a systemd service to run this bash script automatically. The script will ping the switch until it becomes unreachable (indicating a reboot), then it will wait for the switch to come back online before transferring the custom configuration back to the device and restarting the fan control process.

# /usr/local/bin/switch-ping

#!/bin/bash

while true; do
  if ping -c 1 $SWITCH_IP &> /dev/null
  then
    sleep 20s
  else
    echo "switch is unreachable"
    until ping -c 1 $SWITCH_IP &> /dev/null; do
      echo "waiting for switch to come back online..."
      sleep 10s
    done
    echo "transferring ubnt-fanctrl-ed76.conf"
    sshpass -f $SWITCH_PASSWORD_FILE scp -O -o StrictHostKeyChecking=no $LOCAL_CONF_FILE_PATH $SWITCH_USER@$SWITCH_IP:/usr/share/fanctrl/ubnt-fanctrl-ed76.conf
    echo "restarting fanctrl"
    sshpass -f $SWITCH_PASSWORD_FILE ssh -o StrictHostKeyChecking=no $SWITCH_USER@$SWITCH_IP 'pkill -f fanctrl; exit'
    echo "done"
    sleep 20s
  fi
done
# /etc/systemd/system/switch-ping.service

[Unit]
Description=Copy fan config file if switch reboots

[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/switch-ping
Restart=always
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target