Hello Hello..! Good to see you here!
If you’ve been following my earlier experiments, you might remember how I used my old laptop to run pihole over my home network and configured it to run DoT, months back the same laptop started overheating.
Laptop in question : MSI GF65 Thin9SEXR, i7 9th gen 12 Core Processor. Unfortunately, MSI does not have a linux fan control utility, Like most of the OEMs. Thanks to the tool OpenFreezeCenter by Aditya Kumar Bajpai managing fan speeds under Linux has been just as easy as on Windows—at least until the fan started giving up.
II’ve been using OpenFreezeCenter since day one, and it never let me down. Unfortunately, the same can’t be said for the physical fans. Over time, they began to run slower and less effectively. Both CPU and GPU temperatures began hitting 90°C+. No, don’t blame Pi-hole—it’s built to run on something as lightweight as a Raspberry Pi. The real load came from everything else:
- Jenkins
- Grafana
- Ollama running DeepSeek server (for my VSCode plugin—article coming soon!)
- Cloudflared
- Docker containers
- …and whatever else I felt like experimenting with.
- And all the 100+ Abandoned projects ( Some projects have been abandoned for so long that I cannot recognize them myself)
So yeah—temps above 70°C were expected. And normally, OpenFreezeCenter should’ve been able to manage that. But with the fans seemingly losing strength, the temps weren’t staying in check. I tried it all—laptop coolers, DC fans, thermal repaste, and more. The results? Minor improvements, nothing consistent.
Then Came the Jugaad Moment
While browsing online, I stumbled upon lightweight drone motors with attached propellers. A thought struck me:
“Why not reverse the polarity, flip the propellers, and turn them into a high-speed laptop cooler?”
Laptop started cooling down instantly.
There was a downside, The fans were as loud as much to ruin my sleep.
I already had a Pi Pico and a relay lying around, So thought why shouldn’t I use the OpenFreezeCenter as my temperature library and automate the fan so that the drone motor runs only when the temperature reaches certain threshold and turned OFF on lower limit?
What I Did:
/dev/ttyACM0Monitored CPU temp using Prometheus and controlled fan operation via a Python script on Linux. (Because why not?)
Result?
A cool, quiet, and controlled setup where the fan runs only when needed, saving power, reducing noise, and keeping temps under check—even with the kind of load this laptop endures.
Final Thoughts
This is far from a polished product. But as a DIY solution, it’s cheap, practical, and super fun. If you’re someone who likes hacking hardware or giving a second life to old laptops, this might just be for you.
System Overview
Prometheus → Linux Script (Fan Logic + Mode Control)
↓
Serial (/dev/ttyACM0)
↓
Pi Pico → Relay → Drone Motor
wget https://github.com/prometheus/node_exporter/releases/latest/download/node_exporter-linux-amd64.tar.gz
tar -xvf node_exporter-linux-amd64.tar.gz
cd node_exporter-*
./node_exporter
scrape_configs:
- job_name: "node"
static_configs:
- targets: ["localhost:9100"]
3. Test: Visit http://localhost:9090 → Query:
node_hwmon_temp_celsius{chip="platform_coretemp_0"}
Code
1.cpu_temp_motor_control.py
import requests
import time
import serial
import os
PROMETHEUS_URL = "http://localhost:9090/api/v1/query"
SERIAL_PORT = "/dev/ttyACM0"
BAUD_RATE = 9600
PATH_TO_CONF = "/home/kuvi41/Documents/ofc/conf.txt"
def get_cpu_temp():
query = 'max(node_hwmon_temp_celsius{job="node", chip="platform_coretemp_0"})'
try:
response = requests.get(PROMETHEUS_URL, params={'query': query})
result = response.json()
value = float(result['data']['result'][0]['value'][1])
return value
except Exception as e:
print("Failed to get temperature:", e)
return None
def set_mode(mode):
if not os.path.exists(PATH_TO_CONF):
print("conf.txt not found")
return
with open(PATH_TO_CONF, "r") as f:
lines = f.readlines()
if mode == "normal":
lines[0] = "2\n"
lines[1] = "0\n"
elif mode == "cooler_booster":
lines[0] = "4\n"
with open(PATH_TO_CONF, "w") as f:
f.writelines(lines)
os.system("sudo python3 /home/kuvi41/Documents/ofc/write_EC.py")
def main():
try:
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
print(f"Serial connected on {SERIAL_PORT}")
except Exception as e:
print("Failed to open serial port:", e)
return
fan_state = None
mode_state = None
while True:
temp = get_cpu_temp()
if temp is not None:
print(f"CPU Temp: {temp} °C")
if temp > 95 and fan_state != "ON":
ser.write(b"ON\n")
print("Sent ON to Pi")
fan_state = "ON"
elif temp < 75 and fan_state != "OFF":
ser.write(b"OFF\n")
print("Sent OFF to Pi")
fan_state = "OFF"
if temp > 85 and mode_state != "cooler_booster":
set_mode("cooler_booster")
print("Switched to Cooler Booster")
mode_state = "cooler_booster"
elif temp < 76 and mode_state != "normal":
set_mode("normal")
print("Switched to Normal Mode")
mode_state = "normal"
time.sleep(5)
if __name__ == "__main__":
main()
2.main.py (pi Pico)
from machine import Pin
import time
import sys
relay = Pin(15, Pin.OUT)
relay.value(0)
def readline():
line = b""
while True:
c = sys.stdin.buffer.read(1)
if c == b"\n":
break
line += c
return line.decode('utf-8').strip()
while True:
cmd = readline()
print("Received:", cmd)
if cmd == "ON":
relay.value(1)
elif cmd == "OFF":
relay.value(0)
Stay tuned for my next post on how I integrated DeepSeek with LLaMA into my dev workflow!
