Skip to content

Instantly share code, notes, and snippets.

@kwilczynski
Last active June 2, 2026 14:27
Show Gist options
  • Select an option

  • Save kwilczynski/f98a6ec07cb6a5d55f2f98b43509f7cb to your computer and use it in GitHub Desktop.

Select an option

Save kwilczynski/f98a6ec07cb6a5d55f2f98b43509f7cb to your computer and use it in GitHub Desktop.
System Sensors Summary on B850 based motherboard
System Sensors Summary
CPU (AMD Ryzen)
──────────────────────────────────────────────────
Tctl: 47.6°C
CCD1: 39.6°C
CCD2: 37.6°C
Motherboard (ASUS)
──────────────────────────────────────────────────
CPU: 38.0°C
CPU Package: 47.0°C
Motherboard: 39.0°C
VRM: 41.0°C
GPU (AMD Radeon)
──────────────────────────────────────────────────
Edge: 50.0°C
Junction: 52.0°C
Memory: 52.0°C
Power: 24.0W / 220W (10.9%)
Fan: 0 RPM @ 0%
Core: 56 MHz
Memory: 772 MHz
VDD: 91 mV
AIO Cooler (NZXT Kraken)
──────────────────────────────────────────────────
Coolant: 35.1°C
Pump: 2040 RPM @ 55%
Fan: 1098 RPM @ 55%
Memory (DDR5)
──────────────────────────────────────────────────
DIMM 1: 45.2°C
DIMM 2: 45.2°C
Storage (NVMe)
──────────────────────────────────────────────────
Composite: 48.9°C
NAND: 48.9°C
Ctrl: 50.9°C
Wireless (MediaTek MT7925)
──────────────────────────────────────────────────
WiFi: 38.0°C
Chassis (Thermistor)
──────────────────────────────────────────────────
Rear: 30.0°C
Case Fans (Super I/O)
──────────────────────────────────────────────────
FAN1: 818 RPM @ 33%
FAN2: 1909 RPM @ 33%
FAN6: 2915 RPM @ 52%
FAN7: 2000 RPM @ 100%
Voltage Rails (Super I/O)
──────────────────────────────────────────────────
+12V: 12.29 V
+5V: 4.96 V
+3.3V: 3.39 V
Standby: 3.39 V
VCore: 840 mV
SoC: 1.00 V
VDD: 1.10 V
DRAM: 1.38 V
DRAM VDDP: 752 mV
DRAM VPP: 1.26 V
#!/usr/bin/env python3
import json
import subprocess
import sys
import time
RESET = ""
BOLD = ""
DIM = ""
GREEN = ""
YELLOW = ""
RED = ""
CYAN = ""
CLEAR = ""
if sys.stdout.isatty():
RESET = "\033[0m"
BOLD = "\033[1m"
DIM = "\033[2m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
RED = "\033[31m"
CYAN = "\033[36m"
CLEAR = "\033[H\033[2J"
def get_sensor_data():
result = subprocess.run(["sensors", "-j"], capture_output=True, text=True)
if result.returncode != 0:
sys.exit(f"sensors command failed: {result.stderr}")
return json.loads(result.stdout)
def find_sensor(data, prefix):
for key in data:
if key.startswith(prefix):
return data[key]
return None
def format_voltage(volts):
if volts >= 1.0:
return f"{volts:5.2f} V"
return f"{volts*1000:5.0f} mV"
def voltage_color(volts, nominal, tolerance=0.05):
deviation = abs(volts - nominal) / nominal
if deviation > tolerance * 2:
return RED
if deviation > tolerance:
return YELLOW
return GREEN
def format_voltage_rail(volts, nominal, name_width=8):
color = voltage_color(volts, nominal)
return f"{color}{format_voltage(volts)}{RESET}"
def temp_color(temp, warn=70, crit=85):
if temp >= crit:
return RED
if temp >= warn:
return YELLOW
return GREEN
def format_temp(temp, warn=70, crit=85):
color = temp_color(temp, warn, crit)
return f"{color}{temp:5.1f}°C{RESET}"
def format_rpm(rpm):
return f"{int(rpm):5d} RPM"
def format_power(watts, cap=None):
if cap:
pct = (watts / cap) * 100
return f"{watts:5.1f}W / {cap:.0f}W ({pct:4.1f}%)"
return f"{watts:5.1f}W"
def format_freq(hz):
mhz = hz / 1_000_000
if mhz >= 1000:
return f"{mhz/1000:5.2f} GHz"
return f"{mhz:5.0f} MHz"
def extract_temp(data, key_prefix="temp"):
for k, v in data.items():
if k.startswith(key_prefix) and k.endswith("_input"):
return v
return None
def extract_val(data, key_prefix):
for k, v in data.items():
if k.startswith(key_prefix) and k.endswith("_input"):
return v
return None
def print_section(title):
print(f"\n{BOLD}{CYAN}{title}{RESET}")
print(f"{DIM}{'─' * 50}{RESET}")
def main():
data = get_sensor_data()
print(f"{BOLD}System Sensors Summary{RESET}")
# CPU (k10temp)
k10 = find_sensor(data, "k10temp")
if k10:
print_section("CPU (AMD Ryzen)")
tctl = k10.get("Tctl", {}).get("temp1_input")
tccd1 = k10.get("Tccd1", {}).get("temp3_input")
tccd2 = k10.get("Tccd2", {}).get("temp4_input")
if tctl:
print(f" Tctl: {format_temp(tctl)}")
if tccd1:
print(f" CCD1: {format_temp(tccd1)}")
if tccd2:
print(f" CCD2: {format_temp(tccd2)}")
# Motherboard (asusec)
asus = find_sensor(data, "asusec")
if asus:
print_section("Motherboard (ASUS)")
for name in ["CPU", "CPU Package", "Motherboard", "VRM"]:
sensor = asus.get(name, {})
temp = extract_temp(sensor)
if temp:
print(f" {name + ':':<13s} {format_temp(temp)}")
# GPU (amdgpu)
gpu = find_sensor(data, "amdgpu")
if gpu:
print_section("GPU (AMD Radeon)")
edge = gpu.get("edge", {}).get("temp1_input")
junction = gpu.get("junction", {}).get("temp2_input")
mem = gpu.get("mem", {}).get("temp3_input")
if edge:
print(f" Edge: {format_temp(edge, warn=80, crit=100)}")
if junction:
print(f" Junction: {format_temp(junction, warn=90, crit=105)}")
if mem:
print(f" Memory: {format_temp(mem, warn=85, crit=100)}")
ppt = gpu.get("PPT", {})
power = ppt.get("power1_average")
cap = ppt.get("power1_cap")
if power:
print(f" Power: {format_power(power, cap)}")
fan = gpu.get("fan1", {}).get("fan1_input")
pwm = gpu.get("pwm1", {}).get("pwm1")
if fan is not None:
if pwm is not None:
pwm_pct = min(pwm / 127.5 * 100, 100)
print(f" Fan: {format_rpm(fan)} @ {pwm_pct:4.0f}%")
else:
print(f" Fan: {format_rpm(fan)}")
sclk = gpu.get("sclk", {}).get("freq1_input")
mclk = gpu.get("mclk", {}).get("freq2_input")
if sclk:
print(f" Core: {format_freq(sclk)}")
if mclk:
print(f" Memory: {format_freq(mclk)}")
vddgfx = gpu.get("vddgfx", {}).get("in0_input")
if vddgfx is not None:
print(f" VDD: {format_voltage(vddgfx)}")
# AIO Cooler (kraken)
kraken = find_sensor(data, "kraken2023elite")
if kraken:
print_section("AIO Cooler (NZXT Kraken)")
coolant = kraken.get("Coolant temp", {}).get("temp1_input")
pump = kraken.get("Pump speed", {}).get("fan1_input")
pump_pwm = kraken.get("pwm1", {}).get("pwm1")
fan = kraken.get("Fan speed", {}).get("fan2_input")
fan_pwm = kraken.get("pwm2", {}).get("pwm2")
if coolant:
print(f" Coolant: {format_temp(coolant, warn=40, crit=50)}")
if pump:
if pump_pwm is not None:
pump_pct = min(pump_pwm / 127.5 * 100, 100)
print(f" Pump: {format_rpm(pump)} @ {pump_pct:4.0f}%")
else:
print(f" Pump: {format_rpm(pump)}")
if fan:
if fan_pwm is not None:
fan_pct = min(fan_pwm / 127.5 * 100, 100)
print(f" Fan: {format_rpm(fan)} @ {fan_pct:4.0f}%")
else:
print(f" Fan: {format_rpm(fan)}")
# RAM (spd5118)
ram_sensors = [(k, v) for k, v in data.items() if k.startswith("spd5118")]
if ram_sensors:
print_section("Memory (DDR5)")
for i, (name, sensor) in enumerate(sorted(ram_sensors)):
temp = sensor.get("temp1", {}).get("temp1_input")
if temp:
print(f" DIMM {i+1}: {format_temp(temp, warn=50, crit=80)}")
# NVMe
nvme = find_sensor(data, "nvme")
if nvme:
print_section("Storage (NVMe)")
composite = nvme.get("Composite", {}).get("temp1_input")
sensor1 = nvme.get("Sensor 1", {}).get("temp2_input")
sensor2 = nvme.get("Sensor 2", {}).get("temp3_input")
if composite:
print(f" Composite: {format_temp(composite, warn=70, crit=80)}")
if sensor1:
print(f" NAND: {format_temp(sensor1, warn=70, crit=80)}")
if sensor2:
print(f" Ctrl: {format_temp(sensor2, warn=70, crit=80)}")
# WiFi
wifi = find_sensor(data, "mt7925")
if wifi:
print_section("Wireless (MediaTek MT7925)")
temp = wifi.get("temp1", {}).get("temp1_input")
if temp:
print(f" WiFi: {format_temp(temp)}")
# Super I/O (nct6799) - optional, may not be loaded
nct = find_sensor(data, "nct6799")
if nct:
rear_chassis = nct.get("AUXTIN3", {}).get("temp6_input")
if rear_chassis is not None:
print_section("Chassis (Thermistor)")
print(f" Rear: {format_temp(rear_chassis, warn=40, crit=50)}")
fans = []
for fan_name in ["fan1", "fan2", "fan6", "fan7"]:
fan_data = nct.get(fan_name, {})
rpm = fan_data.get(f"{fan_name}_input")
if rpm and rpm > 0:
fans.append((fan_name.upper(), rpm))
if fans:
print_section("Case Fans (Super I/O)")
for name, rpm in fans:
pwm_key = name.lower().replace("fan", "pwm")
pwm_data = nct.get(pwm_key, {})
pwm_raw = pwm_data.get(pwm_key)
if pwm_raw is not None:
pwm_pct = min(pwm_raw / 127.5 * 100, 100)
print(f" {name + ':':<9s} {format_rpm(rpm)} @ {pwm_pct:4.0f}%")
else:
print(f" {name + ':':<9s} {format_rpm(rpm)}")
print_section("Voltage Rails (Super I/O)")
rails = [
("in12", "+12V", 12.0, 12.0),
("in1", "+5V", 5.0, 5.0),
("in2", "+3.3V", 3.3, 1.0),
("in7", "Standby", 3.3, 1.0),
("in0", "VCore", None, 1.0),
("in4", "SoC", None, 1.0),
("in11", "VDD", None, 1.0),
("in10", "DRAM", None, 1.0),
("in15", "DRAM VDDP", None, 1.0),
("in17", "DRAM VPP", None, 1.0),
]
for key, label, nominal, mult in rails:
rail_data = nct.get(key, {})
volts = rail_data.get(f"{key}_input")
if volts is not None:
volts *= mult
if nominal:
print(f" {label + ':':<11s} {format_voltage_rail(volts, nominal)}")
else:
print(f" {label + ':':<11s} {format_voltage(volts)}")
print()
if __name__ == "__main__":
interval = None
if len(sys.argv) > 1:
try:
interval = float(sys.argv[1])
except ValueError:
sys.exit(f"Usage: {sys.argv[0]} [INTERVAL SECONDS]")
if interval is None:
main()
else:
try:
while True:
print(CLEAR, end="")
main()
sys.stdout.flush()
time.sleep(interval)
except KeyboardInterrupt:
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment