summaryrefslogtreecommitdiff
path: root/scripts/autofan.py
blob: 9183c36f91a8929eca6edd7f9ede8897cd53543a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import lgpio, re, os, subprocess, logging
from time import sleep
from pathlib import Path


def check_CPU_temp():
    t = 0
    err, msg = subprocess.getstatusoutput(
        "/usr/bin/zsh -c 'LD_LIBRARY_PATH=/opt/vc/lib /opt/vc/bin/vcgencmd measure_temp'"
    )
    if not err:
        m = re.search(r"-?\d\.?\d*", msg)  # a solution with a regex
        try:
            t = int(m.group())
        except ValueError:  # catch only error needed
            pass
    return t, msg


def HIGH_FLAG_callback(old, new):
    if new:
        lgpio.gpio_write(h, channel, 1)
        logger.info("Fan started.")
        Path(flag_file).touch()
        logger.debug(("Wrote flag: %s") % flag_file)
        logger.info(("Current %s") % msg)
    else:
        lgpio.gpio_write(h, channel, 0)
        logger.info("Fan stopped.")
        os.remove(flag_file)
        logger.debug(("Deleted flag: %s") % flag_file)
        logger.info(("Current %s") % msg)


class VariableListenedOnChange:
    def __init__(self, init_value):
        self._value = init_value
        self._callbacks = []

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, new_value):
        old_value = self._value
        self._value = new_value
        for callback in self._callbacks:
            callback(old_value, new_value)

    def register_callback(self, callback):
        self._callbacks.append(callback)


# Logger setup
logger = logging.getLogger()
logger.setLevel(level=logging.INFO)
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
streamHandler = logging.StreamHandler()
streamHandler.setLevel(logging.DEBUG)
streamHandler.setFormatter(formatter)
fileHandler = logging.FileHandler("/var/log/autofan.log", mode="w")
fileHandler.setLevel(logging.INFO)
fileHandler.setFormatter(formatter)
logger.addHandler(streamHandler)
logger.addHandler(fileHandler)

h = lgpio.gpiochip_open(0)
channel = 14
start_temp = 50
end_temp = 43
show_info = True
flag_file = "/usr/local/IS_HIGH_FLAG"
is_high = VariableListenedOnChange(False)
is_high.register_callback(HIGH_FLAG_callback)

if os.path.exists(flag_file):
    lgpio.gpio_write(h, channel, 0)
    logger.info("Got IS_HIGH_FLAG, stopping fan for now just in case.")
    os.remove(flag_file)

try:
    while True:
        temp = open("/sys/class/thermal/thermal_zone0/temp")
        temp = int(temp.read()) / 1000
        msg = "%.1f ℃" % temp
        # temp, msg = check_CPU_temp()

        if temp > start_temp and not is_high.value:  # 当SoC温度超过启动阈值且风扇处于关闭状态
            is_high.value = True
            show_info = True

        elif temp < end_temp and is_high.value:  # 当SoC温度低于关闭阈值且风扇处于打开状态
            is_high.value = False
            show_info = True

        elif show_info:
            logger.info("Nothing to do, Skipping now...")
            logger.info(("Current %s") % msg)
            show_info = False

        sleep(10)  # 每隔10秒监控一次

except:
    lgpio.gpiochip_close(h)
    logger.info("Controller Closed.")

lgpio.gpiochip_close(h)
logger.info("Controller Closed.")