Thermal Collector

The ThermalCollector is the central module in tlBMC responsible for managing thermal zones, executing fan and thermal control loops, and coordinating controllers to maintain platform temperatures.

Overview

The ThermalCollector orchestrates the system's active cooling by instantiating and running ZoneManager instances for each defined thermal zone. It reads telemetry from various sensor types (including temperature, fan speed, power for DFF feedforward control, and current sensors), computes setpoints via various controller algorithms (PID, Stepwise, DFF, EAT), and writes target speed/PWM values to fan speed controllers.

When enabled, the ThermalCollector owns the following Redfish endpoints:

  • /redfish/v1/Chassis/<ChassisId>/ThermalSubsystem and its /Fans
  • /redfish/v1/Chassis/<ChassisId>/PowerSubsystem and its /PowerSupplies
  • /redfish/v1/Managers/<ManagerId> (Oem OpenBmc Fan endpoints)
  • /redfish/v1/Managers/bmc/Actions/Manager.FanMode.Change (POST)
  • /redfish/v1/Managers/bmc/FanMode.Change.ActionInfo
  • /redfish/v1/Chassis/<ChassisId>/Sensors (PATCH for setpoint overrides)

[!NOTE] When the ThermalCollector is active, it removes the legacy /redfish/v1/Chassis/<ChassisId>/Thermal endpoint.

EmptyThermalCollector

If the thermal control submodule is disabled, tlBMC instantiates the EmptyThermalCollector. This is a no-op fallback implementation that exposes placeholder metrics and returns warning payloads indicating that thermal collection is disabled (e.g., "Warning": "EmptyThermalCollector used." in debug store endpoints).


Central Configuration

The thermal collector is configured as a submodule of the sensor collector in the central configuration file.

ThermalControlSubmodule

Declared in central_config.proto under the SensorCollectorModule:

message ThermalControlSubmodule {
  bool enabled = 1 [default = false];
}
Field NameTypeDefault ValueDescription
enabledboolfalseWhen true, enables
: : : : the :
: : : : ThermalCollector :
: : : : and activates the :
: : : : thermal control :
: : : : loops. :

Entity Manager Configuration

Platform integrators configure physical fan hardware and logical fan resources in the Entity Manager JSON configuration files.

Exposes Configuration Types

The JSON config maps keys with TlbmcOwned set to true into the store:

  • I2CFan: Defines hardware-level fan tachometer properties and default controller addresses.
  • Fan: Exposes the high-level physical fan unit linking PWM outputs and tachometer inputs.
  • MAX31790: Defines the hardware fan controller chip characteristics.

Fan Configuration Attributes

The properties for the high-level Fan configuration entry:

Parameter NameExpected TypeDescription
TypestringMust be "Fan".
NamestringUnique name of the fan (e.g.,
: : : "fan0_rear_tach"). :
LocationTypestringRedfish physical location type (e.g.,
: : : "Connector"). :
ServiceLabelstringSilkscreen or service label identifying the
: : : fan slot. :
HotPluggableboolWhether the fan supports hot-swapping.
PWMSensorstringThe associated PWM sensor name (e.g.,
: : : "fan0_pwm"). :
TachSensorstringThe associated Tachometer sensor name
: : : (e.g., "fan0_rear_tach"). :
Modelstring(Optional) Fan model identifier (e.g.,
: : : "fan_92mm"). :

Configuration Example

Below is a mocked Entity Manager JSON extract showing how fans and fan controllers are defined:

[
  {
    "Address": "0x2c",
    "Bus": "96",
    "Connector": {
      "DefaultPwm": 50,
      "Mutable": true,
      "Name": "fan0_rear_tach",
      "Pwm": 0,
      "PwmName": "fan0_pwm",
      "Tachs": [ 0 ]
    },
    "Index": 0,
    "MaxReading": 19800,
    "Name": "fan0_rear_tach",
    "TlbmcOwned": true,
    "PowerState": "Always",
    "RelatedItem": {
      "Id": "Fan0",
      "Type": "RESOURCE_TYPE_FAN",
      "User": "tlbmc"
    },
    "Type": "I2CFan"
  },
  {
    "HotPluggable": false,
    "LocationType": "Connector",
    "Model": "fan_92mm",
    "Name": "fan0_rear_tach",
    "PWMSensor": "fan0_pwm",
    "ServiceLabel": "FAN0_rear",
    "TachSensor": "fan0_rear_tach",
    "Type": "Fan",
    "TlbmcOwned": true
  },
  {
    "Address": "0x2c",
    "Bus": "96",
    "Name": "FAN_CONTROLLER_U19",
    "Type": "MAX31790",
    "TlbmcOwned": true
  }
]

Protobuf Configuration

The control loops, thermal zones, and controllers are structured in thermal_config.proto.

Key submessages parsed into ThermalConfigs:

ZoneManagerConfig

Defines the attributes and timing limits of a thermal zone:

