Skip to content

Commit 3ce6c3b

Browse files
committed
add Thinkpad fan module
1 parent 1579d02 commit 3ce6c3b

5 files changed

Lines changed: 82 additions & 0 deletions

File tree

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ linux_platform_headers = \
204204
linux/ProcessField.h \
205205
linux/SELinuxMeter.h \
206206
linux/SystemdMeter.h \
207+
linux/ThinkpadFan.h \
207208
linux/ZramMeter.h \
208209
linux/ZramStats.h \
209210
linux/ZswapStats.h \
@@ -230,6 +231,7 @@ linux_platform_sources = \
230231
linux/PressureStallMeter.c \
231232
linux/SELinuxMeter.c \
232233
linux/SystemdMeter.c \
234+
linux/ThinkpadFan.c \
233235
linux/ZramMeter.c \
234236
zfs/ZfsArcMeter.c \
235237
zfs/ZfsCompressedArcMeter.c

linux/Platform.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ in the source distribution for its full text.
5656
#include "linux/OpenRCMeter.h"
5757
#include "linux/SELinuxMeter.h"
5858
#include "linux/SystemdMeter.h"
59+
#include "linux/ThinkpadFan.h"
5960
#include "linux/ZramMeter.h"
6061
#include "linux/ZramStats.h"
6162
#include "linux/ZswapStats.h"
@@ -277,6 +278,7 @@ const MeterClass* const Platform_meterTypes[] = {
277278
&OpenRCUserMeter_class,
278279
&FileDescriptorMeter_class,
279280
&GPUMeter_class,
281+
&ThinkpadFanMeter_class,
280282
NULL
281283
};
282284

@@ -991,6 +993,24 @@ void Platform_getBattery(double* percent, ACPresence* isOnAC) {
991993
Platform_Battery_cacheTime = now;
992994
}
993995

996+
int Platform_getThinkpadFan(void) {
997+
char fandata[256];
998+
ssize_t fanread = Compat_readfile(PROCDIR "/acpi/ibm/fan", fandata, sizeof(fandata));
999+
if (fanread < 1)
1000+
return -1;
1001+
1002+
const char* speed = strstr(fandata, "speed:");
1003+
if (!speed)
1004+
return -1;
1005+
1006+
int rpm;
1007+
int n = sscanf(speed, "speed: %d", &rpm);
1008+
if (n != 1)
1009+
return -1;
1010+
1011+
return rpm;
1012+
}
1013+
9941014
void Platform_longOptionsUsage(const char* name)
9951015
{
9961016
#ifdef HAVE_LIBCAP

linux/Platform.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ bool Platform_getNetworkIO(NetworkIOData* data);
9494

9595
void Platform_getBattery(double* percent, ACPresence* isOnAC);
9696

97+
int Platform_getThinkpadFan(void);
98+
9799
static inline void Platform_getHostname(char* buffer, size_t size) {
98100
Generic_hostname(buffer, size);
99101
}

linux/ThinkpadFan.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
htop - ThinkpadFan.c
3+
(C) 2026 Murad Karammaev
4+
Released under the GNU GPLv2+, see the COPYING file
5+
in the source distribution for its full text.
6+
*/
7+
8+
#include "config.h" // IWYU pragma: keep
9+
10+
#include "linux/ThinkpadFan.h"
11+
12+
#include "CRT.h"
13+
#include "Object.h"
14+
#include "linux/Platform.h"
15+
#include "XUtils.h"
16+
17+
static const int ThinkpadFanMeter_attributes[] = {
18+
METER_VALUE
19+
};
20+
21+
static void ThinkpadFanMeter_updateValues(Meter* this) {
22+
int fanspeed = Platform_getThinkpadFan();
23+
if (fanspeed < 0)
24+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "N/A");
25+
else
26+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%d RPM", fanspeed);
27+
}
28+
29+
const MeterClass ThinkpadFanMeter_class = {
30+
.super = {
31+
.extends = Class(Meter),
32+
.delete = Meter_delete
33+
},
34+
.updateValues = ThinkpadFanMeter_updateValues,
35+
.defaultMode = TEXT_METERMODE,
36+
.supportedModes = (1 << TEXT_METERMODE) | (1 << LED_METERMODE),
37+
.maxItems = 0,
38+
.total = 0.0,
39+
.attributes = ThinkpadFanMeter_attributes,
40+
.name = "ThinkpadFan",
41+
.uiName = "Thinkpad fan speed",
42+
.caption = "Thinkpad fan: ",
43+
};

linux/ThinkpadFan.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef HEADER_ThinkpadFan
2+
#define HEADER_ThinkpadFan
3+
/*
4+
htop - ThinkpadFan.h
5+
(C) 2026 Murad Karammaev
6+
Released under the GNU GPLv2+, see the COPYING file
7+
in the source distribution for its full text.
8+
*/
9+
10+
#include "Meter.h"
11+
12+
13+
extern const MeterClass ThinkpadFanMeter_class;
14+
15+
#endif

0 commit comments

Comments
 (0)