0
# Hardware Sensors
1
2
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.
3
4
**Note:** Sensor support is highly platform-dependent and may require specific hardware/software configurations.
5
6
## Temperature Monitoring
7
8
### System Temperatures
9
10
```python
11
import psutil
12
13
# Get all temperature sensors
14
try:
15
temperatures = psutil.sensors_temperatures()
16
17
if not temperatures:
18
print("No temperature sensors available")
19
else:
20
for name, entries in temperatures.items():
21
print(f"Sensor: {name}")
22
for entry in entries:
23
print(f" Label: {entry.label or 'N/A'}")
24
print(f" Current: {entry.current}°C")
25
if entry.high is not None:
26
print(f" High threshold: {entry.high}°C")
27
if entry.critical is not None:
28
print(f" Critical threshold: {entry.critical}°C")
29
print()
30
31
except AttributeError:
32
print("Temperature sensors not supported on this platform")
33
```
34
{ .api }
35
36
### Temperature Monitoring with Fahrenheit
37
38
```python
39
# Get temperatures in Fahrenheit directly
40
try:
41
temperatures_f = psutil.sensors_temperatures(fahrenheit=True)
42
for name, entries in temperatures_f.items():
43
print(f"Sensor: {name}")
44
for entry in entries:
45
print(f" {entry.label or 'Sensor'}: {entry.current}°F")
46
if entry.high is not None:
47
print(f" High threshold: {entry.high}°F")
48
if entry.critical is not None:
49
print(f" Critical threshold: {entry.critical}°F")
50
51
except AttributeError:
52
print("Temperature sensors not supported on this platform")
53
54
# Or convert manually if needed
55
def celsius_to_fahrenheit(celsius):
56
"""Convert Celsius to Fahrenheit."""
57
return (celsius * 9/5) + 32
58
59
temperatures = psutil.sensors_temperatures() # Default: Celsius
60
for name, entries in temperatures.items():
61
print(f"Sensor: {name}")
62
for entry in entries:
63
temp_f = celsius_to_fahrenheit(entry.current)
64
print(f" {entry.label or 'Sensor'}: {entry.current}°C ({temp_f:.1f}°F)")
65
66
if entry.high:
67
high_f = celsius_to_fahrenheit(entry.high)
68
print(f" High: {entry.high}°C ({high_f:.1f}°F)")
69
70
except AttributeError:
71
print("Temperature sensors not available")
72
```
73
{ .api }
74
75
## Fan Monitoring
76
77
### Fan Speed Information
78
79
```python
80
# Get fan speed information
81
try:
82
fans = psutil.sensors_fans()
83
84
if not fans:
85
print("No fan sensors available")
86
else:
87
for name, entries in fans.items():
88
print(f"Fan controller: {name}")
89
for entry in entries:
90
print(f" Label: {entry.label or 'N/A'}")
91
print(f" Current speed: {entry.current} RPM")
92
print()
93
94
except AttributeError:
95
print("Fan sensors not supported on this platform")
96
```
97
{ .api }
98
99
## Battery Information
100
101
### Battery Status and Statistics
102
103
```python
104
# Get battery information
105
try:
106
battery = psutil.sensors_battery()
107
108
if battery is None:
109
print("No battery found or battery info not available")
110
else:
111
print(f"Battery percentage: {battery.percent}%")
112
print(f"Power plugged: {battery.power_plugged}")
113
114
if battery.secsleft != psutil.POWER_TIME_UNLIMITED:
115
if battery.secsleft != psutil.POWER_TIME_UNKNOWN:
116
# Convert seconds to hours and minutes
117
hours, remainder = divmod(battery.secsleft, 3600)
118
minutes, _ = divmod(remainder, 60)
119
print(f"Time remaining: {hours}h {minutes}m")
120
else:
121
print("Time remaining: Unknown")
122
else:
123
print("Time remaining: Unlimited (plugged in)")
124
125
except AttributeError:
126
print("Battery information not supported on this platform")
127
```
128
{ .api }
129
130
### Battery Monitoring Loop
131
132
```python
133
import time
134
135
def monitor_battery(duration=300, interval=30):
136
"""Monitor battery status over time."""
137
try:
138
print(f"{'Time':<8} {'Battery%':<10} {'Plugged':<8} {'Time Left':<12}")
139
print("-" * 40)
140
141
start_time = time.time()
142
while time.time() - start_time < duration:
143
battery = psutil.sensors_battery()
144
145
if battery:
146
timestamp = time.strftime("%H:%M:%S")
147
plugged = "Yes" if battery.power_plugged else "No"
148
149
if battery.secsleft == psutil.POWER_TIME_UNLIMITED:
150
time_left = "Unlimited"
151
elif battery.secsleft == psutil.POWER_TIME_UNKNOWN:
152
time_left = "Unknown"
153
else:
154
hours, remainder = divmod(battery.secsleft, 3600)
155
minutes, _ = divmod(remainder, 60)
156
time_left = f"{hours}h {minutes}m"
157
158
print(f"{timestamp:<8} {battery.percent:<10.1f} {plugged:<8} {time_left:<12}")
159
else:
160
print("Battery information not available")
161
break
162
163
time.sleep(interval)
164
165
except AttributeError:
166
print("Battery monitoring not supported on this platform")
167
except KeyboardInterrupt:
168
print("\nMonitoring stopped")
169
170
# Monitor battery for 5 minutes
171
# monitor_battery(duration=300)
172
```
173
{ .api }
174
175
## Platform Availability
176
177
### Platform Support Matrix
178
179
Different platforms have varying levels of sensor support:
180
181
```python
182
def check_sensor_support():
183
"""Check what sensor features are available on this platform."""
184
features = {
185
'temperatures': hasattr(psutil, 'sensors_temperatures'),
186
'fans': hasattr(psutil, 'sensors_fans'),
187
'battery': hasattr(psutil, 'sensors_battery')
188
}
189
190
print("Sensor feature availability:")
191
for feature, available in features.items():
192
status = "Available" if available else "Not available"
193
print(f" {feature.capitalize()}: {status}")
194
195
return features
196
197
# Check platform support
198
sensor_support = check_sensor_support()
199
```
200
{ .api }
201
202
### Linux Sensor Requirements
203
204
```python
205
if psutil.LINUX:
206
# On Linux, sensor support may require:
207
# - lm-sensors package installed
208
# - Proper kernel modules loaded
209
# - /sys/class/hwmon/ accessible
210
211
def check_linux_sensors():
212
"""Check Linux-specific sensor requirements."""
213
import os
214
215
hwmon_path = '/sys/class/hwmon'
216
if os.path.exists(hwmon_path):
217
hwmon_devices = os.listdir(hwmon_path)
218
print(f"Hardware monitoring devices found: {len(hwmon_devices)}")
219
for device in hwmon_devices[:5]: # Show first 5
220
print(f" {device}")
221
else:
222
print("Hardware monitoring path not found")
223
224
# check_linux_sensors()
225
```
226
{ .api }
227
228
## Comprehensive Sensor Monitoring
229
230
### All Sensors Overview
231
232
```python
233
def get_all_sensors():
234
"""Get comprehensive sensor information."""
235
sensor_data = {}
236
237
# Temperature sensors
238
try:
239
temperatures = psutil.sensors_temperatures()
240
if temperatures:
241
sensor_data['temperatures'] = {}
242
for name, entries in temperatures.items():
243
sensor_data['temperatures'][name] = [
244
{
245
'label': entry.label,
246
'current': entry.current,
247
'high': entry.high,
248
'critical': entry.critical
249
}
250
for entry in entries
251
]
252
except AttributeError:
253
sensor_data['temperatures'] = None
254
255
# Fan sensors
256
try:
257
fans = psutil.sensors_fans()
258
if fans:
259
sensor_data['fans'] = {}
260
for name, entries in fans.items():
261
sensor_data['fans'][name] = [
262
{
263
'label': entry.label,
264
'current': entry.current
265
}
266
for entry in entries
267
]
268
except AttributeError:
269
sensor_data['fans'] = None
270
271
# Battery
272
try:
273
battery = psutil.sensors_battery()
274
if battery:
275
sensor_data['battery'] = {
276
'percent': battery.percent,
277
'power_plugged': battery.power_plugged,
278
'secsleft': battery.secsleft
279
}
280
else:
281
sensor_data['battery'] = None
282
except AttributeError:
283
sensor_data['battery'] = None
284
285
return sensor_data
286
287
# Get all available sensor data
288
all_sensors = get_all_sensors()
289
```
290
{ .api }
291
292
### Sensor Alert System
293
294
```python
295
def check_sensor_alerts(temp_threshold=80, battery_threshold=20):
296
"""Check for sensor-based alerts."""
297
alerts = []
298
299
# Temperature alerts
300
try:
301
temperatures = psutil.sensors_temperatures()
302
if temperatures:
303
for sensor_name, entries in temperatures.items():
304
for entry in entries:
305
if entry.current > temp_threshold:
306
alerts.append(f"High temperature: {sensor_name} "
307
f"({entry.label or 'N/A'}) = {entry.current}°C")
308
309
if entry.critical and entry.current > entry.critical:
310
alerts.append(f"CRITICAL temperature: {sensor_name} "
311
f"({entry.label or 'N/A'}) = {entry.current}°C")
312
except AttributeError:
313
pass
314
315
# Battery alerts
316
try:
317
battery = psutil.sensors_battery()
318
if battery and not battery.power_plugged:
319
if battery.percent < battery_threshold:
320
alerts.append(f"Low battery: {battery.percent}% remaining")
321
322
if (battery.secsleft != psutil.POWER_TIME_UNKNOWN and
323
battery.secsleft != psutil.POWER_TIME_UNLIMITED and
324
battery.secsleft < 1800): # Less than 30 minutes
325
minutes = battery.secsleft // 60
326
alerts.append(f"Battery time low: {minutes} minutes remaining")
327
except AttributeError:
328
pass
329
330
return alerts
331
332
# Check for alerts
333
alerts = check_sensor_alerts()
334
for alert in alerts:
335
print(f"ALERT: {alert}")
336
```
337
{ .api }
338
339
## Error Handling and Fallbacks
340
341
### Robust Sensor Access
342
343
```python
344
def safe_get_sensors():
345
"""Safely get sensor information with proper error handling."""
346
result = {
347
'temperatures': None,
348
'fans': None,
349
'battery': None,
350
'errors': []
351
}
352
353
# Temperature sensors
354
try:
355
result['temperatures'] = psutil.sensors_temperatures()
356
except AttributeError:
357
result['errors'].append("Temperature sensors not supported")
358
except Exception as e:
359
result['errors'].append(f"Temperature sensor error: {e}")
360
361
# Fan sensors
362
try:
363
result['fans'] = psutil.sensors_fans()
364
except AttributeError:
365
result['errors'].append("Fan sensors not supported")
366
except Exception as e:
367
result['errors'].append(f"Fan sensor error: {e}")
368
369
# Battery
370
try:
371
result['battery'] = psutil.sensors_battery()
372
except AttributeError:
373
result['errors'].append("Battery information not supported")
374
except Exception as e:
375
result['errors'].append(f"Battery error: {e}")
376
377
return result
378
379
# Get sensors with error handling
380
sensor_info = safe_get_sensors()
381
```
382
{ .api }
383
384
## Performance Considerations
385
386
- Sensor readings can be relatively slow operations
387
- Cache sensor data when monitoring continuously
388
- Some sensors may require elevated privileges to access
389
- Platform support varies significantly - always check availability
390
- Hardware sensor availability depends on the specific system configuration
391
392
## Platform-Specific Notes
393
394
### Linux
395
- Requires lm-sensors package for most temperature sensors
396
- May need specific kernel modules loaded
397
- Access to /sys/class/hwmon/ filesystem
398
399
### Windows
400
- Limited sensor support compared to Linux
401
- Battery information generally available on laptops
402
- Temperature sensors may require third-party software
403
404
### macOS
405
- Battery information available on MacBooks
406
- Temperature sensor support varies by hardware
407
- May require additional permissions
408
409
## Related Documentation
410
411
- [System Information](system-info.md) - General system monitoring functions
412
- [Process Management](process.md) - Process-level resource monitoring
413
- [Constants](constants.md) - Sensor-related constants
414
- [Exceptions](exceptions.md) - Error handling for sensor operations