cros_ec_python.commands.thermal

Thermal engine commands.

  1"""
  2Thermal engine commands.
  3"""
  4
  5from typing import Final
  6from enum import Enum, auto
  7import struct
  8from ..baseclass import CrosEcClass
  9from ..constants.COMMON import *
 10from .memmap import get_temps
 11
 12EC_CMD_THERMAL_SET_THRESHOLD: Final = 0x0050
 13EC_CMD_THERMAL_GET_THRESHOLD: Final = 0x0051
 14
 15
 16class EcTempThresholds(Enum):
 17    EC_TEMP_THRESH_WARN = 0
 18    EC_TEMP_THRESH_HIGH = auto()
 19    EC_TEMP_THRESH_HALT = auto()
 20
 21    EC_TEMP_THRESH_COUNT = auto()
 22
 23
 24def thermal_get_thresholds(
 25    ec: CrosEcClass, sensor_num: int, adjust: int | float = -273
 26) -> dict[str, list[int | float] | int | float]:
 27    """
 28    Get the temperature threshold configuration for a given sensor.
 29    :param ec: The CrOS_EC object.
 30    :param sensor_num: The sensor number.
 31    :param adjust: The adjustment to apply to the temperature. Default is -273 to convert from Kelvin to Celsius.
 32    :return: A dictionary containing the threshold configuration.
 33    """
 34    data = struct.pack("<I", sensor_num)
 35    thresh_count: Final = EcTempThresholds.EC_TEMP_THRESH_COUNT.value
 36    resp = ec.command(
 37        1,
 38        EC_CMD_THERMAL_GET_THRESHOLD,
 39        4,
 40        4 * thresh_count + 4 * thresh_count + 4 + 4,
 41        data,
 42    )
 43    config = struct.unpack(f"<{thresh_count}I{thresh_count}III", resp)
 44    return {
 45        "temp_host": [(i + adjust) for i in config[0:thresh_count]],
 46        "temp_host_release": [
 47            (i + adjust) for i in config[thresh_count : thresh_count * 2]
 48        ],
 49        "temp_fan_off": config[thresh_count * 2] + adjust,
 50        "temp_fan_max": config[thresh_count * 2 + 1] + adjust,
 51    }
 52
 53
 54def thermal_set_thresholds(
 55    ec: CrosEcClass,
 56    sensor_num: int,
 57    config: dict[str, list[int | float] | int | float],
 58    adjust: int | float = 273,
 59) -> None:
 60    """
 61    Set the temperature thresholds for a given sensor.
 62    :param ec: The CrOS_EC object.
 63    :param sensor_num: The sensor number.
 64    :param config: A dictionary containing the threshold configuration.
 65    :param adjust: The adjustment to apply to the temperature. Default is 273 to convert from Celsius to Kelvin.
 66    """
 67    thresh_count: Final = EcTempThresholds.EC_TEMP_THRESH_COUNT.value
 68    data = struct.pack(
 69        f"<I{thresh_count}I{thresh_count}III",
 70        sensor_num,
 71        *[int(i + adjust) for i in config["temp_host"]],
 72        *[int(i + adjust) for i in config["temp_host_release"]],
 73        int(config["temp_fan_off"] + adjust),
 74        int(config["temp_fan_max"] + adjust),
 75    )
 76    ec.command(1, EC_CMD_THERMAL_SET_THRESHOLD, len(data), 0, data)
 77
 78
 79EC_CMD_THERMAL_AUTO_FAN_CTRL: Final = 0x0052
 80
 81
 82def thermal_auto_fan_ctrl(ec: CrosEcClass, fan_idx: UInt8 | None = None) -> None:
 83    """
 84    Toggle automatic fan control.
 85    :param ec: The CrOS_EC object.
 86    :param fan_idx: The fan index to control (v1 command). If None, it will set all fans (v0 command).
 87    """
 88    if fan_idx is None:
 89        ec.command(0, EC_CMD_THERMAL_AUTO_FAN_CTRL, 0, 0)
 90    else:
 91        data = struct.pack("<B", fan_idx)
 92        ec.command(1, EC_CMD_THERMAL_AUTO_FAN_CTRL, 1, 0, data)
 93
 94
 95EC_CMD_TMP006_GET_CALIBRATION: Final = 0x0053
 96EC_CMD_TMP006_SET_CALIBRATION: Final = 0x0054
 97EC_CMD_TMP006_GET_RAW: Final = 0x0055
 98
 99EC_CMD_TEMP_SENSOR_GET_INFO: Final = 0x0070
