3 files changed, 100 insertions(+), 0 deletions(-)

A => README.md
A => macfan.py
A => macfan.sh
A => README.md +13 -0
@@ 0,0 1,13 @@ 
+# MacBook Fan Control for Linux
+
+> note: This is just a simple stupid one, read the source, Luke.
+
+Clone this repo to `/opt/macfan`, and then just put a single line below
+in your `rc.local`.
+
+```bash
+/opt/macfan/macfan.sh
+```
+
+Please also adjust values at the head of `macfan.py` to suite your environment.
+

          
A => macfan.py +82 -0
@@ 0,0 1,82 @@ 
+#!/usr/bin/env python3
+
+from glob import glob
+from os.path import basename, join
+from statistics import mean
+
+
+SPEED_MIN = 2000
+Tavr_MIN = 35
+Tavr_MAX = 45
+Tcpu_LABEL = 'TC0P'
+Tcpu_MIN = 38
+Tcpu_MAX = 55
+
+SMC_PATH='/sys/devices/platform/applesmc.768'
+
+
+def read_sensors():
+    sensors = {}
+    label_files = glob(join(SMC_PATH, 'temp*_label'))
+    for label_file in label_files:
+        label = open(label_file, 'r').read().strip()
+        temp = open(label_file.replace('label', 'input'), 'r').read().strip()
+        temp = int(temp)/1000
+        if temp > 0:
+            sensors[label] = temp
+    sensors['Tavr'] = mean(sensors.values())
+    return sensors
+
+
+def list_fans():
+    fan_files = glob(join(SMC_PATH, 'fan*'))
+    fans = set([basename(fan_file).split('_')[0] for fan_file in fan_files])
+    return list(fans)
+
+
+def set_fan(fan, percent, speed_min):
+    speed_max = int(open(join(SMC_PATH, f'{fan}_max'), 'r').read())
+    speed = int(speed_min + (((speed_max - speed_min) * percent) / 100))
+    with open(join(SMC_PATH, f'{fan}_manual'), 'w') as manual:
+        manual.write('1')
+    with open(join(SMC_PATH, f'{fan}_output'), 'w') as fan_output:
+        fan_output.write(f'{speed}')
+
+
+if __name__ == '__main__':
+    sensors = read_sensors()
+
+    temp_cpu = sensors[Tcpu_LABEL]
+    temp_cpu_percent = 100 * (temp_cpu - Tcpu_MIN) / (Tcpu_MAX - Tcpu_MIN)
+    if temp_cpu_percent > 100:
+        temp_cpu_percent = 100
+    elif temp_cpu_percent < 0:
+        temp_cpu_percent = 0
+    
+    temp_avr = sensors['Tavr']
+    temp_avr_percent = 100 * (temp_avr - Tavr_MIN) / (Tavr_MAX - Tavr_MIN)
+    if temp_avr_percent > 100:
+        temp_avr_percent = 100
+    elif temp_avr_percent < 0:
+        temp_avr_percent = 0
+ 
+    percent_adjust = max(temp_cpu_percent, temp_avr_percent)
+
+
+    print(f'CPU Temp '
+          f'Min: {Tcpu_MIN:.2f} '
+          f'Max: {Tcpu_MAX:.2f} '
+          f'Now: {temp_cpu:.2f} '
+          f'({temp_cpu_percent:.2f}%)')
+
+    print(f'Avr Temp '
+          f'Min: {Tavr_MIN:.2f} '
+          f'Max: {Tavr_MAX:.2f} '
+          f'Now: {temp_avr:.2f} '
+          f'({temp_avr_percent:.2f}%)')
+
+    print(f'Adjust Fan Speed: {percent_adjust:.2f}%')
+
+    for fan in list_fans():
+        set_fan(fan, percent_adjust, SPEED_MIN)
+

          
A => macfan.sh +5 -0
@@ 0,0 1,5 @@ 
+#!/bin/bash
+
+tmux new-session -d -s macfan 'watch /opt/macfan/macfan.py'
+
+exit 0