用于在MacOS中电池电量低于阈值时播放警告的脚本 [英] Script to play a warning when battery level is under a threshold in MacOS

查看:57
本文介绍了用于在MacOS中电池电量低于阈值时播放警告的脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是MacBook,电池不稳定。我正在尝试找到一个脚本命令,可以使笔记本电脑在电池电量低于阈值时发出嘟嘟声。经过一番搜索和测试,我找到了下面的快速解决方案:

1)我首先创建了一个名为check_Batch的文件,内容如下:

ioreg -l | awk '$3~/Capacity/{c[$3]=$5}END{OFMT="%.3f";max=c[""MaxCapacity""]; bat= (max>0?100*c[""CurrentCapacity""]/max:"?"); printf("%d", bat)}'

2)然后我创建了以下文件:

#!/bin/bash
sh check_battery>battery;
let t=60
read a < battery
if(( "$a" < "$t" ));
  then
  say "Battery level is lower than 60%!";
  say "BEAP BEAP"
fi;
3)最后,我尝试将其添加到我的crontab作业中,但crontab已被iOS停止。然后我发现我必须使用Launchd,具体如下: https://alvinalexander.com/mac-os-x/mac-osx-startup-crontab-launchd-jobs

它现在可以在我的MacBook Labtop上运行,但可能会有更好的解决方案。如果您有其他解决方案,请与我分享。非常感谢。

推荐答案

我认为您的脚本本身就是一个很好的脚本,但是在定期运行时可能会非常耗费资源,因为它调用一个外壳进程和两个程序来获取您需要的信息。

在这种情况下,我认为AppleScript具有shell脚本的几个优点,这在很大程度上要归功于osascript,它是运行AppleScript需要执行的唯一程序,而且它无需创建shell进程就可以做到这一点。

用于检索电池信息的AppleScript

这里有一个这样的脚本,它可以检索有关计算机电池的信息,并在适当的时间发出警告:

property threshold : 20 -- The level below which the script issues warnings
property verbose : false -- Report current battery level on every run
property file : "/tmp/battery.log" -- The path to the log file (from plist)


set eof of my file to 0

tell the battery()
    set warning_level to the warningLevel()
    if the warning_level = 1 then return check()
    warn about (warning_level - 1) * 5 with alert
end tell

# warn
#   Sends out a visible and audible warning with information about the
#   remaining charge (+level) on the battery.  Invoke without alert to have
#   the +level reported in the notification centre as a percentage.  Invoke 
#   with alert to have the +level reported in a pop-up alert dialog as an
#   estimation of the remaining battery time (in minutes), and which must be
#   dismissed by the user.
to warn about level without alert
    if not alert then display notification ¬
        ["Current battery level: ", level, "%"] as text ¬
        with title ["⚠️ Battery Warning"] sound name "Basso"

    say "Warning: battery low" using "Moira" pitch 127 ¬
        speaking rate 180 without waiting until completion

    if alert then display alert ["Warning: battery level is very low"] ¬
        message ["Estimated time remaining: " & level & " minutes"] ¬
        as critical giving up after 0
end warn

# battery()
#   Contains a script object that defines a number of convenience handlers that
#   retrieve information about the on-board power source
on battery()
    script
        use framework "IOKit"
        use scripting additions
        property warninglevels : ["None", "Early", "Final"]

        on warningLevel() -- A ten-minute warning indicator
            IOPSGetBatteryWarningLevel() of the current application
        end warningLevel

        on info()
            IOPSCopyPowerSourcesInfo() of the current application ¬
                as record
        end info

        to check()
            copy [it, |current capacity|, |is charging|] of ¬
                info() to [ps_info, percentage, charging]

            if the percentage ≤ threshold ¬
                and it is not charging ¬
                then warn about percentage ¬
                without alert

            if verbose then return display notification [¬
                "Percentage: ", percentage, linefeed, ¬
                "Charging: ", charging] as text ¬
                with title ["🔋 Battery Information"]

            ["Script last run on ", current date, linefeed, ¬
                linefeed, __string(ps_info), linefeed] as text
        end check
    end script
end battery

# __string()
#   A that will return an AppleScript record as a formatted string, modified
#   specifically for use in this script, therefore may not port very well to
#   handle other records from other scripts
to __string(obj)
    if class of obj = text then return obj

    try
        set E to {_:obj} as text
    on error E
        my tid:{null, "Can’t make {_:", ¬
            "} into type text.", ¬
            "{", "}", "|"}
        set E to E's text items as text
        my tid:{linefeed, ", "}
        set E to E's text items as text
    end try
end __string

