Cross-platform library for retrieving information on running processes and system utilization (CPU, memory, disks, network, sensors) in Python
—
psutil provides access to hardware sensor information including temperature monitoring, fan speeds, and battery status. These features enable monitoring of system health and power management.
Note: Sensor support is highly platform-dependent and may require specific hardware/software configurations.
import psutil
# Get all temperature sensors
try:
temperatures = psutil.sensors_temperatures()
if not temperatures:
print("No temperature sensors available")
else:
for name, entries in temperatures.items():
print(f"Sensor: {name}")
for entry in entries:
print(f" Label: {entry.label or 'N/A'}")
print(f" Current: {entry.current}°C")
if entry.high is not None:
print(f" High threshold: {entry.high}°C")
if entry.critical is not None:
print(f" Critical threshold: {entry.critical}°C")
print()
except AttributeError:
print("Temperature sensors not supported on this platform"){ .api }
# Get temperatures in Fahrenheit directly
try:
temperatures_f = psutil.sensors_temperatures(fahrenheit=True)
for name, entries in temperatures_f.items():
print(f"Sensor: {name}")
for entry in entries:
print(f" {entry.label or 'Sensor'}: {entry.current}°F")
if entry.high is not None:
print(f" High threshold: {entry.high}°F")
if entry.critical is not None:
print(f" Critical threshold: {entry.critical}°F")
except AttributeError:
print("Temperature sensors not supported on this platform")
# Or convert manually if needed
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit."""
return (celsius * 9/5) + 32
temperatures = psutil.sensors_temperatures() # Default: Celsius
for name, entries in temperatures.items():
print(f"Sensor: {name}")
for entry in entries:
temp_f = celsius_to_fahrenheit(entry.current)
print(f" {entry.label or 'Sensor'}: {entry.current}°C ({temp_f:.1f}°F)")
if entry.high:
high_f = celsius_to_fahrenheit(entry.high)
print(f" High: {entry.high}°C ({high_f:.1f}°F)")
except AttributeError:
print("Temperature sensors not available"){ .api }
# Get fan speed information
try:
fans = psutil.sensors_fans()
if not fans:
print("No fan sensors available")
else:
for name, entries in fans.items():
print(f"Fan controller: {name}")
for entry in entries:
print(f" Label: {entry.label or 'N/A'}")
print(f" Current speed: {entry.current} RPM")
print()
except AttributeError:
print("Fan sensors not supported on this platform"){ .api }
# Get battery information
try:
battery = psutil.sensors_battery()
if battery is None:
print("No battery found or battery info not available")
else:
print(f"Battery percentage: {battery.percent}%")
print(f"Power plugged: {battery.power_plugged}")
if battery.secsleft != psutil.POWER_TIME_UNLIMITED:
if battery.secsleft != psutil.POWER_TIME_UNKNOWN:
# Convert seconds to hours and minutes
hours, remainder = divmod(battery.secsleft, 3600)
minutes, _ = divmod(remainder, 60)
print(f"Time remaining: {hours}h {minutes}m")
else:
print("Time remaining: Unknown")
else:
print("Time remaining: Unlimited (plugged in)")
except AttributeError:
print("Battery information not supported on this platform"){ .api }
import time
def monitor_battery(duration=300, interval=30):
"""Monitor battery status over time."""
try:
print(f"{'Time':<8} {'Battery%':<10} {'Plugged':<8} {'Time Left':<12}")
print("-" * 40)
start_time = time.time()
while time.time() - start_time < duration:
battery = psutil.sensors_battery()
if battery:
timestamp = time.strftime("%H:%M:%S")
plugged = "Yes" if battery.power_plugged else "No"
if battery.secsleft == psutil.POWER_TIME_UNLIMITED:
time_left = "Unlimited"
elif battery.secsleft == psutil.POWER_TIME_UNKNOWN:
time_left = "Unknown"
else:
hours, remainder = divmod(battery.secsleft, 3600)
minutes, _ = divmod(remainder, 60)
time_left = f"{hours}h {minutes}m"
print(f"{timestamp:<8} {battery.percent:<10.1f} {plugged:<8} {time_left:<12}")
else:
print("Battery information not available")
break
time.sleep(interval)
except AttributeError:
print("Battery monitoring not supported on this platform")
except KeyboardInterrupt:
print("\nMonitoring stopped")
# Monitor battery for 5 minutes
# monitor_battery(duration=300){ .api }
Different platforms have varying levels of sensor support:
def check_sensor_support():
"""Check what sensor features are available on this platform."""
features = {
'temperatures': hasattr(psutil, 'sensors_temperatures'),
'fans': hasattr(psutil, 'sensors_fans'),
'battery': hasattr(psutil, 'sensors_battery')
}
print("Sensor feature availability:")
for feature, available in features.items():
status = "Available" if available else "Not available"
print(f" {feature.capitalize()}: {status}")
return features
# Check platform support
sensor_support = check_sensor_support(){ .api }
if psutil.LINUX:
# On Linux, sensor support may require:
# - lm-sensors package installed
# - Proper kernel modules loaded
# - /sys/class/hwmon/ accessible
def check_linux_sensors():
"""Check Linux-specific sensor requirements."""
import os
hwmon_path = '/sys/class/hwmon'
if os.path.exists(hwmon_path):
hwmon_devices = os.listdir(hwmon_path)
print(f"Hardware monitoring devices found: {len(hwmon_devices)}")
for device in hwmon_devices[:5]: # Show first 5
print(f" {device}")
else:
print("Hardware monitoring path not found")
# check_linux_sensors(){ .api }
def get_all_sensors():
"""Get comprehensive sensor information."""
sensor_data = {}
# Temperature sensors
try:
temperatures = psutil.sensors_temperatures()
if temperatures:
sensor_data['temperatures'] = {}
for name, entries in temperatures.items():
sensor_data['temperatures'][name] = [
{
'label': entry.label,
'current': entry.current,
'high': entry.high,
'critical': entry.critical
}
for entry in entries
]
except AttributeError:
sensor_data['temperatures'] = None
# Fan sensors
try:
fans = psutil.sensors_fans()
if fans:
sensor_data['fans'] = {}
for name, entries in fans.items():
sensor_data['fans'][name] = [
{
'label': entry.label,
'current': entry.current
}
for entry in entries
]
except AttributeError:
sensor_data['fans'] = None
# Battery
try:
battery = psutil.sensors_battery()
if battery:
sensor_data['battery'] = {
'percent': battery.percent,
'power_plugged': battery.power_plugged,
'secsleft': battery.secsleft
}
else:
sensor_data['battery'] = None
except AttributeError:
sensor_data['battery'] = None
return sensor_data
# Get all available sensor data
all_sensors = get_all_sensors(){ .api }
def check_sensor_alerts(temp_threshold=80, battery_threshold=20):
"""Check for sensor-based alerts."""
alerts = []
# Temperature alerts
try:
temperatures = psutil.sensors_temperatures()
if temperatures:
for sensor_name, entries in temperatures.items():
for entry in entries:
if entry.current > temp_threshold:
alerts.append(f"High temperature: {sensor_name} "
f"({entry.label or 'N/A'}) = {entry.current}°C")
if entry.critical and entry.current > entry.critical:
alerts.append(f"CRITICAL temperature: {sensor_name} "
f"({entry.label or 'N/A'}) = {entry.current}°C")
except AttributeError:
pass
# Battery alerts
try:
battery = psutil.sensors_battery()
if battery and not battery.power_plugged:
if battery.percent < battery_threshold:
alerts.append(f"Low battery: {battery.percent}% remaining")
if (battery.secsleft != psutil.POWER_TIME_UNKNOWN and
battery.secsleft != psutil.POWER_TIME_UNLIMITED and
battery.secsleft < 1800): # Less than 30 minutes
minutes = battery.secsleft // 60
alerts.append(f"Battery time low: {minutes} minutes remaining")
except AttributeError:
pass
return alerts
# Check for alerts
alerts = check_sensor_alerts()
for alert in alerts:
print(f"ALERT: {alert}"){ .api }
def safe_get_sensors():
"""Safely get sensor information with proper error handling."""
result = {
'temperatures': None,
'fans': None,
'battery': None,
'errors': []
}
# Temperature sensors
try:
result['temperatures'] = psutil.sensors_temperatures()
except AttributeError:
result['errors'].append("Temperature sensors not supported")
except Exception as e:
result['errors'].append(f"Temperature sensor error: {e}")
# Fan sensors
try:
result['fans'] = psutil.sensors_fans()
except AttributeError:
result['errors'].append("Fan sensors not supported")
except Exception as e:
result['errors'].append(f"Fan sensor error: {e}")
# Battery
try:
result['battery'] = psutil.sensors_battery()
except AttributeError:
result['errors'].append("Battery information not supported")
except Exception as e:
result['errors'].append(f"Battery error: {e}")
return result
# Get sensors with error handling
sensor_info = safe_get_sensors(){ .api }
Install with Tessl CLI
npx tessl i tessl/pypi-psutil