Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

system/hardware: refactor thermal config #34177

Merged
merged 3 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading