Raspberry Pi Fan

I followed your guide and can control fan now, but do you know how to control pi fan speed?
Tks,

for controlling the speed you should follow this article http://www.sensorsiot.org/variable-speed-cooling-fan-for-raspberry-pi-using-pwm-video138/

Hey, which lovelace card is this that shows the Server Stats?

icon - name - value
icon - name - value

Just the default thermostat lovelace card. :slight_smile:

1 Like

Thanks! exactly what I was looking for!!

Hay, Can you share how did you make the mqtt sensor.
Thanks.

Hi, I dont have these sensors anymore as i switched from RPI to a proper intel pc. But try the following

  - platform: mqtt
    name: "CPU Temperature"
    state_topic: "RPI/Temperature"
    unit_of_measurement: "°C"
    value_template: '{{ value | round(2)  }}'

Good afternoon to everyone and happy new year.
Sorry if I do not express myself properly, but I do not have enough knowledge to write directly in English, so I use “Google translator”.
I am new in Hass.io and I need your help. I am trying to make the CPU fan on my Raspberry Pi 4 work (Home Assistant 0.103 and System, HassOS 3.7) following the design and indications of the Andreas Spiess blog (videos # 131 and # 138), the contributions of “umerfraz” and rest of that thread.
I have got nothing at all. I have the file “fancontrol.py”, but I don’t know neither where to place it, from where nor how to execute it. I would like to know how to make it runs at start the system and keeps it running and what should be added in “configuration.yaml” or in another file.
I’ve been testing for a couple of weeks and I haven’t been able to make it works. The hardware is OK, but the fan does not spin.
Thanks for listening and I hope someone can guide me.

Happy to help ropda, but can you make sure you have setup the hardware properly. i.e. your fan has one ground, one positive and a control/signal wire? Exactly as per Andreas Spiess’s blog? Thats the tricky part.

For the software part I would suggest you go with Home Assistant only option instead of python script as that is much simpler and already explained above. It basically involves setting up a sensor to sense Raspbrery Pi’s CPU temperature. Setting up a GPIO pin as switch in HA where you have connected your Fan’s control pin and finally using both of these in a generic thermostat component of HA. You can even change the temperature threshold dynamically. Let me know which step you are stuck on.

Hello again, thanks for your quick response umerfraz, in principle the hardware is ok. Following your instructions I have been able to operate the gpio17 depending on the temperature, the fan does not work because with the 3.3V output of the gpio17 you cannot activate the transistor I use (IRF510A, the other components R1 = 2.2k Ohms , R2 = 100 Ohms and D = 1N4007) but with 5V if it works. I will be testing, I will appreciate if you have any suggestions.
With this programming done with Home Assistant I do not see that it regulates the speed of the fan (gpio17 PWM), like in the first option you gave (based on the Andreas Spiess file) written in Python. Would it be possible to do so with the option of Home Assistant?
Thanks again and regards

Ropda, i am no good in electronics but I believe this would be a problem as Pi’s GPIOs are 3.3volts. But if you really followed Andreas’ post then you would have Pi compatible setup. The Pi’s btw do have atleast two 5v pins to POWER stuff.
Once you have the hardware ready, Homeassistant has the ability to directly monitor/control GPIOs of host Raspberry Pi using the GPIO component. All i have done is to use that for controlling the pin connected to Fan’s control. See the 3 liner config for that in my post above.
Next step is to setup CPU tempreature sensor and finally setting up a generic thermostat to link both of these things.

Thanks umerfraz, about the hardware, I’m working on it.
About programming, I am sorry for expressing myself incorrectly. I made the correct integration following your instructionsControl Temperatura CPU
, but I understand that with this method we are not regulating the fan speed. My question was about being able to regulate the fan speed to achieve the following effect, for example.
Reference temperature 45º

  • The fan turns on at 50º working at 80% speed
  • When the temperature drops to 47º the fan speed drops to 60%
  • When the temperature drops to 43º the fan speed drops to 40%
  • When the temperature drops to 40º, the fan turns off.
    I understand that it is not necessary, but I think it would be an interesting exercise.
    Thanks again and regards
2 Likes

Ropda, yes after replying to you I realised I dint clarify my self that this approach will not allow you to regulate the speed as Andreas’ code is doing. We can surely regulate speed in HA too as that is just done by turning the fan on and off on very short intervals but that will make things a bit more complicated.
It might be better to revert to Andreas’ code in that case. Did you say you have tried that and it just doesnt run automatically? or is the code not working at all ? i am copying the slightly modified version of Andreas’ code i was using the lat time, below labeled fancontrol.py. Disclaimer it might not be clean/optimum. once you have this stored somewhere, you do need to create a service for it that will be configured in the daemon to run on every system start. And towards the end of this post i am pasting the commands i ran to get everything working.

fancontrol.service (service file)

[Unit]
Description=RPI Fan Control
After=multi-user.target

[Service]
ExecStartPre=/bin/sleep 10
Type=idle
ExecStart=/usr/bin/python3 /home/pi/projects/fancontrol.py
Restart=on-abort

[Install]
WantedBy=multi-user.target

fancontrol.py (The Python code)

#!/usr/bin/env python3
# Author: Andreas Spiess
import os
import time
from time import sleep
import signal
import sys
#sys.path.append('/home/pi/.local/lib/python3.5/site-packages/paho/mqtt')
sys.path.append('/usr/local/lib/python3.5/dist-packages/paho/mqtt')
sys.path.append('/home/pi/.local/lib/python3.5/site-packages/RPi')
sys.path.append('/home/pi/.local/lib/python3.5/site-packages/RPi.GPIO-0.6.3.dist-info')
sys.path.append('/usr/lib/python2.7/dist-packages/RPi')
import RPi.GPIO as GPIO
#import publish as publish
import paho.mqtt.publish as publish
fanPin = 17 # The pin ID, edit here to change it
desiredTemp = 40 # The maximum temperature in Celsius after which we trigger the fan
fanSpeed=100
sum=0
pTemp=15
iTemp=0.4
loopDelay=10 #seconds
publishDelay=30 # = seconds/loodelay
#/opt/vc/bin/vcgencmd measure_temp
def Shutdown():
    fanOFF()
    os.system("sudo shutdown -h 1")
    sleep(100)
def publishRPIStats():
    corev = os.popen('vcgencmd measure_volts core').readline().replace("volt=","").replace("V\n","")
    cores = os.popen('lscpu | grep -oP "CPU(.s.):\s*\K.+"').readline()
    maxfreq = os.popen('vcgencmd get_config arm_freq str').readline().replace("arm_freq=","").replace("\n","")
    modelname = os.popen('lscpu | grep -oP "Model name:\s*\K.+"').readline()
    cpu0frequency = os.popen('sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq').readline()
    cpu1frequency = os.popen('sudo cat /sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq').readline()
    cpu2frequency = os.popen('sudo cat /sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq').readline()
    cpu3frequency = os.popen('sudo cat /sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_cur_freq').readline()
    coreram = os.popen('vcgencmd get_mem arm').readline().replace("arm=","").replace("M\n","")
    gpuram = os.popen('vcgencmd get_mem gpu').readline().replace("gpu=","").replace("M\n","")

#        publish.single("RPI/CoreVoltage", corev, hostname="[YOUR MQTT SERVER]", auth = {'username':"[MQTT SERVER PASSWORD]",'password':"[MQTT SERVER PASSWORD]"})
#        publish.single("RPI/NoOfCores", cores, hostname="[YOUR MQTT SERVER]", auth = {'username':"[MQTT SERVER PASSWORD]",'password':"[MQTT SERVER PASSWORD]"})
#        publish.single("RPI/MaxCPUFrequency", maxfreq, hostname="[YOUR MQTT SERVER]", auth = {'username':"[MQTT SERVER PASSWORD]",'password':"####"})
#        publish.single("RPI/CPUArchitecture", modelname, hostname="[YOUR MQTT SERVER]", auth = {'username':"[MQTT SERVER PASSWORD]",'password':"[MQTT SERVER PASSWORD]"})
#        publish.single("RPI/CPU0Frequency", cpu0frequency, hostname="[YOUR MQTT SERVER]", auth = {'username':"[MQTT SERVER PASSWORD]",'password':"[MQTT SERVER PASSWORD]"})

    msgs = [("RPI/CoreVoltage", corev),("RPI/NoOfCores", cores),("RPI/MaxCPUFrequency",maxfreq),("RPI/CPUArchitecture",modelname),               \
            ("RPI/CPU0Frequency",cpu0frequency), ("RPI/CPU1Frequency",cpu1frequency),("RPI/CPU2Frequency",cpu2frequency ), \
            ("RPI/CPU3Frequency",cpu3frequency),("RPI/TotalRam",(int(coreram)+int(gpuram))),("RPI/GPURam",gpuram),("RPI/CoreRam",coreram)]
    try:
        publish.multiple(msgs=msgs, hostname="[YOUR MQTT SERVER]", auth = {'username':"[MQTT SERVER PASSWORD]",'password':"[MQTT SERVER PASSWORD]"})
    except:
        print("Unexpected error:", sys.exc_info()[0])
    finally:
        return()
def getCPUtemperature():
    res = os.popen('vcgencmd measure_temp').readline()
    temp =(res.replace("temp=","").replace("'C\n",""))
    #print("temp is {0}".format(temp)) #Uncomment here for testing
    return temp
def fanOFF():
    myPWM.ChangeDutyCycle(0) # switch fan off
    return()
def handleFan():
    global fanSpeed,sum
    actualTemp = float(getCPUtemperature())
    diff=actualTemp-desiredTemp
    sum=sum+diff
    pDiff=diff*pTemp
    iDiff=sum*iTemp
    fanSpeed=pDiff +iDiff
    if fanSpeed>100:
        fanSpeed=100
    if fanSpeed<15:
        fanSpeed=0
    if sum>100:
        sum=100
    if sum<-100:
        sum=-100
    #print("actualTemp %4.2f TempDiff %4.2f pDiff %4.2f iDiff %4.2f fanSpeed %5d" % (actualTemp,diff,pDiff,iDiff,fanSpeed))
    myPWM.ChangeDutyCycle(fanSpeed)
    try:
        publish.single("RPI/FanSpeed", fanSpeed,hostname="[YOUR MQTT SERVER]", auth = {'username':"[MQTT SERVER USER]",'password':"[MQTT SERVER PASSWORD]"})
    except:
        print("Unexpected error:", sys.exc_info()[0])
    finally:
        return()
def on_disconnect(client, userdata, rc):
    logging.info("disconnecting reason " +str(rc))
    client.connected_flag=False
    client.disconnect_flag=True
def setPin(mode): # A little redundantfunction but useful if you want to add logging
    GPIO.output(fanPin, mode)
    return()
try:
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(fanPin, GPIO.OUT)
    myPWM=GPIO.PWM(fanPin,50)
    myPWM.start(50)
    #GPIO.setup(batterySensPin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
    GPIO.setwarnings(False)
    fanOFF()
    publishDelayCounter = 0
    while True:
        publishDelayCounter = publishDelayCounter + 1
        handleFan()
        #publishFrequency()
        if publishDelayCounter >= publishDelay:
           publishRPIStats()
           publishDelayCounter = 0
        sleep(loopDelay) # Read the temperature every 5 sec, increase or decrease this limit if you want
except KeyboardInterrupt: # trap a CTRL+C keyboard interrupt
    fanOFF()
    GPIO.cleanup() # resets all GPIO ports used by this program

raspberry pi commands

sudo apt-get install mosquitto

sudo apt-get install python3-pip

sudo pip3 install paho-mqtt

sudo apt-get install python-rpi.gpio python3-rpi.gpio

 sudo nano /lib/systemd/system/fancontrol.service  
sudo chmod 644 /lib/systemd/system/fancontrol.service
 sudo systemctl enable fancontrol

sudo chmod +x /home/pi/projects/fancontrol.py  
sudo systemctl daemon-reload      
sudo systemctl start fancontrol.service   

Thanks umerfraz, I see that there is a lot of code and information in your answer, I will need a little time to organize everything and see the doubts that arise in the process. I also want to prepare the best possible information about my Raspberry Pi and Add-ons installed. When I have it ready, I will contact you again to ask you any questions or comment on how the project is going, until then, greetings

Hello again, umerfraz before you start commenting on the computer and the software I use. I’m sorry if I should have started with this. I have a Model B Raspberry Pi 4, 4 GB, SD 32GB Class 10 in which I installed “Hass.io” (version for Model B Raspberry Pi 4 32bit) and have added the following Add-ons.


After studying everything that you put, I do not know whether “Hass.io” as S.O. And with the Add-ons that I already have installed, should I continue executing the entire list of commands that you indicate?
Thanks and regards

Yes that is a problem. I did this on a raspbian stretch with Hassio manually installed, so that gave me full access to raspbian os/terminal. Hassio does allow you to run python scripts adhoc but you want this code to be running in the background and from startup. One option could be to resetup your raspberry pi (after taking backup i would suggest) by installing raspbian stretch first and then you can install the generic linux version of Hassio. That will allow you to run and change any python code desired in the background fairly easliy.

another option could be to build an addon just like the ones you are using (mosquitto for example) :slightly_smiling_face:

The option i mentioned above, around oscilating the GPIO from Hassio to set variable speed of fan was a shot in the dark but might work too.

Thanks umerfraz, for what I have read so far, the options you offer me are the best.
Regarding the second one, the “Hass.io” Add-ons I have read about one in this forum, https://www.home-assistant.io/integrations/rpi_gpio_pwm/. It would be configured as a monochrome LED (type: simple) to work with Andreas’s circuit. I’ve tried to install it and I haven’t been able. I’m going to keep trying for a while, and if I don’t get it, we’ll move on to “plan B,” raspbian.
If you have any other suggestions I will be happy to receive it.

Sure Ropda, thanks for sharing. I have learnt something new. PWN GPIO should do what we want ideally. maybe try changing the parameters a bit e.g. frequency etc. BTW have you made sure the circut is working? e.g. setting the GPIO to high/on then low/off where the CONTROL pin is connected to see if the fan starts and stops?

Thanks umerfraz, I thought I had already commented. The hardware works correctly, I have mounted the Andreas circuit but with other component values and I have it working with the first option that you indicated to mePltaforma Climate
I leave the circuit that I have assembled with the values, in case it can help someone


I still can’t install “pigpio Daemon PWM LED” on my Raspbrery with Hass.io to userpi_gpio_pwm
Greetings and see you soon

Woow that looks great @umerfraz ! Would you be so kind to please share your code for this page?