Manual fan control for Huawei laptops on Windows.
This program intervenes in your machine's cooling. Use it at your own risk. There is no warranty of any kind. MateFan only ever raises fan speeds above the factory curve and puts the factory automatic back when it exits, but you are the one running it.
The factory automatic lets the CPU sit above 70 °C before it lifts the fans at all, and even under full load it uses only about 3540–4620 rpm. The reference machine's fans measure out at 8300 rpm. MateFan makes the rest of that range reachable — roughly 3500 rpm of cooling that otherwise sits unused.
Huawei laptops whose firmware exposes the HWMI interface (root\wmi → OemWMIMethod). That is the
whole requirement: no model list to be on, no driver to install.
Machines that have been measured ship with a profile, so they skip calibration entirely:
| Model | Name | Fans | Control range | CPU sensor |
|---|---|---|---|---|
FLMH-XX |
MateBook 14 (2024) | 2 | 2000–8300 rpm | index 0 |
Every other Huawei machine measures itself on first start (see below) and stores the result.
Other manufacturers are not supported and are not a goal. MateFan drives the fans through a Huawei firmware interface; on anything else it says so and exits without touching the hardware.
- Windows 11, 64-bit
- Administrator rights —
root\wmiis out of reach without them
Both downloads carry the .NET runtime with them, so there is nothing else to install.
Get the latest build from the releases page. Three files are attached to every release:
| File | What it is |
|---|---|
MateFan-Setup-x.y.z.exe |
Recommended. Installs into Program Files with a start menu entry and a clean uninstall. |
MateFan-x.y.z-portable.exe |
One file, no installer. Starts a little slower, because it unpacks itself into a temp folder every time. |
SHA256SUMS.txt |
Checksums for both of the above. |
Windows will show "Windows protected your PC" with an unknown publisher. MateFan is not code-signed — a certificate costs several hundred euros a year, and this is a hobby project. Choose More info → Run anyway.
If you would rather verify the download first, compare it against
SHA256SUMS.txtfrom the same release:Get-FileHash .\MateFan-Setup-1.0.0.exe -Algorithm SHA256
MateFan is English and German, and it follows your Windows display language — decided fresh at every start, not fixed at install time. Change the display language and MateFan follows on the next start. Any display language other than German gets the English interface.
MateFan always runs elevated, because the firmware interface it uses requires it. That is also why autostart goes through a scheduled task rather than the Startup folder — from the Startup folder, an elevated program would raise a User Account Control prompt at every single logon.
Through Windows Settings → Apps, like any other program. The autostart task is removed with it.
Your device profile and settings are kept under %LOCALAPPDATA%\MateFan and
%APPDATA%\MateFan, so reinstalling later will not make you measure the machine again. Delete
those two folders by hand if you want them gone.
You need the .NET 10 SDK and Windows.
dotnet build matefan.slnx
dotnet test tests/MateFan.Tests
dotnet run --project src/MateFan.App # as administratorTo produce the same two artefacts a release does:
# Installer payload: self-contained, not single-file
dotnet publish src/MateFan.App -c Release -r win-x64 --self-contained true `
-p:PublishSingleFile=false -o publish/installer
& "$env:LOCALAPPDATA\Programs\Inno Setup 6\ISCC.exe" /DAppVersion=0.0.0 installer\matefan.iss
# Portable: one self-extracting file
dotnet publish src/MateFan.App -c Release -r win-x64 --self-contained true `
-p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -o publish/portableSee CONTRIBUTING.md for conventions and for how to contribute a device profile.
On a machine MateFan has no profile for, the first start opens a measurement wizard. It finds out how many fans there are, which sensor reports the CPU temperature, and the speed range the fans can actually be driven across.
The trick is that MateFan does not have to guess the ceiling: it asks once for a deliberately excessive speed, and the firmware caps that request at whatever the machine can really do. From there it steps downwards until the fan stops slowing.
Three things worth knowing before you start it:
- It takes about two minutes and the fans run flat out the whole time. It is loud.
- You can cancel at any point. The fans go straight back to factory automatic, and nothing is stored. Declining the measurement altogether is just as harmless: MateFan writes nothing to the firmware and quits, leaving the machine exactly as it was.
- MateFan never drives past what it measured. The stored range is the ceiling for everything afterwards — the slider, the curve and the tray quick levels all live inside it.
Start MateFan.exe as administrator. The program keeps living in the notification area — the
window's close button only hides it; quitting goes through the right-click menu on the icon.
| Mode | Behaviour |
|---|---|
| Factory automatic | MateFan does not intervene |
| Fixed speed | The speed stays at the slider value |
| Curve | The speed follows the curve (the default at start) |
The chart shows the curve, with the current operating point as a red dot. Editing happens in the table beside it: temperature and speed per row, two to ten points. Changes take effect immediately.
So the fans do not pump up and down under fluctuating load, three readings are averaged and the control is asymmetric: on rising temperature the fan follows at once, on falling temperature it gives way by at most 0.15 °C per second. After a load spike it therefore runs on for about a minute — that is deliberate, not a fault.
The shipped curve is defined as positions in the control range (25 % / 41 % / 66 % / 90 % / 100 % at 50/60/70/80/85 °C), so every machine gets the same character stretched over its own range. On the reference MateBook 14 that works out to 3600/4600/6200/7700/8300 rpm — close to the factory behaviour at idle, and 6200 instead of the factory's ~4000 at 70 °C.
The colour shows the mode — grey for factory automatic, blue for fixed speed, green for curve. The tooltip names the fan speeds and the temperature. The right-click menu switches between modes and offers three quick levels, again as positions in the range: quiet (8 %), normal (41 %) and maximum (100 %). On the reference machine that is 2500, 4600 and 8300 rpm.
The "Start with Windows" checkbox creates a scheduled task that starts MateFan at logon with highest
privileges and a hidden window — without a User Account Control prompt. The Startup folder is no
good for this, because a program marked requireAdministrator would prompt there at every logon.
The state of the checkbox is read back from the task scheduler rather than stored. Delete the task by hand and MateFan reports that correctly at the next start.
The control range comes from the device profile. Asking for more than the measured maximum achieves nothing: the firmware caps the request itself — which is precisely how calibration finds the ceiling in the first place.
All fans are set together. The firmware actively regulates towards the target; the deviation stays under 100 rpm.
- Above 95 °C MateFan switches back to the automatic on its own and only releases manual control again below 85 °C. The hysteresis prevents flapping at the threshold.
- On a normal exit, the factory automatic is always put back.
- If a firmware call fails, the app falls back to the automatic rather than quietly carrying on.
- If the program is killed outright (Task Manager), the last speed set stays in effect until the next "automatic" or until a restart. Since MateFan only ever sets speeds above the factory curve, that is harmless.
If MateFan measured your machine, that profile is worth having in the bundled catalogue — then the next person with the same model never has to run the measurement.
- Run the calibration (first start, or "Measure this machine again" in the main window).
- On the result page, press Copy as JSON.
- Open an issue with the Device profile template and paste it in. No pull request needed.
The JSON holds the model string, the fan count, the measured range and the CPU sensor index — nothing that identifies you or your machine beyond the model name the firmware reports.
CONTRIBUTING.md has the details, including the limits a profile has to satisfy before the catalogue tests accept it.
Control runs through the firmware's ACPI-WMI interface (root\wmi → OemWMIMethod.OemWMIfun, ASL
method WMAA) — with no kernel driver, no PawnIO and no Huawei PC Manager. That means it also works
with Secure Boot and memory integrity switched on.
The derivation, the full command table and every measurement are in docs/discovery.md.
Two pitfalls documented at length there: the input buffer must be exactly 64 bytes long, and
u8Output starts directly with the status byte — the 4-byte offset known from the Linux
huawei-wmi driver does not apply on Windows.
| Project | Responsibility |
|---|---|
MateFan.Core |
State model, DeviceProfile, curve, control loop, overtemperature rule, persistence — no hardware, fully testable |
MateFan.Hardware |
HwmiCodec (byte layout, no WMI), WmiFanController (the only place that calls WMI) and CalibrationRunner (measures an unknown machine) |
MateFan.App |
The WPF interface; holds no logic beyond display and binding |
tools/IconGen |
Generates the embedded icon file from the same drawing routine |
dotnet test tests/MateFan.Tests # the full suite
dotnet run --project tools/SmokeTest # raw values straight out of the firmwareinstaller/matefan.iss builds the setup, and .github/workflows/release.yml turns a vX.Y.Z tag
into a release. The tag is the only place a version number lives.
tools/ also holds the PowerShell tooling from the analysis phase (HwmiClient.psm1,
Watch-HwmiSensors.ps1), which lets you cross-check the app's readings independently.
The rotor is not kept as an image file; it is defined in IconFactory as a drawing path. Two things
come out of that:
- The notification area draws it at runtime in the colour of the active mode.
tools/IconGenwritessrc/MateFan.App/assets/matefan.icofrom it, in sizes 16 through 256, whichApplicationIconembeds into the exe. The taskbar, start menu and Explorer show only the embedded icon, never the one set at runtime.
Regenerate after a change to the shape:
dotnet run --project tools/IconGenAlongside the .ico that also writes analysis/icon-preview.png with every size and mode colour for
a visual check. If Explorer still shows the old image afterwards, ie4uinit.exe -show helps.
The interface ships in English and German. English is the neutral resource, so a machine whose
display language is neither gets English — a new string has to go into both .resx files or
LocalizationTests fails the build.
docs/discovery.md is the reference for everything about the firmware
interface: it was written first, from a static analysis of the ACPI tables, and every number in it
is backed by a file under analysis/.
MIT — see LICENSE.