# tid:
#   Set the text item delimiters
on tid:(d as list)
    local d

    if d = {} or d = {0} then set d to ""
    set my text item delimiters to d
end tid:

它最值得注意的是检索当前电池剩余电量百分比,以及电池当前是否正在充电。

脚本顶部有三个属性,您可以根据自己的喜好安全地进行更改。在verbose模式下,每次运行脚本时都会报告电池百分比和充电状态。如果您按分钟运行该脚本,这可能会令人恼火,因此默认情况下将其设置为false

但是,当电池电量低于threshold时,通知中心会发出通知,并发出舒缓的苏格兰音调,提示您面糊电量不足。

如果电池电量严重不足,您将收到一条弹出警报,提示您必须自行关闭电源。

该脚本还返回一系列有关电池的其他信息,一般来说,您不会看到这些信息。但是,如果脚本由launchdplist执行,则返回的信息将记录在日志文件中,您可以在空闲时检查该文件。

launchd

launchd提供了一种很好的、相当经济高效的定期运行脚本的方法,并且比创建用于轮询数据的保持打开应用程序要好得多(这效率极低,但在其他方案中也有其用途)。

您已经找到了一个很好的链接来描述编写.plist文件的基础知识以及如何保存它,然后调用(启动)它。我将在这里总结一下要点:

  1. 创建如下所示的.plist

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
            <key>Disabled</key>
            <false/>
            <key>Label</key>
            <string>local.battery</string>
            <key>ProgramArguments</key>
            <array>
                    <string>/usr/bin/osascript</string>
                    <string>/Users/CK/Documents/Scripts/AppleScript/scripts/Battery.applescript</string>
            </array>
            <key>RunAtLoad</key>
            <true/>
            <key>StartInterval</key>
            <integer>60</integer>
            <key>StandardErrorPath</key>
            <string>/tmp/battery.err</string>
            <key>StandardOutPath</key>
            <string>/tmp/battery.log</string>
    </dict>
    </plist>
    
    使用与Label项下的<string>条目匹配的文件名保存它。在本例中,我将我的保存为local.battery.plist。我还将AppleScript保存在plist中指定的路径。在我的实验中,我很惊讶launchd不喜欢路径中有任何空格(即使转义),或者如果我使用波浪号(~)作为我的主目录的缩写。因此,我将AppleScript保存为简单的Battery.applescript,并提供了放置它的完整路径。

    StartInterval是您可以指定脚本应该运行的间隔(以秒为单位)的位置。就我个人而言,我认为60秒有点过头了,但我把它设在那里是为了测试。实际上,我可能会选择将其设置为600(10分钟)左右,但您可以判断什么是最适合您的。

    末尾的两个/tmp/路径分别是写入错误和返回值的位置。如果更改日志文件的路径,请不要忘记更新AppleScript中的file属性。

  2. 将plist保存或移动到目录~/Library/LaunchAgents/

  3. 从终端使用以下shell命令加载:

    launchctl load ~/Library/LaunchAgents/local.battery.plist
    
  4. 如果稍后您对.plist.applescript进行了任何更改,请记住卸载,然后使用launchctl重新加载:

    launchctl unload ~/Library/LaunchAgents/local.battery.plist
    launchctl load ~/Library/LaunchAgents/local.battery.plist
    

.plist成功加载到launchd后,应立即运行AppleScript,并将返回的数据写入日志文件。以下是输出到我的/tmp/battery.log文件的内容:

Script last run on Tuesday, 1 January 2019 at 22:01:52

is present:true
is charged:true
power source state:"AC Power"
Current:0
max capacity:100
DesignCycleCount:1000
current capacity:100
name:"InternalBattery-0"
battery provides time remaining:true
is charging:false
hardware serial number:"D8663230496GLLHBJ"
transport type:"Internal"
time to empty:0
power source id:4391011
Type:"InternalBattery"
BatteryHealth:"Check Battery"
time to full charge:0

结账思路

电池信息第一次非常有趣,但对于大多数用例来说可能是相当多余的。(也就是说,我刚刚注意到它建议我在BatteryHealth"Check Battery",所以我现在很高兴我提取了额外的数据)。

不管怎样,如果您认为自己不需要额外的数据,我已经看到user3439894留下的注释,它提供了一种非常好、简洁和简单的方式来检索关于电池的更重要的信息,即电池的百分比水平和是否正在充电。可以说,这可能是比我的objc方法更合适的AppleScriiting解决方案,我的objc方法会带来很小的开销,而且脚本要短得多。

目前,我坚持使用我的电池,因为我显然有电池健康问题,可能应该解决这个问题。

这篇关于用于在MacOS中电池电量低于阈值时播放警告的脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