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

Yes, webMAN MOD supports custom fan control algorithms by replacing the default fancontrol2.h include in 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, 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. Each iteration checks the webman_config->fanc flag:

  • If fan control is enabled, the loop includes and executes 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 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. 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) 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, locate the line:

#include "fancontrol2.h"

Replace it with your custom include:

#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 to add a new radio button:

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:

#define FAN_CUSTOM 3

Then update main.c to route execution based on the selected mode:

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:

/* 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 to include your header:

/* 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 to branch based on the fanc configuration value:

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 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 or adding conditional logic in 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →