This repo contains an application to control the fan of a Raspberry Pi in order to avoid overheating. It is based on ASP.NET Core Blazor Server and uses the .NET Core IoT Library to access the GPIO pins of the Raspberry Pi.
I wrote the following blog posts describing the complete ceremony a bit more in detail:
- Is .NET Core cool enough to cool a Raspberry Pi? - Part 1
- Is .NET Core cool enough to cool a Raspberry Pi? - Part 2
I've integrated the two classes Logic\DevFanController.cs
and Logic\DevTemperatureProvider.cs
for development purposes: they're simulating the temperature measurement and fan controlling when running the app in development mode.
The app is deployed both as a self-contained executable and the Docker image mu88/raspifancontroller
.
Use the following command to generate the app:
dotnet publish -r linux-arm64 /p:PublishSingleFile=true --self-contained
The following command copies the build results:
scp -r E:\Development\GitHub\RaspiFanController\RaspiFanController\bin\Release\net*.0\linux-arm64\publish user@yourRaspi:/tmp/RaspiFanController/
On the Raspberry, we have to allow the app to be executed:
chmod 777 /tmp/RaspiFanController/RaspiFanController
And finally, start the app using sudo
. This is important because otherwise, reading the temperature doesn't work.
sudo /tmp/RaspiFanController/RaspiFanController
You can either grab the prepared docker-compose.yml
or start a new container with the following command:
docker run -p 8080:8080 -d -v /sys/class/thermal/thermal_zone0:/sys/class/thermal/thermal_zone0:ro --device /dev/gpiomem --restart always --name raspifancontroller mu88/raspifancontroller:latest
This will do the following:
- Mount the necessary directory so that the file containing the current temperature can be accessed by the .NET IoT library.
- Mount the necessary device so that the Raspberry's GPIO pins can be controlled from within the container.
Within appsettings.json
, the following app parameters can be controlled:
RefreshMilliseconds
→ The polling interval of the temperature controller. The shorter, the more often the current temperature will be retrieved from the OS.UpperTemperatureThreshold
→ When this temperature is exceeded, the fan will be turned on.LowerTemperatureThreshold
→ When this temperature is undershot, the fan will be turned off.GpioPin
→ The GPIO pin that will control the transistor and therefore turning the fan on/off.AppPathBase
→ This path will be used as the app's path base, seeUsePathBase()
.
These parameters are read on app startup. When the app is running, they can be overridden via http://localhost:8080/cool, but they won't be written to appsettings.json
.
The app is running on my Raspberry Pi 4 Model B using Raspberry Pi OS x64.
Theoretically, the code can be used on any IoT device and OS that provides its own temperature. For this, the ITemperatureProvider
interface has to be implemented and registered within the DI container.
If you're interested in adding support for another device and/or OS, please file an issue. I'm curious whether it will work on other devices as well!