Controlling cooling fan for Raspberry Pi 4

Hi all! I thought I would share my setup for controlling a cooling fan for a Raspberry Pi 4 since the guides I could find online had stopped working due to changes in the climate integration in Home Assistant.

I’m using a Pimoroni Fan SHIM but you can also build your own fan easily using these instructions.

The following code for your configuration.yaml file does this:

  • adds a sensor that gets the CPU temp from the Pi every 10 seconds
  • adds a switch that controls the power to the fan using the GPIO pins of the Pi.
    • The Pimoroni Fan SHIM uses pin 18 as the control pin (you can use another if you build your own fan).
  • adds a climate controller to HA.
    • The ‘min_temp’ and ‘max_temp’ variables set the range of target temperatures available in the interface.
    • The ‘target_temp’ variable sets the initial target temperature. You change this via the interface. I don’t suggest setting it to 55°C for other than testing. The rPi4 starts to thermal throttle at around 80°C so maybe 70°C is a good setting.
    • The ‘cold_tolerance’ and ‘hot_tolerance’ variables set how much the temperature can deviate from the target temperature before turning on/off the fan. With the values set as below the fan turns on at 55.1°C and off at 54.9°C (though this is not actually the case as you’ll see soon).
    • The ‘min_cycle_duration’ sets the minimum amount of time the fan is on. Setting it to for example 30 seconds keeps the fan from cycling on/off rapidly as the temperature goes between 55.1°C and 54.9°C (you could also change the tolerances).

configuration.yaml code:

# Raspberry Pi Cooling Fan
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
switch:
  - platform: rpi_gpio
    ports:
      18: RPI Cooling Fan
climate:
  - platform: generic_thermostat
    name: RPI Cooling Fan Controller
    heater: switch.rpi_cooling_fan
    target_sensor: sensor.cpu_temperature
    min_temp: 55
    max_temp: 80
    ac_mode: true
    target_temp: 55
    cold_tolerance: 0.1
    hot_tolerance: 0.1
    min_cycle_duration:
      seconds: 30
    keep_alive:
      minutes: 5
    initial_hvac_mode: "cool"

The code above was based on the work of ‘@umerfraz’.

You now have this cool interface for controlling the cooling:

42 Likes

Thank you very much for this code!
Thanks to this code I can integrate and control this fan.
It has been very useful for me.

don’t works for me at all, I ve copied everything and reboot the system but I can’t get the temperature or either on or off the fan shim

Hi. Thank you so much for posting the code, as I want to implement my fanshim

I just can not figure how to get that code into Home Assistant if that makes sense? I’ve added ‘file editor’ and added the code but no idea where I go from there. Any suggestions please

1 Like

You’re amazing! Thank you, it is all working.

I’ll get it on the dash now, well the next lesson.

Edit: No I don’t, the config did it all. Cheers again!

The button is on pin 17

Any idea how to control the LED? I’m reading over the serial information but I just don’t see a port in the documentation, only plasma and “/tmp/plasma”

No idea how to control the led, thats my next step but I’ve not tried. I’m assuming it’s integrating this code?

Yeah, but also this code:

import RPi.GPIO as GPIO
import time
try:
    from plasma import legacy as plasma
except ImportError:
    import plasma
import atexit
from threading import Thread
        
__version__ = '0.0.4'
    
        
class FanShim():
...
    def set_light(self, r, g, b):
        """Set LED.
        :param r: Red (0-255)
        :param g: Green (0-255)
        :param b: Blue (0-255)
        """
        plasma.set_light(0, r, g, b)
        plasma.show()

Best I can tell is that the code you posted is calling the object fanshim, which has a function set_light. That function is defined in the file I linked to, which is importing this plasma function and that is what’s actually writing to the two data pins when it gets called.

I just found this, but I haven’t had time to read through it yet. https://github.com/pimoroni/plasma

Not had time to look into this further, will do this evening. It’d be nice to get the LED working.

I did find this last night, but I’m working on a different little project right now.

I figure with I2C and some system command it’ll be a lot easier.

1 Like

So I got annoyed with how difficult this was for me to understand, but here’s what I did and specifically what didn’t work.

