如何在2020款M1 MacBook Air上用Python读取电池温度并实现温控
解决方案
1. 读取M1 MacBook Air的电池温度
M1设备的电池温度数据可以通过系统原生的ioreg命令获取,Stats应用也是基于这个接口读取数据的。在Python中可以通过subprocess调用并解析输出:
import subprocess import re def get_battery_temperature(): # 调用ioreg获取电池温度数据(单位:0.01℃) result = subprocess.run( ["ioreg", "-r", "-c", "AppleSmartBattery"], capture_output=True, text=True ) # 匹配温度数值 temp_match = re.search(r'"BatteryTemperature" = (\d+)', result.stdout) if temp_match: # 转换为摄氏度 return int(temp_match.group(1)) / 100 return None
这个函数会返回电池的当前温度(比如返回44.5代表44.5℃),对应Stats里显示的电池综合温度。
2. 切换为电池供电(停止充电)
通过pmset命令可以控制Mac的充电行为,当温度超过阈值时,执行停止充电命令,系统会自动切换为电池供电:
def switch_to_battery_power(): # 停止充电,切换到电池供电 subprocess.run(["pmset", "-c", "stopcharging"], check=True)
注:该命令需要管理员权限运行,因此脚本执行时需要用
sudo,或者在系统设置中给终端赋予完全磁盘访问权限。
3. 降低主显示屏亮度50%
可以通过AppleScript调用系统事件调整屏幕亮度,无需额外安装工具:
def get_current_brightness(): result = subprocess.run( ["osascript", "-e", 'tell application "System Events" to get brightness of display 1'], capture_output=True, text=True ) return float(result.stdout.strip()) def lower_brightness_by_half(): current_brightness = get_current_brightness() new_brightness = max(0.1, current_brightness * 0.5) # 最低保留10%亮度,避免黑屏 subprocess.run( ["osascript", "-e", f'tell application "System Events" to set brightness of display 1 to {new_brightness}'], check=True )
如果不需要基于当前亮度减半,直接设置为最大亮度的50%,可以用更简单的版本:
def lower_brightness(): subprocess.run( ["osascript", "-e", 'tell application "System Events" to set brightness of display 1 to 0.5'], check=True )
4. 整合完整脚本
将上述功能整合为循环检测脚本,添加阈值判断和冷却机制避免频繁操作:
import time def main(): temp_threshold = 44.0 last_action_time = 0 cooldown_period = 300 # 5分钟冷却期,防止短时间内重复切换 while True: current_temp = get_battery_temperature() if current_temp is None: print("无法读取电池温度") time.sleep(60) continue print(f"当前电池温度: {current_temp}℃") current_time = time.time() if current_temp > temp_threshold and (current_time - last_action_time) > cooldown_period: print("温度超过阈值,切换为电池供电并降低亮度...") try: switch_to_battery_power() lower_brightness_by_half() last_action_time = current_time except subprocess.CalledProcessError as e: print(f"执行操作失败: {e}") time.sleep(30) # 每30秒检测一次 if __name__ == "__main__": main()
注意事项
- 脚本需要管理员权限运行,执行时输入
sudo python3 battery_temp_control.py。 - 若希望脚本开机自启,可以将其添加到LaunchDaemon,或用自动操作创建定时任务。
- 长期使用建议添加日志记录功能,方便排查问题。
内容的提问来源于stack exchange,提问作者riddhimanrana
相关产品推荐
相关产品推荐

