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-containedThe 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/RaspiFanControllerAnd finally, start the app using sudo. This is important because otherwise, reading the temperature doesn't work.
sudo /tmp/RaspiFanController/RaspiFanControllerYou 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:latestThis 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, see- UsePathBase().
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!