I wrote a python script based off of the example LED script that can be command line run and takes 0-255 RGB values as an input.

On the command line of the RPi it works great, you call the script once and the light stays on with the color you set.

So I had a python script that works, but how to implement it? I’m not well versed enough to turn the script with all of its dependencies into home assistant. So I tried to implement it as a command line switch for on/off and then go from there.

Using the command line requires the pi to actually have an OS that you can interact with. After some research, there are 3 versions of home assistant:

  • Home Assistant - Hass.io - a locked down black box thats easy to work with.
  • Home Assistant - Manual Install - No Add in support.
  • Home Assistant - Supervised Install - This installs docker onto the pi, and runs very similarly to Hass.io.

So if I had tried the manual install, I’m almost positive that this would have worked. But I did the supervised install because I wanted ease of use for simple features, and trying to use shell commands works differently in docker.

So that’s where I’m at now, I need to figure out how to break out of docker to run my script, or go back to the drawing board and just write a custom integration. But I can control the LED, just not from home assistant.

I tried this config
i can get the temperature but i am not able to turn off the fan.
Fan is connected to pin 4 (5v) and 6 (ground).
what am i missing ?

What did you try exactly?

Because the fan on this board (fan shim) is on the GPIO 18, not pin 4.

Also, pin 4 is a constant power pin, not a controllable output. You need to change your wiring to a gpio pin for your + if you want to control it. This thread is for a specific add on board, not any random fan, but I’m happy to help.

Edit: so I’m going to apologise because I thought this was a thread on the fanshim. But it’s for just any fan. My advice still applies, that pin 4 is a constant source and cannot be used for control.

God this has been tough. Using the manual install somehow I broke my rpi_gpio so right now I’m using command line sensors to control the pins. But with that I’ve been able to control everything how I want.

What I’ve learned is that the fanshim led was not that important, and if I do anything, I’ll probably swap back to the Hass.io because everything is so much easier.

I might work on a HACS addon to control everything, but I can’t see myself doing that soon.

At this point I’m debating on going back to where I was a week ago so that I have some of the features I don’t have with the manual install. Biggest is the in app yaml editor. While I’d like a remote desktop to a pi, it’s less headache to just buy a new pi. Seriously just for control of a LED it isn’t worth it to do a complete reinstall like I’ve done.

Edit: 100% back to where I was in something like 8 hours, except for LED control.

Can anyone help me with this and the Argon housing with built in fan unit? I cannot figure it out. I added terminal as well but every time I open it I get “bad gateway”

1 Like

Hoping for a bit of guidance on this. I’ve got a Noctua NF-A4x20 (3-pin) connected to my Rpi4, and using just the 5V and ground I am able to get the fan running on pins 4 and 6. After reading this, I hooked up the yellow wire to GPIO 18 (pin 12) and implemented this code, but I’m not seeing the fan turn off while it’s below the threshold, however the code is turning off the switch. I’ve copied everything here verbatim, my only difference is the fan (noctua vs pimoroni).

EDIT: It’s also entirely possible I don’t understand how the pins on the fan work and that this isn’t possible with my config.

2 Likes

I had the same situation and found out the power in the GPIO was not sufficient. I had to put a transistor inbetween to allow this to happen like in the link here : https://www.instructables.com/id/PWM-Regulated-Fan-Based-on-CPU-Temperature-for-Ras/

So I use above code, but the circuit in the link.
Hope that helps. If you do not want to build it first, you might want to check with a multimeter if you are addressing the right pin.

1 Like

Thanks @Piggyback, that’s what I was kind of afraid of. As much as I love the Noctua, I’m more of a plug-and-play guy, so I’ve ordered the pimoroni fan shim, and the pibow coupe case so that hopefully this just “works”. I’ll probably re-purpose the Noctua to my RPi3b running my unifi controller/pi-hole, just because I don’t care if that fan is running continuously for where it’s located.

Hi, I have followed the steps above but cannot control my fan (pimoroni shim on rpi4 b)
Hostname: homeassistant
System: HassOS 4.10

The thermostat and the switch have both appeared in my front-end and I can control them but the fan just always runs, no matter what I do it won’t stop.