100
101class EcTempSensorType(Enum):
102    TEMP_SENSOR_TYPE_IGNORED = -1
103    TEMP_SENSOR_TYPE_CPU = 0
104    TEMP_SENSOR_TYPE_BOARD = auto()
105    TEMP_SENSOR_TYPE_CASE = auto()
106    TEMP_SENSOR_TYPE_BATTERY = auto()
107
108    TEMP_SENSOR_TYPE_COUNT = auto()
109
110def temp_sensor_get_info(ec: CrosEcClass, sensor_idx: UInt8) -> dict[str, EcTempSensorType]:
111    """
112    Get information about a temperature sensor.
113    :param ec: The CrOS_EC object.
114    :param sensor_idx: The sensor index.
115    :return: The response data.
116    """
117    data = struct.pack("<B", sensor_idx)
118    resp = ec.command(0, EC_CMD_TEMP_SENSOR_GET_INFO, 1, 33, data)
119    unpacked = struct.unpack("<32sB", resp)
120    return {
121        "name": unpacked[0].decode("utf-8").rstrip("\x00"),
122        "type": EcTempSensorType(unpacked[1])
123    }
124
125def get_temp_sensors(ec: CrosEcClass) -> dict[str, tuple[int, EcTempSensorType]]:
126    """
127    Get information about all temperature sensors.
128    :param ec: The CrOS_EC object.
129    :return: The response data.
130    """
131    temps = get_temps(ec)
132    ret = {}
133    for i, j in enumerate(temps):
134        info = temp_sensor_get_info(ec, i)
135        ret[info["name"]] = (j, info["type"])
136    return ret
EC_CMD_THERMAL_SET_THRESHOLD: Final = 80
EC_CMD_THERMAL_GET_THRESHOLD: Final = 81
class EcTempThresholds(enum.Enum):
17class EcTempThresholds(Enum):
18    EC_TEMP_THRESH_WARN = 0
19    EC_TEMP_THRESH_HIGH = auto()
20    EC_TEMP_THRESH_HALT = auto()
21
22    EC_TEMP_THRESH_COUNT = auto()
EC_TEMP_THRESH_WARN = <EcTempThresholds.EC_TEMP_THRESH_WARN: 0>
EC_TEMP_THRESH_HIGH = <EcTempThresholds.EC_TEMP_THRESH_HIGH: 1>
EC_TEMP_THRESH_HALT = <EcTempThresholds.EC_TEMP_THRESH_HALT: 2>
EC_TEMP_THRESH_COUNT = <EcTempThresholds.EC_TEMP_THRESH_COUNT: 3>
def thermal_get_thresholds( ec: cros_ec_python.baseclass.CrosEcClass, sensor_num: int, adjust: int | float = -273) -> dict[str, list[int | float] | int | float]:
25def thermal_get_thresholds(
26    ec: CrosEcClass, sensor_num: int, adjust: int | float = -273
27) -> dict[str, list[int | float] | int | float]:
28    """
29    Get the temperature threshold configuration for a given sensor.
30    :param ec: The CrOS_EC object.
31    :param sensor_num: The sensor number.
32    :param adjust: The adjustment to apply to the temperature. Default is -273 to convert from Kelvin to Celsius.
33    :return: A dictionary containing the threshold configuration.
34    """
35    data = struct.pack("<I", sensor_num)
36    thresh_count: Final = EcTempThresholds.EC_TEMP_THRESH_COUNT.value
37    resp = ec.command(
38        1,
39        EC_CMD_THERMAL_GET_THRESHOLD,
40        4,
41        4 * thresh_count + 4 * thresh_count + 4 + 4,
42        data,
43    )
44    config = struct.unpack(f"<{thresh_count}I{thresh_count}III", resp)
45    return {
46        "temp_host": [(i + adjust) for i in config[0:thresh_count]],
47        "temp_host_release": [
48            (i + adjust) for i in config[thresh_count : thresh_count * 2]
49        ],
50        "temp_fan_off": config[thresh_count * 2] + adjust,
51        "temp_fan_max": config[thresh_count * 2 + 1] + adjust,
52    }

Get the temperature threshold configuration for a given sensor.

Parameters
  • ec: The CrOS_EC object.
  • sensor_num: The sensor number.
  • adjust: The adjustment to apply to the temperature. Default is -273 to convert from Kelvin to Celsius.
Returns

A dictionary containing the threshold configuration.

def thermal_set_thresholds( ec: cros_ec_python.baseclass.CrosEcClass, sensor_num: int, config: dict[str, list[int | float] | int | float], adjust: int | float = 273) -> None:
55def thermal_set_thresholds(
56    ec: CrosEcClass,
57    sensor_num: int,
58    config: dict[str, list[int | float] | int | float],
59    adjust: int | float = 273,
60) -> None:
61    """
62    Set the temperature thresholds for a given sensor.
63    :param ec: The CrOS_EC object.
64    :param sensor_num: The sensor number.
65    :param config: A dictionary containing the threshold configuration.
66    :param adjust: The adjustment to apply to the temperature. Default is 273 to convert from Celsius to Kelvin.
67    """
68    thresh_count: Final = EcTempThresholds.EC_TEMP_THRESH_COUNT.value
69    data = struct.pack(
70        f"<I{thresh_count}I{thresh_count}III",
71        sensor_num,
72        *[int(i + adjust) for i in config["temp_host"]],
73        *[int(i + adjust) for i in config["temp_host_release"]],
74        int(config["temp_fan_off"] + adjust),
75        int(config["temp_fan_max"] + adjust),
76    )
77    ec.command(1, EC_CMD_THERMAL_SET_THRESHOLD, len(data), 0, data)

