Skip to content

Commit

Permalink
system/hardware: refactor thermal config (#34177)
Browse files Browse the repository at this point in the history
* system/hardware: refactor thermal config

* fix

* fixup

---------

Co-authored-by: Comma Device <[email protected]>
  • Loading branch information
adeebshihadeh and Comma Device authored Dec 7, 2024
1 parent be67d5a commit 2e9540d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 54 deletions.
1 change: 1 addition & 0 deletions cereal/log.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ struct DeviceState @0xa4d8b5af2aa492eb {
pmicTempC @39 :List(Float32);
intakeTempC @46 :Float32;
exhaustTempC @47 :Float32;
caseTempC @48 :Float32;
maxTempC @44 :Float32; # max of other temps, used to control fan
thermalZones @38 :List(ThermalZone);
thermalStatus @14 :ThermalStatus;
Expand Down
50 changes: 46 additions & 4 deletions system/hardware/base.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,54 @@
import os
from abc import abstractmethod, ABC
from collections import namedtuple
from dataclasses import dataclass, fields

from cereal import log

ThermalConfig = namedtuple('ThermalConfig', ['cpu', 'gpu', 'mem', 'pmic', 'intake', 'exhaust'])
NetworkType = log.DeviceState.NetworkType

@dataclass
class ThermalZone:
# a zone from /sys/class/thermal/thermal_zone*
name: str # a.k.a type
scale: float = 1000. # scale to get degrees in C
zone_number = -1

def read(self) -> float:
if self.zone_number < 0:
for n in os.listdir("/sys/devices/virtual/thermal"):
if not n.startswith("thermal_zone"):
continue
with open(os.path.join("/sys/devices/virtual/thermal", n, "type")) as f:
if f.read().strip() == self.name:
self.zone_number = int(n.removeprefix("thermal_zone"))
break

try:
with open(f"/sys/devices/virtual/thermal/thermal_zone{self.zone_number}/temp") as f:
return int(f.read()) / self.scale
except FileNotFoundError:
return 0

@dataclass
class ThermalConfig:
cpu: list[ThermalZone] | None = None
gpu: list[ThermalZone] | None = None
pmic: list[ThermalZone] | None = None
memory: ThermalZone | None = None
intake: ThermalZone | None = None
exhaust: ThermalZone | None = None
case: ThermalZone | None = None

def get_msg(self):
ret = {}
for f in fields(ThermalConfig):
v = getattr(self, f.name)
if v is not None:
if isinstance(v, list):
ret[f.name + "TempC"] = [x.read() for x in v]
else:
ret[f.name + "TempC"] = v.read()
return ret

class HardwareBase(ABC):
@staticmethod
Expand Down Expand Up @@ -84,9 +127,8 @@ def get_som_power_draw(self):
def shutdown(self):
pass

@abstractmethod
def get_thermal_config(self):
pass
return ThermalConfig()

@abstractmethod
def set_screen_brightness(self, percentage):
Expand Down
38 changes: 2 additions & 36 deletions system/hardware/hardwared.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,41 +51,6 @@

prev_offroad_states: dict[str, tuple[bool, str | None]] = {}

tz_by_type: dict[str, int] | None = None
def populate_tz_by_type():
global tz_by_type
tz_by_type = {}
for n in os.listdir("/sys/devices/virtual/thermal"):
if not n.startswith("thermal_zone"):
continue
with open(os.path.join("/sys/devices/virtual/thermal", n, "type")) as f:
tz_by_type[f.read().strip()] = int(n.removeprefix("thermal_zone"))

def read_tz(x):
if x is None:
return 0

if isinstance(x, str):
if tz_by_type is None:
populate_tz_by_type()
x = tz_by_type[x]

try:
with open(f"/sys/devices/virtual/thermal/thermal_zone{x}/temp") as f:
return int(f.read())
except FileNotFoundError:
return 0


def read_thermal(thermal_config):
dat = messaging.new_message('deviceState', valid=True)
dat.deviceState.cpuTempC = [read_tz(z) / thermal_config.cpu[1] for z in thermal_config.cpu[0]]
dat.deviceState.gpuTempC = [read_tz(z) / thermal_config.gpu[1] for z in thermal_config.gpu[0]]
dat.deviceState.memoryTempC = read_tz(thermal_config.mem[0]) / thermal_config.mem[1]
dat.deviceState.pmicTempC = [read_tz(z) / thermal_config.pmic[1] for z in thermal_config.pmic[0]]
dat.deviceState.intakeTempC = read_tz(thermal_config.intake[0]) / thermal_config.intake[1]
dat.deviceState.exhaustTempC = read_tz(thermal_config.exhaust[0]) / thermal_config.exhaust[1]
return dat


def set_offroad_alert_if_changed(offroad_alert: str, show_alert: bool, extra_text: str | None=None):
Expand Down Expand Up @@ -234,7 +199,8 @@ def hardware_thread(end_event, hw_queue) -> None:
if (sm.frame % round(SERVICE_LIST['pandaStates'].frequency * DT_HW) != 0) and not ign_edge:
continue

msg = read_thermal(thermal_config)
msg = messaging.new_message('deviceState', valid=True)
msg.deviceState = thermal_config.get_msg()
msg.deviceState.deviceType = HARDWARE.get_device_type()

try:
Expand Down
5 changes: 1 addition & 4 deletions system/hardware/pc/hardware.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import random

from cereal import log
from openpilot.system.hardware.base import HardwareBase, ThermalConfig
from openpilot.system.hardware.base import HardwareBase

NetworkType = log.DeviceState.NetworkType
NetworkStrength = log.DeviceState.NetworkStrength
Expand Down Expand Up @@ -53,9 +53,6 @@ def get_som_power_draw(self):
def shutdown(self):
print("SHUTDOWN!")

def get_thermal_config(self):
return ThermalConfig(cpu=((None,), 1), gpu=((None,), 1), mem=(None, 1), pmic=((None,), 1), intake=(None, 1), exhaust=(None, 1))

def set_screen_brightness(self, percentage):
pass

Expand Down
22 changes: 12 additions & 10 deletions system/hardware/tici/hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from cereal import log
from openpilot.common.gpio import gpio_set, gpio_init, get_irqs_for_action
from openpilot.system.hardware.base import HardwareBase, ThermalConfig
from openpilot.system.hardware.base import HardwareBase, ThermalConfig, ThermalZone
from openpilot.system.hardware.tici import iwlist
from openpilot.system.hardware.tici.pins import GPIO
from openpilot.system.hardware.tici.amplifier import Amplifier
Expand Down Expand Up @@ -323,17 +323,19 @@ def shutdown(self):
os.system("sudo poweroff")

def get_thermal_config(self):
intake, exhaust = (None, 1), (None, 1)
intake, exhaust, case = None, None, None
if self.get_device_type() == "mici":
intake = ("intake", 1000)
exhaust = ("exhaust", 1000)
return ThermalConfig(cpu=([f"cpu{i}-silver-usr" for i in range(4)] +
[f"cpu{i}-gold-usr" for i in range(4)], 1000),
gpu=(("gpu0-usr", "gpu1-usr"), 1000),
mem=("ddr-usr", 1000),
pmic=(("pm8998_tz", "pm8005_tz"), 1000),
case = ThermalZone("case")
intake = ThermalZone("intake")
exhaust = ThermalZone("exhaust")
return ThermalConfig(cpu=[ThermalZone(f"cpu{i}-silver-usr") for i in range(4)] +
[ThermalZone(f"cpu{i}-gold-usr") for i in range(4)],
gpu=[ThermalZone("gpu0-usr"), ThermalZone("gpu1-usr")],
memory=ThermalZone("ddr-usr"),
pmic=[ThermalZone("pm8998_tz"), ThermalZone("pm8005_tz")],
intake=intake,
exhaust=exhaust)
exhaust=exhaust,
case=case)

def set_screen_brightness(self, percentage):
try:
Expand Down

0 comments on commit 2e9540d

Please sign in to comment.