Field NameTypeDefault ValueDescription
idint32-Unique ID of the
: : : : zone. :
setpoint_upper_bounddouble-Upper bound for
: : : : calculated thermal :
: : : : setpoints. :
setpoint_lower_bounddouble-Lower bound for
: : : : calculated thermal :
: : : : setpoints. :
minimum_thermal_setpointdouble-Hard-minimum
: : : : thermal setpoint :
: : : : value allowed. :
zone_failsafe_percentdouble100PWM output
: : : : percentage written :
: : : : during zone :
: : : : failsafe mode. :
ms_per_fan_cycleuint64100Timing interval
: : : : (ms) between fan :
: : : : speed evaluations. :
ms_per_thermal_cycleuint641000Timing interval
: : : : (ms) between :
: : : : thermal controller :
: : : : evaluations. :
input_sensorsrepeated-Sensor inputs
: : : : monitored by this :
: : : : zone. :
output_fansrepeated-Fan outputs driven
: : : : by this zone. :

PidControllerConfig

Sets parameters for a standard PID (Proportional-Integral-Derivative) control loop:

Field NameTypeDescription
idstringUnique ID of the controller.
zone_manager_idrepeated int32IDs of the zones this controller
: : : belongs to. :
setpointdoubleTarget temperature/margin value.
input_process_typeenumType of process input (TEMP_PID,
: : : MARGIN_PID, POWER_PID, etc.). :
pid_loop_configPidLoopConfigContains coefficients
: : : (coeff_proportional, :
: : : coeff_integral, :
: : : coeff_derivative, :
: : : feed_forward_gain, offsets, :
: : : etc.). :

Control Loop Timing

The main control loop runs asynchronously in ProcessThermalControl using boost::asio::steady_timer structures.

Yes No Yes No Yes No Yes No Yes No ProcessThermalControl Loop Started Stop Requested? Exit Loop Tuning Enabled? ApplyPendingTuningRequests Manual Mode Enabled? Schedule Next Fan Cycle Elapsed >= ms_per_thermal_cycle? ProcessOneThermalLoop Process Fan Controllers Update Fan RPM Sensors Write Fan PWM/Speeds to HW Debug Enabled? Dump/Clear Sampled Data Accumulate ms_per_fan_cycle

Execution Rules

  1. Fan Cycles (ms_per_fan_cycle): Executed every cycle (typically 100ms). Fan sensors are updated, fan PID controllers are processed, and target speeds are written to hardware registers.
  2. Thermal Cycles (ms_per_thermal_cycle): Executed periodically (typically every 1000ms). Invokes ProcessOneThermalLoop to update temperature sensors, run PID/Stepwise controllers, and compute zone setpoints.
  3. Failsafe Handling: If any monitored sensor reports a fault, goes missing, or returns readings exceeding its critical limits (max_threshold_critical / min_threshold_critical), the zone triggers Failsafe Mode, locking the fans to the configured zone_failsafe_percent (or individual failsafe_percent).

Runtime Tuning & Overrides

tlBMC provides interfaces to inspect and tune controller behavior at runtime via Redfish actions.

Fan Mode Control

To toggle manual fan speed control, make a POST request to the Manager action:

  • URL: /redfish/v1/Managers/bmc/Actions/Manager.FanMode.Change

  • Payload:

    {
      "FanMode": "Manual"
    }
    

    (Set FanMode to "Auto" to return control to the active loops).

Controller Tuning

Integrators can tune PID coefficients and setpoints on-the-fly by issuing a PATCH request to the Manager endpoint:

  • URL: /redfish/v1/Managers/bmc

  • Payload:

    {
      "Oem": {
        "OpenBmc": {
          "Fan": {
            "PidControllers": {
              "TEMP_PID_0": {
                "PCoefficient": -3.5,
                "ICoefficient": -0.15,
                "DCoefficient": 0.0,
                "FFGainCoefficient": 1.0,
                "SetPoint": 90.0
              }
            },
            "FanControllers": {
              "FAN_CTRL_01": {
                "PCoefficient": 0.1,
                "FFGainCoefficient": 1.2
              }
            }
          }
        }
      }
    }
    

[!TIP] The coefficients map to coeff_proportional, coeff_integral, coeff_derivative, feed_forward_gain, and setpoint in the PID implementation. They are queued and thread-safely applied via ApplyPendingTuningRequests at the start of the next control cycle.


Key Classes & Architecture

  • ThermalCollector: Instantiates and manages all thermal zones, schedules tasks, and coordinates tuning threads.
  • ZoneManager: Orchestrates a single zone's loop, maintains sensor values, processes controllers, and writes outputs.
  • PidController: Implements standard Proportional-Integral-Derivative math for temperature and power regulation.
  • StepwiseController: Evaluates step-based lookup tables (e.g., temperatures mapping to discrete fan speed values).
  • FanPidController: Regulates fan RPM speeds based on target PWM inputs.
  • DffController: Performs Dynamic Feedforward calculations to pre-emptively adjust cooling when workload power changes.
  • EatController: Handles Entering Air Temperature calculations.

Code References