Set the temperature thresholds for a given sensor.

Parameters
  • ec: The CrOS_EC object.
  • sensor_num: The sensor number.
  • config: A dictionary containing the threshold configuration.
  • adjust: The adjustment to apply to the temperature. Default is 273 to convert from Celsius to Kelvin.
EC_CMD_THERMAL_AUTO_FAN_CTRL: Final = 82
def thermal_auto_fan_ctrl( ec: cros_ec_python.baseclass.CrosEcClass, fan_idx: int | None = None) -> None:
83def thermal_auto_fan_ctrl(ec: CrosEcClass, fan_idx: UInt8 | None = None) -> None:
84    """
85    Toggle automatic fan control.
86    :param ec: The CrOS_EC object.
87    :param fan_idx: The fan index to control (v1 command). If None, it will set all fans (v0 command).
88    """
89    if fan_idx is None:
90        ec.command(0, EC_CMD_THERMAL_AUTO_FAN_CTRL, 0, 0)
91    else:
92        data = struct.pack("<B", fan_idx)
93        ec.command(1, EC_CMD_THERMAL_AUTO_FAN_CTRL, 1, 0, data)

Toggle automatic fan control.

Parameters
  • ec: The CrOS_EC object.
  • fan_idx: The fan index to control (v1 command). If None, it will set all fans (v0 command).
EC_CMD_TMP006_GET_CALIBRATION: Final = 83
EC_CMD_TMP006_SET_CALIBRATION: Final = 84
EC_CMD_TMP006_GET_RAW: Final = 85
EC_CMD_TEMP_SENSOR_GET_INFO: Final = 112
class EcTempSensorType(enum.Enum):
102class EcTempSensorType(Enum):
103    TEMP_SENSOR_TYPE_IGNORED = -1
104    TEMP_SENSOR_TYPE_CPU = 0
105    TEMP_SENSOR_TYPE_BOARD = auto()
106    TEMP_SENSOR_TYPE_CASE = auto()
107    TEMP_SENSOR_TYPE_BATTERY = auto()
108
109    TEMP_SENSOR_TYPE_COUNT = auto()
TEMP_SENSOR_TYPE_IGNORED = <EcTempSensorType.TEMP_SENSOR_TYPE_IGNORED: -1>
TEMP_SENSOR_TYPE_CPU = <EcTempSensorType.TEMP_SENSOR_TYPE_CPU: 0>
TEMP_SENSOR_TYPE_BOARD = <EcTempSensorType.TEMP_SENSOR_TYPE_BOARD: 1>
TEMP_SENSOR_TYPE_CASE = <EcTempSensorType.TEMP_SENSOR_TYPE_CASE: 2>
TEMP_SENSOR_TYPE_BATTERY = <EcTempSensorType.TEMP_SENSOR_TYPE_BATTERY: 3>
TEMP_SENSOR_TYPE_COUNT = <EcTempSensorType.TEMP_SENSOR_TYPE_COUNT: 4>
def temp_sensor_get_info( ec: cros_ec_python.baseclass.CrosEcClass, sensor_idx: int) -> dict[str, EcTempSensorType]:
111def temp_sensor_get_info(ec: CrosEcClass, sensor_idx: UInt8) -> dict[str, EcTempSensorType]:
112    """
113    Get information about a temperature sensor.
114    :param ec: The CrOS_EC object.
115    :param sensor_idx: The sensor index.
116    :return: The response data.
117    """
118    data = struct.pack("<B", sensor_idx)
119    resp = ec.command(0, EC_CMD_TEMP_SENSOR_GET_INFO, 1, 33, data)
120    unpacked = struct.unpack("<32sB", resp)
121    return {
122        "name": unpacked[0].decode("utf-8").rstrip("\x00"),
123        "type": EcTempSensorType(unpacked[1])
124    }

Get information about a temperature sensor.

Parameters
  • ec: The CrOS_EC object.
  • sensor_idx: The sensor index.
Returns

The response data.

def get_temp_sensors( ec: cros_ec_python.baseclass.CrosEcClass) -> dict[str, tuple[int, EcTempSensorType]]:
126def get_temp_sensors(ec: CrosEcClass) -> dict[str, tuple[int, EcTempSensorType]]:
127    """
128    Get information about all temperature sensors.
129    :param ec: The CrOS_EC object.
130    :return: The response data.
131    """
132    temps = get_temps(ec)
133    ret = {}
134    for i, j in enumerate(temps):
135        info = temp_sensor_get_info(ec, i)
136        ret[info["name"]] = (j, info["type"])
137    return ret

Get information about all temperature sensors.

Parameters
  • ec: The CrOS_EC object.
Returns

The response data.