如何编写脚本来“监听”电池状态并在电量高于 60% 或低于 40% 时提醒我?

如何编写脚本来“监听”电池状态并在电量高于 60% 或低于 40% 时提醒我?

我想制作一个工具,当电池电量低于 40% 或高于 60% 时发出警报,以便我可以相应地开始/停止充电。

我知道有些工具会在电池电量低时发出警报,但这还不够。有没有一种工具可以在电池电量高时发出警报?

我想编写一个脚本(shell 或 python 都可以)来执行此操作。我知道检查 bat 状态的命令:

upower -i /org/freedesktop/UPower/devices/battery_BAT0

但不知道如何“监听”电池,以便每当电池状态发生变化时,我都可以自动执行操作。如果有文档链接就好了,如果有教程就更好了。

答案1

如果我理解正确的话,你应该每隔 X 个时间间隔检查一次电池状态。最简单的方法是在后台运行,在 while 循环内:

while true
 do
    # Any script or command
    sleep [number of seconds]
 done

如果您想在启动时运行该脚本,然后每 5 分钟运行一次,那么构造方法如下:

  • 添加一行/etc/rc.local来调用你的脚本(你的battery_status.sh)+“&”使其退出。
  • battery_status.sh添加您想要在while 循环中执行的命令(在 battery_status.sh 内)。

请注意,如果你想从计划任务,您需要设置完整路径,因为cron它使用有限的环境变量运行。

例子

#!/bin/bash
while true
do
    battery_level=`acpi -b | grep -P -o '[0-9]+(?=%)'`
    if [ $battery_level -ge 60 ]; then
       notify-send "Battery is above 60%!" "Charging: ${battery_level}%"    
    elif [ $battery_level -le 40 ]; then
       notify-send "Battery is lower 40%!" "Charging: ${battery_level}%"    
    fi

    sleep 300 # 300 seconds or 5 minutes
done

将此文件保存battery_status.sh在您最喜欢的位置(我的是home目录)并在文件中添加此行/etc/rc.local(在我的示例中,只需将您的 battery_status.sh 位置替换为/home/username/):

sh /home/username/battery_status.sh &

就这样。重启并见证奇迹。

如果你没有 instell acpi,只需使用sudo apt-get install acpi

奖金

如果您想让此脚本对交流适配器负责,则不需要额外的变量来检查该脚本是否运行一次。如果您的交流适配器已插入且电池电量超过 60%,它会发出警报“拔下您的适配器!”,直到您不拔下它。如果警报告诉您

                             在此处输入图片描述

只需拔掉交流适配器,然后您就会看到消息警报不会再次出现,直到您的电池电量降至 40%。然后另一条消息警报会告诉您

                             在此处输入图片描述

如果您在电量超过 60% 时没有拔下交流适配器,或者在电量低于 40% 时没有插入交流适配器,则每 5 分钟会显示一次警报消息(您可以在代码中自行调整,请参阅sleep [seconds])并提醒您。

 #!/bin/bash

    while true
    do
        export DISPLAY=:0.0
        battery_level=`acpi -b | grep -P -o '[0-9]+(?=%)'`
        if on_ac_power; then
            if [ $battery_level -ge 60 ]; then
                notify-send "Battery charging above 60%. Please unplug your AC adapter!" "Charging: ${battery_level}% "
                sleep 20
                if on_ac_power; then
                    gnome-screensaver-command -l   ## lock the screen if you don't unplug AC adapter after 20 seconds
                fi
             fi
        else
             if [ $battery_level -le 40 ]; then
                notify-send "Battery is lower 40%. Need to charging! Please plug your AC adapter." "Charging: ${battery_level}%"
                sleep 20
                if ! on_ac_power; then
                    gnome-screensaver-command -l   ## lock the screen if you don't plug AC adapter after 20 seconds
                fi
             fi
        fi
    
        sleep 300 # 300 seconds or 5 minutes
    done

答案2

你不能写教程来创建脚本。这类似于一般的 Python 教程,您可以在网络上的许多地方找到它。

我所做的就是编写一个小脚本,并附上注释来解释我所做的事情,每 10 秒检查一次电池电量。这可能有点过头了。更改行time.sleep(10)以设置间隔(以秒为单位)。当然可以更改命令,我让它按原样发送通知。

在此处输入图片描述

我让它运行消息,或者您给它的任何命令,每个事件只运行一次,因此,例如,如果电量超过 80%,则该命令只运行一次,直到下一次超过定义的值。

如何使用

该脚本旨在在后台运行;将其复制到一个空文件中,保存为check_battery.py可执行文件并使其在登录时运行:Dash > 启动应用程序 > 添加,添加命令:

/path/to/check_battery.py

剧本

#!/usr/bin/env python3

import subprocess
import time

def read_status():
    """
    This function reads the output of your command, finds the line with
    'percentage' (line 17, where first line = 0) and reads the figure
    """
    command = "upower -i $(upower -e | grep BAT) | grep --color=never -E percentage|xargs|cut -d' ' -f2|sed s/%//"
    get_batterydata = subprocess.Popen(["/bin/bash", "-c", command], stdout=subprocess.PIPE)
    return get_batterydata.communicate()[0].decode("utf-8").replace("\n", "")

def take_action():
    """
    When the charge is over 60% or below 40%, I assume the action does
    not have to be repeated every 10 seconds. As it is, it only runs
    1 time if charge exceeds the values. Then only if it exceeds the
    limit again.
    """
    # the two commands to run if charged over 80% or below 60%
    command_above = "notify-send 'charged over 80'%"
    command_below = "notify-send 'charged below 80%'"
    times = 0
    while True:
        charge = int(read_status())
        if charge > 60:
            if times == 0:
                subprocess.Popen(["/bin/bash", "-c", command_above])
                times = 1
        elif charge < 40:
            if times == 0:
                subprocess.Popen(["/bin/bash", "-c", command_below])
                times = 1
        else:
            times = 0
        time.sleep(10)

take_action()

相关内容