Controlling a CPU/case fan with GPIO PWM based on CPU temperature

This guide are for those that are running Home Assistant OS on a Raspberry (or similar platform) with a case that includes a PWM-controlled CPU fan and where that fan is normally controlled by installing some software. I am using a Geekworm NASPI case, which has a X-C1 power management board that controls the fan using GPIO pin 18, which seems to be more or less standard also for other case fans.

If you are running HA Core, this guide is not for you, as you can simply install the software needed to control the fan speed.

Some parts of this guide is information I found in this thread:

NOTE! For Home Assistant ver 2022.4 or later, the support for GPIO has been removed. The instructions below still works, but you will need to install a custom add-on to be able to control the fan speed using PWM:

1. Install pigpio add-on

There is an excellent collection of add-ons called “Poeschl Home Assistant Add-ons”, one of them is pigpio which will let you send PWM data on a GPIO pin.

To install, open the “Add-ons, Backups and Supervisor” from the Configuration and then click on ADD-ON STORE button. Now you need to add the repository by clicking the menu button (the tree-dots button in the top right corner) and add the following URL:

https://github.com/Poeschl/Hassio-Addons

Then find the pigpio add-in and install it. Make sure it’s set to start on boot. When it’s installed, start it.

2. Add CPU temp sensor and PWM light devices

This step requires changing the file configuration.yaml. If you don’t know how to do this, refer to this guide:
https://www.home-assistant.io/getting-started/configuration/

Add the following lines to the configuration:

# RPi fan control
sensor:
  - platform: command_line
    name: CPU Temperature
    command: "cat /sys/class/thermal/thermal_zone0/temp"
    unit_of_measurement: "°C"
    value_template: '{{ value | multiply(0.001) | round(1) }}'
    scan_interval: 10
light:
  - platform: rpi_gpio_pwm
    leds:
      - name: RPI Cooling Fan
        driver: gpio
        pins: [18]
        type: simple

As you will later also need to add a Python script, you will also need one more entry to enable Python scripts:

# Enable python scripts
python_script:

Save your changes and reload the configuration. You an already now control the fan and monitor the CPU temperature. Simply add an “Entities” card with the CPU temperature sensor (sensor.cpu_temperature) and the fan control (light.rpi_cooling_fan).

Turning on the fan will set it to full speed, but if you click the CPU fan entity, you can now adjust the “brightness” (the pigpio add-on was designed to control LED’s…) but in fact this now controls the fan speed!

You should play around with the best value to keep your CPU at a comfortable temperature. In my case I set this to 50%, which keeps the CPU at around 40 degrees C.

3. Create Python script to set fan speed

To be able to set the fan speed from automations, I use a simple Python script. The script should be created in folder “python-scripts”, and in my setup I saved it as “rpi_fan_pwm.py”:

fan_speed = data.get("fan_speed")
service_data = {"entity_id": "light.rpi_cooling_fan", "brightness": fan_speed}
hass.services.call("light", "turn_on", service_data)

Make sure you either restart HA, or reload Python scripts. You should then test the script from the Developer Tools:

Please note that parameter fan_speed is a value between 0 and 255, where 255 = full speed. Check that the fan speed is set accordingly.

4. Automations

You can now control the fan with some simple automations. This is how I control mine.

Set fan speed on startup:

alias: Set CPU fan speed on startup
description: ''
trigger:
  - platform: homeassistant
    event: start
condition: []
action:
  - service: python_script.rpi_fan_pwm
    data:
      fan_speed: 128
mode: single

Set fan to high speed:

alias: CPU fan high speed
description: Turn up fan speed when CPU is over 55 degrees
trigger:
  - platform: numeric_state
    entity_id: sensor.cpu_temperature
    above: '55'
condition: []
action:
  - service: python_script.rpi_fan_pwm
    data:
      fan_speed: 255
mode: single

Set fan back to normal speed:

alias: CPU fan normal speed
description: Set CPU fan to normal speed when temp is below 40
trigger:
  - platform: numeric_state
    entity_id: sensor.cpu_temperature
    below: '38'
condition: []
action:
  - service: python_script.rpi_fan_pwm
    data:
      fan_speed: 128
mode: single
1 Like

Thank you for this. I was halfway through setting up my Pi and hard drive in this case and realized I may not be able to control the fan in Home Assistant OS.

I’ve got it working, but I’m wondering if you were able to get the power button working to shut it down safely. I’m assuming it doesn’t work out of the box and needs something, but I’m not sure what do. Did you tackle that task also?

I never bothered with the power button, was thinking I would return to this later on but now when GPIO control is deprecated and the pigpio add-on will stop working if we upgrade to the 2022.4 release, I guess this whole little project was a waste of time. There are ways to continue using GPIO by adding a custom integration (via HACS), but this solution does not support PWM and therefor not useful for controlling the CPU fan.

I ordered a cheap PWN fan controller on AliExpress and will wait with the upgrade until I installed it, hopw it will fit inside the case :slight_smile:

I don’t follow. I’m on 2022.4.5 and used your instructions to get the fan control working. I used this integration via HACS. It works, is it not meant to?

I also got some stuff from the linked thread (where I set up a climate entity, but don’t really use that).

Interesting, but is your fan PWM-controlled? As far as I can tell, that specific GPIO integration does not support PWM. This would mean that the speed of the fan cannot be controlled, only be turned on or off, and this is why I never even tested it.

If you managed to also control the speed with this integration, could you share the details?

I have pigpio installed, as well as the integration i linked to, and added this to my config.

light:
  - platform: rpi_gpio_pwm
    leds:
      - name: RPI Cooling Fan
        driver: gpio
        pins: [18]
        type: simple

Honestly, I’m just good enough to follow directions and maybe find a replacement if something is missing, but otherwise i’m kind of a greenhorn.I didn’t even know what PWM is until this afternoon. I just saw it thrown around a lot in these contexts.

To answer your question, i am able to control the speed… 100% is super loud, 33% is barely audible, below that i’m not sure if the fan is even running.

Correction,

I have two integrations installed, the one linked to, which has a platform name of ‘rpi_gpio’ and this one. that one supports PWM

Thanks for posting this info, you saved me some searching and work! So it’s that second integration that makes it possible to control the fan speed. That is very good news, it means this solution is still valid.

I will update my original post to reflect these changes, when time permits.