# How to Implement Custom Fan Control Algorithms in webMAN MOD for Advanced Temperature Management

> Learn how to implement custom fan control algorithms in webMAN MOD to gain advanced temperature management. Replace default fancontrol2h with your own logic for precise cooling.

- Repository: [Aldo Vargas/webman-mod](https://github.com/aldostools/webman-mod)
- Tags: how-to-guide
- Published: 2026-02-24

---

**Yes, webMAN MOD supports custom fan control algorithms by replacing the default [`fancontrol2.h`](https://github.com/aldostools/webman-mod/blob/main/fancontrol2.h) include in [`include/poll/poll.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/poll.h) with your own logic that reads temperature and calls `set_fan_speed()`.**

webMAN MOD is a feature-rich homebrew plugin for PlayStation 3 systems that includes a flexible fan-control subsystem capable of being extended with custom algorithms. According to the `aldostools/webman-mod` source code, the modular architecture allows developers to implement advanced temperature management strategies—from PID controllers to per-core cooling curves—without modifying the core server logic.

## Understanding the Built-in Fan Control Architecture

The fan control system in webMAN MOD is deliberately isolated from the main server code, making customization straightforward. The architecture consists of three main components: configuration storage, a polling loop, and the algorithm implementation itself.

### Configuration Storage in setup.h

User preferences are parsed from the WebMAN Settings page and stored in the global `webman_config` structure. In [`include/setup.h`](https://github.com/aldostools/webman-mod/blob/main/include/setup.h), the system reads:

- `webman_config->fanc` – enables or disables custom fan control
- `webman_config->minfan` and `webman_config->maxfan` – constrain the fan speed range
- `webman_config->dyn_temp` – sets the target temperature threshold
- `webman_config->man_rate` – stores manual fan speed values

These parameters provide the boundary conditions that any custom algorithm must respect.

### The Polling Loop in poll.h

The main execution cycle resides in [`include/poll/poll.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/poll.h). Each iteration checks the `webman_config->fanc` flag:

- If fan control is **enabled**, the loop includes and executes [`fancontrol2.h`](https://github.com/aldostools/webman-mod/blob/main/fancontrol2.h)
- If fan control is **disabled**, the system restores the default SYSCON fan policy

This single `#include` directive is the injection point for custom algorithms. By replacing [`fancontrol2.h`](https://github.com/aldostools/webman-mod/blob/main/fancontrol2.h) with your own header file, you redirect the polling loop to execute your logic while maintaining all surrounding safety checks.

### The Default Auto #2 Algorithm

The built-in dynamic controller lives in [`include/poll/fancontrol2.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/fancontrol2.h). It reads the current temperature into variable `t1`, calculates a target speed using the configured min/max percentages and target temperature, then writes the value via `set_fan_speed()`. This function wraps the PlayStation 3's `sys_sm_set_fan_policy` system call, converting percentage values to the 8-bit (0-255) hardware format required by the SYSCON.

## Implementing a Custom Fan Control Algorithm

Creating a custom fan controller requires three steps: implementing your logic in a new header, redirecting the polling loop to use it, and optionally exposing a UI toggle for runtime selection.

### Creating Your Custom Header File

Create a new file (for example, [`my_fancontrol.h`](https://github.com/aldostools/webman-mod/blob/main/my_fancontrol.h)) that implements a `void my_fan_control(void)` function. The webMAN MOD infrastructure provides several global variables your code can access:

- `int t1` – current temperature in Celsius
- `int max_temp` – the target temperature from user settings
- `u8 old_fan` – the previous fan speed for smoothing algorithms
- `set_fan_speed(u8 speed)` – applies the new fan policy

Helper macros like `PERCENT_TO_8BIT` translate percentage values to the 0-255 hardware range. Your function must handle the full control loop: reading temperature, computing the desired speed, clamping it to `minfan`/`maxfan` limits, and calling `set_fan_speed()`.

### Modifying the Polling Loop

In [`include/poll/poll.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/poll.h), locate the line:

```c
#include "fancontrol2.h"

```

Replace it with your custom include:

```c
#include "my_fancontrol.h"

```

The polling loop will now execute your routine every cycle. If you wish to maintain both algorithms and switch between them, use a conditional compilation flag or runtime check instead of a hard replacement.

### Adding UI Controls (Optional)

To allow users to select your algorithm from the WebMAN Settings page, modify [`include/setup.h`](https://github.com/aldostools/webman-mod/blob/main/include/setup.h) to add a new radio button:

```c
add_radio_button("temp\" onchange=\"fc.checked=1;",
                 4, "t_4", "Custom PID", _BR_, (webman_config->fanc == FAN_CUSTOM), buffer);

```

Define the constant in [`include/setup.h`](https://github.com/aldostools/webman-mod/blob/main/include/setup.h):

```c
#define FAN_CUSTOM 3

```

Then update [`main.c`](https://github.com/aldostools/webman-mod/blob/main/main.c) to route execution based on the selected mode:

```c
if (webman_config->fanc == FAN_CUSTOM)
    my_fan_control();      // from my_fancontrol.h
else if (webman_config->fanc == FAN_AUTO2)
    fan_control_auto2();   // original routine

```

## Practical Code Examples

### PID Controller Implementation

The following example replaces the default algorithm with a proportional-integral-derivative (PID) controller that calculates fan speed based on temperature error and rate of change.

Create [`my_fancontrol.h`](https://github.com/aldostools/webman-mod/blob/main/my_fancontrol.h):

```c
/* my_fancontrol.h – custom PID fan algorithm */
#ifndef MY_FANCONTROL_H
#define MY_FANCONTROL_H

#include "setup.h"          // access webman_config
#include "poll.h"           // provides t1, max_temp, old_fan
#include "fancontrol.h"     // declares set_fan_speed()

static void my_fan_control(void)
{
    static double integral = 0.0;
    static double previous_error = 0.0;

    const double Kp = 2.0;   // proportional gain
    const double Ki = 0.05;  // integral gain
    const double Kd = 1.0;   // derivative gain

    /* error = current temp – target temp */
    double error = (double)t1 - (double)webman_config->dyn_temp;

    /* integral with anti‑windup */
    integral += error;
    if (integral > 1000)  integral = 1000;
    if (integral < -1000) integral = -1000;

    /* derivative */
    double derivative = error - previous_error;
    previous_error = error;

    /* PID output (raw percent) */
    double output = Kp * error + Ki * integral + Kd * derivative;

    /* clamp to user‑defined min/max fan percentages */
    if (output < webman_config->minfan) output = webman_config->minfan;
    if (output > webman_config->maxfan) output = webman_config->maxfan;

    /* convert percent → 0‑255 hardware value */
    u8 fan_speed = (u8)(output * 255.0 / 100.0);
    set_fan_speed(fan_speed);
}
#endif /* MY_FANCONTROL_H */

```

Update [`include/poll/poll.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/poll.h) to include your header:

```c
/* poll.h – line that pulls in the fan routine */
-#include "fancontrol2.h"
+#include "my_fancontrol.h"

```

### Runtime Algorithm Selection

To support multiple algorithms simultaneously, modify [`main.c`](https://github.com/aldostools/webman-mod/blob/main/main.c) to branch based on the `fanc` configuration value:

```c
if (webman_config->fanc == FAN_CUSTOM)
    my_fan_control();
else if (webman_config->fanc == FAN_AUTO2)
    fan_control_auto2();
else
    restore_syscon_default();

```

This structure allows users to switch between "Auto #2", your custom implementation, and system defaults without recompiling the entire project.

## Summary

- **webMAN MOD** exposes a single include point in [`include/poll/poll.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/poll.h) that determines which fan control algorithm runs during each polling cycle.
- **Custom algorithms** read the current temperature from `t1`, calculate a percentage within `minfan`/`maxfan` bounds, and call `set_fan_speed()` to apply the hardware policy.
- **Infrastructure support** includes global configuration variables, helper macros for 8-bit conversion, and automatic restoration of SYSCON defaults when fan control is disabled.
- **Advanced strategies** such as PID control, per-sensor curves, and event-driven boosts can be implemented by replacing [`fancontrol2.h`](https://github.com/aldostools/webman-mod/blob/main/fancontrol2.h) or adding conditional logic in [`main.c`](https://github.com/aldostools/webman-mod/blob/main/main.c).

## Frequently Asked Questions

### Can I use multiple temperature sensors in my custom algorithm?

Yes. While the default implementation primarily uses `t1` (the main system temperature), the PlayStation 3 exposes additional thermal zones through other system calls. You can extend your custom header to read CPU, GPU, or memory temperatures separately and compute weighted fan speeds based on the hottest component or specific thermal zones.

### What hardware limits exist for fan speeds?

The PlayStation 3 fan controller accepts values in the range 0-255, representing 0-100% duty cycle. The `set_fan_speed()` function and helper macros like `PERCENT_TO_8BIT` handle this translation automatically. However, setting speeds below 20% (approximately 51/255) may cause insufficient cooling, while sustained 100% operation increases noise and wear. Always respect the user's `minfan` and `maxfan` configuration bounds.

### How do I revert to the original algorithm?

To restore the built-in "Auto #2" behavior, simply revert the include directive in [`include/poll/poll.h`](https://github.com/aldostools/webman-mod/blob/main/include/poll/poll.h) back to `#include "fancontrol2.h"` and recompile. If you added a UI option for your custom mode, setting `webman_config->fanc` to `FAN_AUTO2` (value 2) or disabling fan control entirely will bypass your custom code and restore standard operation.

### Is it safe to experiment with custom fan curves?

The webMAN MOD architecture provides safety mechanisms: if your custom code crashes or sets invalid values, the watchdog and temperature limits of the underlying `sys_sm_set_fan_policy` system call provide hardware-level protection. However, implementing aggressive curves that allow high temperatures or sudden fan speed changes could stress components. Always test new algorithms under monitored conditions and ensure the `maxfan` limit prevents zero-cooling scenarios.